From 527bb0459cf488e5021696e326dc10d28ecdd74c Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 24 May 2012 02:18:20 -0400 Subject: Trying to get stuff working under new structure --- wqflask/base/GeneralObject.py | 71 ++ wqflask/base/JinjaPage.py | 28 + wqflask/base/__init__.py | 0 wqflask/base/admin.py | 88 ++ wqflask/base/cgiData.py | 70 ++ wqflask/base/cookieData.py | 52 + wqflask/base/footer.py | 6 + wqflask/base/header.py | 6 + wqflask/base/indexBody.py | 290 +++++ wqflask/base/myCookie.py | 55 + wqflask/base/sessionData.py | 53 + wqflask/base/template.py | 123 ++ wqflask/base/templatePage.py | 222 ++++ wqflask/base/webqtlCaseData.py | 54 + wqflask/base/webqtlConfig.py | 73 ++ wqflask/base/webqtlConfigLocal.py | 19 + wqflask/base/webqtlDataset.py | 160 +++ wqflask/base/webqtlFormData.py | 289 +++++ wqflask/base/webqtlTrait.py | 581 ++++++++++ wqflask/dbFunction/__init__.py | 0 wqflask/dbFunction/webqtlDatabaseFunction.py | 265 +++++ wqflask/htmlgen.py | 14 + wqflask/requirements.txt | 6 + wqflask/runserver.py | 15 + wqflask/utility/AJAX_table.py | 153 +++ wqflask/utility/Plot.py | 1283 ++++++++++++++++++++ wqflask/utility/TDCell.py | 42 + wqflask/utility/THCell.py | 44 + wqflask/utility/__init__.py | 0 wqflask/utility/formatting.py | 109 ++ wqflask/utility/svg.py | 1069 +++++++++++++++++ wqflask/utility/webqtlUtil.py | 977 ++++++++++++++++ wqflask/wqflask/__init__.py | 13 + wqflask/wqflask/search_results.py | 1288 +++++++++++++++++++++ wqflask/wqflask/static/css | 1 + wqflask/wqflask/static/images | 1 + wqflask/wqflask/static/javascript | 1 + wqflask/wqflask/templates/base.html | 215 ++++ wqflask/wqflask/templates/index_page.html | 313 +++++ wqflask/wqflask/templates/search_result_page.html | 203 ++++ wqflask/wqflask/views.py | 23 + 41 files changed, 8275 insertions(+) create mode 100755 wqflask/base/GeneralObject.py create mode 100644 wqflask/base/JinjaPage.py create mode 100755 wqflask/base/__init__.py create mode 100755 wqflask/base/admin.py create mode 100755 wqflask/base/cgiData.py create mode 100755 wqflask/base/cookieData.py create mode 100755 wqflask/base/footer.py create mode 100755 wqflask/base/header.py create mode 100755 wqflask/base/indexBody.py create mode 100755 wqflask/base/myCookie.py create mode 100755 wqflask/base/sessionData.py create mode 100755 wqflask/base/template.py create mode 100755 wqflask/base/templatePage.py create mode 100755 wqflask/base/webqtlCaseData.py create mode 100755 wqflask/base/webqtlConfig.py create mode 100755 wqflask/base/webqtlConfigLocal.py create mode 100755 wqflask/base/webqtlDataset.py create mode 100755 wqflask/base/webqtlFormData.py create mode 100755 wqflask/base/webqtlTrait.py create mode 100755 wqflask/dbFunction/__init__.py create mode 100755 wqflask/dbFunction/webqtlDatabaseFunction.py create mode 100644 wqflask/htmlgen.py create mode 100644 wqflask/requirements.txt create mode 100644 wqflask/runserver.py create mode 100755 wqflask/utility/AJAX_table.py create mode 100755 wqflask/utility/Plot.py create mode 100755 wqflask/utility/TDCell.py create mode 100755 wqflask/utility/THCell.py create mode 100755 wqflask/utility/__init__.py create mode 100644 wqflask/utility/formatting.py create mode 100755 wqflask/utility/svg.py create mode 100755 wqflask/utility/webqtlUtil.py create mode 100644 wqflask/wqflask/__init__.py create mode 100644 wqflask/wqflask/search_results.py create mode 120000 wqflask/wqflask/static/css create mode 120000 wqflask/wqflask/static/images create mode 120000 wqflask/wqflask/static/javascript create mode 100644 wqflask/wqflask/templates/base.html create mode 100644 wqflask/wqflask/templates/index_page.html create mode 100644 wqflask/wqflask/templates/search_result_page.html create mode 100644 wqflask/wqflask/views.py diff --git a/wqflask/base/GeneralObject.py b/wqflask/base/GeneralObject.py new file mode 100755 index 00000000..311c9e22 --- /dev/null +++ b/wqflask/base/GeneralObject.py @@ -0,0 +1,71 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +class GeneralObject: + """ + Base class to define an Object. + a = [Spam(1, 4), Spam(9, 3), Spam(4,6)] + a.sort(lambda x, y: cmp(x.eggs, y.eggs)) + """ + + def __init__(self, *args, **kw): + self.contents = list(args) + for name, value in kw.items(): + setattr(self, name, value) + + def __setitem__(self, key, value): + setattr(self, key, value) + + def __getitem__(self, key): + return getattr(self, key) + + def __getattr__(self, key): + if key in self.__dict__.keys(): + return self.__dict__[key] + else: + return eval("self.__dict__.%s" % key) + + def __len__(self): + return len(self.__dict__) - 1 + + def __str__(self): + s = '' + for key in self.__dict__.keys(): + if key != 'contents': + s += '%s = %s\n' % (key,self.__dict__[key]) + return s + + def __repr__(self): + s = '' + for key in self.__dict__.keys(): + s += '%s = %s\n' % (key,self.__dict__[key]) + return s + + def __cmp__(self,other): + return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys())) + + + diff --git a/wqflask/base/JinjaPage.py b/wqflask/base/JinjaPage.py new file mode 100644 index 00000000..07e485b1 --- /dev/null +++ b/wqflask/base/JinjaPage.py @@ -0,0 +1,28 @@ +import logging +logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) +_log = logging.getLogger("search") + +from pprint import pformat as pf + +import templatePage + +from utility import formatting + +import jinja2 +JinjaEnv = jinja2.Environment(loader=jinja2.FileSystemLoader('/gnshare/gn/web/webqtl/templates')) +JinjaEnv.globals['numify'] = formatting.numify + + +class JinjaPage(templatePage.templatePage): + """Class derived from our regular templatePage, but uses Jinja2 instead. + + When converting pages from Python generated templates, change the base class from templatePage + to JinjaPage + + """ + + + def write(self): + """We override the base template write so we can use Jinja2.""" + _log.info(pf(self.__dict__)) + return self.jtemplate.render(**self.__dict__) diff --git a/wqflask/base/__init__.py b/wqflask/base/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/base/admin.py b/wqflask/base/admin.py new file mode 100755 index 00000000..a04df2da --- /dev/null +++ b/wqflask/base/admin.py @@ -0,0 +1,88 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + + + + + +#XZ, 04/02/2009: we should put this into database. + + +###LIST of databases used into gene name query + + +ADMIN_search_dbs = { + 'rat': {'PERITONEAL FAT': ['FT_2A_0605_Rz'], + 'KIDNEY': ['KI_2A_0405_Rz'], + 'ADRENAL GLAND': ['HXB_Adrenal_1208'], + 'HEART': ['HXB_Heart_1208'] + }, + 'mouse': {'CEREBELLUM': ['CB_M_0305_R'], + 'STRIATUM': ['SA_M2_0905_R', 'SA_M2_0405_RC', 'UTHSC_1107_RankInv', 'Striatum_Exon_0209'], + 'HIPPOCAMPUS': ['HC_M2_0606_R', 'UMUTAffyExon_0209_RMA'], + 'WHOLE BRAIN': ['BR_M2_1106_R', 'IBR_M_0106_R', 'BRF2_M_0805_R', 'UCLA_BHF2_BRAIN_0605'], + 'LIVER': ['LV_G_0106_B', 'UCLA_BHF2_LIVER_0605'], + 'EYE': ['Eye_M2_0908_R'], + 'HEMATOPOIETIC STEM CELLS': ['HC_U_0304_R'], + 'KIDNEY': ['MA_M2_0806_R'], + 'MAMMARY TUMORS': ['MA_M_0704_R', 'NCI_Agil_Mam_Tum_RMA_0409'], + 'PREFRONTAL CORTEX': ['VCUSal_1206_R'], + 'SPLEEN': ['IoP_SPL_RMA_0509'], + 'NUCLEUS ACCUMBENS': ['VCUSalo_1007_R'], + 'NEOCORTEX': ['HQFNeoc_0208_RankInv'], + 'ADIPOSE': ['UCLA_BHF2_ADIPOSE_0605'], + 'RETINA': ['Illum_Retina_BXD_RankInv0410'] + }, + 'human': { + 'LYMPHOBLAST B CELL': ['Human_1008', 'UT_CEPH_RankInv0909'], + 'WHOLE BRAIN': ['GSE5281_F_RMA0709', 'GSE15222_F_RI_0409'] + } + } + + +###LIST of tissue alias + +ADMIN_tissue_alias = {'CEREBELLUM': ['Cb'], + 'STRIATUM': ['Str'], + 'HIPPOCAMPUS': ['Hip'], + 'WHOLE BRAIN': ['Brn'], + 'LIVER': ['Liv'], + 'EYE': ['Eye'], + 'PERITONEAL FAT': ['Fat'], + 'HEMATOPOIETIC STEM CELLS': ['Hsc'], + 'KIDNEY': ['Kid'], + 'ADRENAL GLAND': ['Adr'], + 'HEART': ['Hea'], + 'MAMMARY TUMORS': ['Mam'], + 'PREFRONTAL CORTEX': ['Pfc'], + 'SPLEEN': ['Spl'], + 'NUCLEUS ACCUMBENS': ['Nac'], + 'NEOCORTEX': ['Ctx'], + 'ADIPOSE': ['Wfat'], + 'RETINA': ['Ret'] + } + + diff --git a/wqflask/base/cgiData.py b/wqflask/base/cgiData.py new file mode 100755 index 00000000..57416060 --- /dev/null +++ b/wqflask/base/cgiData.py @@ -0,0 +1,70 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +######################################### +#convert Field storage object to Dict object +#in order to be able to saved into a session file +######################################### + +class cgiData(dict): + '''convert Field storage object to Dict object + Filed storage object cannot be properly dumped + ''' + + def __init__(self, field_storage=None): + + if not field_storage: + field_storage={} + + for key in field_storage.keys(): + temp = field_storage.getlist(key) + if len(temp) > 1: + temp = map(self.toValue, temp) + elif len(temp) == 1: + temp = self.toValue(temp[0]) + else: + temp = None + self[key]= temp + + def toValue(self, obj): + '''fieldstorge returns different type of objects, \ + need to convert to string or None''' + try: + return obj.value + except: + return "" + + def getvalue(self, k, default= None): + try: + return self[k] + except: + return default + + getfirst = getvalue + + + + diff --git a/wqflask/base/cookieData.py b/wqflask/base/cookieData.py new file mode 100755 index 00000000..4b7c9046 --- /dev/null +++ b/wqflask/base/cookieData.py @@ -0,0 +1,52 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +######################################### +#convert mod_python object to Dict object +#in order to be able to be pickled +######################################### + +class cookieData(dict): + 'convert mod python Cookie object to Dict object' + + def __init__(self, cookies=None): + + if not cookies: + cookies={} + + for key in cookies.keys(): + self[key.lower()]= cookies[key].value + + def getvalue(self, k, default= None): + try: + return self[k.lower()] + except: + return default + + getfirst = getvalue + + + diff --git a/wqflask/base/footer.py b/wqflask/base/footer.py new file mode 100755 index 00000000..6f92fdf8 --- /dev/null +++ b/wqflask/base/footer.py @@ -0,0 +1,6 @@ +import webqtlConfig + +footer_html = open(webqtlConfig.HTMLPATH + 'footer.html', 'r').read() +footer = footer_html.replace('%"','%%"') + +footer_string = footer.replace('', '%s') diff --git a/wqflask/base/header.py b/wqflask/base/header.py new file mode 100755 index 00000000..b6136b51 --- /dev/null +++ b/wqflask/base/header.py @@ -0,0 +1,6 @@ +import webqtlConfig + +header_string = open(webqtlConfig.HTMLPATH + 'header.html', 'r').read() +header_string = header_string.replace("\\'", "'") +header_string = header_string.replace('%"','%%"') +header_string = header_string.replace('', '%s') \ No newline at end of file diff --git a/wqflask/base/indexBody.py b/wqflask/base/indexBody.py new file mode 100755 index 00000000..aa67dffa --- /dev/null +++ b/wqflask/base/indexBody.py @@ -0,0 +1,290 @@ +index_body_string = """ + +

Select and Search +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Species: + + + +
+ Group: + + + +
+ Type: + + + +
+ Database: + + + + +
+ + +

    Databases marked with ** suffix are not public yet. +
    Access requires user login.

+
+ Get Any: + + + + +
+ + + +

    Enter terms, genes, ID numbers in the Get Any field. +
    Use * or ? wildcards (Cyp*a?, synap*). +
    Use Combined for terms such as tyrosine kinase.

+ +
+ Combined: + + + + +
+ + +      +      + + +
+ + + +
+ + + + + + + + +

 ______________________________________________________ + +

  + +Quick HELP Examples and + + User's Guide

+ + +  You can also use advanced commands. Copy these simple examples +
  into the Get Any or Combined search fields: + + + + + + + + +

Websites Affiliated with GeneNetwork

+

+

+

+

____________________________ + +

Getting Started   

+
    +
  1. Select Species (or select All) +
  2. Select Group (a specific sample) +
  3. Select Type of data: + +
  4. Select a Database +
  5. Enter search terms in the Get Any or Combined field: words, genes, ID numbers, probes, advanced search commands +
  6. Click on the Search button +
  7. Optional: Use the Make Default button to save your preferences +
+ +

____________________________ + +

How to Use GeneNetwork + +

+

Take a 20-40 minute GeneNetwork Tour that includes screen shots and typical steps in the analysis.

+
+
+

For information about resources and methods, select the INFO buttons.

+ + + +

Try the Workstation site to explore data and features that are being implemented.

+ + +

Review the Conditions and Contacts pages for information on the status of data sets and advice on their use and citation.

+ + +
+ + + +

Mirror and Development Sites

+ + + + +

History and Archive + +

+

GeneNetwork's Time Machine links to earlier versions that correspond to specific publication dates.

+ +
+ + +

+ +""" diff --git a/wqflask/base/myCookie.py b/wqflask/base/myCookie.py new file mode 100755 index 00000000..db5320df --- /dev/null +++ b/wqflask/base/myCookie.py @@ -0,0 +1,55 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +######################################### +## python cookie and mod python cookie are +## not compatible +######################################### + +class myCookie(dict): + 'define my own cookie' + + def __init__(self, name="", value="", expire = None, path="/"): + self['name']= name + self['value']= value + self['expire']= expire + self['path']= path + + def __getattr__(self, key): + if key in self.keys(): + return self[key] + else: + return None + + def __nonzero__ (self): + if self['name']: + return 1 + else: + return 0 + + + + diff --git a/wqflask/base/sessionData.py b/wqflask/base/sessionData.py new file mode 100755 index 00000000..01555f87 --- /dev/null +++ b/wqflask/base/sessionData.py @@ -0,0 +1,53 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +######################################### +#convert mod_python object to Dict object +#in order to be able to be pickled +######################################### + +class sessionData(dict): + 'convert mod python Session object to Dict object' + + def __init__(self, mod_python_session=None): + + if not mod_python_session: + mod_python_session = {} + + for key in mod_python_session.keys(): + self[key]= mod_python_session[key] + + + def getvalue(self, k, default= None): + try: + return self[k] + except: + return default + + getfirst = getvalue + + + diff --git a/wqflask/base/template.py b/wqflask/base/template.py new file mode 100755 index 00000000..85bd86df --- /dev/null +++ b/wqflask/base/template.py @@ -0,0 +1,123 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +template = """ + + + + +%s + + + + + + + +%s + + + + + + + + + + + + + + +%s + + + + +%s + + + + + %s + + + + + + + + + + + + + + +
+ + + %s + +
+
+ %s
+
+ + + + + + + + + + +""" diff --git a/wqflask/base/templatePage.py b/wqflask/base/templatePage.py new file mode 100755 index 00000000..4dece24a --- /dev/null +++ b/wqflask/base/templatePage.py @@ -0,0 +1,222 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +#templatePage.py +# +#--Genenetwork generates a lot of pages; this file is the generic version of them, defining routines they all use. +# +#Classes: +#templatePage +# +#Functions (of templatePage): +#__init__(...) -- class constructor, allows a more specific template to be used in addition to templatePage +#__str__(self) -- returns the object's elements as a tuple +#__del__(self) -- closes the current connection to MySQL, if there is one +#write -- explained below +#writefile -- explained below +#openMysql(self) -- opens a MySQL connection and stores the resulting cursor in the object's cursor variable +#updMysql(self) -- same as openMysql +#error -- explained below +#session -- explained below + + +import socket +import time +import shutil +import MySQLdb +import os + +from htmlgen import HTMLgen2 as HT + +import template +import webqtlConfig +import header +import footer +from utility import webqtlUtil + + + +class templatePage: + + contents = ['title','basehref','js1','js2', 'layer', 'header', 'body', 'footer'] + + # you can pass in another template here if you want + def __init__(self, fd=None, template=template.template): + + # initiate dictionary + self.starttime = time.time() + self.dict = {} + self.template = template + + for item in self.contents: + self.dict[item] = "" + + self.dict['basehref'] = "" #webqtlConfig.BASEHREF + self.cursor = None + + self.cookie = [] #XZ: list to hold cookies (myCookie object) being changed + self.content_type = 'text/html' + self.content_disposition = '' + self.redirection = '' + self.debug = '' + self.attachment = '' + + #XZ: Holding data (new data or existing data being changed) that should be saved to session. The data must be picklable!!! + self.session_data_changed = {} + + self.userName = 'Guest' + self.privilege = 'guest' + if fd.input_session_data.has_key('user'): + self.userName = fd.input_session_data['user'] + if fd.input_session_data.has_key('privilege'): + self.privilege = fd.input_session_data['privilege'] + + def __str__(self): + + #XZ: default setting + thisUserName = self.userName + thisPrivilege = self.privilege + #XZ: user may just go through login or logoff page + if self.session_data_changed.has_key('user'): + thisUserName = self.session_data_changed['user'] + if self.session_data_changed.has_key('privilege'): + thisPrivilege = self.session_data_changed['privilege'] + + if thisUserName == 'Guest': + userInfo = 'Welcome! Login' + else: + userInfo = 'Hi, %s! Logout' % thisUserName + + reload(header) + self.dict['header'] = header.header_string % userInfo + + serverInfo = "It took %2.3f second(s) for %s to generate this page" % (time.time()-self.starttime, socket.getfqdn()) + reload(footer) + self.dict['footer'] = footer.footer_string % serverInfo + + slist = [] + for item in self.contents: + slist.append(self.dict[item]) + return self.template % tuple(slist) + + + def __del__(self): + if self.cursor: + self.cursor.close() + + def write(self): + 'return string representation of this object' + + if self.cursor: + self.cursor.close() + + return str(self) + + def writeFile(self, filename): + 'save string representation of this object into a file' + if self.cursor: + self.cursor.close() + + try: + 'it could take a long time to generate the file, save to .tmp first' + fp = open(os.path.join(webqtlConfig.TMPDIR, filename+'.tmp'), 'wb') + fp.write(str(self)) + fp.close() + path_tmp = os.path.join(webqtlConfig.TMPDIR, filename+'.tmp') + path_html = os.path.join(webqtlConfig.TMPDIR, filename) + shutil.move(path_tmp,path_html) + except: + pass + + def openMysql(self): + try: + self.con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \ + user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) + self.cursor = self.con.cursor() + return 1 + except: + heading = "Connect MySQL Server" + detail = ["Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_SERVER+"':100061. \ + The server may be down at this time"] + self.error(heading=heading,detail=detail,error="Error 2003") + return 0 + + def updMysql(self): + try: + self.con = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \ + user=webqtlConfig.DB_UPDUSER,passwd=webqtlConfig.DB_UPDPASSWD) + self.cursor = self.con.cursor() + return 1 + except: + heading = "Connect MySQL Server" + detail = ["update: Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_UPDSERVER+"':100061. \ + The server may be down at this time "] + self.error(heading=heading,detail=detail,error="Error 2003") + return 0 + + def error(self,heading="",intro=[],detail=[],title="Error",error="Error"): + 'generating a WebQTL style error page' + Heading = HT.Paragraph(heading) + Heading.__setattr__("class","title") + + Intro = HT.Blockquote() + if intro: + for item in intro: + Intro.append(item) + else: + Intro.append(HT.Strong('Sorry!'),' Error occurred while processing\ + your request.', HT.P(),'The nature of the error generated is as\ + follows:') + + Detail = HT.Blockquote() + Detail.append(HT.Span("%s : " % error,Class="fwb cr")) + if detail: + Detail2 = HT.Blockquote() + for item in detail: + Detail2.append(item) + Detail.append(HT.Italic(Detail2)) + + #Detail.__setattr__("class","subtitle") + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") + TD_LR.append(Heading,Intro,Detail) + self.dict['body'] = str(TD_LR) + self.dict['title'] = title + + def session(self,mytitle="",myHeading=""): + 'generate a auto-refreshing temporary html file(waiting page)' + self.filename = webqtlUtil.generate_session() + self.dict['title'] = mytitle + self.dict['basehref'] = webqtlConfig.REFRESHSTR % (webqtlConfig.CGIDIR, self.filename) + "" #webqtlConfig.BASEHREF + + TD_LR = HT.TD(align="center", valign="middle", height=200,width="100%", bgColor='#eeeeee') + Heading = HT.Paragraph(myHeading, Class="fwb fs16 cr") + # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py; + TD_LR.append(Heading, HT.BR(), webqtlUtil.PROGRESSBAR) + self.dict['body'] = TD_LR + self.writeFile(self.filename + '.html') + return self.filename + + diff --git a/wqflask/base/webqtlCaseData.py b/wqflask/base/webqtlCaseData.py new file mode 100755 index 00000000..4df32ca4 --- /dev/null +++ b/wqflask/base/webqtlCaseData.py @@ -0,0 +1,54 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +class webqtlCaseData: + """ + one case data in one trait + """ + + val = None #Trait Value + var = None #Trait Variance + N = None #Number of individuals + + def __init__(self, val=val, var=var, N=N): + self.val = val + self.var = var + self.N = N + + def __str__(self): + str = "" + if self.val != None: + str += "value=%2.3f" % self.val + if self.var != None: + str += " variance=%2.3f" % self.var + if self.N != None: + str += " ndata=%d" % self.N + return str + + __repr__ = __str__ + + + diff --git a/wqflask/base/webqtlConfig.py b/wqflask/base/webqtlConfig.py new file mode 100755 index 00000000..755595e0 --- /dev/null +++ b/wqflask/base/webqtlConfig.py @@ -0,0 +1,73 @@ +from webqtlConfigLocal import * +#########################################' +# Environment Variables - public +######################################### + +#Debug Level +#1 for debug, mod python will reload import each time +DEBUG = 1 + +#USER privilege +USERDICT = {'guest':1,'user':2, 'admin':3, 'root':4} + +#minimum number of informative strains +KMININFORMATIVE = 5 + +#maximum number of traits for interval mapping +MULTIPLEMAPPINGLIMIT = 11 + +#maximum number of traits for correlation +MAXCORR = 100 + +#Daily download limit from one IP +DAILYMAXIMUM = 1000 + +#maximum LRS value +MAXLRS = 460.0 + +#temporary data life span +MAXLIFE = 86400 + +#MINIMUM Database public value +PUBLICTHRESH = 0 + +#NBCI address +NCBI_LOCUSID = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" +UCSC_REFSEQ = "http://genome.cse.ucsc.edu/cgi-bin/hgGene?db=%s&hgg_gene=%s&hgg_chrom=chr%s&hgg_start=%s&hgg_end=%s" +GENBANK_ID = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=Nucleotide&cmd=search&doptcmdl=DocSum&term=%s" +OMIM_ID = "http://www.ncbi.nlm.nih.gov/omim/%s" +UNIGEN_ID = "http://www.ncbi.nlm.nih.gov/UniGene/clust.cgi?ORG=%s&CID=%s" +HOMOLOGENE_ID = "http://www.ncbi.nlm.nih.gov/sites/entrez?Db=homologene&Cmd=DetailsSearch&Term=%s" +PUBMEDLINK_URL = "http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=PubMed&list_uids=%s&dopt=Abstract" +UCSC_POS = "http://genome.ucsc.edu/cgi-bin/hgTracks?clade=mammal&org=%s&db=%s&position=chr%s:%s-%s&pix=800&Submit=submit" +UCSC_BLAT = 'http://genome.ucsc.edu/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s' +UTHSC_BLAT = 'http://ucscbrowser.genenetwork.org/cgi-bin/hgBlat?org=%s&db=%s&type=0&sort=0&output=0&userSeq=%s' +UCSC_GENOME = "http://genome.ucsc.edu/cgi-bin/hgTracks?db=%s&position=chr%s:%d-%d&hgt.customText=http://web2qtl.utmem.edu:88/snp/chr%s" +ENSEMBLE_BLAT = 'http://www.ensembl.org/Mus_musculus/featureview?type=AffyProbe&id=%s' +DBSNP = 'http://www.ncbi.nlm.nih.gov/SNP/snp_ref.cgi?type=rs&rs=%s' +UCSC_RUDI_TRACK_URL = " http://genome.cse.ucsc.edu/cgi-bin/hgTracks?org=%s&db=%s&hgt.customText=http://gbic.biol.rug.nl/~ralberts/tracks/%s/%s" +GENOMEBROWSER_URL="http://ucscbrowser.genenetwork.org/cgi-bin/hgTracks?clade=mammal&org=Mouse&db=mm9&position=%s&hgt.suggest=&pix=800&Submit=submit" +ENSEMBLETRANSCRIPT_URL="http://useast.ensembl.org/Mus_musculus/Lucene/Details?species=Mus_musculus;idx=Transcript;end=1;q=%s" + +SECUREDIR = GNROOT + 'secure/' +COMMON_LIB = GNROOT + 'support/admin' +HTMLPATH = GNROOT + 'web/' +IMGDIR = HTMLPATH +'image/' +IMAGESPATH = HTMLPATH + 'images/' +UPLOADPATH = IMAGESPATH + 'upload/' +TMPDIR = '/tmp/' +GENODIR = HTMLPATH + 'genotypes/' +GENO_ARCHIVE_DIR = GENODIR + 'archive/' +TEXTDIR = HTMLPATH + 'ProbeSetFreeze_DataMatrix/' +CMDLINEDIR = HTMLPATH + 'webqtl/cmdLine/' +ChangableHtmlPath = GNROOT + 'web/' + +SITENAME = 'GN' +PORTADDR = "http://132.192.47.32" +BASEHREF = '' +INFOPAGEHREF = '/dbdoc/%s.html' +GLOSSARYFILE = "/glossary.html" +CGIDIR = '/webqtl/' #XZ: The variable name 'CGIDIR' should be changed to 'PYTHONDIR' +SCRIPTFILE = 'main.py' +REFRESHSTR = '' +REFRESHDIR = '%s' + SCRIPTFILE +'?sid=%s' diff --git a/wqflask/base/webqtlConfigLocal.py b/wqflask/base/webqtlConfigLocal.py new file mode 100755 index 00000000..35da73c2 --- /dev/null +++ b/wqflask/base/webqtlConfigLocal.py @@ -0,0 +1,19 @@ +#########################################' +# Environment Variables - private +######################################### + +MYSQL_SERVER = 'localhost' +DB_NAME = 'db_webqtl' +DB_USER = 'webqtlupd' +DB_PASSWD = 'zhou&yan@ut' + +MYSQL_UPDSERVER = 'localhost' +DB_UPDNAME = 'db_webqtl' +DB_UPDUSER = 'webqtlupd' +DB_UPDPASSWD = 'zhou&yan@ut' + +GNROOT = '/gnshare/gn/' +PythonPath = '/usr/bin/python' +PIDDLE_FONT_PATH = '/usr/lib/python2.4/site-packages/piddle/truetypefonts/' + +TEXTUI=1 # XZ: This is to protect GN production server. If set to 0, no text UI is allowed. diff --git a/wqflask/base/webqtlDataset.py b/wqflask/base/webqtlDataset.py new file mode 100755 index 00000000..da1b8601 --- /dev/null +++ b/wqflask/base/webqtlDataset.py @@ -0,0 +1,160 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT + +import webqtlConfig + + + +class webqtlDataset: + """ + Database class defines a database in webqtl, can be either Microarray, + Published phenotype, genotype, or user input database(temp) + """ + + def __init__(self, dbName, cursor=None): + + assert dbName + self.id = 0 + self.name = '' + self.type = '' + self.riset = '' + self.cursor = cursor + + #temporary storage + if dbName.find('Temp') >= 0: + self.searchfield = ['name','description'] + self.disfield = ['name','description'] + self.type = 'Temp' + self.id = 1 + self.fullname = 'Temporary Storage' + self.shortname = 'Temp' + elif dbName.find('Publish') >= 0: + self.searchfield = ['name','post_publication_description','abstract','title','authors'] + self.disfield = ['name','pubmed_id', + 'pre_publication_description', 'post_publication_description', 'original_description', + 'pre_publication_abbreviation', 'post_publication_abbreviation', + 'lab_code', 'submitter', 'owner', 'authorized_users', + 'authors','title','abstract', 'journal','volume','pages','month', + 'year','sequence', 'units', 'comments'] + self.type = 'Publish' + elif dbName.find('Geno') >= 0: + self.searchfield = ['name','chr'] + self.disfield = ['name','chr','mb', 'source2', 'sequence'] + self.type = 'Geno' + else: #ProbeSet + self.searchfield = ['name','description','probe_target_description', + 'symbol','alias','genbankid','unigeneid','omim', + 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] + self.disfield = ['name','symbol','description','probe_target_description', + 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', + 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', + 'strand_probe','strand_gene','probe_set_target_region', + 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', + 'probe_set_blat_mb_end', 'probe_set_strand', + 'probe_set_note_by_rw', 'flag'] + self.type = 'ProbeSet' + self.name = dbName + if self.cursor and self.id == 0: + self.retrieveName() + + def __str__(self): + return self.name + + __repr__ = __str__ + + + def getRISet(self): + assert self.cursor + if self.type == 'Publish': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, PublishFreeze + WHERE + PublishFreeze.InbredSetId = InbredSet.Id AND + PublishFreeze.Name = "%s" + ''' % self.name + elif self.type == 'Geno': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, GenoFreeze + WHERE + GenoFreeze.InbredSetId = InbredSet.Id AND + GenoFreeze.Name = "%s" + ''' % self.name + elif self.type == 'ProbeSet': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, ProbeSetFreeze, ProbeFreeze + WHERE + ProbeFreeze.InbredSetId = InbredSet.Id AND + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % self.name + else: + return "" + self.cursor.execute(query) + RISet, RIID = self.cursor.fetchone() + if RISet == 'BXD300': + RISet = "BXD" + self.riset = RISet + self.risetid = RIID + return RISet + + + def retrieveName(self): + assert self.id == 0 and self.cursor + query = ''' + SELECT + Id, Name, FullName, ShortName + FROM + %sFreeze + WHERE + public > %d AND + (Name = "%s" OR FullName = "%s" OR ShortName = "%s") + '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) + try: + self.cursor.execute(query) + self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() + except: + raise KeyError, `self.name`+' doesn\'t exist.' + + + def genHTML(self, Class='c0dd'): + return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), + url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") + + + + + diff --git a/wqflask/base/webqtlFormData.py b/wqflask/base/webqtlFormData.py new file mode 100755 index 00000000..84e41cae --- /dev/null +++ b/wqflask/base/webqtlFormData.py @@ -0,0 +1,289 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from mod_python import Cookie +import string +import os + +import reaper + +import webqtlConfig +import cookieData +import sessionData +from cgiData import cgiData +from webqtlCaseData import webqtlCaseData +from utility import webqtlUtil + + + +class webqtlFormData: + 'Represents data from a WebQTL form page, needed to generate the next page' + attrs = ('formID','RISet','genotype','strainlist','allstrainlist', + 'suggestive','significance','submitID','identification', 'enablevariance', + 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo') + + #XZ: Attention! All attribute values must be picklable! + + def __init__(self, req = None, mod_python_session=None, FieldStorage_formdata=None): + + for item in self.attrs: + setattr(self,item, None) + + try: + self.remote_ip = req.connection.remote_ip + except: + self.remote_ip = '1.2.3.4' + + if req and req.headers_in.has_key('referer'): + self.refURL = req.headers_in['referer'] + else: + self.refURL = None + + + self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie. + + #XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable. + self.input_session_data = sessionData.sessionData( mod_python_session ) + + #XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data. + self.formdata = cgiData( FieldStorage_formdata ) + + #get Form ID + self.formID = self.formdata.getfirst('FormID') + + #get rest of the attributes + if self.formID: + for item in self.attrs: + value = self.formdata.getfirst(item) + if value != None: + setattr(self,item,string.strip(value)) + + self.ppolar = "" + self.mpolar = "" + if self.RISet: + try: + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + f1, f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet] + except: + f1 = f12 = self.mpolar = self.ppolar = None + + try: + self.nperm = int(self.nperm) + self.nboot = int(self.nboot) + except: + self.nperm = 2000 #XZ: Rob asked to change the default value to 2000 + self.nboot = 2000 #XZ: Rob asked to change the default value to 2000 + + if self.allstrainlist: + self.allstrainlist = map(string.strip, string.split(self.allstrainlist)) + #self.readGenotype() + #self.readData() + + if self.RISet == 'BXD300': + self.RISet = 'BXD' + else: + pass + + def __str__(self): + rstr = '' + for item in self.attrs: + if item != 'genotype': + rstr += '%s:%s\n' % (item,str(getattr(self,item))) + return rstr + + + def readGenotype(self): + 'read genotype from .geno file' + if self.RISet == 'BXD300': + self.RISet = 'BXD' + else: + pass + assert self.RISet + #genotype_1 is Dataset Object without parents and f1 + #genotype_2 is Dataset Object with parents and f1 (not for intercross) + self.genotype_1 = reaper.Dataset() + self.genotype_1.read(os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno')) + try: + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] + except: + _f1 = _f12 = _mat = _pat = None + + self.genotype_2 =self.genotype_1 + if self.genotype_1.type == "riset" and _mat and _pat: + self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) + + #determine default genotype object + if self.incparentsf1 and self.genotype_1.type != "intercross": + self.genotype = self.genotype_2 + else: + self.incparentsf1 = 0 + self.genotype = self.genotype_1 + self.strainlist = list(self.genotype.prgy) + self.f1list = self.parlist = [] + if _f1 and _f12: + self.f1list = [_f1, _f12] + if _mat and _pat: + self.parlist = [_mat, _pat] + + def readData(self, strainlst=[], incf1=[]): + 'read user input data or from trait data and analysis form' + + if not self.genotype: + self.readGenotype() + if not strainlst: + if incf1: + strainlst = self.f1list + self.strainlist + else: + strainlst = self.strainlist + + + traitfiledata = self.formdata.getfirst('traitfile') + traitpastedata = self.formdata.getfirst('traitpaste') + variancefiledata = self.formdata.getfirst('variancefile') + variancepastedata = self.formdata.getfirst('variancepaste') + Nfiledata = self.formdata.getfirst('Nfile') + + + if traitfiledata: + tt = string.split(traitfiledata) + vals = map(webqtlUtil.StringAsFloat, tt) + elif traitpastedata: + tt = string.split(traitpastedata) + vals = map(webqtlUtil.StringAsFloat, tt) + else: + vals = map(self.FormDataAsFloat, strainlst) + + if len(vals) < len(strainlst): + vals += [None]*(len(strainlst) - len(vals)) + elif len(vals) > len(strainlst): + vals = vals[:len(strainlst)] + else: + pass + + + if variancefiledata: + tt = string.split(variancefiledata) + vars = map(webqtlUtil.StringAsFloat, tt) + elif variancepastedata: + tt = string.split(variancepastedata) + vars = map(webqtlUtil.StringAsFloat, tt) + else: + vars = map(self.FormVarianceAsFloat, strainlst) + + if len(vars) < len(strainlst): + vars += [None]*(len(strainlst) - len(vars)) + elif len(vars) > len(strainlst): + vars = vars[:len(strainlst)] + else: + pass + + if Nfiledata: + tt = string.split(Nfiledata) + nstrains = map(webqtlUtil.IntAsFloat, tt) + if len(nstrains) < len(strainlst): + nstrains += [None]*(len(strainlst) - len(nstrains)) + else: + nstrains = map(self.FormNAsFloat, strainlst) + + ##vals, vars, nstrains is obsolete + self.allTraitData = {} + for i, _strain in enumerate(strainlst): + if vals[i] != None: + self.allTraitData[_strain] = webqtlCaseData(vals[i], vars[i], nstrains[i]) + + + + def informativeStrains(self, strainlst=[], incVars = 0): + '''if readData was called, use this to output the informative strains + (strain with values)''' + if not strainlst: + strainlst = self.strainlist + strains = [] + vals = [] + vars = [] + for _strain in strainlst: + if self.allTraitData.has_key(_strain): + _val, _var = self.allTraitData[_strain].val, self.allTraitData[_strain].var + if _val != None: + if incVars: + if _var != None: + strains.append(_strain) + vals.append(_val) + vars.append(_var) + else: + strains.append(_strain) + vals.append(_val) + vars.append(None) + return strains, vals, vars, len(strains) + + + + def FormDataAsFloat(self, key): + try: + return float(self.formdata.getfirst(key)) + except: + return None + + + def FormVarianceAsFloat(self, key): + try: + return float(self.formdata.getfirst('V' + key)) + except: + return None + + def FormNAsFloat(self, key): + try: + return int(self.formdata.getfirst('N' + key)) + except: + return None + + def Sample(self): + 'Create some dummy data for testing' + self.RISet = 'BXD' + self.incparentsf1 = 'on' + #self.display = 9.2 + #self.significance = 16.1 + self.readGenotype() + self.identification = 'BXD : Coat color example by Lu Lu, et al' + #self.readGenotype() + #self.genotype.ReadMM('AXBXAforQTL') + #self.strainlist = map((lambda x, y='': '%s%s' % (y,x)), self.genotype.prgy) + #self.strainlist.sort() + self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2), + 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2), + 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4), + 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2), + 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3), + 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3), + 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2), + 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4), + 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4), + 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1), + 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4), + 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4), + 'BXD42': webqtlCaseData(4), 'BXD40': webqtlCaseData(3)} + diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py new file mode 100755 index 00000000..f5051e45 --- /dev/null +++ b/wqflask/base/webqtlTrait.py @@ -0,0 +1,581 @@ +import string + +from htmlgen import HTMLgen2 as HT + +import webqtlConfig +from webqtlCaseData import webqtlCaseData +from webqtlDataset import webqtlDataset +from dbFunction import webqtlDatabaseFunction +from utility import webqtlUtil + + +class webqtlTrait: + """ + Trait class defines a trait in webqtl, can be either Microarray, + Published phenotype, genotype, or user input trait + """ + + def __init__(self, cursor = None, **kw): + self.cursor = cursor + self.db = None # database object + self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. + self.cellid = '' + self.identification = 'un-named trait' + self.riset = '' + self.haveinfo = 0 + self.sequence = '' # Blat sequence, available for ProbeSet + self.data = {} + for name, value in kw.items(): + if self.__dict__.has_key(name): + setattr(self, name, value) + elif name == 'fullname': + name2 = value.split("::") + if len(name2) == 2: + self.db, self.name = name2 + elif len(name2) == 3: + self.db, self.name, self.cellid = name2 + else: + raise KeyError, `value` + ' parameter format error.' + else: + raise KeyError, `name`+' not a valid parameter for this class.' + + if self.db and type(self.db) == type("1"): + assert self.cursor + self.db = webqtlDataset(self.db, self.cursor) + + #if self.db == None, not from a database + if self.db: + if self.db.type == "Temp": + self.cursor.execute(''' + SELECT + InbredSet.Name + FROM + InbredSet, Temp + WHERE + Temp.InbredSetId = InbredSet.Id AND + Temp.Name = "%s" + ''' % self.name) + self.riset = self.cursor.fetchone()[0] + else: + self.riset = self.db.getRISet() + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + + #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. + # The variable self.sequence should be changed to self.BlatSeq + # It also should be changed in other places where it are used. + + if self.db: + if self.db.type == 'ProbeSet': + query = ''' + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and + ProbeSet.Name = "%s" and + ProbeSetFreeze.Name = "%s" + ''' % (self.name, self.db.name) + self.cursor.execute(query) + self.sequence = self.cursor.fetchone()[0] + + + def getName(self): + str = "" + if self.db and self.name: + str = "%s::%s" % (self.db, self.name) + if self.cellid: + str += "::" + self.cellid + else: + str = self.description + return str + + # + # when user enter a trait or GN generate a trait, user want show the name + # not the name that generated by GN randomly, the two follow function are + # used to give the real name and the database. displayName() will show the + # database also, getGivenName() just show the name. + # For other trait, displayName() as same as getName(), getGivenName() as + # same as self.name + # + # Hongqiang 11/29/07 + # + def getGivenName(self): + str = self.name + if self.db and self.name: + if self.db.type=='Temp': + self.cursor.execute('SELECT description FROM Temp WHERE Name=%s',self.name) + desc = self.cursor.fetchone()[0] + if desc.__contains__('PCA'): + desc = desc[desc.rindex(':')+1:].strip() + else: + desc = desc[:desc.index('entered')].strip() + str = desc + return str + + def displayName(self): + str = "" + if self.db and self.name: + if self.db.type=='Temp': + desc = self.description + if desc.__contains__('PCA'): + desc = desc[desc.rindex(':')+1:].strip() + else: + desc = desc[:desc.index('entered')].strip() + str = "%s::%s" % (self.db, desc) + else: + str = "%s::%s" % (self.db, self.name) + if self.cellid: + str += "::" + self.cellid + else: + str = self.description + + return str + + + #def __str__(self): + # #return "%s %s" % (self.getName(), self.riset) + # return self.getName() + __str__ = getName + __repr__ = __str__ + + def exportData(self, strainlist, type="val"): + """ + export data according to strainlist + mostly used in calculating correlation + """ + result = [] + for strain in strainlist: + if self.data.has_key(strain): + if type=='val': + result.append(self.data[strain].val) + elif type=='var': + result.append(self.data[strain].var) + elif type=='N': + result.append(self.data[strain].N) + else: + raise KeyError, `type`+' type is incorrect.' + else: + result.append(None) + return result + + def exportInformative(self, incVar=0): + """ + export informative strain + mostly used in qtl regression + """ + strains = [] + vals = [] + vars = [] + for strain, value in self.data.items(): + if value.val != None: + if not incVar or value.var != None: + strains.append(strain) + vals.append(value.val) + vars.append(value.var) + return strains, vals, vars + + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + def getSequence(self): + assert self.cursor + if self.db.type == 'ProbeSet': + query = ''' + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and + ProbeSet.Name = %s + ProbeSetFreeze.Name = %s + ''' , (self.name, self.db.name) + self.cursor.execute(query) + results = self.fetchone() + + return results[0] + + + + def retrieveData(self, strainlist=[]): + assert self.db and self.cursor + + if self.db.type == 'Temp': + query = ''' + SELECT + Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id + FROM + TempData, Temp, Strain + WHERE + TempData.StrainId = Strain.Id AND + TempData.Id = Temp.DataId AND + Temp.name = '%s' + Order BY + Strain.Name + ''' % self.name + #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE + elif self.db.type == 'Publish': + query = ''' + SELECT + Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + FROM + (PublishData, Strain, PublishXRef, PublishFreeze) + left join PublishSE on + (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) + left join NStrain on + (NStrain.DataId = PublishData.Id AND + NStrain.StrainId = PublishData.StrainId) + WHERE + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND + PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.name, self.db.id) + + #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE + elif self.cellid: + #Probe Data + query = ''' + SELECT + Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id + FROM + (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, + Strain, Probe, ProbeSet) + left join ProbeSE on + (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) + WHERE + Probe.Name = '%s' AND ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id AND + ProbeXRef.ProbeId = Probe.Id AND + ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeXRef.DataId = ProbeData.Id AND + ProbeData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.cellid, self.name, self.db.name) + #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE + elif self.db.type == 'ProbeSet': + #ProbeSet Data + query = ''' + SELECT + Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id + FROM + (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) + left join ProbeSetSE on + (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) + WHERE + ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSetXRef.DataId = ProbeSetData.Id AND + ProbeSetData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.name, self.db.name) + #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE + else: + #Geno Data + #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. + query = ''' + SELECT + Strain.Name, GenoData.value, GenoSE.error, GenoData.Id + FROM + (GenoData, GenoFreeze, Strain, Geno, GenoXRef) + left join GenoSE on + (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) + WHERE + Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoFreeze.Name = '%s' AND + GenoXRef.DataId = GenoData.Id AND + GenoData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name) + + + self.cursor.execute(query) + results = self.cursor.fetchall() + self.data.clear() + if results: + self.mysqlid = results[0][-1] + if strainlist: + for item in results: + if item[0] in strainlist: + val = item[1] + if val != None: + var = item[2] + ndata = None + if self.db.type in ('Publish', 'Temp'): + ndata = item[3] + self.data[item[0]] = webqtlCaseData(val, var, ndata) + #end for + else: + for item in results: + val = item[1] + if val != None: + var = item[2] + ndata = None + if self.db.type in ('Publish', 'Temp'): + ndata = item[3] + self.data[item[0]] = webqtlCaseData(val, var, ndata) + #end for + #end if + else: + pass + + def keys(self): + return self.__dict__.keys() + + def has_key(self, key): + return self.__dict__.has_key(key) + + def items(self): + return self.__dict__.items() + + def retrieveInfo(self, QTL = None): + assert self.db and self.cursor + if self.db.type == 'Publish': + #self.db.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ + # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ + # 'Units', 'comments'] + query = ''' + SELECT + PublishXRef.Id, Publication.PubMed_ID, + Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, + Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, + Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, + Publication.Authors, Publication.Title, Publication.Abstract, + Publication.Journal, Publication.Volume, Publication.Pages, + Publication.Month, Publication.Year, PublishXRef.Sequence, + Phenotype.Units, PublishXRef.comments + FROM + PublishXRef, Publication, Phenotype, PublishFreeze + WHERE + PublishXRef.Id = %s AND + Phenotype.Id = PublishXRef.PhenotypeId AND + Publication.Id = PublishXRef.PublicationId AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id =%s + ''' % (self.name, self.db.id) + #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name + #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + elif self.db.type == 'ProbeSet': + disfieldString = string.join(self.db.disfield,',ProbeSet.') + disfieldString = 'ProbeSet.' + disfieldString + query = """ + SELECT %s + FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' + """ % (disfieldString, self.db.name, self.name) + #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name + # to avoid the problem of same marker name from different species. + elif self.db.type == 'Geno': + disfieldString = string.join(self.db.disfield,',Geno.') + disfieldString = 'Geno.' + disfieldString + query = """ + SELECT %s + FROM Geno, GenoFreeze, GenoXRef + WHERE + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoXRef.GenoId = Geno.Id AND + GenoFreeze.Name = '%s' AND + Geno.Name = '%s' + """ % (disfieldString, self.db.name, self.name) + else: #Temp type + query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ + (string.join(self.db.disfield,','), self.db.type, self.name) + + + self.cursor.execute(query) + traitInfo = self.cursor.fetchone() + if traitInfo: + self.haveinfo = 1 + + #XZ: assign SQL query result to trait attributes. + for i, field in enumerate(self.db.disfield): + setattr(self, field, traitInfo[i]) + + if self.db.type == 'Publish': + self.confidential = 0 + if self.pre_publication_description and not self.pubmed_id: + self.confidential = 1 + + self.homologeneid = None + if self.db.type == 'ProbeSet' and self.riset and self.geneid: + #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. + #XZ: So I have to test if geneid is number before execute the query. + #XZ: The geneid values in database should be cleaned up. + try: + junk = float(self.geneid) + geneidIsNumber = 1 + except: + geneidIsNumber = 0 + + if geneidIsNumber: + query = """ + SELECT + HomologeneId + FROM + Homologene, Species, InbredSet + WHERE + Homologene.GeneId =%s AND + InbredSet.Name = '%s' AND + InbredSet.SpeciesId = Species.Id AND + Species.TaxonomyId = Homologene.TaxonomyId + """ % (self.geneid, self.riset) + self.cursor.execute(query) + result = self.cursor.fetchone() + else: + result = None + + if result: + self.homologeneid = result[0] + + if QTL: + if self.db.type == 'ProbeSet' and not self.cellid: + query = ''' + SELECT + ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean + FROM + ProbeSetXRef, ProbeSet + WHERE + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSet.Name = "%s" AND + ProbeSetXRef.ProbeSetFreezeId =%s + ''' % (self.name, self.db.id) + self.cursor.execute(query) + traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs, self.pvalue, self.mean = traitQTL + else: + self.locus = self.lrs = self.pvalue = self.mean = "" + if self.db.type == 'Publish': + query = ''' + SELECT + PublishXRef.Locus, PublishXRef.LRS + FROM + PublishXRef, PublishFreeze + WHERE + PublishXRef.Id = %s AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id =%s + ''' % (self.name, self.db.id) + self.cursor.execute(query) + traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs = traitQTL + else: + self.locus = self.lrs = "" + else: + raise KeyError, `self.name`+' information is not found in the database.' + + def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): + if not self.haveinfo: + self.retrieveInfo() + + if self.db.type == 'Publish': + PubMedLink = "" + if self.pubmed_id: + PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, + target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) + else: + PubMedLink = HT.Span("Unpublished : ", Class="fs15") + + if formName: + setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % + (formName, self.db.name, self.name), Class = "fs14") + else: + setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % + (self.db.name,self.name), Class = "fs14") + + if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): + setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) + else: + setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description)) + + #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1. + #if self.sequence > 1: + # setDescription2.append(' btach %d' % self.sequence) + if self.authors: + a1 = string.split(self.authors,',')[0] + while a1[0] == '"' or a1[0] == "'" : + a1 = a1[1:] + setDescription2.append(' by ') + setDescription2.append(HT.Italic('%s, and colleagues' % a1)) + setDescription = HT.Span(PubMedLink, setDescription2) + + elif self.db.type == 'Temp': + setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ + ('%s','%s','')" % (self.db.name,self.name), Class = "fs14") + setDescription = HT.Span(setDescription) + + elif self.db.type == 'Geno': # Genome DB only available for single search + if formName: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ + (formName, self.db.name, self.name), Class = "fs14") + else: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ + (self.db.name,self.name), Class = "fs14") + + setDescription = HT.Span(setDescription) + + else: + if self.cellid: + if formName: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ + "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ + "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \ + Class = "fs14") + else: + if formName: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name,self.name), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), \ + Class = "fs14") + if self.symbol and self.chr and self.mb: + setDescription.append(' [') + setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb")) + setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb)) + if self.description: + setDescription.append(': %s' % self.description) + if self.probe_target_description: + setDescription.append('; %s' % self.probe_target_description) + setDescription = HT.Span(setDescription) + + if self.db.type != 'Temp' and dispFromDatabase: + setDescription.append( ' --- FROM : ') + setDescription.append(self.db.genHTML(Class='cori')) + return setDescription + + diff --git a/wqflask/dbFunction/__init__.py b/wqflask/dbFunction/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/dbFunction/webqtlDatabaseFunction.py b/wqflask/dbFunction/webqtlDatabaseFunction.py new file mode 100755 index 00000000..772e0526 --- /dev/null +++ b/wqflask/dbFunction/webqtlDatabaseFunction.py @@ -0,0 +1,265 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by Xiaodong Zhou 2011/Jan/20 + +#webqtlDatabaseFunction.py +# +#This file consists of various database related functions; the names are generally self-explanatory. + +import MySQLdb +import string +from base import webqtlConfig + +########################################################################### +#output: cursor instance +#function: connect to database and return cursor instance +########################################################################### +def getCursor(): + try: + con = MySQLdb.Connect(db=webqtlConfig.DB_NAME, host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER, passwd=webqtlConfig.DB_PASSWD) + cursor = con.cursor() + return cursor + except: + return None + + + +########################################################################### +#input: cursor, groupName (string) +#output: mappingMethodId (int) info, value will be Null or else +#function: retrieve mappingMethodId info from InbredSet table +########################################################################### + +def getMappingMethod(cursor=None, groupName=None): + cursor.execute("select MappingMethodId from InbredSet where Name= '%s'" % groupName) + mappingMethodId = cursor.fetchone()[0] + return mappingMethodId + +########################################################################### +#input: cursor, inbredSetId (int), strainId (int) +#output: isMappingId (bull) info, value will be 0,1,2 or else, 0 or Null means +# "can not do mapping", >0 means "can do mapping", >1 means "there exsists +# redundant data, user needs to choose one to do mapping function" +#function: retrieve isMappingId info from StrainXRef table +########################################################################### + +def isMapping(cursor=None, inbredSetId=None, strainId=None): + cursor.execute("select IsMapping from StrainXRef where InbredSetId='%d' and StrainId = '%d'" %(inbredSetId, strainId)) + isMappingId = cursor.fetchone()[0] + return isMappingId + +########################################################################### +#input: cursor, groupName (string) +#output: all species data info (array), value will be Null or else +#function: retrieve all species info from Species table +########################################################################### + +def getAllSpecies(cursor=None): + cursor.execute("select Id, Name, MenuName, FullName, TaxonomyId,OrderId from Species Order by OrderId") + allSpecies = cursor.fetchall() + return allSpecies + +########################################################################### +#input: cursor, RISet (string) +#output: specie's name (string), value will be None or else +#function: retrieve specie's name info based on RISet +########################################################################### + +def retrieveSpecies(cursor=None, RISet=None): + try: + cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % RISet) + return cursor.fetchone()[0] + except: + return None + +########################################################################### +#input: cursor, RISet (string) +#output: specie's Id (string), value will be None or else +#function: retrieve specie's Id info based on RISet +########################################################################### + +def retrieveSpeciesId(cursor=None, RISet=None): + try: + cursor.execute("select SpeciesId from InbredSet where Name = '%s'" % RISet) + return cursor.fetchone()[0] + except: + return None + +########################################################################### +# input: cursor +# output: tissProbeSetFreezeIdList (list), +# nameList (list), +# fullNameList (list) +# function: retrieve all TissueProbeSetFreezeId,Name,FullName info +# from TissueProbeSetFreeze table. +# These data will listed in the dropdown menu in the first page of Tissue Correlation +########################################################################### + +def getTissueDataSet(cursor=None): + tissProbeSetFreezeIdList=[] + nameList =[] + fullNameList = [] + + query = "select Id,Name,FullName from TissueProbeSetFreeze; " + try: + cursor.execute(query) + result = cursor.fetchall() + + for row in result: + tissProbeSetFreezeIdList.append(row[0]) + nameList.append(row[1]) + fullNameList.append(row[2]) + except: + return None + + return tissProbeSetFreezeIdList,nameList,fullNameList + +########################################################################### +# input: cursor,GeneSymbol (string), and TissueProbeSetFreezeId (string) +# output: geneId (string), dataId (string) +# function: retrieve geneId and DataId from TissueProbeSetXRef table +########################################################################### + +def getGeneIdDataIdForTissueBySymbol(cursor=None, GeneSymbol=None, TissueProbeSetFreezeId= 0): + query ="select GeneId, DataId from TissueProbeSetXRef where Symbol = '%s' and TissueProbeSetFreezeId=%s order by Mean desc" %(GeneSymbol,TissueProbeSetFreezeId) + try: + cursor.execute(query) + result = cursor.fetchone() + geneId = result[0] + dataId = result[1] + except: + geneId = 0 + dataId = 0 + + return geneId,dataId + +########################################################################### +# input: cursor, TissueProbeSetFreezeId (int) +# output: chipId (int) +# function: retrieve chipId from TissueProbeFreeze table +########################################################################### + +def getChipIdByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): + query = "select TissueProbeFreezeId from TissueProbeSetFreeze where Id =%s" % TissueProbeSetFreezeId + try: + cursor.execute(query) + result = cursor.fetchone() + TissueProbeFreezeId = result[0] + except: + TissueProbeFreezeId =0 + + query1 = "select ChipId from TissueProbeFreeze where Id =%s" % TissueProbeFreezeId + try: + cursor.execute(query1) + result1 = cursor.fetchone() + chipId = result1[0] + except: + chipId =0 + + return chipId + +########################################################################### +# input: cursor, TissueProbeSetFreezeId (int) +# output: TissueCount (int) +# function: retrieve how many tissue used in the specific dataset based on TissueProbeSetFreezeId +########################################################################### +def getTissueCountByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): + query1 ="select DataId from TissueProbeSetXRef where TissueProbeSetFreezeId =%s limit 1" % TissueProbeSetFreezeId + try: + cursor.execute(query1) + result1 = cursor.fetchone() + DataId = result1[0] + + query2 =" select count(*) from TissueProbeSetData where Id=%s" % DataId + try: + cursor.execute(query2) + result2 = cursor.fetchone() + TissueCount = result2[0] + except: + TissueCount =0 + except: + TissueCount =0 + + return TissueCount + +########################################################################### +# input: cursor, TissueProbeSetFreezeId (int) +# output: DatasetName(string),DatasetFullName(string) +# function: retrieve DatasetName, DatasetFullName based on TissueProbeSetFreezeId +########################################################################### +def getDatasetNamesByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): + query ="select Name, FullName from TissueProbeSetFreeze where Id=%s" % TissueProbeSetFreezeId + try: + cursor.execute(query) + result = cursor.fetchone() + DatasetName = result[0] + DatasetFullName =result[1] + except: + DatasetName =None + DatasetFullName =None + + return DatasetName, DatasetFullName + +########################################################################### +# input: cursor, geneIdLst (list) +# output: geneIdSymbolPair(dict),key is geneId, value is geneSymbol +# function: retrieve GeneId, GeneSymbol based on geneId List +########################################################################### +def getGeneIdSymbolPairByGeneId(cursor=None, geneIdLst =None): + geneIdSymbolPair={} + for geneId in geneIdLst: + geneIdSymbolPair[geneId]=None + + query ="select GeneId,GeneSymbol from GeneList where GeneId in (%s)" % string.join(geneIdLst, ", ") + try: + cursor.execute(query) + results = cursor.fetchall() + for item in results: + geneId =item[0] + geneSymbol =item[1] + geneIdSymbolPair[geneId]=geneSymbol + except: + geneIdSymbolPair=None + + return geneIdSymbolPair + + +def updateTissueProbesetXRefByProbesetId(cursor=None, probesetId=None): + query ="select Symbol,GeneId,Chr,Mb,description, Probe_Target_Description from ProbeSet where Id =%s"%probesetId + try: + cursor.execute(query) + result =cursor.fetchone() + + updateQuery =''' + Update TissueProbeSetXRef + Set Symbol='%s',GeneId='%s', Chr='%s', Mb='%s', description ='%s',Probe_Target_Description='%s' + where ProbesetId=%s + '''%(result[0],result[1],result[2],result[3],result[4],result[5],probesetId) + + cursor.execute(updateQuery) + + except: + return None + \ No newline at end of file diff --git a/wqflask/htmlgen.py b/wqflask/htmlgen.py new file mode 100644 index 00000000..8406d925 --- /dev/null +++ b/wqflask/htmlgen.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, print_function + +class HTMLgen(object): + """A redefined HT until we manage to completely eliminate it""" + def __getattr__(self, name): + return "" + + def Item(self, *args, **kw): + print("This way of generating html is obsolete!") + return "foo" + + Href = Span = TD = Blockquote = Image = Item + +HTMLgen2 = HTMLgen() diff --git a/wqflask/requirements.txt b/wqflask/requirements.txt new file mode 100644 index 00000000..caa5d61e --- /dev/null +++ b/wqflask/requirements.txt @@ -0,0 +1,6 @@ +Flask==0.8 +Jinja2==2.6 +MySQL-python==1.2.3 +Werkzeug==0.8.3 +pyXLWriter==0.4a3 +wsgiref==0.1.2 diff --git a/wqflask/runserver.py b/wqflask/runserver.py new file mode 100644 index 00000000..bf73ed37 --- /dev/null +++ b/wqflask/runserver.py @@ -0,0 +1,15 @@ +from wqflask import app + +# Please note, running with host set externally below combined with debug mode +# is a big security no-no +# Unless you have a firewall setup +# +# Something like /sbin/iptables -A INPUT -p tcp -i eth0 -s ! 71.236.239.43 --dport 5000 -j DROP +# should do the trick +# +# You'll probably have to firewall the main port and the +# +# For more info see: http://www.cyberciti.biz/faq/iptables-block-port/ + + +app.run(host='0.0.0.0') diff --git a/wqflask/utility/AJAX_table.py b/wqflask/utility/AJAX_table.py new file mode 100755 index 00000000..963a530e --- /dev/null +++ b/wqflask/utility/AJAX_table.py @@ -0,0 +1,153 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import cPickle +import os +import MySQLdb +import time +import pyXLWriter as xl + +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig +from THCell import THCell +from TDCell import TDCell +import webqtlUtil + + +class AJAX_table: + def __init__(self, fd): + file = fd.formdata.getfirst("file", "") + sort = fd.formdata.getfirst("sort", "") + order = fd.formdata.getfirst("order", "up") + cmd = fd.formdata.getfirst("cmd", "") + tableID = fd.formdata.getfirst("tableID", "") + addIndex = fd.formdata.getfirst("addIndex", "1") + hiddenColumnsString = fd.formdata.getfirst("hiddenColumns", "") + hiddenColumns = hiddenColumnsString.split(',') + + try: + fp = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'rb') + tblobj = cPickle.load(fp) + fp.close() + + if cmd == 'addCorr': + dbId = int(fd.formdata.getfirst("db")) + dbFullName = fd.formdata.getfirst("dbname") + trait = fd.formdata.getfirst("trait") + form = fd.formdata.getfirst("form") + ids = fd.formdata.getfirst("ids") + vals = fd.formdata.getfirst("vals") + ids = eval(ids) + nnCorr = len(ids) + vals = eval(vals) + + workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+file)) + worksheet = workbook.add_worksheet() + + con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) + cursor = con.cursor() + + cursor.execute("Select name, ShortName from ProbeSetFreeze where Id = %s", dbId) + dbName, dbShortName = cursor.fetchone() + + tblobj['header'][0].append( + THCell(HT.TD(dbShortName, Class="fs11 ffl b1 cw cbrb"), + text="%s" % dbShortName, idx=tblobj['header'][0][-1].idx + 1), + ) + + headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") + for i, item in enumerate(tblobj['header'][0]): + if (i > 0): + worksheet.write([8, i-1], item.text, headingStyle) + worksheet.set_column([i-1, i-1], 2*len(item.text)) + + for i, row in enumerate(tblobj['body']): + ProbeSetId = row[1].text + #XZ, 03/02/2009: Xiaodong changed Data to ProbeSetData + cursor.execute(""" + Select ProbeSetData.StrainId, ProbeSetData.Value + From ProbeSetData, ProbeSetXRef, ProbeSet + where ProbeSetXRef.ProbeSetFreezeId = %d AND + ProbeSetXRef.DataId = ProbeSetData.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSet.Name = '%s' + """ % (dbId, ProbeSetId)) + results = cursor.fetchall() + vdict = {} + for item in results: + vdict[item[0]] = item[1] + newvals = [] + for id in ids: + if vdict.has_key(id): + newvals.append(vdict[id]) + else: + newvals.append(None) + corr,nOverlap= webqtlUtil.calCorrelation(newvals,vals,nnCorr) + repr = '%0.4f' % corr + row.append( + TDCell(HT.TD(HT.Href(text=repr, url="javascript:showCorrPlotThird('%s', '%s', '%s')" % (form, dbName, ProbeSetId), Class="fs11 fwn ffl"), " / ", nOverlap, Class="fs11 fwn ffl b1 c222", align="middle"),repr,abs(corr)) + ) + + last_row=0 + for j, item in enumerate(tblobj['body'][i]): + if (j > 0): + worksheet.write([9+i, j-1], item.text) + last_row = 9+i + last_row += 1 + + titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray") + ##Write title Info + # Modified by Hongqiang Li + worksheet.write([0, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) + worksheet.write([1, 0], "Trait : %s" % trait, titleStyle) + worksheet.write([2, 0], "Database : %s" % dbFullName, titleStyle) + worksheet.write([3, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle) + worksheet.write([4, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle) + worksheet.write([5, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle) + #Write footer info + worksheet.write([1 + last_row, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle) + worksheet.write([2 + last_row, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle) + + cursor.close() + workbook.close() + + objfile = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + else: + pass + + self.value = str(webqtlUtil.genTableObj(tblobj=tblobj, file=file, sortby=(sort, order), tableID = tableID, addIndex = addIndex, hiddenColumns = hiddenColumns)) + + except: + self.value = "The table is no longer available on this server" + + def __str__(self): + return self.value + + def write(self): + return str(self) diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py new file mode 100755 index 00000000..2401c85c --- /dev/null +++ b/wqflask/utility/Plot.py @@ -0,0 +1,1283 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import piddle as pid +from math import * +import random +import sys, os +from numarray import linear_algebra as la +from numarray import ones, array, dot, swapaxes + +import reaper + +import svg +import webqtlUtil +from base import webqtlConfig + + +def cformat(d, rank=0): + 'custom string format' + strD = "%2.6f" % d + + if rank == 0: + while strD[-1] in ('0','.'): + if strD[-1] == '0' and strD[-2] == '.' and len(strD) <= 4: + break + elif strD[-1] == '.': + strD = strD[:-1] + break + else: + strD = strD[:-1] + + else: + strD = strD.split(".")[0] + + if strD == '-0.0': + strD = '0.0' + return strD + +def frange(start, end=None, inc=1.0): + "A faster range-like function that does accept float increments..." + if end == None: + end = start + 0.0 + start = 0.0 + else: + start += 0.0 # force it to be a float + count = int((end - start) / inc) + if start + count * inc != end: + # Need to adjust the count. AFAICT, it always comes up one short. + count += 1 + L = [start] * count + for i in xrange(1, count): + L[i] = start + i * inc + return L + + +def gammln(xx): + cof=[76.18009173,-86.50532033,24.01409822,-1.231739516,0.120858003e-2,-0.536382e-5] + x=xx-1.0 + tmp=x+5.5 + tmp -=(x+0.5)*log(tmp) + ser=1.0 + for item in cof: + x+=1.0 + ser+=item/x + + return -tmp+log(2.50662827465*ser) + + +def gser(a,x): + gln=gammln(a) + ITMAX=100 + EPS=3.0e-7 + + if x<=0.0: + gamser=0.0 + return [gamser,gln] + else: + ap=a + sum=1.0/a + dele=sum + for i in range(1,ITMAX+1): + ap+=1.0 + dele*=x/ap + sum+=dele + if abs(dele)=0.0: + return ans + else: + return 2.0-ans + +def calMeanVar(data): + n=len(data) + if n<2: + return None + else: + sum=reduce(lambda x,y:x+y,data,0.0) + mean=sum/n + z=data[:] + for i in range(n): + z[i]=z[i]-mean + variance=reduce(lambda x,y:x+y*y,z,0.0) + variance /= n-1 + variance =sqrt(variance) + for i in range(n): + z[i]=z[i]/variance + return z + +def inverseCumul(p): + #Coefficients in rational approximations. + a = [-3.969683028665376e+01,2.209460984245205e+02,-2.759285104469687e+02,1.383577518672690e+02,-3.066479806614716e+01,2.506628277459239e+00] + + b = [-5.447609879822406e+01,1.615858368580409e+02,-1.556989798598866e+02,6.680131188771972e+01,-1.328068155288572e+01] + + c = [-7.784894002430293e-03,-3.223964580411365e-01,-2.400758277161838e+00,-2.549732539343734e+00,4.374664141464968e+00,2.938163982698783e+00] + + d = [7.784695709041462e-03,3.224671290700398e-01,2.445134137142996e+00,3.754408661907416e+00] + + #Define break-points. + + p_low = 0.02425 + p_high = 1 - p_low + + #Rational approximation for lower region. + + if p > 0 and p < p_low: + q = sqrt(-2*log(p)) + x = (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) + + + #Rational approximation for central region. + + elif p>= p_low and p <= p_high: + q = p - 0.5 + r = q*q + x = (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /(((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1) + + #Rational approximation for upper region. + + elif p>p_high and p < 1: + q = sqrt(-2*log(1-p)) + x = -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) + + else: + return None + + if p>0 and p < 1: + e = 0.5 * erfcc(-x/sqrt(2)) - p + u = e * sqrt(2*pi) * exp(x*x/2) + x = x - u/(1 + x*u/2) + return x + else: + return None + +def gmean(lst): + N = len(lst) + if N == 0: + return 0 + else: + return (reduce(lambda x,y: x+y, lst, 0.0))/N + +def gmedian(lst2): + lst = lst2[:] + N = len(lst) + if N == 0: + return 0 + else: + lst.sort() + if N % 2 == 0: + return (lst[N/2]+lst[(N-2)/2])/2.0 + else: + return lst[(N-1)/2] + +def gpercentile(lst2, np): + lst = lst2[:] + N = len(lst) + if N == 0 or np > 100 or np < 0: + return None + else: + lst.sort() + pNadd1 = (np/100.0)*N + k = int(pNadd1) + d = pNadd1 - k + if k == 0: + return lst[0] + elif k >= N-1: + return lst[N-1] + else: + return lst[k-1] + d*(lst[k] - lst[k-1]) + +def findOutliers(vals): + + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) + + data = [('', valsOnly[:])] + + for item in data: + itemvalue = item[1] + nValue = len(itemvalue) + catValue = [] + + for item2 in itemvalue: + try: + tstrain, tvalue = item2 + except: + tvalue = item2 + if nValue <= 4: + continue + else: + catValue.append(tvalue) + + if catValue != []: + lowHinge = gpercentile(catValue, 25) + upHinge = gpercentile(catValue, 75) + Hstep = 1.5*(upHinge - lowHinge) + + outlier = [] + extreme = [] + + upperBound = upHinge + Hstep + lowerBound = lowHinge - Hstep + + for item in catValue: + if item >= upHinge + 2*Hstep: + extreme.append(item) + elif item >= upHinge + Hstep: + outlier.append(item) + else: + pass + + for item in catValue: + if item <= lowHinge - 2*Hstep: + extreme.append(item) + elif item <= lowHinge - Hstep: + outlier.append(item) + else: + pass + else: + upperBound = 1000 + lowerBound = -1000 + + return upperBound, lowerBound + + +def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabel="Value"): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + iValues = [] + for item in data: + for item2 in item[1]: + try: + iValues.append(item2[1]) + except: + iValues.append(item2) + + #draw frame + max_Y = max(iValues) + min_Y = min(iValues) + scaleY = detScale(min_Y, max_Y) + Yll = scaleY[0] + Yur = scaleY[1] + nStep = scaleY[2] + stepY = (Yur - Yll)/nStep + stepYPixel = plotHeight/(nStep) + canvas.drawRect(plotWidth+xLeftOffset, plotHeight + yTopOffset, xLeftOffset, yTopOffset) + + ##draw Y Scale + YYY = Yll + YCoord = plotHeight + yTopOffset + scaleFont=pid.Font(ttf="cour",size=11,bold=1) + for i in range(nStep+1): + strY = cformat(d=YYY, rank=0) + YCoord = max(YCoord, yTopOffset) + canvas.drawLine(xLeftOffset,YCoord,xLeftOffset-5,YCoord) + canvas.drawString(strY, xLeftOffset -30,YCoord +5,font=scaleFont) + YYY += stepY + YCoord -= stepYPixel + + ##draw X Scale + stepX = plotWidth/len(data) + XCoord = xLeftOffset + 0.5*stepX + YCoord = plotHeight + yTopOffset + scaleFont = pid.Font(ttf="tahoma",size=12,bold=0) + labelFont = pid.Font(ttf="tahoma",size=13,bold=0) + for item in data: + itemname, itemvalue = item + canvas.drawLine(XCoord, YCoord,XCoord, YCoord+5, color=pid.black) + canvas.drawString(itemname, XCoord - canvas.stringWidth(itemname,font=labelFont)/2.0,\ + YCoord +20,font=labelFont) + + nValue = len(itemvalue) + catValue = [] + for item2 in itemvalue: + try: + tstrain, tvalue = item2 + except: + tvalue = item2 + if nValue <= 4: + canvas.drawCross(XCoord, plotHeight + yTopOffset - (tvalue-Yll)*plotHeight/(Yur - Yll), color=pid.red,size=5) + else: + catValue.append(tvalue) + if catValue != []: + catMean = gmean(catValue) + catMedian = gmedian(catValue) + lowHinge = gpercentile(catValue, 25) + upHinge = gpercentile(catValue, 75) + Hstep = 1.5*(upHinge - lowHinge) + + outlier = [] + extrem = [] + + upperAdj = None + for item in catValue: + if item >= upHinge + 2*Hstep: + extrem.append(item) + elif item >= upHinge + Hstep: + outlier.append(item) + elif item > upHinge and item < upHinge + Hstep: + if upperAdj == None or item > upperAdj: + upperAdj = item + else: + pass + lowerAdj = None + for item in catValue: + if item <= lowHinge - 2*Hstep: + extrem.append(item) + elif item <= lowHinge - Hstep: + outlier.append(item) + if item < lowHinge and item > lowHinge - Hstep: + if lowerAdj == None or item < lowerAdj: + lowerAdj = item + else: + pass + canvas.drawRect(XCoord-20, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll)) + if upperAdj != None: + canvas.drawLine(XCoord, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) + if lowerAdj != None: + canvas.drawLine(XCoord, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) + + outlierFont = pid.Font(ttf="cour",size=12,bold=0) + if outlier != []: + for item in outlier: + yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) + #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) + canvas.drawString('o', XCoord-3, yc+5, font=outlierFont, color=pid.orange) + if extrem != []: + for item in extrem: + yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) + #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) + canvas.drawString('*', XCoord-3, yc+6, font=outlierFont, color=pid.red) + + canvas.drawCross(XCoord, plotHeight + yTopOffset - (catMean-Yll)*plotHeight/(Yur - Yll), \ + color=pid.blue,size=3) + #print (catMean, catMedian, cat25per, cat75per) + pass + + XCoord += stepX + + labelFont=pid.Font(ttf="verdana",size=18,bold=0) + canvas.drawString(XLabel, xLeftOffset + (plotWidth -canvas.stringWidth(XLabel,font=labelFont))/2.0, \ + YCoord +40, font=labelFont) + canvas.drawString(YLabel,xLeftOffset-40, YCoord-(plotHeight -canvas.stringWidth(YLabel,font=labelFont))/2.0,\ + font=labelFont, angle =90) + +def plotSecurity(canvas, text="12345"): + if not text: + return + + plotWidth = canvas.size[0] + plotHeight = canvas.size[1] + if plotHeight<=0 or plotWidth<=0: + return + + bgColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) + canvas.drawRect(0,0,plotWidth,plotHeight, edgeColor=bgColor, fillColor=bgColor) + + for i in range(30): + randomColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) + scaleFont=pid.Font(ttf="cour",size=random.choice(range(20, 50))) + canvas.drawString(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), + int(random.random()*plotWidth), int(random.random()*plotHeight), font=scaleFont, + color=randomColor, angle=random.choice(range(-45, 50))) + + step = (plotWidth-20)/len(text) + startX = 20 + for item in text: + randomColor = pid.Color(0.6*random.random(),0.6*random.random(), 0.6*random.random()) + scaleFont=pid.Font(ttf="verdana",size=random.choice(range(50, 60)),bold=1) + canvas.drawString(item, startX, plotHeight/2-10, font=scaleFont, + color=randomColor, angle=random.choice(range(-45, 50))) + startX += step + +# parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py) +# or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) +def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + + if len(data) < 2: + return + + max_D = max(data) + min_D = min(data) + #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong + if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: + max_D=webqtlConfig.MAXLRS #maximum LRS value + + xLow, xTop, stepX = detScale(min_D, max_D) + + #reduce data + step = ceil((xTop-xLow)/50.0) + j = xLow + dataXY = [] + Count = [] + while j <= xTop: + dataXY.append(j) + Count.append(0) + j += step + + for i, item in enumerate(data): + if item == float('inf') or item>webqtlConfig.MAXLRS: + item = webqtlConfig.MAXLRS #maximum LRS value + j = int((item-xLow)/step) + Count[j] += 1 + + yLow, yTop, stepY=detScale(0,max(Count)) + + #draw data + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + barWidth = xScale*step + + for i, count in enumerate(Count): + if count: + xc = (dataXY[i]-xLow)*xScale+xLeftOffset + yc =-(count-yLow)*yScale+yTopOffset+plotHeight + canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) + + #draw drawing region + canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) + + #draw scale + scaleFont=pid.Font(ttf="cour",size=11,bold=1) + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) + strX = cformat(d=x, rank=0) + canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) + strY = "%d" %y + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) + y+= (yTop - yLow)/stepY + + #draw label + labelFont=pid.Font(ttf="tahoma",size=17,bold=0) + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, + yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, + font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=16,bold=0) + if title: + canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, + 20,font=labelFont,color=labelColor) + +def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, sLabel = None, offset= (80, 20, 40, 100), barSpace = 2, zoom = 1): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + + NNN = len(data) + if NNN < 2 or NNN != len(label): + return + if variance and len(variance)!=NNN: + variance = [] + + Y2 = data[:] + if variance: + for i in range(NNN): + if variance[i]: + Y2 += [data[i]-variance[i]] + + #Y axis + YLow, YTop, stepY = detScale(min(Y2), max(Y2)) + YScale = plotHeight/(YTop - YLow) + + if YLow < 0 and YTop > 0: + drawZero = 1 + else: + drawZero = 0 + + #X axis + X = range(NNN) + Xll= 0 + Xur= NNN-1 + + + if drawZero: + YZero = yTopOffset+plotHeight-YScale*(0-YLow) + canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) + else: + YZero = yTopOffset+plotHeight + #draw data + spaceWidth = barSpace + if spaceWidth < 1: + spaceWidth = 1 + barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) + + xc= xLeftOffset + scaleFont=pid.Font(ttf="verdana",size=11,bold=0) + for i in range(NNN): + yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale + canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) + if variance and variance[i]: + varlen = variance[i]*YScale + if yc-varlen < yTopOffset: + topYd = yTopOffset + else: + topYd = yc-varlen + canvas.drawLine(xc+barWidth/2-2,yc-varlen,xc+barWidth/2+2,yc-varlen,color=pid.red) + canvas.drawLine(xc+barWidth/2,yc+varlen,xc+barWidth/2,topYd,color=pid.red) + canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) + strX = label[i] + canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) + xc += barWidth + spaceWidth + + #draw drawing region + canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) + + #draw Y scale + scaleFont=pid.Font(ttf="cour",size=16,bold=1) + y=YLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-YLow)*YScale + canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) + strY = cformat(d=y, rank=0) + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) + y+= (YTop - YLow)/stepY + + #draw label + labelFont=pid.Font(ttf="verdana",size=17,bold=0) + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=18,bold=0) + if title: + canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) + + return + +def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, axesColor=pid.black, labelColor=pid.black, lineSize="thin", lineColor=pid.grey, idFont="arial", idColor=pid.blue, idSize="14", symbolColor=pid.black, symbolType="circle", filled="yes", symbolSize="tiny", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1, bufferSpace = 15): + 'displayR : correlation scatter plot, loadings : loading plot' + + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) + + #get ID font size + idFontSize = int(idSize) + + #If filled is yes, set fill color + if filled == "yes": + fillColor = symbolColor + else: + fillColor = None + + if symbolSize == "large": + sizeModifier = 7 + fontModifier = 12 + elif symbolSize == "medium": + sizeModifier = 5 + fontModifier = 8 + elif symbolSize == "small": + sizeModifier = 3 + fontModifier = 3 + else: + sizeModifier = 1 + fontModifier = -1 + + if rank == 0: # Pearson correlation + bufferSpace = 0 + dataXPrimary = dataX + dataYPrimary = dataY + dataXAlt = dataXRanked #Values used just for printing the other corr type to the graph image + dataYAlt = dataYRanked #Values used just for printing the other corr type to the graph image + else: # Spearman correlation: Switching Ranked and Unranked X and Y values + dataXPrimary = dataXRanked + dataYPrimary = dataYRanked + dataXAlt = dataX #Values used just for printing the other corr type to the graph image + dataYAlt = dataY #Values used just for printing the other corr type to the graph image + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): + return + + max_X=max(dataXPrimary) + min_X=min(dataXPrimary) + max_Y=max(dataYPrimary) + min_Y=min(dataYPrimary) + + #for some reason I forgot why I need to do this + if loadingPlot: + min_X = min(-0.1,min_X) + max_X = max(0.1,max_X) + min_Y = min(-0.1,min_Y) + max_Y = max(0.1,max_Y) + + xLow, xTop, stepX=detScale(min_X,max_X) + yLow, yTop, stepY=detScale(min_Y,max_Y) + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + + #draw drawing region + canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) + canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) + + #calculate data points + data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) + xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) + + labelFont=pid.Font(ttf=idFont,size=idFontSize,bold=0) + + if loadingPlot: + xZero = -xLow*xScale+xLeftOffset + yZero = yTopOffset+plotHeight+yLow*yScale + for point in xCoord: + canvas.drawLine(xZero,yZero,point[0],point[1],color=pid.red) + else: + if connectdot: + canvas.drawPolygon(xCoord,edgeColor=plotColor,closed=0) + else: + pass + + symbolFont = pid.Font(ttf="fnt_bs", size=12+fontModifier,bold=0) + + for i, item in enumerate(xCoord): + if dataLabel and dataLabel[i] in specialCases: + canvas.drawRect(item[0]-3, item[1]-3, item[0]+3, item[1]+3, edgeColor=pid.green) + #canvas.drawCross(item[0],item[1],color=pid.blue,size=5) + else: + if symbolType == "vertRect": + canvas.drawRect(x1=item[0]-sizeModifier+2,y1=item[1]-sizeModifier-2, x2=item[0]+sizeModifier-1,y2=item[1]+sizeModifier+2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "circle" and filled != "yes"): + canvas.drawString(":", item[0]-canvas.stringWidth(":",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) + elif (symbolType == "circle" and filled == "yes"): + canvas.drawString("5", item[0]-canvas.stringWidth("5",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) + elif symbolType == "horiRect": + canvas.drawRect(x1=item[0]-sizeModifier-1,y1=item[1]-sizeModifier+3, x2=item[0]+sizeModifier+3,y2=item[1]+sizeModifier-2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "square"): + canvas.drawRect(x1=item[0]-sizeModifier+1,y1=item[1]-sizeModifier-4, x2=item[0]+sizeModifier+2,y2=item[1]+sizeModifier-3, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "diamond" and filled != "yes"): + canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) + elif (symbolType == "diamond" and filled == "yes"): + canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) + elif symbolType == "4-star": + canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + elif symbolType == "3-star": + canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + else: + canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) + + if showLabel and dataLabel: + if (symbolType == "vertRect" or symbolType == "diamond"): + labelGap = 15 + elif (symbolType == "4-star" or symbolType == "3-star"): + labelGap = 12 + else: + labelGap = 11 + canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], + font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) + + #draw scale + scaleFont=pid.Font(ttf="cour",size=16,bold=1) + + + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + if ((x == 0) & (rank == 1)): + pass + else: + canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) + strX = cformat(d=x, rank=rank) + if ((strX == "0") & (rank == 1)): + pass + else: + canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + if ((y == 0) & (rank == 1)): + pass + else: + canvas.drawLine(xLeftOffset - bufferSpace,yc,xLeftOffset-5 - bufferSpace,yc, color=axesColor) + strY = cformat(d=y, rank=rank) + if ((strY == "0") & (rank == 1)): + pass + else: + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) + y+= (yTop - yLow)/stepY + + #draw label + + labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) + titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) + + if (rank == 1 and not title): + canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, + 25,font=titleFont,color=labelColor) + elif (rank == 0 and not title): + canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, + 25,font=titleFont,color=labelColor) + + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, + yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, + font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=20,bold=0) + if title: + canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, + 20,font=labelFont,color=labelColor) + + if fitcurve: + import sys + sys.argv = [ "mod_python" ] + #from numarray import linear_algebra as la + #from numarray import ones, array, dot, swapaxes + fitYY = array(dataYPrimary) + fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) + AA = dot(fitXX,swapaxes(fitXX,0,1)) + BB = dot(fitXX,fitYY) + bb = la.linear_least_squares(AA,BB)[0] + + xc1 = xLeftOffset + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + if yc1 > yTopOffset+plotHeight: + yc1 = yTopOffset+plotHeight + xc1 = (yLow-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + elif yc1 < yTopOffset: + yc1 = yTopOffset + xc1 = (yTop-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + else: + pass + + xc2 = xLeftOffset + plotWidth + yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale + if yc2 > yTopOffset+plotHeight: + yc2 = yTopOffset+plotHeight + xc2 = (yLow-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + elif yc2 < yTopOffset: + yc2 = yTopOffset + xc2 = (yTop-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + else: + pass + + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace,xc2,yc2,color=lineColor) + if lineSize == "medium": + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) + if lineSize == "thick": + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) + + + if displayR: + labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) + NNN = len(dataX) + corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] + + if NNN < 3: + corrPValue = 1.0 + else: + if abs(corr) >= 1.0: + corrPValue = 0.0 + else: + ZValue = 0.5*log((1.0+corr)/(1.0-corr)) + ZValue = ZValue*sqrt(NNN-3) + corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) + + NStr = "N = %d" % NNN + strLenN = canvas.stringWidth(NStr,font=labelFont) + + if rank == 1: + if corrPValue < 0.0000000000000001: + corrStr = "Rho = %1.3f P < 1.00 E-16" % (corr) + else: + corrStr = "Rho = %1.3f P = %3.2E" % (corr, corrPValue) + else: + if corrPValue < 0.0000000000000001: + corrStr = "r = %1.3f P < 1.00 E-16" % (corr) + else: + corrStr = "r = %1.3f P = %3.2E" % (corr, corrPValue) + strLen = canvas.stringWidth(corrStr,font=labelFont) + + canvas.drawString(NStr,xLeftOffset,yTopOffset-10,font=labelFont,color=labelColor) + canvas.drawString(corrStr,xLeftOffset+plotWidth-strLen,yTopOffset-10,font=labelFont,color=labelColor) + + return xCoord + +def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black", axesColor="black", labelColor="black", symbolColor="red", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1): + 'displayR : correlation scatter plot, loadings : loading plot' + + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) + + # Switching Ranked and Unranked X and Y values if a Spearman Rank Correlation + if rank == 0: + dataXPrimary = dataX + dataYPrimary = dataY + dataXAlt = dataXRanked + dataYAlt = dataYRanked + + else: + dataXPrimary = dataXRanked + dataYPrimary = dataYRanked + dataXAlt = dataX + dataYAlt = dataY + + + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = drawSpace.attributes['width'] - xLeftOffset - xRightOffset + plotHeight = drawSpace.attributes['height'] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): + return + + max_X=max(dataXPrimary) + min_X=min(dataXPrimary) + max_Y=max(dataYPrimary) + min_Y=min(dataYPrimary) + + #for some reason I forgot why I need to do this + if loadingPlot: + min_X = min(-0.1,min_X) + max_X = max(0.1,max_X) + min_Y = min(-0.1,min_Y) + max_Y = max(0.1,max_Y) + + xLow, xTop, stepX=detScale(min_X,max_X) + yLow, yTop, stepY=detScale(min_Y,max_Y) + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + + #draw drawing region + r = svg.rect(xLeftOffset, yTopOffset, plotWidth, plotHeight, 'none', axesColor, 1) + drawSpace.addElement(r) + + #calculate data points + data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) + xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) + labelFontF = "verdana" + labelFontS = 11 + + if loadingPlot: + xZero = -xLow*xScale+xLeftOffset + yZero = yTopOffset+plotHeight+yLow*yScale + for point in xCoord: + drawSpace.addElement(svg.line(xZero,yZero,point[0],point[1], "red", 1)) + else: + if connectdot: + pass + #drawSpace.drawPolygon(xCoord,edgeColor=plotColor,closed=0) + else: + pass + + for i, item in enumerate(xCoord): + if dataLabel and dataLabel[i] in specialCases: + drawSpace.addElement(svg.rect(item[0]-3, item[1]-3, 6, 6, "none", "green", 0.5)) + #drawSpace.drawCross(item[0],item[1],color=pid.blue,size=5) + else: + drawSpace.addElement(svg.line(item[0],item[1]+5,item[0],item[1]-5,symbolColor,1)) + drawSpace.addElement(svg.line(item[0]+5,item[1],item[0]-5,item[1],symbolColor,1)) + if showLabel and dataLabel: + pass + drawSpace.addElement(svg.text(item[0], item[1]+14, dataLabel[i], labelFontS, + labelFontF, text_anchor="middle", style="stroke:blue;stroke-width:0.5;")) + #canvas.drawString(, item[0]- canvas.stringWidth(dataLabel[i], + # font=labelFont)/2, item[1]+14, font=labelFont, color=pid.blue) + + #draw scale + #scaleFont=pid.Font(ttf="cour",size=14,bold=1) + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + drawSpace.addElement(svg.line(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, axesColor, 1)) + strX = cformat(d=x, rank=rank) + drawSpace.addElement(svg.text(xc,yTopOffset+plotHeight+20,strX,13, "courier", text_anchor="middle")) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + drawSpace.addElement(svg.line(xLeftOffset,yc,xLeftOffset-5,yc, axesColor, 1)) + strY = cformat(d=y, rank=rank) + drawSpace.addElement(svg.text(xLeftOffset-10,yc+5,strY,13, "courier", text_anchor="end")) + y+= (yTop - yLow)/stepY + + #draw label + labelFontF = "verdana" + labelFontS = 17 + if XLabel: + drawSpace.addElement(svg.text(xLeftOffset+plotWidth/2.0, + yTopOffset+plotHeight+yBottomOffset-10,XLabel, + labelFontS, labelFontF, text_anchor="middle")) + + if YLabel: + drawSpace.addElement(svg.text(xLeftOffset-50, + yTopOffset+plotHeight/2,YLabel, + labelFontS, labelFontF, text_anchor="middle", style="writing-mode:tb-rl", transform="rotate(270 %d %d)" % (xLeftOffset-50, yTopOffset+plotHeight/2))) + #drawSpace.drawString(YLabel, xLeftOffset-50, yTopOffset+plotHeight- (plotHeight-drawSpace.stringWidth(YLabel,font=labelFont))/2.0, + # font=labelFont,color=labelColor,angle=90) + + + if fitcurve: + sys.argv = [ "mod_python" ] + #from numarray import linear_algebra as la + #from numarray import ones, array, dot, swapaxes + fitYY = array(dataYPrimary) + fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) + AA = dot(fitXX,swapaxes(fitXX,0,1)) + BB = dot(fitXX,fitYY) + bb = la.linear_least_squares(AA,BB)[0] + + xc1 = xLeftOffset + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + if yc1 > yTopOffset+plotHeight: + yc1 = yTopOffset+plotHeight + xc1 = (yLow-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + elif yc1 < yTopOffset: + yc1 = yTopOffset + xc1 = (yTop-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + else: + pass + + xc2 = xLeftOffset + plotWidth + yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale + if yc2 > yTopOffset+plotHeight: + yc2 = yTopOffset+plotHeight + xc2 = (yLow-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + elif yc2 < yTopOffset: + yc2 = yTopOffset + xc2 = (yTop-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + else: + pass + + drawSpace.addElement(svg.line(xc1,yc1,xc2,yc2,"green", 1)) + + if displayR: + labelFontF = "trebuc" + labelFontS = 14 + NNN = len(dataX) + + corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] + + if NNN < 3: + corrPValue = 1.0 + else: + if abs(corr) >= 1.0: + corrPValue = 0.0 + else: + ZValue = 0.5*log((1.0+corr)/(1.0-corr)) + ZValue = ZValue*sqrt(NNN-3) + corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) + + NStr = "N of Cases=%d" % NNN + + if rank == 1: + corrStr = "Spearman's r=%1.3f P=%3.2E" % (corr, corrPValue) + else: + corrStr = "Pearson's r=%1.3f P=%3.2E" % (corr, corrPValue) + + drawSpace.addElement(svg.text(xLeftOffset,yTopOffset-10,NStr, + labelFontS, labelFontF, text_anchor="start")) + drawSpace.addElement(svg.text(xLeftOffset+plotWidth,yTopOffset-25,corrStr, + labelFontS, labelFontF, text_anchor="end")) + """ + """ + return + + +# This function determines the scale of the plot +def detScaleOld(min,max): + if min>=max: + return None + elif min == -1.0 and max == 1.0: + return [-1.2,1.2,12] + else: + a=max-min + b=floor(log10(a)) + c=pow(10.0,b) + if a < c*5.0: + c/=2.0 + #print a,b,c + low=c*floor(min/c) + high=c*ceil(max/c) + return [low,high,round((high-low)/c)] + +def detScale(min=0,max=0,bufferSpace=3): + + if min>=max: + return None + elif min == -1.0 and max == 1.0: + return [-1.2,1.2,12] + else: + a=max-min + if max != 0: + max += 0.1*a + if min != 0: + if min > 0 and min < 0.1*a: + min = 0.0 + else: + min -= 0.1*a + a=max-min + b=floor(log10(a)) + c=pow(10.0,b) + low=c*floor(min/c) + high=c*ceil(max/c) + n = round((high-low)/c) + div = 2.0 + while n < 5 or n > 15: + if n < 5: + c /= div + else: + c *= div + if div == 2.0: + div =5.0 + else: + div =2.0 + low=c*floor(min/c) + high=c*ceil(max/c) + n = round((high-low)/c) + + return [low,high,n] + + + +def colorSpectrumOld(n): + if n == 1: + return [pid.Color(1,0,0)] + elif n == 2: + return [pid.Color(1,0,0),pid.Color(0,0,1)] + elif n == 3: + return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] + else: + step = 2.0/(n-1) + red = 1.0 + green = 0.0 + blue = 0.0 + colors = [pid.Color(red,green,blue)] + i = 1 + greenpeak = 0 + while i < n: + if red >= step: + red -= step + green += step + if green >= 1.0: + greenpeak = 1 + blue += green -1.0 + green = 1.0 + else: + red = 0.0 + if greenpeak: + green -= step + blue += step + else: + green += step + if green >= 1.0: + greenpeak = 1 + blue += green -1.0 + green = 2.0 -green + elif green < 0.0: + green = 0.0 + else: + pass + colors.append(pid.Color(red,green,blue)) + i += 1 + return colors + + + + +def bluefunc(x): + return 1.0 / (1.0 + exp(-10*(x-0.6))) + + +def redfunc(x): + return 1.0 / (1.0 + exp(10*(x-0.5))) + +def greenfunc(x): + return 1 - pow(redfunc(x+0.2),2) - bluefunc(x-0.3) + +def colorSpectrum(n=100): + multiple = 10 + if n == 1: + return [pid.Color(1,0,0)] + elif n == 2: + return [pid.Color(1,0,0),pid.Color(0,0,1)] + elif n == 3: + return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] + N = n*multiple + out = [None]*N; + for i in range(N): + x = float(i)/N + out[i] = pid.Color(redfunc(x), greenfunc(x), bluefunc(x)); + out2 = [out[0]] + step = N/float(n-1) + j = 0 + for i in range(n-2): + j += step + out2.append(out[int(j)]) + out2.append(out[-1]) + return out2 + + +def colorSpectrumSVG(n=100): + multiple = 10 + if n == 1: + return ["rgb(255,0,0)"] + elif n == 2: + return ["rgb(255,0,0)","rgb(0,0,255)"] + elif n == 3: + return ["rgb(255,0,0)","rgb(0,255,0)","rgb(0,0,255)"] + N = n*multiple + out = [None]*N; + for i in range(N): + x = float(i)/N + out[i] = "rgb(%d, %d, %d)" % (redfunc(x)*255, greenfunc(x)*255, bluefunc(x)*255); + out2 = [out[0]] + step = N/float(n-1) + j = 0 + for i in range(n-2): + j += step + out2.append(out[int(j)]) + out2.append(out[-1]) + return out2 + + +def BWSpectrum(n=100): + multiple = 10 + if n == 1: + return [pid.Color(0,0,0)] + elif n == 2: + return [pid.Color(0,0,0),pid.Color(1,1,1)] + elif n == 3: + return [pid.Color(0,0,0),pid.Color(0.5,0.5,0.5),pid.Color(1,1,1)] + + step = 1.0/n + x = 0.0 + out = [] + for i in range(n): + out.append(pid.Color(x,x,x)); + x += step + return out diff --git a/wqflask/utility/TDCell.py b/wqflask/utility/TDCell.py new file mode 100755 index 00000000..76b9c5db --- /dev/null +++ b/wqflask/utility/TDCell.py @@ -0,0 +1,42 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +########################################################## +# +# Table Cell Class +# +########################################################## + + +class TDCell: + def __init__(self, html="", text="", val=0.0): + self.html = html #html, for web page + self.text = text #text value, for output to a text file + self.val = val #sort by value + + def __str__(self): + return self.text + diff --git a/wqflask/utility/THCell.py b/wqflask/utility/THCell.py new file mode 100755 index 00000000..a96b9e49 --- /dev/null +++ b/wqflask/utility/THCell.py @@ -0,0 +1,44 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +########################################################## +# +# Table Header Class +# +########################################################## + + +class THCell: + def __init__(self, html="", text="", sort=1, idx=-1): + self.html = html #html, for web page + self.text = text #Column text value + self.sort = sort #0: not sortable, 1: yes + self.idx = idx #sort by value + + def __str__(self): + return self.text + + diff --git a/wqflask/utility/__init__.py b/wqflask/utility/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/utility/formatting.py b/wqflask/utility/formatting.py new file mode 100644 index 00000000..52173417 --- /dev/null +++ b/wqflask/utility/formatting.py @@ -0,0 +1,109 @@ +def numify(number, singular=None, plural=None): + """Turn a number into a word if less than 13 and optionally add a singular or plural word + + >>> numify(3) + 'three' + + >>> numify(1, 'item', 'items') + 'one item' + + >>> numify(9, 'book', 'books') + 'nine books' + + >>> numify(15) + '15' + + >>> numify(0) + '0' + + >>> numify(12334, 'hippopotamus', 'hippopotami') + '12,334 hippopotami' + + """ + num_repr = {1 : "one", + 2 : "two", + 3 : "three", + 4 : "four", + 5 : "five", + 6 : "six", + 7 : "seven", + 8 : "eight", + 9 : "nine", + 10 : "ten", + 11 : "eleven", + 12 : "twelve"} + + #Below line commented out cause doesn't work in Python 2.4 + #assert all((singular, plural)) or not any((singular, plural)), "Need to pass two words or none" + if number == 1: + word = singular + else: + word = plural + + if number in num_repr: + number = num_repr[number] + elif number > 9999: + number = commify(number) + + if word: + return "%s %s" % (number, word) + else: + return str(number) + + +def commify(n): + """Add commas to an integer n. + + See http://stackoverflow.com/questions/3909457/whats-the-easiest-way-to-add-commas-to-an-integer-in-python + But I (Sam) made some small changes based on http://www.grammarbook.com/numbers/numbers.asp + + >>> commify(1) + '1' + >>> commify(123) + '123' + >>> commify(1234) + '1234' + >>> commify(12345) + '12,345' + >>> commify(1234567890) + '1,234,567,890' + >>> commify(123.0) + '123.0' + >>> commify(1234.5) + '1234.5' + >>> commify(1234.56789) + '1234.56789' + >>> commify(123456.789) + '123,456.789' + >>> commify('%.2f' % 1234.5) + '1234.50' + >>> commify(None) + >>> + + """ + if n is None: + return None + + n = str(n) + + if len(n) <= 4: # Might as well do this early + return n + + if '.' in n: + dollars, cents = n.split('.') + else: + dollars, cents = n, None + + # Don't commify numbers less than 10000 + if len(dollars) <= 4: + return n + + r = [] + for i, c in enumerate(reversed(str(dollars))): + if i and (not (i % 3)): + r.insert(0, ',') + r.insert(0, c) + out = ''.join(r) + if cents: + out += '.' + cents + return out diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py new file mode 100755 index 00000000..e49a6c3c --- /dev/null +++ b/wqflask/utility/svg.py @@ -0,0 +1,1069 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +#!/usr/bin/env python +##Copyright (c) 2002, Fedor Baart & Hans de Wit (Stichting Farmaceutische Kengetallen) +##All rights reserved. +## +##Redistribution and use in source and binary forms, with or without modification, +##are permitted provided that the following conditions are met: +## +##Redistributions of source code must retain the above copyright notice, this +##list of conditions and the following disclaimer. +## +##Redistributions in binary form must reproduce the above copyright notice, +##this list of conditions and the following disclaimer in the documentation and/or +##other materials provided with the distribution. +## +##Neither the name of the Stichting Farmaceutische Kengetallen nor the names of +##its contributors may be used to endorse or promote products derived from this +##software without specific prior written permission. +## +##THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +##AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +##IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +##DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +##FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +##DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +##SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +##CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +##OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +##OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +##Thanks to Gerald Rosennfellner for his help and useful comments. + +__doc__="""Use SVGdraw to generate your SVGdrawings. + +SVGdraw uses an object model drawing and a method toXML to create SVG graphics +by using easy to use classes and methods usualy you start by creating a drawing eg + + d=drawing() + #then you create a SVG root element + s=svg() + #then you add some elements eg a circle and add it to the svg root element + c=circle() + #you can supply attributes by using named arguments. + c=circle(fill='red',stroke='blue') + #or by updating the attributes attribute: + c.attributes['stroke-width']=1 + s.addElement(c) + #then you add the svg root element to the drawing + d.setSVG(s) + #and finaly you xmlify the drawing + d.toXml() + + +this results in the svg source of the drawing, which consists of a circle +on a white background. Its as easy as that;) +This module was created using the SVG specification of www.w3c.org and the +O'Reilly (www.oreilly.com) python books as information sources. A svg viewer +is available from www.adobe.com""" + +__version__="1.0" + +# there are two possibilities to generate svg: +# via a dom implementation and directly using text strings +# the latter is way faster (and shorter in coding) +# the former is only used in debugging svg programs +# maybe it will be removed alltogether after a while +# with the following variable you indicate whether to use the dom implementation +# Note that PyXML is required for using the dom implementation. +# It is also possible to use the standard minidom. But I didn't try that one. +# Anyway the text based approach is about 60 times faster than using the full dom implementation. +use_dom_implementation=0 + + +import exceptions +if use_dom_implementation<>0: + try: + from xml.dom import implementation + from xml.dom.ext import PrettyPrint + except: + raise exceptions.ImportError, "PyXML is required for using the dom implementation" +#The implementation is used for the creating the XML document. +#The prettyprint module is used for converting the xml document object to a xml file + +import sys +assert sys.version_info[0]>=2 +if sys.version_info[1]<2: + True=1 + False=0 + file=open + +sys.setrecursionlimit=50 +#The recursion limit is set conservative so mistakes like s=svg() s.addElement(s) +#won't eat up too much processor time. + +#the following code is pasted form xml.sax.saxutils +#it makes it possible to run the code without the xml sax package installed +#To make it possible to have in your text elements, it is necessary to escape the texts +def _escape(data, entities={}): + """Escape &, <, and > in a string of data. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + #data = data.replace("&", "&") + data = data.replace("<", "<") + data = data.replace(">", ">") + for chars, entity in entities.items(): + data = data.replace(chars, entity) + return data + +def _quoteattr(data, entities={}): + """Escape and quote an attribute value. + + Escape &, <, and > in a string of data, then quote it for use as + an attribute value. The \" character will be escaped as well, if + necessary. + + You can escape other strings of data by passing a dictionary as + the optional entities parameter. The keys and values must all be + strings; each key will be replaced with its corresponding value. + """ + data = _escape(data, entities) + if '"' in data: + if "'" in data: + data = '"%s"' % data.replace('"', """) + else: + data = "'%s'" % data + else: + data = '"%s"' % data + return data + + + +def _xypointlist(a): + """formats a list of xy pairs""" + s='' + for e in a: #this could be done more elegant + s+=str(e)[1:-1] +' ' + return s + +def _viewboxlist(a): + """formats a tuple""" + s='' + for e in a: + s+=str(e)+' ' + return s + +def _pointlist(a): + """formats a list of numbers""" + return str(a)[1:-1] + +class pathdata: + """class used to create a pathdata object which can be used for a path. + although most methods are pretty straightforward it might be useful to look at the SVG specification.""" + #I didn't test the methods below. + def __init__(self,x=None,y=None): + self.path=[] + if x is not None and y is not None: + self.path.append('M '+str(x)+' '+str(y)) + def closepath(self): + """ends the path""" + self.path.append('z') + def move(self,x,y): + """move to absolute""" + self.path.append('M '+str(x)+' '+str(y)) + def relmove(self,x,y): + """move to relative""" + self.path.append('m '+str(x)+' '+str(y)) + def line(self,x,y): + """line to absolute""" + self.path.append('L '+str(x)+' '+str(y)) + def relline(self,x,y): + """line to relative""" + self.path.append('l '+str(x)+' '+str(y)) + def hline(self,x): + """horizontal line to absolute""" + self.path.append('H'+str(x)) + def relhline(self,x): + """horizontal line to relative""" + self.path.append('h'+str(x)) + def vline(self,y): + """verical line to absolute""" + self.path.append('V'+str(y)) + def relvline(self,y): + """vertical line to relative""" + self.path.append('v'+str(y)) + def bezier(self,x1,y1,x2,y2,x,y): + """bezier with xy1 and xy2 to xy absolut""" + self.path.append('C'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) + def relbezier(self,x1,y1,x2,y2,x,y): + """bezier with xy1 and xy2 to xy relative""" + self.path.append('c'+str(x1)+','+str(y1)+' '+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) + def smbezier(self,x2,y2,x,y): + """smooth bezier with xy2 to xy absolut""" + self.path.append('S'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) + def relsmbezier(self,x2,y2,x,y): + """smooth bezier with xy2 to xy relative""" + self.path.append('s'+str(x2)+','+str(y2)+' '+str(x)+','+str(y)) + def qbezier(self,x1,y1,x,y): + """quadratic bezier with xy1 to xy absolut""" + self.path.append('Q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) + def relqbezier(self,x1,y1,x,y): + """quadratic bezier with xy1 to xy relative""" + self.path.append('q'+str(x1)+','+str(y1)+' '+str(x)+','+str(y)) + def smqbezier(self,x,y): + """smooth quadratic bezier to xy absolut""" + self.path.append('T'+str(x)+','+str(y)) + def relsmqbezier(self,x,y): + """smooth quadratic bezier to xy relative""" + self.path.append('t'+str(x)+','+str(y)) + def ellarc(self,rx,ry,xrot,laf,sf,x,y): + """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy absolut""" + self.path.append('A'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) + def relellarc(self,rx,ry,xrot,laf,sf,x,y): + """elliptival arc with rx and ry rotating with xrot using large-arc-flag and sweep-flag to xy relative""" + self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) + def __repr__(self): + return ' '.join(self.path) + + + + +class SVGelement: + """SVGelement(type,attributes,elements,text,namespace,**args) + Creates a arbitrary svg element and is intended to be subclassed not used on its own. + This element is the base of every svg element it defines a class which resembles + a xml-element. The main advantage of this kind of implementation is that you don't + have to create a toXML method for every different graph object. Every element + consists of a type, attribute, optional subelements, optional text and an optional + namespace. Note the elements==None, if elements = None:self.elements=[] construction. + This is done because if you default to elements=[] every object has a reference + to the same empty list.""" + def __init__(self,type='',attributes=None,elements=None,text='',namespace='',cdata=None, **args): + self.type=type + if attributes==None: + self.attributes={} + else: + self.attributes=attributes + if elements==None: + self.elements=[] + else: + self.elements=elements + self.text=text + self.namespace=namespace + self.cdata=cdata + for arg in args.keys(): + arg2 = arg.replace("__", ":") + arg2 = arg2.replace("_", "-") + self.attributes[arg2]=args[arg] + def addElement(self,SVGelement): + """adds an element to a SVGelement + + SVGelement.addElement(SVGelement) + """ + self.elements.append(SVGelement) + + def toXml(self,level,f): + f.write('\t'*level) + f.write('<'+self.type) + for attkey in self.attributes.keys(): + f.write(' '+_escape(str(attkey))+'='+_quoteattr(str(self.attributes[attkey]))) + if self.namespace: + f.write(' xmlns="'+ _escape(str(self.namespace))+'" xmlns:xlink="http://www.w3.org/1999/xlink"') + if self.elements or self.text or self.cdata: + f.write('>') + if self.elements: + f.write('\n') + for element in self.elements: + element.toXml(level+1,f) + if self.cdata: + f.write('\n'+'\t'*(level+1)+'\n') + if self.text: + if type(self.text)==type(''): #If the text is only text + f.write(_escape(str(self.text))) + else: #If the text is a spannedtext class + f.write(str(self.text)) + if self.elements: + f.write('\t'*level+'\n') + elif self.text: + f.write('\n') + elif self.cdata: + f.write('\t'*level+'\n') + else: + f.write('/>\n') + +class tspan(SVGelement): + """ts=tspan(text='',**args) + + a tspan element can be used for applying formatting to a textsection + usage: + ts=tspan('this text is bold') + ts.attributes['font-weight']='bold' + st=spannedtext() + st.addtspan(ts) + t=text(3,5,st) + """ + def __init__(self,text=None,**args): + SVGelement.__init__(self,'tspan',**args) + if self.text<>None: + self.text=text + def __repr__(self): + s="None: + raise ValueError, 'height is required' + if height<>None: + raise ValueError, 'width is required' + else: + raise ValueError, 'both height and width are required' + SVGelement.__init__(self,'rect',{'width':width,'height':height},**args) + if x<>None: + self.attributes['x']=x + if y<>None: + self.attributes['y']=y + if fill<>None: + self.attributes['fill']=fill + if stroke<>None: + self.attributes['stroke']=stroke + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + +class ellipse(SVGelement): + """e=ellipse(rx,ry,x,y,fill,stroke,stroke_width,**args) + + an ellipse is defined as a center and a x and y radius. + """ + def __init__(self,cx=None,cy=None,rx=None,ry=None,fill=None,stroke=None,stroke_width=None,**args): + if rx==None or ry== None: + if rx<>None: + raise ValueError, 'rx is required' + if ry<>None: + raise ValueError, 'ry is required' + else: + raise ValueError, 'both rx and ry are required' + SVGelement.__init__(self,'ellipse',{'rx':rx,'ry':ry},**args) + if cx<>None: + self.attributes['cx']=cx + if cy<>None: + self.attributes['cy']=cy + if fill<>None: + self.attributes['fill']=fill + if stroke<>None: + self.attributes['stroke']=stroke + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + + +class circle(SVGelement): + """c=circle(x,y,radius,fill,stroke,stroke_width,**args) + + The circle creates an element using a x, y and radius values eg + """ + def __init__(self,cx=None,cy=None,r=None,fill=None,stroke=None,stroke_width=None,**args): + if r==None: + raise ValueError, 'r is required' + SVGelement.__init__(self,'circle',{'r':r},**args) + if cx<>None: + self.attributes['cx']=cx + if cy<>None: + self.attributes['cy']=cy + if fill<>None: + self.attributes['fill']=fill + if stroke<>None: + self.attributes['stroke']=stroke + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + +class point(circle): + """p=point(x,y,color) + + A point is defined as a circle with a size 1 radius. It may be more efficient to use a + very small rectangle if you use many points because a circle is difficult to render. + """ + def __init__(self,x,y,fill='black',**args): + circle.__init__(self,x,y,1,fill,**args) + +class line(SVGelement): + """l=line(x1,y1,x2,y2,stroke,stroke_width,**args) + + A line is defined by a begin x,y pair and an end x,y pair + """ + def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args): + SVGelement.__init__(self,'line',**args) + if x1<>None: + self.attributes['x1']=x1 + if y1<>None: + self.attributes['y1']=y1 + if x2<>None: + self.attributes['x2']=x2 + if y2<>None: + self.attributes['y2']=y2 + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + if stroke<>None: + self.attributes['stroke']=stroke + +class polyline(SVGelement): + """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) + + a polyline is defined by a list of xy pairs + """ + def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): + SVGelement.__init__(self,'polyline',{'points':_xypointlist(points)},**args) + if fill<>None: + self.attributes['fill']=fill + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + if stroke<>None: + self.attributes['stroke']=stroke + +class polygon(SVGelement): + """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) + + a polygon is defined by a list of xy pairs + """ + def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): + SVGelement.__init__(self,'polygon',{'points':_xypointlist(points)},**args) + if fill<>None: + self.attributes['fill']=fill + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + if stroke<>None: + self.attributes['stroke']=stroke + +class path(SVGelement): + """p=path(path,fill,stroke,stroke_width,**args) + + a path is defined by a path object and optional width, stroke and fillcolor + """ + def __init__(self,pathdata,fill=None,stroke=None,stroke_width=None,id=None,**args): + SVGelement.__init__(self,'path',{'d':str(pathdata)},**args) + if stroke<>None: + self.attributes['stroke']=stroke + if fill<>None: + self.attributes['fill']=fill + if stroke_width<>None: + self.attributes['stroke-width']=stroke_width + if id<>None: + self.attributes['id']=id + + +class text(SVGelement): + """t=text(x,y,text,font_size,font_family,**args) + + a text element can bge used for displaying text on the screen + """ + def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args): + SVGelement.__init__(self,'text',**args) + if x<>None: + self.attributes['x']=x + if y<>None: + self.attributes['y']=y + if font_size<>None: + self.attributes['font-size']=font_size + if font_family<>None: + self.attributes['font-family']=font_family + if text<>None: + self.text=text + if text_anchor<>None: + self.attributes['text-anchor']=text_anchor + + +class textpath(SVGelement): + """tp=textpath(text,link,**args) + + a textpath places a text on a path which is referenced by a link. + """ + def __init__(self,link,text=None,**args): + SVGelement.__init__(self,'textPath',{'xlink:href':link},**args) + if text<>None: + self.text=text + +class pattern(SVGelement): + """p=pattern(x,y,width,height,patternUnits,**args) + + A pattern is used to fill or stroke an object using a pre-defined + graphic object which can be replicated ("tiled") at fixed intervals + in x and y to cover the areas to be painted. + """ + def __init__(self,x=None,y=None,width=None,height=None,patternUnits=None,**args): + SVGelement.__init__(self,'pattern',**args) + if x<>None: + self.attributes['x']=x + if y<>None: + self.attributes['y']=y + if width<>None: + self.attributes['width']=width + if height<>None: + self.attributes['height']=height + if patternUnits<>None: + self.attributes['patternUnits']=patternUnits + +class title(SVGelement): + """t=title(text,**args) + + a title is a text element. The text is displayed in the title bar + add at least one to the root svg element + """ + def __init__(self,text=None,**args): + SVGelement.__init__(self,'title',**args) + if text<>None: + self.text=text + +class description(SVGelement): + """d=description(text,**args) + + a description can be added to any element and is used for a tooltip + Add this element before adding other elements. + """ + def __init__(self,text=None,**args): + SVGelement.__init__(self,'desc',**args) + if text<>None: + self.text=text + +class lineargradient(SVGelement): + """lg=lineargradient(x1,y1,x2,y2,id,**args) + + defines a lineargradient using two xy pairs. + stop elements van be added to define the gradient colors. + """ + def __init__(self,x1=None,y1=None,x2=None,y2=None,id=None,**args): + SVGelement.__init__(self,'linearGradient',**args) + if x1<>None: + self.attributes['x1']=x1 + if y1<>None: + self.attributes['y1']=y1 + if x2<>None: + self.attributes['x2']=x2 + if y2<>None: + self.attributes['y2']=y2 + if id<>None: + self.attributes['id']=id + +class radialgradient(SVGelement): + """rg=radialgradient(cx,cy,r,fx,fy,id,**args) + + defines a radial gradient using a outer circle which are defined by a cx,cy and r and by using a focalpoint. + stop elements van be added to define the gradient colors. + """ + def __init__(self,cx=None,cy=None,r=None,fx=None,fy=None,id=None,**args): + SVGelement.__init__(self,'radialGradient',**args) + if cx<>None: + self.attributes['cx']=cx + if cy<>None: + self.attributes['cy']=cy + if r<>None: + self.attributes['r']=r + if fx<>None: + self.attributes['fx']=fx + if fy<>None: + self.attributes['fy']=fy + if id<>None: + self.attributes['id']=id + +class stop(SVGelement): + """st=stop(offset,stop_color,**args) + + Puts a stop color at the specified radius + """ + def __init__(self,offset,stop_color=None,**args): + SVGelement.__init__(self,'stop',{'offset':offset},**args) + if stop_color<>None: + self.attributes['stop-color']=stop_color + +class style(SVGelement): + """st=style(type,cdata=None,**args) + + Add a CDATA element to this element for defing in line stylesheets etc.. + """ + def __init__(self,type,cdata=None,**args): + SVGelement.__init__(self,'style',{'type':type},cdata=cdata, **args) + + +class image(SVGelement): + """im=image(url,width,height,x,y,**args) + + adds an image to the drawing. Supported formats are .png, .jpg and .svg. + """ + def __init__(self,url,x=None,y=None,width=None,height=None,**args): + if width==None or height==None: + if width<>None: + raise ValueError, 'height is required' + if height<>None: + raise ValueError, 'width is required' + else: + raise ValueError, 'both height and width are required' + SVGelement.__init__(self,'image',{'xlink:href':url,'width':width,'height':height},**args) + if x<>None: + self.attributes['x']=x + if y<>None: + self.attributes['y']=y + +class cursor(SVGelement): + """c=cursor(url,**args) + + defines a custom cursor for a element or a drawing + """ + def __init__(self,url,**args): + SVGelement.__init__(self,'cursor',{'xlink:href':url},**args) + + +class marker(SVGelement): + """m=marker(id,viewbox,refX,refY,markerWidth,markerHeight,**args) + + defines a marker which can be used as an endpoint for a line or other pathtypes + add an element to it which should be used as a marker. + """ + def __init__(self,id=None,viewBox=None,refx=None,refy=None,markerWidth=None,markerHeight=None,**args): + SVGelement.__init__(self,'marker',**args) + if id<>None: + self.attributes['id']=id + if viewBox<>None: + self.attributes['viewBox']=_viewboxlist(viewBox) + if refx<>None: + self.attributes['refX']=refx + if refy<>None: + self.attributes['refY']=refy + if markerWidth<>None: + self.attributes['markerWidth']=markerWidth + if markerHeight<>None: + self.attributes['markerHeight']=markerHeight + +class group(SVGelement): + """g=group(id,**args) + + a group is defined by an id and is used to contain elements + g.addElement(SVGelement) + """ + def __init__(self,id=None,**args): + SVGelement.__init__(self,'g',**args) + if id<>None: + self.attributes['id']=id + +class symbol(SVGelement): + """sy=symbol(id,viewbox,**args) + + defines a symbol which can be used on different places in your graph using + the use element. A symbol is not rendered but you can use 'use' elements to + display it by referencing its id. + sy.addElement(SVGelement) + """ + + def __init__(self,id=None,viewBox=None,**args): + SVGelement.__init__(self,'symbol',**args) + if id<>None: + self.attributes['id']=id + if viewBox<>None: + self.attributes['viewBox']=_viewboxlist(viewBox) + +class defs(SVGelement): + """d=defs(**args) + + container for defining elements + """ + def __init__(self,**args): + SVGelement.__init__(self,'defs',**args) + +class switch(SVGelement): + """sw=switch(**args) + + Elements added to a switch element which are "switched" by the attributes + requiredFeatures, requiredExtensions and systemLanguage. + Refer to the SVG specification for details. + """ + def __init__(self,**args): + SVGelement.__init__(self,'switch',**args) + + +class use(SVGelement): + """u=use(link,x,y,width,height,**args) + + references a symbol by linking to its id and its position, height and width + """ + def __init__(self,link,x=None,y=None,width=None,height=None,**args): + SVGelement.__init__(self,'use',{'xlink:href':link},**args) + if x<>None: + self.attributes['x']=x + if y<>None: + self.attributes['y']=y + + if width<>None: + self.attributes['width']=width + if height<>None: + self.attributes['height']=height + + +class link(SVGelement): + """a=link(url,**args) + + a link is defined by a hyperlink. add elements which have to be linked + a.addElement(SVGelement) + """ + def __init__(self,link='',**args): + SVGelement.__init__(self,'a',{'xlink:href':link},**args) + +class view(SVGelement): + """v=view(id,**args) + + a view can be used to create a view with different attributes""" + def __init__(self,id=None,**args): + SVGelement.__init__(self,'view',**args) + if id<>None: + self.attributes['id']=id + +class script(SVGelement): + """sc=script(type,type,cdata,**args) + + adds a script element which contains CDATA to the SVG drawing + + """ + def __init__(self,type,cdata=None,**args): + SVGelement.__init__(self,'script',{'type':type},cdata=cdata,**args) + +class animate(SVGelement): + """an=animate(attribute,from,to,during,**args) + + animates an attribute. + """ + def __init__(self,attribute,fr=None,to=None,dur=None,**args): + SVGelement.__init__(self,'animate',{'attributeName':attribute},**args) + if fr<>None: + self.attributes['from']=fr + if to<>None: + self.attributes['to']=to + if dur<>None: + self.attributes['dur']=dur + +class animateMotion(SVGelement): + """an=animateMotion(pathdata,dur,**args) + + animates a SVGelement over the given path in dur seconds + """ + def __init__(self,pathdata,dur,**args): + SVGelement.__init__(self,'animateMotion',**args) + if pathdata<>None: + self.attributes['path']=str(pathdata) + if dur<>None: + self.attributes['dur']=dur + +class animateTransform(SVGelement): + """antr=animateTransform(type,from,to,dur,**args) + + transform an element from and to a value. + """ + def __init__(self,type=None,fr=None,to=None,dur=None,**args): + SVGelement.__init__(self,'animateTransform',{'attributeName':'transform'},**args) + #As far as I know the attributeName is always transform + if type<>None: + self.attributes['type']=type + if fr<>None: + self.attributes['from']=fr + if to<>None: + self.attributes['to']=to + if dur<>None: + self.attributes['dur']=dur +class animateColor(SVGelement): + """ac=animateColor(attribute,type,from,to,dur,**args) + + Animates the color of a element + """ + def __init__(self,attribute,type=None,fr=None,to=None,dur=None,**args): + SVGelement.__init__(self,'animateColor',{'attributeName':attribute},**args) + if type<>None: + self.attributes['type']=type + if fr<>None: + self.attributes['from']=fr + if to<>None: + self.attributes['to']=to + if dur<>None: + self.attributes['dur']=dur +class set(SVGelement): + """st=set(attribute,to,during,**args) + + sets an attribute to a value for a + """ + def __init__(self,attribute,to=None,dur=None,**args): + SVGelement.__init__(self,'set',{'attributeName':attribute},**args) + if to<>None: + self.attributes['to']=to + if dur<>None: + self.attributes['dur']=dur + + + +class svg(SVGelement): + """s=svg(viewbox,width,height,**args) + + a svg or element is the root of a drawing add all elements to a svg element. + You can have different svg elements in one svg file + s.addElement(SVGelement) + + eg + d=drawing() + s=svg((0,0,100,100),'100%','100%') + c=circle(50,50,20) + s.addElement(c) + d.setSVG(s) + d.toXml() + """ + def __init__(self,viewBox=None, width=None, height=None,**args): + SVGelement.__init__(self,'svg',**args) + if viewBox<>None: + self.attributes['viewBox']=_viewboxlist(viewBox) + if width<>None: + self.attributes['width']=width + if height<>None: + self.attributes['height']=height + self.namespace="http://www.w3.org/2000/svg" + +class drawing: + """d=drawing() + + this is the actual SVG document. It needs a svg element as a root. + Use the addSVG method to set the svg to the root. Use the toXml method to write the SVG + source to the screen or to a file + d=drawing() + d.addSVG(svg) + d.toXml(optionalfilename) + """ + + def __init__(self, entity={}): + self.svg=None + self.entity = entity + def setSVG(self,svg): + self.svg=svg + #Voeg een element toe aan de grafiek toe. + if use_dom_implementation==0: + def toXml(self, filename='',compress=False): + import cStringIO + xml=cStringIO.StringIO() + xml.write("\n") + xml.write("\n" % (item, self.entity[item])) + xml.write("]") + xml.write(">\n") + self.svg.toXml(0,xml) + if not filename: + if compress: + import gzip + f=cStringIO.StringIO() + zf=gzip.GzipFile(fileobj=f,mode='wb') + zf.write(xml.getvalue()) + zf.close() + f.seek(0) + return f.read() + else: + return xml.getvalue() + else: + if filename[-4:]=='svgz': + import gzip + f=gzip.GzipFile(filename=filename,mode="wb", compresslevel=9) + f.write(xml.getvalue()) + f.close() + else: + f=file(filename,'w') + f.write(xml.getvalue()) + f.close() + + else: + def toXml(self,filename='',compress=False): + """drawing.toXml() ---->to the screen + drawing.toXml(filename)---->to the file + writes a svg drawing to the screen or to a file + compresses if filename ends with svgz or if compress is true + """ + doctype = implementation.createDocumentType('svg',"-//W3C//DTD SVG 1.0//EN""",'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ') + + global root + #root is defined global so it can be used by the appender. Its also possible to use it as an arugument but + #that is a bit messy. + root=implementation.createDocument(None,None,doctype) + #Create the xml document. + global appender + def appender(element,elementroot): + """This recursive function appends elements to an element and sets the attributes + and type. It stops when alle elements have been appended""" + if element.namespace: + e=root.createElementNS(element.namespace,element.type) + else: + e=root.createElement(element.type) + if element.text: + textnode=root.createTextNode(element.text) + e.appendChild(textnode) + for attribute in element.attributes.keys(): #in element.attributes is supported from python 2.2 + e.setAttribute(attribute,str(element.attributes[attribute])) + if element.elements: + for el in element.elements: + e=appender(el,e) + elementroot.appendChild(e) + return elementroot + root=appender(self.svg,root) + if not filename: + import cStringIO + xml=cStringIO.StringIO() + PrettyPrint(root,xml) + if compress: + import gzip + f=cStringIO.StringIO() + zf=gzip.GzipFile(fileobj=f,mode='wb') + zf.write(xml.getvalue()) + zf.close() + f.seek(0) + return f.read() + else: + return xml.getvalue() + else: + try: + if filename[-4:]=='svgz': + import gzip + import cStringIO + xml=cStringIO.StringIO() + PrettyPrint(root,xml) + f=gzip.GzipFile(filename=filename,mode='wb',compresslevel=9) + f.write(xml.getvalue()) + f.close() + else: + f=open(filename,'w') + PrettyPrint(root,f) + f.close() + except: + print "Cannot write SVG file: " + filename + def validate(self): + try: + import xml.parsers.xmlproc.xmlval + except: + raise exceptions.ImportError,'PyXml is required for validating SVG' + svg=self.toXml() + xv=xml.parsers.xmlproc.xmlval.XMLValidator() + try: + xv.feed(svg) + except: + raise "SVG is not well formed, see messages above" + else: + print "SVG well formed" +if __name__=='__main__': + + + d=drawing() + s=svg((0,0,100,100)) + r=rect(-100,-100,300,300,'cyan') + s.addElement(r) + + t=title('SVGdraw Demo') + s.addElement(t) + g=group('animations') + e=ellipse(0,0,5,2) + g.addElement(e) + c=circle(0,0,1,'red') + g.addElement(c) + pd=pathdata(0,-10) + for i in range(6): + pd.relsmbezier(10,5,0,10) + pd.relsmbezier(-10,5,0,10) + an=animateMotion(pd,10) + an.attributes['rotate']='auto-reverse' + an.attributes['repeatCount']="indefinite" + g.addElement(an) + s.addElement(g) + for i in range(20,120,20): + u=use('#animations',i,0) + s.addElement(u) + for i in range(0,120,20): + for j in range(5,105,10): + c=circle(i,j,1,'red','black',.5) + s.addElement(c) + d.setSVG(s) + + print d.toXml() + diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py new file mode 100755 index 00000000..6af7f846 --- /dev/null +++ b/wqflask/utility/webqtlUtil.py @@ -0,0 +1,977 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import string +import time +import re +import math +from math import * + +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig + + + + +# NL, 07/27/2010. moved from webqtlForm.py +#Dict of Parents and F1 information, In the order of [F1, Mat, Pat] +ParInfo ={ +'BXH':['BHF1', 'HBF1', 'C57BL/6J', 'C3H/HeJ'], +'AKXD':['AKF1', 'KAF1', 'AKR/J', 'DBA/2J'], +'BXD':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], +'BXD300':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], +'B6BTBRF2':['B6BTBRF1', 'BTBRB6F1', 'C57BL/6J', 'BTBRT<+>tf/J'], +'BHHBF2':['B6HF2','HB6F2','C57BL/6J','C3H/HeJ'], +'BHF2':['B6HF2','HB6F2','C57BL/6J','C3H/HeJ'], +'B6D2F2':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], +'BDF2-1999':['B6D2F2', 'D2B6F2', 'C57BL/6J', 'DBA/2J'], +'BDF2-2005':['B6D2F1', 'D2B6F1', 'C57BL/6J', 'DBA/2J'], +'CTB6F2':['CTB6F2','B6CTF2','C57BL/6J','Castaneous'], +'CXB':['CBF1', 'BCF1', 'C57BL/6ByJ', 'BALB/cByJ'], +'AXBXA':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'], +'AXB':['ABF1', 'BAF1', 'C57BL/6J', 'A/J'], +'BXA':['BAF1', 'ABF1', 'C57BL/6J', 'A/J'], +'LXS':['LSF1', 'SLF1', 'ISS', 'ILS'], +'HXBBXH':['HSRBNF1', 'BNHSRF1', 'BN', 'HSR'], +'BayXSha':['BayXShaF1', 'ShaXBayF1', 'Bay-0','Shahdara'], +'ColXBur':['ColXBurF1', 'BurXColF1', 'Col-0','Bur-0'], +'ColXCvi':['ColXCviF1', 'CviXColF1', 'Col-0','Cvi'], +'SXM':['SMF1', 'MSF1', 'Steptoe','Morex'] +} + + +# NL, 07/27/2010. moved from template.py +IMGSTEP1 = HT.Image('/images/step1.gif', alt='STEP 1',border=0) #XZ, Only be used in inputPage.py +IMGSTEP2 = HT.Image('/images/step2.gif', alt='STEP 2',border=0) #XZ, Only be used in inputPage.py +IMGSTEP3 = HT.Image('/images/step3.gif', alt='STEP 3',border=0) #XZ, Only be used in inputPage.py +IMGNEXT = HT.Image('/images/arrowdown.gif', alt='NEXT',border=0) #XZ, Only be used in inputPage.py + +IMGASC = HT.Image("/images/sortup.gif", border=0) +IMGASCON = HT.Image("/images/sortupon.gif", border=0) +IMGDESC = HT.Image("/images/sortdown.gif", border=0) +IMGDESCON = HT.Image("/images/sortdownon.gif", border=0) + +""" +IMGASC = HT.Image("/images/sortup_icon.gif", border=0) +IMGASCON = HT.Image("/images/sortupon.gif", border=0) +IMGDESC = HT.Image("/images/sortdown_icon.gif", border=0) +IMGDESCON = HT.Image("/images/sortdownon.gif", border=0) +IMG_UNSORTED = HT.Image("/images/unsorted_icon.gif", border=0) +""" + +PROGRESSBAR = HT.Image('/images/waitAnima2.gif', alt='checkblue',align="middle",border=0) + +######################################### +# Accessory Functions +######################################### + +def decodeEscape(str): + a = str + pattern = re.compile('(%[0-9A-Fa-f][0-9A-Fa-f])') + match = pattern.findall(a) + matched = [] + for item in match: + if item not in matched: + a = a.replace(item, '%c' % eval("0x"+item[-2:])) + matched.append(item) + return a + +def exportData(hddn, tdata, NP = None): + for key in tdata.keys(): + _val, _var, _N = tdata[key].val, tdata[key].var, tdata[key].N + if _val != None: + hddn[key] = _val + if _var != None: + hddn['V'+key] = _var + if NP and _N != None: + hddn['N'+key] = _N + +def genShortStrainName(RISet='', input_strainName=''): + #aliasStrainDict = {'C57BL/6J':'B6','DBA/2J':'D2'} + strainName = input_strainName + if RISet != 'AXBXA': + if RISet == 'BXD300': + this_RISet = 'BXD' + elif RISet == 'BDF2-2005': + this_RISet = 'CASE05_' + else: + this_RISet = RISet + strainName = string.replace(strainName,this_RISet,'') + strainName = string.replace(strainName,'CASE','') + try: + strainName = "%02d" % int(strainName) + except: + pass + else: + strainName = string.replace(strainName,'AXB','A') + strainName = string.replace(strainName,'BXA','B') + try: + strainName = strainName[0] + "%02d" % int(strainName[1:]) + except: + pass + return strainName + +def toInt(in_str): + "Converts an arbitrary string to an unsigned integer" + start = -1 + end = -1 + for i, char in enumerate(in_str): + if char >= '0' and char <= '9': + if start < 0: + start = i + end = i+1 + else: + if start >= 0: + break + if start < end: + return int(in_str[start:end]) + else: + return -1 + +def transpose(m): + 'transpose a matrix' + n = len(m) + return [[m[j][i] for i in range(len(m[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m[0]))] + +def asymTranspose(m): + 'transpose a matrix' + t = max(map(len, m)) + n = len(m) + m2 = [["-"]]*n + for i in range(n): + m2[i] = m[i] + [""]*(t- len(m[i])) + return [[m2[j][i] for i in range(len(m2[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m2[0]))] + +def genRandStr(prefix = "", length=8, chars=string.letters+string.digits): + from random import choice + _str = prefix[:] + for i in range(length): + _str += choice(chars) + return _str + +def generate_session(): + import sha + return sha.new(str(time.time())).hexdigest() + +def cvt2Dict(x): + tmp = {} + for key in x.keys(): + tmp[key] = x[key] + return tmp + +def dump_session(session_obj, filename): + "It seems mod python can only cPickle most basic data type" + import cPickle + session_file = open(filename, 'wb') + #try: + # pass + #except: + # pass + cPickle.dump(session_obj, session_file) + session_file.close() + +def StringAsFloat(str): + 'Converts string to float but catches any exception and returns None' + try: + return float(str) + except: + return None + +def IntAsFloat(str): + 'Converts string to Int but catches any exception and returns None' + try: + return int(str) + except: + return None + +def FloatAsFloat(flt): + 'Converts float to string but catches any exception and returns None' + try: + return float("%2.3f" % flt) + except: + return None + +def RemoveZero(flt): + 'Converts string to float but catches any exception and returns None' + try: + if abs(flt) < 1e-6: + return None + else: + return flt + except: + return None + + +def SciFloat(d): + 'Converts string to float but catches any exception and returns None' + + try: + if abs(d) <= 1.0e-4: + return "%1.2e" % d + else: + return "%1.5f" % d + except: + return None + +###To be removed +def FloatList2String(lst): + 'Converts float list to string but catches any exception and returns None' + tt='' + try: + for item in lst: + if item == None: + tt += 'X ' + else: + tt += '%f ' % item + return tt + except: + return "" + +def ListNotNull(lst): + 'Determine if the elements in a list are all null' + for item in lst: + if item is not None: + return 1 + return None + +###To be removed +def FileDataProcess(str): + 'Remove the description text from the input file if theres any' + i=0 + while i'\x20': + break + else: + i+=1 + str=str[i:] + str=string.join(string.split(str,'\000'),'') + i=string.find(str,"*****") + if i>-1: + return str[i+5:] + else: + return str + +def rank(a,lst,offset=0): + """Calculate the integer rank of a number in an array, can be used to calculate p-value""" + n = len(lst) + if n == 2: + if a lst[1]: + return offset + 2 + else: + return offset +1 + elif n == 1: + if a B.LRS: + return 1 + elif A.LRS == B.LRS: + return 0 + else: + return -1 + except: + return 0 + + +def cmpScanResult2(A,B): + try: + if A.LRS < B.LRS: + return 1 + elif A.LRS == B.LRS: + return 0 + else: + return -1 + except: + return 0 + +def cmpOrder(A,B): + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 + +def cmpOrder2(A,B): + try: + if A[-1] < B[-1]: + return -1 + elif A[-1] == B[-1]: + return 0 + else: + return 1 + except: + return 0 + + + + +def calRank(xVals, yVals, N): ### Zach Sloan, February 4 2010 + """ + Returns a ranked set of X and Y values. These are used when generating + a Spearman scatterplot. Bear in mind that this sets values equal to each + other as the same rank. + """ + XX = [] + YY = [] + X = [0]*len(xVals) + Y = [0]*len(yVals) + j = 0 + + for i in range(len(xVals)): + + if xVals[i] != None and yVals[i] != None: + XX.append((j, xVals[i])) + YY.append((j, yVals[i])) + j = j + 1 + + NN = len(XX) + + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + + j = 1 + rank = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + return (X,Y) + +def calCorrelationRank(xVals,yVals,N): + """ + Calculated Spearman Ranked Correlation. The algorithm works + by setting all tied ranks to the average of those ranks (for + example, if ranks 5-10 all have the same value, each will be set + to rank 7.5). + """ + + XX = [] + YY = [] + j = 0 + + for i in range(len(xVals)): + if xVals[i]!= None and yVals[i]!= None: + XX.append((j,xVals[i])) + YY.append((j,yVals[i])) + j = j+1 + + NN = len(XX) + if NN <6: + return (0.0,NN) + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + X = [0]*NN + Y = [0]*NN + + j = 1 + rank = 0.0 + t = 0.0 + sx = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + t = jt-j + sx = sx + (t*t*t-t) + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + t = 0.0 + sy = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + t = jt - j + sy = sy + (t*t*t-t) + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + D = 0.0 + + for i in range(NN): + D += (X[i]-Y[i])*(X[i]-Y[i]) + + fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) + + return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) + + +def calCorrelationRankText(dbdata,userdata,N): ### dcrowell = David Crowell, July 2008 + """Calculates correlation ranks with data formatted from the text file. + dbdata, userdata are lists of strings. N is an int. Returns a float. + Used by correlationPage""" + XX = [] + YY = [] + j = 0 + for i in range(N): + if (dbdata[i]!= None and userdata[i]!=None) and (dbdata[i]!= 'None' and userdata[i]!='None'): + XX.append((j,float(dbdata[i]))) + YY.append((j,float(userdata[i]))) + j += 1 + NN = len(XX) + if NN <6: + return (0.0,NN) + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + X = [0]*NN + Y = [0]*NN + + j = 1 + rank = 0.0 + t = 0.0 + sx = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + t = jt-j + sx = sx + (t*t*t-t) + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + t = 0.0 + sy = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + t = jt - j + sy = sy + (t*t*t-t) + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + D = 0.0 + + for i in range(NN): + D += (X[i]-Y[i])*(X[i]-Y[i]) + + fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) + + return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) + + + +def calCorrelation(dbdata,userdata,N): + X = [] + Y = [] + for i in range(N): + if dbdata[i]!= None and userdata[i]!= None: + X.append(dbdata[i]) + Y.append(userdata[i]) + NN = len(X) + if NN <6: + return (0.0,NN) + sx = reduce(lambda x,y:x+y,X,0.0) + sy = reduce(lambda x,y:x+y,Y,0.0) + meanx = sx/NN + meany = sy/NN + xyd = 0.0 + sxd = 0.0 + syd = 0.0 + for i in range(NN): + xyd += (X[i] - meanx)*(Y[i]-meany) + sxd += (X[i] - meanx)*(X[i] - meanx) + syd += (Y[i] - meany)*(Y[i] - meany) + try: + corr = xyd/(sqrt(sxd)*sqrt(syd)) + except: + corr = 0 + return (corr,NN) + +def calCorrelationText(dbdata,userdata,N): ### dcrowell July 2008 + """Calculates correlation coefficients with values formatted from text files. dbdata, userdata are lists of strings. N is an int. Returns a float + Used by correlationPage""" + X = [] + Y = [] + for i in range(N): + #if (dbdata[i]!= None and userdata[i]!= None) and (dbdata[i]!= 'None' and userdata[i]!= 'None'): + # X.append(float(dbdata[i])) + # Y.append(float(userdata[i])) + if dbdata[i] == None or dbdata[i] == 'None' or userdata[i] == None or userdata[i] == 'None': + continue + else: + X.append(float(dbdata[i])) + Y.append(float(userdata[i])) + NN = len(X) + if NN <6: + return (0.0,NN) + sx = sum(X) + sy = sum(Y) + meanx = sx/float(NN) + meany = sy/float(NN) + xyd = 0.0 + sxd = 0.0 + syd = 0.0 + for i in range(NN): + x1 = X[i]-meanx + y1 = Y[i]-meany + xyd += x1*y1 + sxd += x1**2 + syd += y1**2 + try: + corr = xyd/(sqrt(sxd)*sqrt(syd)) + except: + corr = 0 + return (corr,NN) + + +def readLineCSV(line): ### dcrowell July 2008 + """Parses a CSV string of text and returns a list containing each element as a string. + Used by correlationPage""" + returnList = line.split('","') + returnList[-1]=returnList[-1][:-2] + returnList[0]=returnList[0][1:] + return returnList + + +def cmpCorr(A,B): + try: + if abs(A[1]) < abs(B[1]): + return 1 + elif abs(A[1]) == abs(B[1]): + return 0 + else: + return -1 + except: + return 0 + +def cmpLitCorr(A,B): + try: + if abs(A[3]) < abs(B[3]): return 1 + elif abs(A[3]) == abs(B[3]): + if abs(A[1]) < abs(B[1]): return 1 + elif abs(A[1]) == abs(B[1]): return 0 + else: return -1 + else: return -1 + except: + return 0 + +def cmpPValue(A,B): + try: + if A.corrPValue < B.corrPValue: + return -1 + elif A.corrPValue == B.corrPValue: + if abs(A.corr) > abs(B.corr): + return -1 + elif abs(A.corr) < abs(B.corr): + return 1 + else: + return 0 + else: + return 1 + except: + return 0 + +def cmpEigenValue(A,B): + try: + if A[0] > B[0]: + return -1 + elif A[0] == B[0]: + return 0 + else: + return 1 + except: + return 0 + + +def cmpLRSFull(A,B): + try: + if A[0] < B[0]: + return -1 + elif A[0] == B[0]: + return 0 + else: + return 1 + except: + return 0 + +def cmpLRSInteract(A,B): + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 + + +def cmpPos(A,B): + try: + try: + AChr = int(A.chr) + except: + AChr = 20 + try: + BChr = int(B.chr) + except: + BChr = 20 + if AChr > BChr: + return 1 + elif AChr == BChr: + if A.mb > B.mb: + return 1 + if A.mb == B.mb: + return 0 + else: + return -1 + else: + return -1 + except: + return 0 + +def cmpGenoPos(A,B): + try: + A1 = A.chr + B1 = B.chr + try: + A1 = int(A1) + except: + A1 = 25 + try: + B1 = int(B1) + except: + B1 = 25 + if A1 > B1: + return 1 + elif A1 == B1: + if A.mb > B.mb: + return 1 + if A.mb == B.mb: + return 0 + else: + return -1 + else: + return -1 + except: + return 0 + +#XZhou: Must use "BINARY" to enable case sensitive comparison. +def authUser(name,password,db, encrypt=None): + try: + if encrypt: + query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY \'%s\'' % (name,password) + else: + query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY SHA(\'%s\')' % (name,password) + db.execute(query) + records = db.fetchone() + if not records: + raise ValueError + return records#(privilege,id,name,password,grpName) + except: + return (None, None, None, None, None) + + +def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users): + access_to_confidential_phenotype_trait = 0 + if webqtlConfig.USERDICT[privilege] > webqtlConfig.USERDICT['user']: + access_to_confidential_phenotype_trait = 1 + else: + AuthorizedUsersList=map(string.strip, string.split(authorized_users, ',')) + if AuthorizedUsersList.__contains__(userName): + access_to_confidential_phenotype_trait = 1 + return access_to_confidential_phenotype_trait + + +class VisualizeException(Exception): + def __init__(self, message): + self.message = message + def __str__(self): + return self.message + +# safeConvert : (string -> A) -> A -> A +# to convert a string to type A, using the supplied default value +# if the given conversion function doesn't work +def safeConvert(f, value, default): + try: + return f(value) + except: + return default + +# safeFloat : string -> float -> float +# to convert a string to a float safely +def safeFloat(value, default): + return safeConvert(float, value, default) + +# safeInt: string -> int -> int +# to convert a string to an int safely +def safeInt(value, default): + return safeConvert(int, value, default) + +# safeString : string -> (arrayof string) -> string -> string +# if a string is not in a list of strings to pick a default value +# for that string +def safeString(value, validChoices, default): + if value in validChoices: + return value + else: + return default + +# yesNoToInt: string -> int +# map "yes" -> 1 and "no" -> 0 +def yesNoToInt(value): + if value == "yes": + return 1 + elif value == "no": + return 0 + else: + return None + +# IntToYesNo: int -> string +# map 1 -> "yes" and 0 -> "no" +def intToYesNo(value): + if value == 1: + return "yes" + elif value == 0: + return "no" + else: + return None + +def formatField(name): + name = name.replace("_", " ") + name = name.title() + #name = name.replace("Mb Mm6", "Mb"); + return name.replace("Id", "ID") + +#XZ, 03/27/2009: This function is very specific. +#It is used by AJAX_table.py, correlationPage.py and dataPage.py + + +def genTableObj(tblobj=None, file="", sortby = ("", ""), tableID = "sortable", addIndex = "1", hiddenColumns=[]): + header = tblobj['header'] + body = tblobj['body'] + field, order = sortby + + #ZAS 9/12/2011 - The hiddenColumns array needs to be converted into a string so they can be placed into the javascript of each up/down button + hiddenColumnsString = ",".join(hiddenColumns) + + tbl = HT.TableLite(Class="collap b2", cellspacing=1, cellpadding=5) + + hiddenColumnIdx = [] #indices of columns to hide + idx = -1 + last_idx = 0 #ZS: This is the index of the last item in the regular table header (without any extra parameters). It is used to determine the index of each extra parameter. + for row in header: + hr = HT.TR() + for i, item in enumerate(row): + if (item.text == '') or (item.text not in hiddenColumns): + if item.sort and item.text: + down = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=down&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGDESC) + up = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=up&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGASC) + if item.text == field: + idx = item.idx + last_idx = idx + if order == 'up': + up = IMGASCON + elif order == 'down': + down = IMGDESCON + item.html.append(HT.Div(up, down, style="float: bottom;")) + hr.append(item.html) + else: + hiddenColumnIdx.append(i) + tbl.append(hr) + + for i, row in enumerate(body): + for j, item in enumerate(row): + if order == 'down': + if (item.val == '' or item.val == 'x' or item.val == 'None'): + item.val = 0 + if order == 'up': + if (item.val == '' or item.val == 'x' or item.val == 'None'): + item.val = 'zzzzz' + + if idx >= 0: + if order == 'down': + body.sort(lambda A, B: cmp(B[idx].val, A[idx].val), key=natsort_key) + elif order == 'up': + body.sort(lambda A, B: cmp(A[idx].val, B[idx].val), key=natsort_key) + else: + pass + + for i, row in enumerate(body): + hr = HT.TR(Id = row[0].text) + for j, item in enumerate(row): + if (j not in hiddenColumnIdx): + if j == 0: + if addIndex == "1": + item.html.contents = [i+1] + item.html.contents + hr.append(item.html) + tbl.append(hr) + + return tbl + +def natsort_key(string): + r = [] + for c in string: + try: + c = int(c) + try: r[-1] = r[-1] * 10 + c + except: r.append(c) + except: + r.append(c) + return r + diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py new file mode 100644 index 00000000..d0484c83 --- /dev/null +++ b/wqflask/wqflask/__init__.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import, division, print_function + +from flask import Flask + +from utility import formatting + +app = Flask(__name__) + +app.jinja_env.globals.update( + numify = formatting.numify +) + +import wqflask.views diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py new file mode 100644 index 00000000..c100645e --- /dev/null +++ b/wqflask/wqflask/search_results.py @@ -0,0 +1,1288 @@ +from __future__ import absolute_import, division, print_function + +from wqflask import app + +from flask import render_template + +################################################### +# +# This file uses only spaces for indentation # +# +################################################### + +import string +import os +import cPickle +import re +from math import * +import time +import pyXLWriter as xl +#import pp - Note from Sam: is this used? +import math +import datetime + +from pprint import pformat as pf + +# Instead of importing HT we're going to build a class below until we can eliminate it +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig +from utility.THCell import THCell +from utility.TDCell import TDCell +from base.webqtlDataset import webqtlDataset +from base.webqtlTrait import webqtlTrait +from base.templatePage import templatePage +from utility import webqtlUtil +from dbFunction import webqtlDatabaseFunction + +import logging +logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) + +_log = logging.getLogger("search") +_ch = logging.StreamHandler() +_log.addHandler(_ch) + +from utility import formatting + +import sys +_log.info("sys.path is: %s" % (sys.path)) + + +#from base.JinjaPage import JinjaEnv, JinjaPage + + + +class SearchResultPage(templatePage): + + maxReturn = 3000 + #NPerPage = 100 + nkeywords = 0 + + def __init__(self, fd): + _log.info("Got here - xerxes2") + _log.info("sys.path: %s" % (sys.path)) + #_log.info(causeanerror) + _log.info("xerxesc") + #self.jtemplate = JinjaEnv.get_template('SearchResultPage.html') + #templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + _log.info("xerxesd") + + #self.dict['title'] = 'Search Results' + #TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") + print("e2.8") + self.database = [fd['database']] + print("e2.9") + if not self.database or self.database == 'spacer': + print("e3") + #Error, No database selected + heading = "Search Result" + detail = ['''No database was selected for this search, please + go back and SELECT at least one database.'''] + self.error(heading=heading,detail=detail,error="No Database Selected") + return + elif type(self.database) == type(""): + print("e3.2") + #convert database into a database list + #was used for multiple databases search, this + #feature has been abandoned, + self.database = string.split(self.database,',') + else: + print("e3.4") + pass + + print("e4") + ########################################### + # Names and IDs of RISet / F2 set + ########################################### + if self.database == ['_allPublish']: + self.cursor.execute("""select PublishFreeze.Name, InbredSet.Name, InbredSet.Id from PublishFreeze, + InbredSet where PublishFreeze.Name not like 'BXD300%' and InbredSet.Id = + PublishFreeze.InbredSetId""") + results = self.cursor.fetchall() + self.database = map(lambda x: webqtlDataset(x[0], self.cursor), results) + self.databaseCrosses = map(lambda x: x[1], results) + self.databaseCrossIds = map(lambda x: x[2], results) + self.singleCross = False + else: + self.database = map(lambda x: webqtlDataset(x, self.cursor), self.database) + #currently, webqtl wouldn't allow multiple crosses + #for other than multiple publish db search + #so we can use the first database as example + if self.database[0].type=="Publish": + pass + elif self.database[0].type in ("Geno", "ProbeSet"): + + #userExist = None + + for individualDB in self.database: + self.cursor.execute('SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM %sFreeze WHERE Name = "%s"' % (self.database[0].type, individualDB)) + indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] + + if confidential == 1: + access_to_confidential_dataset = 0 + + #for the dataset that confidentiality is 1 + #1. 'admin' and 'root' can see all of the dataset + #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: + access_to_confidential_dataset = 1 + else: + AuthorisedUsersList=AuthorisedUsers.split(',') + if AuthorisedUsersList.__contains__(self.userName): + access_to_confidential_dataset = 1 + + if not access_to_confidential_dataset: + #Error, No database selected + heading = "Search Result" + detail = ["The %s database you selected is not open to the public at this time, please go back and SELECT other database." % indFullName] + self.error(heading=heading,detail=detail,error="Confidential Database") + return + else: + heading = "Search Result" + detail = ['''The database has not been established yet, please + go back and SELECT at least one database.'''] + self.error(heading=heading,detail=detail,error="No Database Selected") + return + + self.database[0].getRISet() + self.databaseCrosses = [self.database[0].riset] + self.databaseCrossIds = [self.database[0].risetid] + self.singleCross = True + #XZ, August 24,2010: Since self.singleCross = True, it's safe to assign one species Id. + self.speciesId = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.database[0].riset) + + print("e4.5") + ########################################### + # make sure search from same type of databases + ########################################### + dbTypes = map(lambda X: X.type, self.database) + self.dbType = dbTypes[0] + for item in dbTypes: + if item != self.dbType: + heading = "Search Result" + detail = ["Search can only be performed among the same type of databases"] + self.error(heading=heading,detail=detail,error="Error") + return + if self.dbType == "Publish": + self.searchField = ['Phenotype.Post_publication_description', 'Phenotype.Pre_publication_description', 'Phenotype.Pre_publication_abbreviation', 'Phenotype.Post_publication_abbreviation', 'Phenotype.Lab_code', 'Publication.PubMed_ID', 'Publication.Abstract', 'Publication.Title', 'Publication.Authors', 'PublishXRef.Id'] + + elif self.dbType == "ProbeSet": + self.searchField = ['Name','Description','Probe_Target_Description','Symbol','Alias','GenbankId', 'UniGeneId','RefSeq_TranscriptId'] + elif self.dbType == "Geno": + self.searchField = ['Name','Chr'] + + print("e4.6") + ########################################### + # Search Options + ########################################### + self.matchwhole = fd['matchwhole'] + print("e4.65") + #split result into pages + self.pageNumber = fd.get('pageno', 0) + print("e4.7") + try: + self.pageNumber = int(self.pageNumber) + except Exception as why: + print(why) + self.pageNumber = 0 + + print("e5") + ########################################### + # Generate Mysql Query + ########################################### + geneIdListQuery = fd.get('geneId', '') + if geneIdListQuery: + geneIdListQuery = string.replace(geneIdListQuery, ",", " ") + geneIdListQuery = " geneId=%s" % string.join(string.split(geneIdListQuery), "-") + + self.ANDkeyword = fd.get('ANDkeyword', "") + self.ORkeyword = fd.get('ORkeyword', "") + + self.ORkeyword += geneIdListQuery + + self.ANDkeyword = self.ANDkeyword.replace("\\", "").strip() + self.ORkeyword = self.ORkeyword.replace("\\", "").strip() + #user defined sort option + self.orderByUserInput = fd.get('orderByUserInput', "").strip() + #default sort option if user have not defined + self.orderByDefalut = "" + + #XZ, Dec/16/2010: I add examples to help understand this block of code. See details in function pattersearch. + + #XZ: self._1mPattern examples: WIKI=xxx, RIF=xxx, GO:0045202 + self._1mPattern = re.compile('\s*(\S+)\s*[:=]\s*([a-zA-Z-\+\d\.]+)\s*') + + #XZ: self._2mPattern examples: Mean=(15.0 16.0), Range=(10 100), LRS=(Low_LRS_limit, High_LRS_limit), pvalue=(Low_limit, High_limit), Range=(10 100) + self._2mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*([-\d\.]+)[, \t]+([-\d\.]+)[, \t]*([-\d\.]*)\s*\)') + + #XZ: self._3mPattern examples: Position=(Chr1 98 104), Pos=(Chr1 98 104), Mb=(Chr1 98 104), CisLRS=(Low_LRS_limit, High_LRS_limit, Mb_buffer), TransLRS=(Low_LRS_limit, High_LRS_limit, Mb_buffer) + self._3mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*[Cc][Hh][Rr]([^, \t]+)[, \t]+([-\d\.]+)[, \t]+([-\d\.]+)\s*\)') + + #XZ: self._5mPattern examples: LRS=(Low_LRS_limit, High_LRS_limit, ChrNN, Mb_Low_Limit, Mb_High_Limit) + self._5mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*([-\d\.]+)[, \t]+([-\d\.]+)[, \t]+[Cc][Hh][Rr]([^, \t]+)[, \t]+([-\d\.]+)[, \t]+([-\d\.]+)\s*\)') + + #Error, No keyword input + if not (self.ORkeyword or self.ANDkeyword): + heading = "Search Result" + detail = ["Please make sure to enter either your search terms (genes, traits, markers), or advanced search commands."] + self.error(heading=heading,detail=detail,error="No search terms were entered") + return + + #query clauses + self.ANDQuery = [] + self.ORQuery = [] + #descriptions, one for OR search, one for AND search + self.ANDDescriptionText = [] + self.ORDescriptionText = [] + + if not self.normalSearch(): + return + if not self.patternSearch(): + return + if not self.assembleQuery(): + return + self.nresults = self.executeQuery() + + if len(self.database) > 1: + dbUrl = "Multiple phenotype databases" + dbUrlLink = " were" + else: + dbUrl = self.database[0].genHTML() + print("glasses:", dbUrl) + dbUrlLink = " was" + + #SearchText = HT.Blockquote('GeneNetwork searched the ', dbUrl, ' for all records ') + #if self.ORkeyword2: + # NNN = len(self.ORkeyword2) + # if NNN > 1: + # SearchText.append(' that match the terms ') + # else: + # SearchText.append(' that match the term ') + # for j, term in enumerate(self.ORkeyword2): + # SearchText.append(HT.U(term)) + # if NNN > 1 and j < NNN-2: + # SearchText.append(", ") + # elif j == NNN-2: + # SearchText.append(", or ") + # else: + # pass + #if self.ORDescriptionText: + # if self.ORkeyword2: + # SearchText.append("; ") + # else: + # SearchText.append(" ") + # for j, item in enumerate(self.ORDescriptionText): + # SearchText.append(item) + # if j < len(self.ORDescriptionText) -1: + # SearchText.append(";") + # + #if (self.ORkeyword2 or self.ORDescriptionText) and (self.ANDkeyword2 or self.ANDDescriptionText): + # SearchText.append("; ") + #if self.ANDkeyword2: + # if (self.ORkeyword2 or self.ORDescriptionText): + # SearchText.append(' records') + # NNN = len(self.ANDkeyword2) + # if NNN > 1: + # SearchText.append(' that match the terms ') + # else: + # SearchText.append(' that match the term ') + # for j, term in enumerate(self.ANDkeyword2): + # SearchText.append(HT.U(term)) + # if NNN > 1 and j < NNN-2: + # SearchText.append(", ") + # elif j == NNN-2: + # SearchText.append(", and ") + # else: + # pass + #if self.ANDDescriptionText: + # if self.ANDkeyword2: + # SearchText.append(" and ") + # else: + # SearchText.append(" ") + # for j, item in enumerate(self.ANDDescriptionText): + # SearchText.append(item) + # if j < len(self.ANDDescriptionText) -1: + # SearchText.append(" and ") + # + #SearchText.append(". ") + _log.info("fweep") + #if self.nresults == 0: + # heading = "Search Result" + # detail = ["Sorry, GeneNetwork did not find any records matching your request. Please check the syntax or try the ANY rather than the ALL field."] + # self.error(heading=heading,intro = SearchText.contents,detail=detail,error="Not Found") + # return + #elif self.nresults == 1: + # SearchText.append(HT.P(), 'GeneNetwork found one record that matches your request. To study this record, click on its text below. To add this record to your Selection window, use the checkbox and then click the ', HT.Strong('Add to Collection'),' button. ') + #elif self.nresults >= 1 and self.nresults <= self.maxReturn: + # SearchText.append(HT.P(), 'GeneNetwork found a total of ', HT.Span(self.nresults, Class='fwb cr'), ' records. To study any one of these records, click on its ID below. To add one or more records to your Selection window, use the checkbox and then click the ' , HT.Strong('Add to Collection'),' button. ') + #else: + # SearchText.append(' A total of ',HT.Span(self.nresults, Class='fwb cr'), ' records were found.') + # heading = "Search Result" + # # Modified by Hongqiang Li + # # detail = ["The terms you entered match %d records. Please modify your search to generate %d or fewer matches, or review " % (self.nresults, self.maxReturn), HT.Href(text='Search Help', target='_blank', url='http://web2qtl.utmem.edu/searchHelp.html', Class='fs14'), " to learn more about syntax and the use of wildcard characters."] + # detail = ["The terms you entered match %d records. Please modify your search to generate %d or fewer matches, or review " % (self.nresults, self.maxReturn), HT.Href(text='Search Help', target='_blank', url='%s/searchHelp.html' % webqtlConfig.PORTADDR, Class='fs14'), " to learn more about syntax and the use of wildcard characters."] + # # + # self.error(heading=heading,intro = SearchText.contents,detail=detail,error="Over %d" % self.maxReturn) + # return + + + #TD_LR.append(HT.Paragraph('Search Results', Class="title"), SearchText) + _log.info("flop") + self.genSearchResultTable() + #self.dict['body'] = str(TD_LR) + #self.dict['js1'] = '' + #self.dict['js2'] = 'onLoad="pageOffset()"' + #self.dict['layer'] = self.generateWarningLayer() + + def genSearchResultTable(self): + + #pageTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="100%",border=0) + + lastone = False + for i, item in enumerate(self.results): + if not item: + continue + lastone = False + + self.traitList = [] + for k, item2 in enumerate(item): + j, ProbeSetID = item2[:2] + thisTrait = webqtlTrait(db=self.database[j], name=ProbeSetID, cursor=self.cursor) + self.traitList.append(thisTrait) + + ############## + # Excel file # + ############## + + # Todo: Replace this with official Python temp file naming functions? + filename= webqtlUtil.genRandStr("Search_") + #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') + # Create a new Excel workbook + #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) + #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") + + #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. + #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=thisTrait.db, returnNumber=len(self.traitList)) + newrow = 7 + + #tbl = HT.TableLite(cellSpacing=2,cellPadding=0,width="90%",border=0) + #seq = self.pageNumber*self.NPerPage+1 //Edited out because we show all results in one page now - Zach 2/22/11 + seq = 1 + RISet = self.databaseCrosses[i] + self.thisFormName = thisFormName = 'showDatabase'+RISet + #selectall = HT.Href(url="#", onClick="checkAll(document.getElementsByName('%s')[0]);" % thisFormName) + #selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;") + #selectall.append(selectall_img) + #reset = HT.Href(url="#", onClick="checkNone(document.getElementsByName('%s')[0]);" % thisFormName) + #reset_img = HT.Image("/images/select_none2_final.jpg", alt="Select None", title="Select None", style="border:none;") + #reset.append(reset_img) + #selectinvert = HT.Href(url="#", onClick="checkInvert(document.getElementsByName('%s')[0]);" % thisFormName) + #selectinvert_img = HT.Image("/images/invert_selection2_final.jpg", name="selectinvert", alt="Invert Selection", title="Invert Selection", style="border:none;") + #selectinvert.append(selectinvert_img) + #addselect = HT.Href(url="#") + #addselect_img = HT.Image("/images/add_collection1_final.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") + #addselect.append(addselect_img) + + #optionsTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="20%",border=0) + #optionsRow = HT.TR(HT.TD(selectall, width="25%"), HT.TD(reset, width="25%"), HT.TD(selectinvert, width="25%"), HT.TD(addselect, width="25%")) + #labelsRow = HT.TR(HT.TD(" "*2,"Select", width="25%"), HT.TD(" ","Deselect", width="255"), HT.TD(" "*3,"Invert", width="25%"), HT.TD(" "*4,"Add", width="25%")) + #optionsTable.append(optionsRow, labelsRow) + + #pageTable.append(HT.TR(HT.TD(optionsTable)), HT.TR(HT.TD(xlsUrl, height=40))) + + tblobj = {} + mainfmName = thisFormName + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet) + _log.info("flap trait is: %s" % (thisTrait.db.type)) + if thisTrait.db.type=="Geno": + tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + + newrow += 1 + sortby = self.getSortByValue(datasetType="Geno") + + tblobj['body'] = self.getTableBodyForGeno(traitList=self.traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow) + + #workbook.close() + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + + pageTable.append(HT.TR(HT.TD(div))) + + elif thisTrait.db.type=="Publish": + #tblobj['header'] = self.getTableHeaderForPublish(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + + newrow += 1 + + sortby = self.getSortByValue(datasetType="Publish") + + #tblobj['body'] = self.getTableBodyForPublish(traitList=self.traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + + #workbook.close() + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() + + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + + #pageTable.append(HT.TR(HT.TD(div))) + + elif thisTrait.db.type=="ProbeSet": + #tblobj['header'] = self.getTableHeaderForProbeSet(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + + newrow += 1 + + sortby = self.getSortByValue(datasetType="ProbeSet") + + tblobj['body'] = self.getTableBodyForProbeSet(traitList=self.traitList, formName=mainfmName, newrow=newrow, species=species) + + #workbook.close() + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + + #pageTable.append(HT.TR(HT.TD(div))) + + + #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','RISet':RISet} + hddn['incparentsf1']='ON' + # for key in hddn.keys(): + # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + # + # traitForm.append(HT.P(),pageTable) + # + # TD_LR.append(traitForm) + # if len(self.results) > 1 and i < len(self.results) - 1: + # lastone = True + #if lastone: + # TD_LR.contents.pop() + + def executeQuery(self): + + ##construct sorting + if self.dbType == "Publish": + sortQuery = " order by Publication_PubMed_ID desc, Phenotype_Name, thistable" + elif self.dbType == "Geno": + if not self.orderByUserInput: + if self.orderByDefalut: + self.orderByUserInput = self.orderByDefalut + else: + self.orderByUserInput = "POSITION" + if self.orderByUserInput.upper() in ["POS", "POSITION", "MB"]: + self.orderByUserInput = "POSITION" + else: + pass + self.orderByUserInput = self.orderByUserInput.upper() + self.orderByUserInputOrig = self.orderByUserInput[:] + if self.orderByUserInput == "NAME": + sortQuery = " order by Geno_Name, Geno_chr_num, Geno_Mb" + elif self.orderByUserInput == "SOURCE": + sortQuery = " order by Geno_Source2, Geno_chr_num, Geno_Mb" + else: + sortQuery = " order by Geno_chr_num, Geno_Mb" + #ProbeSet + else: + if not self.orderByUserInput: + if self.orderByDefalut: + self.orderByUserInput = self.orderByDefalut + else: + self.orderByUserInput = "POSITION" + + self.orderByUserInput = self.orderByUserInput.upper() + self.orderByUserInputOrig = self.orderByUserInput[:] + #XZ: 8/18/2009: "POSITION-" + if self.orderByUserInput[-1] == '-': + self.orderByUserInput = self.orderByUserInput[:-1] + sortDesc = 'desc' + else: + sortDesc = '' + + if self.orderByUserInput in ["MEAN", "LRS", "PVALUE"]: + #sortQuery = " order by T%s %s, TNAME, thistable desc" % (self.orderByUserInput, sortDesc) + sortQuery = " order by T%s desc, TNAME, thistable desc" % self.orderByUserInput + elif self.orderByUserInput in ["POS", "POSITION", "MB"]: + sortQuery = " order by TCHR_NUM %s, TMB %s, TNAME, thistable desc" % (sortDesc, sortDesc) + elif self.orderByUserInput == 'SYMBOL': + sortQuery = " order by TSYMBOL, thistable desc" + else: + sortQuery = " order by TNAME_NUM, thistable desc" + + if self.singleCross: + if len(self.query) > 1: + searchQuery = map(lambda X:'(%s)' % X, self.query) + searchQuery = string.join(searchQuery, ' UNION ALL ') + else: + searchQuery = self.query[0] + searchQuery += sortQuery + #searchCountQuery retrieve all the results + searchCountQuery = [searchQuery] + #searchQuery = searchQuery + " limit %d,%d" % (self.pageNumber*self.NPerPage, self.NPerPage) // We removed the page limit - Zach 2/22/11 + searchQuery = [searchQuery] + else: + searchCountQuery = searchQuery = map(lambda X: X+sortQuery, self.query) + + allResults = [] + self.results = [] + for item in searchCountQuery: + start_time = datetime.datetime.now() + _log.info("foo - Executing query: %s"%(item)) + self.cursor.execute(item) + allResults.append(self.cursor.fetchall()) + end_time = datetime.datetime.now() + _log.info("Total time: %s"%(end_time-start_time)) + + _log.info("Done executing queries") + + + #searchCountQuery retrieve all the results, for counting use only + if searchCountQuery != searchQuery: + for item in searchQuery: + self.cursor.execute(item) + self.results.append(self.cursor.fetchall()) + else: + self.results = allResults + + nresults = reduce(lambda Y,X:len(X)+Y, allResults, 0) + return nresults + + + + def assembleQuery(self): + self.query = [] + if self.ANDQuery or self.ORQuery: + clause = self.ORQuery[:] + + for j, database in enumerate(self.database): + if self.ANDQuery: + clause.append(" (%s) " % string.join(self.ANDQuery, " AND ")) + + newclause = [] + + for item in clause: + ##need to retrieve additional field which won't be used + ##in the future, for sorting purpose only + if self.dbType == "Publish": + if item.find("Geno.name") < 0: + incGenoTbl = "" + else: + incGenoTbl = " Geno, " + newclause.append("SELECT %d, PublishXRef.Id, PublishFreeze.createtime as thistable, Publication.PubMed_ID as Publication_PubMed_ID, Phenotype.Post_publication_description as Phenotype_Name FROM %s PublishFreeze, Publication, PublishXRef, Phenotype WHERE PublishXRef.InbredSetId = %d and %s and PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %d" % (j, incGenoTbl, self.databaseCrossIds[j], item, database.id)) + elif self.dbType == "ProbeSet": + if item.find("GOgene") < 0: + incGoTbl = "" + else: + incGoTbl = " ,db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product " + if item.find("Geno.name") < 0: + incGenoTbl = "" + else: + incGenoTbl = " Geno, " + if item.find("GeneRIF_BASIC.") < 0: + incGeneRIFTbl = "" + else: + incGeneRIFTbl = " GeneRIF_BASIC, " + if item.find("GeneRIF.") < 0: + incGeneRIFTbl += "" + else: + incGeneRIFTbl += " GeneRIF, " + newclause.append("""SELECT distinct %d, ProbeSet.Name as TNAME, 0 as thistable, + ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS, ProbeSetXRef.PVALUE as TPVALUE, + ProbeSet.Chr_num as TCHR_NUM, ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM FROM %s%s ProbeSetXRef, ProbeSet %s + WHERE %s and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %d + """ % (j, incGeneRIFTbl, incGenoTbl, incGoTbl, item, database.id)) + elif self.dbType == "Geno": + newclause.append("SELECT %d, Geno.Name, GenoFreeze.createtime as thistable, Geno.Name as Geno_Name, Geno.Source2 as Geno_Source2, Geno.chr_num as Geno_chr_num, Geno.Mb as Geno_Mb FROM GenoXRef, GenoFreeze, Geno WHERE %s and Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and GenoFreeze.Id = %d"% (j, item, database.id)) + else: + pass + + searchQuery = map(lambda X:'(%s)' % X, newclause) + searchQuery = string.join(searchQuery, ' UNION ') + self.query.append(searchQuery) + return 1 + else: + heading = "Search Result" + detail = ["No keyword was entered for this search, please go back and enter your keyword."] + self.error(heading=heading,detail=detail,error="No Keyword") + return 0 + + + + def normalSearch(self): + self.ANDkeyword2 = re.sub(self._1mPattern, '', self.ANDkeyword) + self.ANDkeyword2 = re.sub(self._2mPattern, '', self.ANDkeyword2) + self.ANDkeyword2 = re.sub(self._3mPattern, '', self.ANDkeyword2) + self.ANDkeyword2 = re.sub(self._5mPattern, '', self.ANDkeyword2) + ##remove remain parethesis, could be input with syntax error + self.ANDkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ANDkeyword2) + self.ANDkeyword2 = self.encregexp(self.ANDkeyword2) + + self.ORkeyword2 = re.sub(self._1mPattern, '', self.ORkeyword) + self.ORkeyword2 = re.sub(self._2mPattern, '', self.ORkeyword2) + self.ORkeyword2 = re.sub(self._3mPattern, '', self.ORkeyword2) + self.ORkeyword2 = re.sub(self._5mPattern, '', self.ORkeyword2) + ##remove remain parethesis, could be input with syntax error + self.ORkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ORkeyword2) + self.ORkeyword2 = self.encregexp(self.ORkeyword2) + + if self.ORkeyword2 or self.ANDkeyword2: + ANDFulltext = [] + ORFulltext = [] + for k, item in enumerate(self.ORkeyword2 + self.ANDkeyword2): + self.nkeywords += 1 + if k >=len(self.ORkeyword2): + query = self.ANDQuery + DescriptionText = self.ANDDescriptionText + clausejoin = ' OR ' + fulltext = ANDFulltext + else: + query = self.ORQuery + DescriptionText = self.ORDescriptionText + clausejoin = ' OR ' + fulltext = ORFulltext + + if self.dbType == "ProbeSet" and item.find('.') < 0 and item.find('\'') < 0: + fulltext.append(item) + else: + if self.matchwhole and item.find("'") < 0: + item = "[[:<:]]"+ item+"[[:>:]]" + clause2 = [] + for field in self.searchField: + if self.dbType == "Publish": + clause2.append("%s REGEXP \"%s\"" % (field,item)) + else: + clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dbType,field),item)) + clauseItem = "(%s)" % string.join(clause2, clausejoin) + query.append(" (%s) " % clauseItem) + if ANDFulltext: + clauseItem = " MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias,GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('+%s' IN BOOLEAN MODE) " % string.join(ANDFulltext, " +") + self.ANDQuery.append(" (%s) " % clauseItem) + if ORFulltext: + clauseItem = " MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias,GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) " % string.join(ORFulltext, " ") + self.ORQuery.append(" (%s) " % clauseItem) + else: + pass + return 1 + + + + def encregexp(self,str): + if not str: + return [] + else: + wildcardkeyword = str.strip() + wildcardkeyword = string.replace(wildcardkeyword,',',' ') + wildcardkeyword = string.replace(wildcardkeyword,';',' ') + wildcardkeyword = wildcardkeyword.split() + NNN = len(wildcardkeyword) + for i in range(NNN): + keyword = wildcardkeyword[i] + keyword = string.replace(keyword,"*",".*") + keyword = string.replace(keyword,"?",".") + wildcardkeyword[i] = keyword#'[[:<:]]'+ keyword+'[[:>:]]' + return wildcardkeyword + + + + def patternSearch(self): + # Lei Yan + ##Process Inputs + m1_AND = self._1mPattern.findall(self.ANDkeyword) + m2_AND = self._2mPattern.findall(self.ANDkeyword) + m3_AND = self._3mPattern.findall(self.ANDkeyword) + m5_AND = self._5mPattern.findall(self.ANDkeyword) + m1_OR = self._1mPattern.findall(self.ORkeyword) + m2_OR = self._2mPattern.findall(self.ORkeyword) + m3_OR = self._3mPattern.findall(self.ORkeyword) + m5_OR = self._5mPattern.findall(self.ORkeyword) + + #pattern search + if m1_AND or m1_OR or m2_AND or m2_OR or m3_AND or m3_OR or m5_AND or m5_OR: + + self.orderByDefalut = 'PROBESETID' + + _1Cmds = map(string.upper, map(lambda x:x[0], m1_AND + m1_OR)) + _2Cmds = map(string.upper, map(lambda x:x[0], m2_AND + m2_OR)) + _3Cmds = map(string.upper, map(lambda x:x[0], m3_AND + m3_OR)) + _5Cmds = map(string.upper, map(lambda x:x[0], m5_AND + m5_OR)) + + self.nkeywords += len(_1Cmds) + len(_2Cmds) + len(_3Cmds) + + if self.dbType == "Publish" and \ + ( (_2Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _2Cmds, False))\ + or (_5Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _5Cmds, False)) ): + heading = "Search Result" + detail = ["Pattern search is not available for phenotype databases at this time."] + self.error(heading=heading,detail=detail,error="Error") + return 0 + elif self.dbType == "ProbeSet" and \ + ((_2Cmds and reduce(lambda x, y: (y not in ["MEAN", "LRS", "PVALUE", "TRANSLRS", "CISLRS", "RANGE", "H2"]) or x, _2Cmds, False))\ + or (_3Cmds and reduce(lambda x, y: (y not in ["POS", "POSITION", "MB"]) or x, _3Cmds, False))\ + or (_5Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _5Cmds, False))\ + or (_1Cmds and reduce(lambda x, y: (y not in ["FLAG", "STRAND_PROBE", "STRAND_GENE", "GO", "WIKI", "RIF", "GENEID"]) or x, _1Cmds, False))): + heading = "Search Result" + detail = ["You entered at least one incorrect search command."] + self.error(heading=heading,detail=detail,error="Error") + return 0 + elif self.dbType == "Geno" and (_1Cmds or _2Cmds or _5Cmds or (_3Cmds and reduce(lambda x, y: (y not in ["POS", "POSITION", "MB"]) or x, _3Cmds, False)) ): + heading = "Search Result" + detail = ["You entered at least one incorrect search command."] + self.error(heading=heading,detail=detail,error="Error") + return 0 + else: + for k, item in enumerate(m1_OR+m1_AND): + if k >=len(m1_OR): + query = self.ANDQuery + DescriptionText = self.ANDDescriptionText + else: + query = self.ORQuery + DescriptionText = self.ORDescriptionText + + if item[1] == '-': + strandName = 'minus' + elif item[1] == '+': + strandName = 'plus' + else: + strandName = item[1] + + if item[0].upper() in ("FLAG"): + clauseItem = " %s.%s = %s " % (self.dbType, item[0], item[1]) + DescriptionText.append(HT.Span(' with ', HT.U('FLAG'), ' equal to ', item[1])) + elif item[0].upper() in ("WIKI"): + clauseItem = " %s.symbol = GeneRIF.symbol and GeneRIF.versionId=0 and GeneRIF.display>0 and (GeneRIF.comment REGEXP \"%s\" or GeneRIF.initial = \"%s\") " % (self.dbType, "[[:<:]]"+ item[1]+"[[:>:]]", item[1]) + DescriptionText.append(HT.Span(' with GeneWiki contains ', HT.U(item[1]))) + elif item[0].upper() in ("RIF"): + clauseItem = " %s.symbol = GeneRIF_BASIC.symbol and MATCH (GeneRIF_BASIC.comment) AGAINST ('+%s' IN BOOLEAN MODE) " % (self.dbType, item[1]) + DescriptionText.append(HT.Span(' with GeneRIF contains ', HT.U(item[1]))) + elif item[0].upper() in ("GENEID"): + clauseItem = " %s.GeneId in ( %s ) " % (self.dbType, string.replace(item[1], '-', ', ')) + DescriptionText.append(HT.Span(' with Entrez Gene ID in ', HT.U(string.replace(item[1], '-', ', ')))) + elif item[0].upper() in ("GO"): + Field = 'GOterm.acc' + Id = 'GO:'+('0000000'+item[1])[-7:] + Statements = '%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id' % (self.dbType); + clauseItem = " %s = '%s' and %s " % (Field, Id, Statements) + #self.incGoTbl = " ,db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product " + DescriptionText.append(HT.Span(' with ', HT.U('GO'), ' ID equal to ', Id)) + else: + clauseItem = " %s.%s = '%s' " % (self.dbType, item[0], item[1]) + if item[0].upper() in ["STRAND_PROBE"]: + DescriptionText.append(' with probe on the %s strand' % strandName) + elif item[0].upper() in ["STRAND_GENE"]: + DescriptionText.append(' with gene on the %s strand' % strandName) + else: + pass + query.append(" (%s) " % clauseItem) + + for k, item in enumerate(m2_OR+m2_AND): + if k >=len(m2_OR): + query = self.ANDQuery + DescriptionText = self.ANDDescriptionText + else: + query = self.ORQuery + DescriptionText = self.ORDescriptionText + + itemCmd = item[0] + lowerLimit = float(item[1]) + upperLimit = float(item[2]) + + if itemCmd.upper() in ("TRANSLRS", "CISLRS"): + if item[3]: + mthresh = float(item[3]) + clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ + (self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) + if itemCmd.upper() == "CISLRS": + clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %2.7f """ % (self.dbType, self.speciesId, self.dbType, self.dbType, mthresh) + DescriptionText.append(HT.Span(' with a ', HT.U('cis-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) + else: + clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and (%s.Chr != Geno.Chr or (%s.Chr != Geno.Chr and ABS(%s.Mb-Geno.Mb) > %2.7f)) """ % (self.dbType, self.speciesId, self.dbType, self.dbType, self.dbType, mthresh) + DescriptionText.append(HT.Span(' with a ', HT.U('trans-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) + query.append(" (%s) " % clauseItem) + self.orderByDefalut = "LRS" + else: + pass + elif itemCmd.upper() in ("RANGE"): + #XZ, 03/05/2009: Xiaodong changed Data to ProbeSetData + clauseItem = " (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) > %2.7f and (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) < %2.7f " % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)) + query.append(" (%s) " % clauseItem) + DescriptionText.append(HT.Span(' with a range of expression that varied between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)), " (fold difference)")) + else: + clauseItem = " %sXRef.%s > %2.7f and %sXRef.%s < %2.7f " % \ + (self.dbType, itemCmd, min(lowerLimit, upperLimit), self.dbType, itemCmd, max(lowerLimit, upperLimit)) + query.append(" (%s) " % clauseItem) + self.orderByDefalut = itemCmd + DescriptionText.append(HT.Span(' with ', HT.U(itemCmd), ' between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)))) + + for k, item in enumerate(m3_OR+m3_AND): + if k >=len(m3_OR): + query = self.ANDQuery + DescriptionText = self.ANDDescriptionText + else: + query = self.ORQuery + DescriptionText = self.ORDescriptionText + itemCmd = item[0] + chrsch = item[1] + lowerLimit = float(item[2]) + upperLimit = float(item[3]) + fname = 'target genes' + if self.dbType == "ProbeSet": + clauseItem = " %s.Chr = '%s' and %s.Mb > %2.7f and %s.Mb < %2.7f " % \ + (self.dbType, chrsch, self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) + elif self.dbType == "Geno": + fname = 'loci' + clauseItem = " %s.Chr = '%s' and %s.Mb > %2.7f and %s.Mb < %2.7f " % \ + (self.dbType, chrsch, self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) + else: + continue + query.append(" (%s) " % clauseItem) + self.orderByDefalut = itemCmd + DescriptionText.append(HT.Span(' with ', HT.U('target genes'), ' on chromosome %s between %g and %g Mb' % \ + (chrsch, min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)))) + + for k, item in enumerate(m5_OR+m5_AND): + if k >=len(m5_OR): + query = self.ANDQuery + DescriptionText = self.ANDDescriptionText + else: + query = self.ORQuery + DescriptionText = self.ORDescriptionText + itemCmd = item[0] + lowerLimit = float(item[1]) + upperLimit = float(item[2]) + chrsch = item[3] + MblowerLimit = float(item[4]) + MbupperLimit = float(item[5]) + if self.dbType == "ProbeSet" or self.dbType == "Publish": + clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ + (self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) + clauseItem += " and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and Geno.Chr = '%s' and Geno.Mb > %2.7f and Geno.Mb < %2.7f" \ + % (self.dbType, self.speciesId, chrsch, min(MblowerLimit, MbupperLimit), max(MblowerLimit, MbupperLimit)) + query.append(" (%s) " % clauseItem) + self.orderByDefalut = "MB" + DescriptionText.append(HT.Span(' with ', HT.U('LRS'), ' between %g and %g' % \ + (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)), \ + ' on chromosome %s between %g and %g Mb' % \ + (chrsch, min(MblowerLimit, MbupperLimit), max(MblowerLimit, MbupperLimit)))) + pass + + return 1 + + def generateWarningLayer(self): + + layerString = """ + + + + + """ + + return layerString + + def getTableHeaderForGeno(self, worksheet=None, newrow=None, headingStyle=None): + + tblobj_header = [] + + className = "fs13 fwb ffl b1 cw cbrb" + + tblobj_header = [[THCell(HT.TD(' ', Class=className), sort=0), + THCell(HT.TD('Record', HT.BR(), 'ID', HT.BR(), Class=className), text='record_id', idx=1), + THCell(HT.TD('Location', HT.BR(), 'Chr and Mb', HT.BR(), Class=className), text='location', idx=2)]] + + for ncol, item in enumerate(['Record ID', 'Location (Chr, Mb)']): + worksheet.write([newrow, ncol], item, headingStyle) + worksheet.set_column([ncol, ncol], 2*len(item)) + + return tblobj_header + + + def getTableBodyForGeno(self, traitList, formName=None, worksheet=None, newrow=None): + + tblobj_body = [] + + className = "fs12 fwn ffl b1 c222" + + for thisTrait in traitList: + tr = [] + + if not thisTrait.haveinfo: + thisTrait.retrieveInfo() + + trId = str(thisTrait) + + tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) + + tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name, thisTrait.name), Class="fs12 fwn ffl"),align="left", Class=className), text=thisTrait.name, val=thisTrait.name.upper())) + + #XZ: trait_location_value is used for sorting + trait_location_repr = 'N/A' + trait_location_value = 1000000 + + if thisTrait.chr and thisTrait.mb: + try: + trait_location_value = int(thisTrait.chr)*1000 + thisTrait.mb + except: + if thisTrait.chr.upper() == 'X': + trait_location_value = 20*1000 + thisTrait.mb + else: + trait_location_value = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb + + trait_location_repr = 'Chr%s: %.6f' % (thisTrait.chr, float(thisTrait.mb) ) + + tr.append(TDCell(HT.TD(trait_location_repr, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value)) + + tblobj_body.append(tr) + + for ncol, item in enumerate([thisTrait.name, trait_location_repr]): + worksheet.write([newrow, ncol], item) + + newrow += 1 + + return tblobj_body + + def getTableHeaderForPublish(self, worksheet=None, newrow=None, headingStyle=None): + + tblobj_header = [] + + className = "fs13 fwb ffl b1 cw cbrb" + + tblobj_header = [[THCell(HT.TD(' ', Class=className, nowrap="on"), sort=0), + THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class=className, nowrap="on"), text="recond_id", idx=1), + THCell(HT.TD('Phenotype',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="pheno", idx=2), + THCell(HT.TD('Authors',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="auth", idx=3), + THCell(HT.TD('Year',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="year", idx=4), + THCell(HT.TD('Max',HT.BR(), 'LRS', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="lrs", idx=5), + THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="lrs_location", idx=6)]] + + for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "Pubmed Id", "Max LRS", "Max LRS Location (Chr: Mb)"]): + worksheet.write([newrow, ncol], item, headingStyle) + worksheet.set_column([ncol, ncol], 2*len(item)) + + return tblobj_header + + def getTableBodyForPublish(self, traitList, formName=None, worksheet=None, newrow=None, species=''): + + tblobj_body = [] + + className = "fs12 fwn b1 c222" + + for thisTrait in traitList: + tr = [] + + if not thisTrait.haveinfo: + thisTrait.retrieveInfo(QTL=1) + + trId = str(thisTrait) + + tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) + + tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name, thisTrait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class=className),str(thisTrait.name), thisTrait.name)) + + PhenotypeString = thisTrait.post_publication_description + if thisTrait.confidential: + if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): + PhenotypeString = thisTrait.pre_publication_description + tr.append(TDCell(HT.TD(PhenotypeString, Class=className), PhenotypeString, PhenotypeString.upper())) + + tr.append(TDCell(HT.TD(thisTrait.authors, Class="fs12 fwn b1 c222 fsI"),thisTrait.authors, thisTrait.authors.strip().upper())) + + try: + PubMedLinkText = myear = repr = int(thisTrait.year) + except: + PubMedLinkText = repr = "N/A" + myear = 0 + + if thisTrait.pubmed_id: + PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id,target='_blank', Class="fs12 fwn") + else: + PubMedLink = repr + + tr.append(TDCell(HT.TD(PubMedLink, Class=className, align='center'), repr, myear)) + + #LRS and its location + LRS_score_repr = 'N/A' + LRS_score_value = 0 + LRS_location_repr = 'N/A' + LRS_location_value = 1000000 + LRS_flag = 1 + + + if thisTrait.lrs: + LRS_score_repr = '%3.1f' % thisTrait.lrs + LRS_score_value = thisTrait.lrs + tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) + + self.cursor.execute(""" + select Geno.Chr, Geno.Mb from Geno, Species + where Species.Name = '%s' and + Geno.Name = '%s' and + Geno.SpeciesId = Species.Id + """ % (species, thisTrait.locus)) + result = self.cursor.fetchone() + + if result: + if result[0] and result[1]: + LRS_Chr = result[0] + LRS_Mb = result[1] + + #XZ: LRS_location_value is used for sorting + try: + LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) + except: + if LRS_Chr.upper() == 'X': + LRS_location_value = 20*1000 + float(LRS_Mb) + else: + LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) + + LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) + LRS_flag = 0 + + tr.append(TDCell(HT.TD(LRS_location_repr, Class=className, nowrap="on"), LRS_location_repr, LRS_location_value)) + + else: + tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + + tblobj_body.append(tr) + + for ncol, item in enumerate([thisTrait.name, PhenotypeString, thisTrait.authors, thisTrait.year, thisTrait.pubmed_id, LRS_score_repr, LRS_location_repr]): + worksheet.write([newrow, ncol], item) + + newrow += 1 + + return tblobj_body + + def getTableHeaderForProbeSet(self, worksheet=None, newrow=None, headingStyle=None): + + tblobj_header = [] + + className = "fs13 fwb ffl b1 cw cbrb" + + #tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0), + # THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="record_id", idx=1), + # THCell(HT.TD('Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="symbol", idx=2), + # THCell(HT.TD('Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="desc", idx=3), + # THCell(HT.TD('Location',HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="location", idx=4), + # THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="mean", idx=5), + # THCell(HT.TD('Max',HT.BR(),'LRS',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lrs", idx=6), + # THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lrs_location", idx=7)]] + # + #for ncol, item in enumerate(['Record', 'Gene ID', 'Homologene ID', 'Symbol', 'Description', 'Location (Chr, Mb)', 'Mean Expr', 'Max LRS', 'Max LRS Location (Chr: Mb)']): + # worksheet.write([newrow, ncol], item, headingStyle) + # worksheet.set_column([ncol, ncol], 2*len(item)) + + return tblobj_header + + def getTableBodyForProbeSet(self, traitList=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): + # Note: setting traitList to [] is probably not a great idea. + tblobj_body = [] + + className = "fs12 fwn b1 c222" + + for thisTrait in traitList: + + if not thisTrait.haveinfo: + thisTrait.retrieveInfo(QTL=1) + + if thisTrait.symbol: + pass + else: + thisTrait.symbol = "N/A" + + tr = [] + + trId = str(thisTrait) + + #XZ, 12/08/2008: checkbox + #tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId)) + + #XZ, 12/08/2008: probeset name + #if thisTrait.cellid: + # tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name, url="javascript:showDatabase3('%s','%s','%s','%s')" % (formName, thisTrait.db.name,thisTrait.name,thisTrait.cellid), Class="fs12 fwn"), Class=className), thisTrait.name, thisTrait.name.upper())) + #else: + # tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name, url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name,thisTrait.name), Class="fs12 fwn"), Class=className), thisTrait.name, thisTrait.name.upper())) + # + #if thisTrait.geneid: + # symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % thisTrait.geneid, Class="font_black fs12 fwn") + #else: + # symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % thisTrait.symbol, Class="font_black fs12 fwn") + # + ##XZ, 12/08/2008: gene symbol + #tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),thisTrait.symbol, thisTrait.symbol.upper())) + + #XZ, 12/08/2008: description + #XZ, 06/05/2009: Rob asked to add probe target description + description_string = str(thisTrait.description).strip() + target_string = str(thisTrait.probe_target_description).strip() + + description_display = '' + + if len(description_string) > 1 and description_string != 'None': + description_display = description_string + else: + description_display = thisTrait.symbol + + if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': + description_display = description_display + '; ' + target_string.strip() + + #tr.append(TDCell(HT.TD(description_display, Class=className), description_display, description_display)) + + # Save it for the jinja2 tablet + thisTrait.description_display = description_display + + #XZ: trait_location_value is used for sorting + trait_location_repr = 'N/A' + trait_location_value = 1000000 + + if thisTrait.chr and thisTrait.mb: + try: + trait_location_value = int(thisTrait.chr)*1000 + thisTrait.mb + except: + if thisTrait.chr.upper() == 'X': + trait_location_value = 20*1000 + thisTrait.mb + else: + trait_location_value = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb + + trait_location_repr = 'Chr%s: %.6f' % (thisTrait.chr, float(thisTrait.mb) ) + thisTrait.trait_location_repr = trait_location_repr + #thisTrait.trait_location_value = trait_location_value + tr.append(TDCell(HT.TD(trait_location_repr, Class=className, nowrap="on"), trait_location_repr, trait_location_value)) + + #XZ, 01/12/08: This SQL query is much faster. + self.cursor.execute(""" + select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet + where ProbeSetXRef.ProbeSetFreezeId = %d and + ProbeSet.Id = ProbeSetXRef.ProbeSetId and + ProbeSet.Name = '%s' + """ % (thisTrait.db.id, thisTrait.name)) + result = self.cursor.fetchone() + if result: + if result[0]: + mean = result[0] + else: + mean=0 + else: + mean = 0 + + #XZ, 06/05/2009: It is neccessary to turn on nowrap + thisTrait.mean = repr = "%2.3f" % mean + tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean)) + + #LRS and its location + LRS_score_repr = 'N/A' + LRS_score_value = 0 + LRS_location_repr = 'N/A' + LRS_location_value = 1000000 + LRS_flag = 1 + + #Max LRS and its Locus location + if thisTrait.lrs and thisTrait.locus: + self.cursor.execute(""" + select Geno.Chr, Geno.Mb from Geno, Species + where Species.Name = '%s' and + Geno.Name = '%s' and + Geno.SpeciesId = Species.Id + """ % (species, thisTrait.locus)) + result = self.cursor.fetchone() + + if result: + if result[0] and result[1]: + LRS_Chr = result[0] + LRS_Mb = result[1] + + #XZ: LRS_location_value is used for sorting + try: + LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) + except: + if LRS_Chr.upper() == 'X': + LRS_location_value = 20*1000 + float(LRS_Mb) + else: + LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) + + thisTrait.LRS_score_repr = LRS_score_repr = '%3.1f' % thisTrait.lrs + thisTrait.LRS_score_value = LRS_score_value = thisTrait.lrs + thisTrait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) + LRS_flag = 0 + + #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, thisTrait.db.shortname, thisTrait.name), Class="fs12 fwn"), Class=className, align='right', nowrap="on"),LRS_score_repr, LRS_score_value)) + tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value)) + tr.append(TDCell(HT.TD(LRS_location_repr, Class=className, nowrap="on"), LRS_location_repr, LRS_location_value)) + + if LRS_flag: + tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) + tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value)) + + else: + tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + + tblobj_body.append(tr) + + #for ncol, item in enumerate([thisTrait.name, thisTrait.geneid, thisTrait.homologeneid, thisTrait.symbol, description_display, trait_location_repr, mean, LRS_score_repr, LRS_location_repr]): + # worksheet.write([newrow, ncol], item) + + + newrow += 1 + + return tblobj_body + + def createExcelFileWithTitleAndFooter(self, workbook=None, identification=None, db=None, returnNumber=None): + + worksheet = workbook.add_worksheet() + + titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray") + + ##Write title Info + # Modified by Hongqiang Li + worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) + worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) + worksheet.write([2, 0], "Trait : %s" % identification, titleStyle) + worksheet.write([3, 0], "Database : %s" % db.fullname, titleStyle) + worksheet.write([4, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle) + worksheet.write([5, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle) + worksheet.write([6, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle) + #Write footer info + worksheet.write([9 + returnNumber, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle) + worksheet.write([10 + returnNumber, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle) + + return worksheet + + def getSortByValue(self, datasetType=''): + + if datasetType == 'Geno': + sortby = ("location", "up") + elif datasetType == 'ProbeSet': + sortby = ("symbol", "up") + else: #Phenotype + sortby = ("record_id", "down") + + return sortby diff --git a/wqflask/wqflask/static/css b/wqflask/wqflask/static/css new file mode 120000 index 00000000..9d8c2f68 --- /dev/null +++ b/wqflask/wqflask/static/css @@ -0,0 +1 @@ +../../../web/css \ No newline at end of file diff --git a/wqflask/wqflask/static/images b/wqflask/wqflask/static/images new file mode 120000 index 00000000..12f0f8b5 --- /dev/null +++ b/wqflask/wqflask/static/images @@ -0,0 +1 @@ +../../../web/images \ No newline at end of file diff --git a/wqflask/wqflask/static/javascript b/wqflask/wqflask/static/javascript new file mode 120000 index 00000000..5f58faf4 --- /dev/null +++ b/wqflask/wqflask/static/javascript @@ -0,0 +1 @@ +../../../web/javascript \ No newline at end of file diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html new file mode 100644 index 00000000..117d26fb --- /dev/null +++ b/wqflask/wqflask/templates/base.html @@ -0,0 +1,215 @@ + + + + + {% block head %} + {% block title %}{% endblock %} - GeneNetwork + + + + + + + + + + + + + + + + + + + + + + + + + {% endblock %} + + + + + + + + + + + + + + + + + + + + + + + +
{% block content %}{% endblock %}
+ + + + + + +
  + + + + + + +
+ + + + + + + + + WebQTL +
+
 
+ + + + + +
+    |    + + Home +    |    + + Search +    |    + + Help +    |    + + + News +    |    + + + References +    |    + + Policies +    |    + + + Links +    |    + + Welcome! Login    +
+
+ + + + + + + + + + + + + + +
+ + CITG + +WWW service initiated January, 1994 as The Portable Dictionary of the Mouse Genome and June 15, 2001 as WebQTL. + +This site is currently operated by + Rob Williams, + Lei Yan, + Zachary Sloan, + Arthur Centeno. Design and code by Xiaodong Zhou, Christian Fernandez, Ning Liu, Rudi Alberts, Elissa Chesler, Jintao Wang, Kenneth Manly, Robert W. Williams, and colleagues. + + + + + Python Powered + + + Registered with Nif +
+ GeneNetwork support from: + +
+     It took 0.041 second(s) for spring211.uthsc.edu to generate this page +
+
+ + + + + + + + + diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html new file mode 100644 index 00000000..89581075 --- /dev/null +++ b/wqflask/wqflask/templates/index_page.html @@ -0,0 +1,313 @@ +{% extends "base.html" %} +{% block title %}GeneNetwork{% endblock %} +{% block content %} + + + + + + + + + + + + + + +
+

Select and Search +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Species: + + + +
+ Group: + + + +
+ Type: + + + +
+ Database: + + + + +
+ + +

    Databases marked with ** suffix are not public yet. +
    Access requires user login.

+
+ Get Any: + + + + +
+ + + +

    Enter terms, genes, ID numbers in the Get Any field. +
    Use * or ? wildcards (Cyp*a?, synap*). +
    Use Combined for terms such as tyrosine kinase.

+ +
+ Combined: + + + + +
+ + +      +      + + +
+ + + +
+ + + + + + + + +

 ______________________________________________________ + +

  + +Quick HELP Examples and + + User's Guide

+ + +  You can also use advanced commands. Copy these simple examples +
  into the Get Any or Combined search fields: +
    + +
  • POSITION=(chr1 25 30) finds genes, markers, or transcripts on chromosome 1 between 25 and 30 Mb. + +
  • MEAN=(15 16) LRS=(23 46) in the Combined field finds highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46. + + +
  • RIF=mitochondrial searches RNA databases for GeneRIF links. + +
  • WIKI=nicotine searches GeneWiki for genes that you or other users have annotated with the word nicotine. + +
  • GO:0045202 searches for synapse-associated genes listed in the Gene Ontology. + + +
  • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)
    in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores between 9 and 999. + +
  • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
    in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS scores between 9 and 999. + + +
+ +
+

Websites Affiliated with GeneNetwork

+

+

+

+

____________________________ + +

Getting Started   

+
    +
  1. Select Species (or select All) +
  2. Select Group (a specific sample) +
  3. Select Type of data: +
      +
    • Phenotype (traits) +
    • Genotype (markers) +
    • Expression (mRNAs) +
    +
  4. Select a Database +
  5. Enter search terms in the Get Any or Combined field: words, genes, ID numbers, probes, advanced search commands +
  6. Click on the Search button +
  7. Optional: Use the Make Default button to save your preferences +
+ +

____________________________ + +

How to Use GeneNetwork + +

+

Take a 20-40 minute GeneNetwork Tour that includes screen shots and typical steps in the analysis.

+
+
+

For information about resources and methods, select the INFO buttons.

+ + + +

Try the Workstation site to explore data and features that are being implemented.

+ + +

Review the Conditions and Contacts pages for information on the status of data sets and advice on their use and citation.

+ + +
+ + + +

Mirror and Development Sites

+ + + + +

History and Archive + +

+

GeneNetwork's Time Machine links to earlier versions that correspond to specific publication dates.

+ +
+ + +

+
+ + + + + + + +{% endblock %} diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html new file mode 100644 index 00000000..f79a19a7 --- /dev/null +++ b/wqflask/wqflask/templates/search_result_page.html @@ -0,0 +1,203 @@ +{% extends "base.html" %} +{% block title %}Search Results{% endblock %} +{% block content %} + + + + + + + +
+

Search Results

+
GeneNetwork searched the following databases: + + + For all records that match: +
    + {% if ORkeyword2 %} +
  • + {% for word in ORkeyword2 %} + {{word}} {% if not loop.last %} or {% endif %} + {% endfor %} +
  • + {% endif %} + {% if ANDkeyword2 %} +
  • + {% for word in ANDkeyword2 %} + {{word}} {% if not loop.last %} and {% endif %} + {% endfor %} +
  • + {% endif %} +
+ +

GeneNetwork found {{ numify(nresults, "record", "records") }}.

+ +

To study a record, click on its ID below.

+ +

To add one or more records to your Selection window, use the checkbox and then click the Add to Collection button.

+
+
+ + + + + + + +

+ + + + + + + + + + +
+ + + + + + + + + + + + +
+ + Select All + + + Select None + + + + Invert Selection + + + + Add To Collection + +
  Select Deselect   Invert    Add
+
+ +
+
+ + + + + + + + + + + + {% for thisTrait in traitList %} + + + + + + + + + + + {% endfor %} +
+ + Record +
ID
+ +
+ Symbol

+
+ sortupon.gif + + sortdown.gif + +
+
+ Description

+ +
Location
Chr and Mb
+ +
Mean
Expr
+ +
Max
LRS
+ +
Max LRS Location
Chr and Mb
+ +
{{ loop.index }} + + + {{ thisTrait.name.upper() }} + + + {{ thisTrait.symbol }} + + {{ thisTrait.description_display }}{{ thisTrait.trait_location_repr }}{{ thisTrait.mean }}{{ thisTrait.LRS_score_repr }}{{ thisTrait.LRS_location_repr }}
+
+
+ +

+
+ + + + +{% endblock %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py new file mode 100644 index 00000000..2f686432 --- /dev/null +++ b/wqflask/wqflask/views.py @@ -0,0 +1,23 @@ +from __future__ import absolute_import, division, print_function + +from wqflask import app + +from flask import render_template, request + +from wqflask import search_results + +from pprint import pformat as pf + +@app.route("/") +def index_page(): + return render_template("index_page.html") + + +@app.route("/search") +def search(): + print("request is:", request.args) + the_search = search_results.SearchResultPage(request.args) + print("At rendering...") + print(pf(the_search.__dict__)) + print("yack:", the_search.database[0].genHTML()) + return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From 26663ce7a4bb75d2602261ed957bf3c1cdc4ebc6 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 24 May 2012 03:10:30 -0400 Subject: Added README, modified requirements --- README-wqflask.txt | 31 ++++++++++++ wqflask/other_config/nginx.conf | 104 ++++++++++++++++++++++++++++++++++++++ wqflask/requirements.txt | 1 - wqflask/wqflask/__init__.py | 3 ++ wqflask/wqflask/search_results.py | 2 +- 5 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 README-wqflask.txt create mode 100644 wqflask/other_config/nginx.conf diff --git a/README-wqflask.txt b/README-wqflask.txt new file mode 100644 index 00000000..fdade7fa --- /dev/null +++ b/README-wqflask.txt @@ -0,0 +1,31 @@ +This readme concerns the directory wqflask - an officially sanctioned fork of the main GeneNetwork +code. It's still very early in the process - but we eventually want to port all of the code +in GeneNetwork to Flask and Jinja2. For more information about the project in general, see +the file README.md. + +For more information about the port to Flask, please keep reading. + +************************* + +Requirements: + +* Python 2.7 + +* virtualenv 1.7.1.2 or later + +* Other python dependencies are listed in the file wqflask/requirements.txt + +************************** + +Installation: + +We highly recommend you create a virtual enviornment called ve27 in your home directory. + +> cd ~ + +> virtualenv ve27 + +> source ~/ve27/bin/activate + +> pip install -r ~/gene/wqflask/requirements.txt +(Or replace gene with the name of the directory holding your repository) diff --git a/wqflask/other_config/nginx.conf b/wqflask/other_config/nginx.conf new file mode 100644 index 00000000..93e6af10 --- /dev/null +++ b/wqflask/other_config/nginx.conf @@ -0,0 +1,104 @@ + +#user nobody; +worker_processes 1; + +#error_log logs/error.log; +#error_log logs/error.log notice; +#error_log logs/error.log info; + +#pid logs/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + + gzip on; + + server { + # Modeled after http://flask.pocoo.org/docs/deploying/wsgi-standalone/ + listen 80; + + server_name _; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + location ^~ /css/ { + root /home/sam/gene/wqflask/wqflask/static/; + } + + location ^~ /javascript/ { + root /home/sam/gene/wqflask/wqflask/static/; + } + + location ^~ /images/ { + root /home/sam/gene/wqflask/wqflask/static/; + } + + location / { + proxy_pass http://127.0.0.1:5000/; + proxy_redirect off; + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + } + + + # another virtual host using mix of IP-, name-, and port-based configuration + # + #server { + # listen 8000; + # listen somename:8080; + # server_name somename alias another.alias; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + + + # HTTPS server + # + #server { + # listen 443; + # server_name localhost; + + # ssl on; + # ssl_certificate cert.pem; + # ssl_certificate_key cert.key; + + # ssl_session_timeout 5m; + + # ssl_protocols SSLv2 SSLv3 TLSv1; + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + +} diff --git a/wqflask/requirements.txt b/wqflask/requirements.txt index caa5d61e..684722aa 100644 --- a/wqflask/requirements.txt +++ b/wqflask/requirements.txt @@ -2,5 +2,4 @@ Flask==0.8 Jinja2==2.6 MySQL-python==1.2.3 Werkzeug==0.8.3 -pyXLWriter==0.4a3 wsgiref==0.1.2 diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index d0484c83..a6119dcc 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -1,5 +1,8 @@ from __future__ import absolute_import, division, print_function +import sys +print("sys.path is:", sys.path) + from flask import Flask from utility import formatting diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index c100645e..9ec676b8 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -16,7 +16,7 @@ import cPickle import re from math import * import time -import pyXLWriter as xl +#import pyXLWriter as xl #import pp - Note from Sam: is this used? import math import datetime -- cgit v1.2.3 From 3912f2bacd87f607e9fdfa7a83fcdc05522589e0 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 24 May 2012 03:28:38 -0400 Subject: Added more to readme --- README-wqflask.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/README-wqflask.txt b/README-wqflask.txt index fdade7fa..03e3a1cc 100644 --- a/README-wqflask.txt +++ b/README-wqflask.txt @@ -21,11 +21,31 @@ Installation: We highly recommend you create a virtual enviornment called ve27 in your home directory. + +Get into your home directory > cd ~ +Create a virtual environment > virtualenv ve27 +Activate the environment > source ~/ve27/bin/activate +Install dependencies > pip install -r ~/gene/wqflask/requirements.txt (Or replace gene with the name of the directory holding your repository) + +************************** + +Running the program: + +Assuming your enviornment is activated (source ~/ve27/bin/activate) just run: + +> python ~/gene/wqflask/runserver.py + +The program as configured runs on port 5000 and does not serve static files. + +You'll have to run a webserver to serve pages on port 80 and to server the static files (or +flask could also be configured to serve the static pages). + +A sample configuration file for nginx is in the directory: wqflask/other_config/nginx.conf -- cgit v1.2.3 From 1fee128fafc491dbe84ebac22d8522bcb6ca1e6b Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 24 May 2012 03:43:09 -0400 Subject: Got rid of a bunch of prints used for debugging --- wqflask/wqflask/search_results.py | 34 +++++++--------------------------- wqflask/wqflask/views.py | 4 ---- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 9ec676b8..ee67c5de 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -59,25 +59,12 @@ class SearchResultPage(templatePage): nkeywords = 0 def __init__(self, fd): - _log.info("Got here - xerxes2") - _log.info("sys.path: %s" % (sys.path)) - #_log.info(causeanerror) - _log.info("xerxesc") - #self.jtemplate = JinjaEnv.get_template('SearchResultPage.html') - #templatePage.__init__(self, fd) - if not self.openMysql(): return - _log.info("xerxesd") - - #self.dict['title'] = 'Search Results' - #TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") - print("e2.8") self.database = [fd['database']] - print("e2.9") + if not self.database or self.database == 'spacer': - print("e3") #Error, No database selected heading = "Search Result" detail = ['''No database was selected for this search, please @@ -85,16 +72,14 @@ class SearchResultPage(templatePage): self.error(heading=heading,detail=detail,error="No Database Selected") return elif type(self.database) == type(""): - print("e3.2") #convert database into a database list #was used for multiple databases search, this #feature has been abandoned, self.database = string.split(self.database,',') else: - print("e3.4") pass - print("e4") + ########################################### # Names and IDs of RISet / F2 set ########################################### @@ -155,7 +140,6 @@ class SearchResultPage(templatePage): #XZ, August 24,2010: Since self.singleCross = True, it's safe to assign one species Id. self.speciesId = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.database[0].riset) - print("e4.5") ########################################### # make sure search from same type of databases ########################################### @@ -175,22 +159,20 @@ class SearchResultPage(templatePage): elif self.dbType == "Geno": self.searchField = ['Name','Chr'] - print("e4.6") ########################################### # Search Options ########################################### self.matchwhole = fd['matchwhole'] - print("e4.65") #split result into pages self.pageNumber = fd.get('pageno', 0) - print("e4.7") + try: self.pageNumber = int(self.pageNumber) except Exception as why: print(why) self.pageNumber = 0 - print("e5") + ########################################### # Generate Mysql Query ########################################### @@ -252,7 +234,6 @@ class SearchResultPage(templatePage): dbUrlLink = " were" else: dbUrl = self.database[0].genHTML() - print("glasses:", dbUrl) dbUrlLink = " was" #SearchText = HT.Blockquote('GeneNetwork searched the ', dbUrl, ' for all records ') @@ -309,7 +290,6 @@ class SearchResultPage(templatePage): # SearchText.append(" and ") # #SearchText.append(". ") - _log.info("fweep") #if self.nresults == 0: # heading = "Search Result" # detail = ["Sorry, GeneNetwork did not find any records matching your request. Please check the syntax or try the ANY rather than the ALL field."] @@ -331,7 +311,7 @@ class SearchResultPage(templatePage): #TD_LR.append(HT.Paragraph('Search Results', Class="title"), SearchText) - _log.info("flop") + self.genSearchResultTable() #self.dict['body'] = str(TD_LR) #self.dict['js1'] = '' @@ -397,7 +377,7 @@ class SearchResultPage(templatePage): tblobj = {} mainfmName = thisFormName species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet) - _log.info("flap trait is: %s" % (thisTrait.db.type)) + if thisTrait.db.type=="Geno": tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) @@ -534,7 +514,7 @@ class SearchResultPage(templatePage): self.results = [] for item in searchCountQuery: start_time = datetime.datetime.now() - _log.info("foo - Executing query: %s"%(item)) + _log.info("Executing query: %s"%(item)) self.cursor.execute(item) allResults.append(self.cursor.fetchall()) end_time = datetime.datetime.now() diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 2f686432..88a6f6a1 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -15,9 +15,5 @@ def index_page(): @app.route("/search") def search(): - print("request is:", request.args) the_search = search_results.SearchResultPage(request.args) - print("At rendering...") - print(pf(the_search.__dict__)) - print("yack:", the_search.database[0].genHTML()) return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From 88022d6c26b320cb614454b706fad26fcd34033e Mon Sep 17 00:00:00 2001 From: root Date: Thu, 31 May 2012 17:10:28 -0500 Subject: On branch develop Changes to be committed: modified: web/javascript/jqueryFunction.js modified: web/webqtl/correlation/CorrelationPage.py modified: web/webqtl/showTrait/DataEditingPage.py --- web/javascript/jqueryFunction.js | 2041 ++++++++++++++--------------- web/webqtl/correlation/CorrelationPage.py | 1118 +++++++++------- web/webqtl/showTrait/DataEditingPage.py | 35 +- 3 files changed, 1648 insertions(+), 1546 deletions(-) mode change 100644 => 100755 web/javascript/jqueryFunction.js mode change 100644 => 100755 web/webqtl/showTrait/DataEditingPage.py diff --git a/web/javascript/jqueryFunction.js b/web/javascript/jqueryFunction.js old mode 100644 new mode 100755 index 5e6641cd..e612098b --- a/web/javascript/jqueryFunction.js +++ b/web/javascript/jqueryFunction.js @@ -1,80 +1,75 @@ /* jquery part */ - /* used by index (base/indexBody.py) */ - -$(document).ready(function(){ +$(document).ready(function () { options_visible = 0; //Whether advanced options are being shown - $('tr .advanced_option').hide(); - $('.toggle_advanced').click(function(){ + $('.toggle_advanced').click(function () { $('tr .advanced_option').toggle(); - - if (options_visible = 0) { - $('.full_search_td').css('display','none;'); - $('.search_td').css('display','inline'); - options_visible = 1; - } - else { - if ($('#type_menu.type_menu').val() = 'Hippocampus'){ - $('.search_td').css('display','none;'); - $('.full_search_td').css('display','inline'); - } - options_visible = 0; - } + + if (options_visible = 0) { + $('.full_search_td').css('display', 'none;'); + $('.search_td').css('display', 'inline'); + options_visible = 1; + } else { + if ($('#type_menu.type_menu').val() = 'Hippocampus') { + $('.search_td').css('display', 'none;'); + $('.full_search_td').css('display', 'inline'); + } + options_visible = 0; + } }); - $('#full_search').click(function(){ + $('#full_search').click(function () { gene_symbol = $('input[name=keyword]').val(); scriptable_interface_url = 'http://alexandria.uthsc.edu:89/webqtl/main.py?cmd=sch&gene=' + gene_symbol; - window.open(scriptable_interface_url,'_self'); + window.open(scriptable_interface_url, '_self'); }); }); -$('select.type_menu').live('change', function() { +$('select.type_menu').live('change', function () { var trait_type = $('select.type_menu option:selected').val(); - $('#tissue').val(trait_type); - $('#tissue').trigger('change'); + $('#tissue').val(trait_type); + $('#tissue').trigger('change'); }); /* used by CorrelationPage.py, AddToSelectionPage.py, and SearchResultPage.py */ -$(document).ready(function(){ - $('img[name=addselect], img[name=networkgraph], img[name=corrmatrix], img[name=partialCorr], img[name=comparecorr], img[name=mintmap], img[name=heatmap]').click(function(){ - if ($('input[name=searchResult]:checked').length < 1){ - for (i=0; i<10; i++){ - $('input[name=searchResult]:eq('+i+')').attr('checked',true); +$(document).ready(function () { + $('img[name=addselect], img[name=networkgraph], img[name=corrmatrix], img[name=partialCorr], img[name=comparecorr], img[name=mintmap], img[name=heatmap]').click(function () { + if ($('input[name=searchResult]:checked').length < 1) { + for (i = 0; i < 10; i++) { + $('input[name=searchResult]:eq(' + i + ')').attr('checked', true); } } }); - $('img[name=addselect]').click(function(){ - addRmvSelection($('input[name=RISet]').val(), document.getElementsByName('showDatabase'+ $('input[name=RISet]').val())[0], 'addToSelection'); + $('img[name=addselect]').click(function () { + addRmvSelection($('input[name=RISet]').val(), document.getElementsByName('showDatabase' + $('input[name=RISet]').val())[0], 'addToSelection'); }); - $('.toggleShowHide').click(function(){ + $('.toggleShowHide').click(function () { var className = '.extra_options'; - if ($(className).css('display') == 'none'){ - var less = 'less'; - $('input[name=showHideOptions]').val(less); + if ($(className).css('display') == 'none') { + var less = 'less'; + $('input[name=showHideOptions]').val(less); $(className).show(); $('input[name=options]').val('Fewer Options'); var display = $('input[name=options]').css('display') - $(display).val('block'); - } - else { - var more = 'more'; - $('input[name=showHideOptions]').val(more); - $(className).hide(); - $('input[name=options]').val('More Options'); - var display = $('input[name=showHideOptions]').css('display') - $(display).val('block'); + $(display).val('block'); + } else { + var more = 'more'; + $('input[name=showHideOptions]').val(more); + $(className).hide(); + $('input[name=options]').val('More Options'); + var display = $('input[name=showHideOptions]').css('display') + $(display).val('block'); } }); }); @@ -83,82 +78,91 @@ $(document).ready(function(){ used by AddToSelectionPage.py */ function validateTraitNumber() { - var checkBoxes = $('.checkallbox'); - if (checkBoxes.filter(":checked").length < 2) { - alert("Please select at least two traits."); - return false; - } - else { - return true; - } + var checkBoxes = $('.checkallbox'); + if (checkBoxes.filter(":checked").length < 2) { + alert("Please select at least two traits."); + return false; + } else { + return true; + } } /* used by TextSearchPage.py */ -$(document).ready(function(){ - - $('.add_traits').click(function(){ - $('input[name=searchResult]').each(function(){ - if ($(this).is(':checked')){ - groupName = $(this).parents().next().next().children('[href]').text(); - addORrmv = 'addToSelection'; - thisForm = $('form[name=showDatabase]'); - addRmvSelection_allGroups(groupName, thisForm, addORrmv); - } - }); - }); - - function addRmvSelection_allGroups(groupName, thisForm, addORrmv){ - thisForm.attr('target',groupName); - thisForm.children('input[name=FormID]:hidden').val(addORrmv); - thisForm.children('input[name=RISet]:hidden').val(groupName); - var newWindow = open("",thisForm.attr('target'),"menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=1,directories=1,width=900"); - thisForm.submit(); - } - - $('.tab_content').hide(); //Hide all tab content - $('div.tab_container').each(function(){ - $(this).parent('td').find('div.tab_container:first').find('div.tab_content:first').show(); - }); - $('ul.tabs').each(function(){ - $(this).find('li:first').addClass('active'); - }); - $('ul.tabs:first').find('li:first').show(); - $('.tab_container:first').find('.tab_content:first').show(); - - //On Click Event - $('ul.tabs li').click(function() { - $('ul.tabs').find('li').removeClass('last_viewed'); - if($(this).parent('ul.tabs').next('div.tab_container').attr('id').indexOf('stats') != 1){ - $(this).addClass('last_viewed'); - } - $(this).parent('ul.tabs').find('li').removeClass('active'); - $(this).addClass('active'); - $(this).parent('ul.tabs').next('div.tab_container').find('.tab_content').hide(); - var activeTab = $(this).find('a').attr('href'); - if ($.browser.msie) - {$(activeTab).show();} - else - {$(activeTab).fadeIn();} //Fade in the active ID content - - return false; - }); +$(document).ready(function () { + + $('.add_traits').click(function () { + $('input[name=searchResult]').each(function () { + if ($(this).is(':checked')) { + groupName = $(this).parents().next().next().children('[href]').text(); + addORrmv = 'addToSelection'; + thisForm = $('form[name=showDatabase]'); + addRmvSelection_allGroups(groupName, thisForm, addORrmv); + } + }); + }); + + function addRmvSelection_allGroups(groupName, thisForm, addORrmv) { + thisForm.attr('target', groupName); + thisForm.children('input[name=FormID]:hidden').val(addORrmv); + thisForm.children('input[name=RISet]:hidden').val(groupName); + var newWindow = open("", thisForm.attr('target'), "menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=1,directories=1,width=900"); + thisForm.submit(); + } + + $('.tab_content').hide(); //Hide all tab content + $('div.tab_container').each(function () { + $(this).parent('td').find('div.tab_container:first').find('div.tab_content:first').show(); + }); + $('ul.tabs').each(function () { + $(this).find('li:first').addClass('active'); + }); + $('ul.tabs:first').find('li:first').show(); + $('.tab_container:first').find('.tab_content:first').show(); + + //On Click Event + $('ul.tabs li').click(function () { + $('ul.tabs').find('li').removeClass('last_viewed'); + if ($(this).parent('ul.tabs').next('div.tab_container').attr('id').indexOf('stats') != 1) { + $(this).addClass('last_viewed'); + } + $(this).parent('ul.tabs').find('li').removeClass('active'); + $(this).addClass('active'); + $(this).parent('ul.tabs').next('div.tab_container').find('.tab_content').hide(); + var activeTab = $(this).find('a').attr('href'); + if ($.browser.msie) { + $(activeTab).show(); + } else { + $(activeTab).fadeIn(); + } //Fade in the active ID content + return false; + }); }); /* used by DataEditingPage.py */ -$(document).ready(function() { +$(document).ready(function () { + + // ZS: This checks the number of columns in order to determine which column to not sort; in this case the plus-minus symbol shouldn't be sortable + $('#sortable1,#sortable2').find('th').each(function () { + if ($(this).text() == 'SE') { + $.tablesorter.defaults.headers = { + 3: { + sorter: false + } + }; + return false; + } + }); + + if ($('#sortable1,#sortable2').find('.outlier').size() > 0) { + $('input[name=sample_method]:eq(1)').attr('checked','checked'); + $('input[name=tissue_method]:eq(1)').attr('checked','checked'); + } - // ZS: This checks the number of columns in order to determine which column to not sort; in this case the plus-minus symbol shouldn't be sortable - $('#sortable1,#sortable2').find('th').each(function() { - if ($(this).text() == 'SE'){ - $.tablesorter.defaults.headers = { 3: {sorter: false} }; - return false; - } - }); /* ZS: This segment is called by tablesorter.js; it determines where to get the text used when sorting, based on the type of cell. @@ -167,949 +171,922 @@ $(document).ready(function() { This segment is repeated twice. Ideally this wouldn't be the case, but I can't find a way to reuse the inner textExtraction function. */ - //ZS: Defining these here, so they don't need to be searched for in the DOM for every single node - primaryTable = $("#sortable1"); - otherTable = $("#sortable2"); - - primaryValueHeader = primaryTable.find('th:contains("Value"):eq(0)'); - primarySEHeader = primaryTable.find('th:contains("SE"):eq(0)'); - otherValueHeader = otherTable.find('th:contains("Value"):eq(1)'); - otherSEHeader = otherTable.find('th:contains("SE"):eq(1)'); - - $("#sortable1").tablesorter({ - textExtraction: function(node) { - if ((node.children[0] == "[object HTMLInputElement]" && node.children[0].type == "text") || (/\S/.test(node.id))) { - cellId = node.id; - thisCell = $('#'+cellId).children(':eq(0)') - valueClassNames = thisCell.attr('class').split(/\s+/); - capitalized_column_name = cellId.split('_')[0].charAt(0).toUpperCase() + cellId.split('_')[0].slice(1); - value = valueClassNames[valueClassNames.length - 1]; - newValue = thisCell.val(); - - if (newValue == 'x' || value == '9999' || value == '-9999') { - valueType = cellId.split('_')[0]; - if (valueType == 'value'){ - header = primaryValueHeader; - } else { - header = primarySEHeader; - } - - if (header.hasClass('headerSortUp')){ - sort_order = 'desc'; - } else if (header.hasClass('headerSortDown')){ - sort_order = 'asc'; - } else { - sort_order = 'desc'; - } - - if (sort_order == 'desc') { - value = 9999; - thisCell.removeClass(value).addClass('9999'); - } else if (sort_order == 'asc'){ - value = -9999; - thisCell.removeClass(value).addClass('-9999'); - } else { - value = 9999; - thisCell.removeClass(value).addClass('9999'); - } - } - - text = value; - } - - else { - if (node.textContent) { - text = node.textContent; - } else { - if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { - text = node.childNodes[0].innerHTML; - } else { - text = node.innerText; - } - } - } - return text - } - }); - - $("#sortable2").tablesorter({ - textExtraction: function(node) { - if ((node.children[0] == "[object HTMLInputElement]" && node.children[0].type == "text") || (/\S/.test(node.id))) { - cellId = node.id; - thisCell = $('#'+cellId).children(':eq(0)') - valueClassNames = thisCell.attr('class').split(/\s+/); - capitalized_column_name = cellId.split('_')[0].charAt(0).toUpperCase() + cellId.split('_')[0].slice(1); - value = valueClassNames[valueClassNames.length - 1]; - newValue = thisCell.val(); - - if (newValue == 'x' || value == '9999' || value == '-9999') { - valueType = cellId.split('_')[0]; - if (valueType == 'value'){ - header = otherValueHeader; - } else { - header = otherSEHeader; - } - - if (header.hasClass('headerSortUp')){ - sort_order = 'desc'; - } else if (header.hasClass('headerSortDown')){ - sort_order = 'asc'; - } else { - sort_order = 'desc'; - } - - if (sort_order == 'desc') { - value = 9999; - thisCell.removeClass(value).addClass('9999'); - } else if (sort_order == 'asc'){ - value = -9999; - thisCell.removeClass(value).addClass('-9999'); - } else { - value = 9999; - thisCell.removeClass(value).addClass('9999'); - } - } - - text = value; - } - - else { - if (node.textContent) { - text = node.textContent; - } else { - if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { - text = node.childNodes[0].innerHTML; - } else { - text = node.innerText; - } - } - } - return text - } - }); + //ZS: Defining these here, so they don't need to be searched for in the DOM for every single node + primaryTable = $("#sortable1"); + otherTable = $("#sortable2"); + + primaryValueHeader = primaryTable.find('th:contains("Value"):eq(0)'); + primarySEHeader = primaryTable.find('th:contains("SE"):eq(0)'); + otherValueHeader = otherTable.find('th:contains("Value"):eq(1)'); + otherSEHeader = otherTable.find('th:contains("SE"):eq(1)'); + + $("#sortable1").tablesorter({ + textExtraction: function (node) { + if ((node.children[0] == "[object HTMLInputElement]" && node.children[0].type == "text") || (/\S/.test(node.id))) { + cellId = node.id; + thisCell = $('#' + cellId).children(':eq(0)') + valueClassNames = thisCell.attr('class').split(/\s+/); + capitalized_column_name = cellId.split('_')[0].charAt(0).toUpperCase() + cellId.split('_')[0].slice(1); + value = valueClassNames[valueClassNames.length - 1]; + newValue = thisCell.val(); + + if (newValue == 'x' || value == '9999' || value == '-9999') { + valueType = cellId.split('_')[0]; + if (valueType == 'value') { + header = primaryValueHeader; + } else { + header = primarySEHeader; + } + + if (header.hasClass('headerSortUp')) { + sort_order = 'desc'; + } else if (header.hasClass('headerSortDown')) { + sort_order = 'asc'; + } else { + sort_order = 'desc'; + } + + if (sort_order == 'desc') { + value = 9999; + thisCell.removeClass(value).addClass('9999'); + } else if (sort_order == 'asc') { + value = -9999; + thisCell.removeClass(value).addClass('-9999'); + } else { + value = 9999; + thisCell.removeClass(value).addClass('9999'); + } + } -/* + text = value; + } else { + if (node.textContent) { + text = node.textContent; + } else { + if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { + text = node.childNodes[0].innerHTML; + } else { + text = node.innerText; + } + } + } + return text + } + }); + + $("#sortable2").tablesorter({ + textExtraction: function (node) { + if ((node.children[0] == "[object HTMLInputElement]" && node.children[0].type == "text") || (/\S/.test(node.id))) { + cellId = node.id; + thisCell = $('#' + cellId).children(':eq(0)') + valueClassNames = thisCell.attr('class').split(/\s+/); + capitalized_column_name = cellId.split('_')[0].charAt(0).toUpperCase() + cellId.split('_')[0].slice(1); + value = valueClassNames[valueClassNames.length - 1]; + newValue = thisCell.val(); + + if (newValue == 'x' || value == '9999' || value == '-9999') { + valueType = cellId.split('_')[0]; + if (valueType == 'value') { + header = otherValueHeader; + } else { + header = otherSEHeader; + } + + if (header.hasClass('headerSortUp')) { + sort_order = 'desc'; + } else if (header.hasClass('headerSortDown')) { + sort_order = 'asc'; + } else { + sort_order = 'desc'; + } + + if (sort_order == 'desc') { + value = 9999; + thisCell.removeClass(value).addClass('9999'); + } else if (sort_order == 'asc') { + value = -9999; + thisCell.removeClass(value).addClass('-9999'); + } else { + value = 9999; + thisCell.removeClass(value).addClass('9999'); + } + } + + text = value; + } else { + if (node.textContent) { + text = node.textContent; + } else { + if (node.childNodes[0] && node.childNodes[0].hasChildNodes()) { + text = node.childNodes[0].innerHTML; + } else { + text = node.innerText; + } + } + } + return text + } + }); + + /* ZS: When the user changes the value in the text field, the new value is added as a class. This is because $('input[type=text]').val() gets the value attribute, which is always the default value, instead of the value property (which can be changed) */ - var thisTable = $('#sortable1,#sortable2'); - - thisTable.bind("update propertychange keyup input paste", function(e){ - - var target = e.target; - $target = $(target); - - if (target.nodeName.toLowerCase() == 'input'){ - thisClassNames = $target.attr('class').split(/\s+/); - valueClass = thisClassNames[thisClassNames.length - 1]; - newValue = $target.val(); - thisParent = $target.parent('td'); - thisParentId = thisParent.attr('id'); - - $target.removeClass(valueClass); - - if (newValue == 'x'){ - thisParent.parent('tr').addClass('blocked'); - } else { - $('#'+thisParentId).children('input.valueField:eq(0)').addClass(newValue); - } - } - }); - - //////////////////////////////////// - // Initially close tabs - //////////////////////////////////// - - thisForm = $('form[name="dataInput"]'); - - $('#sectionbody2').hide(); - $('#sectionbody3').hide(); - $('#sectionbody4').hide(); - - $('#title1').click(function() { - $('#sectionbody1').toggle(); - return false; - }); - $('#title2').click(function() { - $('#sectionbody2').toggle(); - return false; - }); - $('#title3').click(function() { - $('#sectionbody3').toggle(); - return false; - }); - $('#title4').click(function() { - $('#sectionbody4').toggle(); - return false; - }); - $('#title5').click(function() { - $('#sectionbody5').toggle(); - return false; - }); - - - - ////////////////////////////////////////////////////////////// - // Switch out + and - icon when you click each section header - ////////////////////////////////////////////////////////////// - - var expand_html = "  \"Expand\""; - var contract_html = "  \"Contract\""; - - $('#title2, #title3, #title4').prepend(expand_html).addClass('1'); - - $('#title1, #title5').prepend(contract_html).addClass('0'); - - for(i=1;i<=5;i++){ - $('#title'+i).click(function(){ - if ($(this).hasClass('0')) { - $(this).find('span').replaceWith(expand_html); - $(this).removeClass('0'); - $(this).addClass('1'); - } - else { - $(this).find('span').replaceWith(contract_html); - $(this).removeClass('1'); - $(this).addClass('0'); - } - }); - } - - // Exclude cases by attributes - - $('div.attribute_values:first').css('display', 'inline'); //Display the dropdown menu with the first attribute's distinct values - - $('select[name=exclude_menu]').change(function(){ - $('div.attribute_values').css('display', 'none'); //clear all other menus when a new attribute is selected - attribute = $(this).val(); - //attribute = $('select[name=exclude_menu]').val(); - menu = $('div.attribute_values').find('[name=\''+attribute+'\']'); - menu.parent().css('display', 'inline'); - }); - - primary_row_count = $('#primary').find('tr').length - 1; - other_row_count = $('#other').find('tr').length - 1; - - if (primary_row_count >= other_row_count) { - row_count = primary_row_count; - } - else { - row_count = other_row_count; - } - - $('div.attribute_values').children('select').change(function(){ - exclude_value = $(this).val(); - }); -}); - -$(window).load(function(){ - - //ZS: These are needed in a few places; looping through rows by index is faster than doing a "find" search - numPrimaryRows = $('#sortable1').find('tr').length; - numOtherRows = $('#sortable2').find('tr').length; - - -/////////////////////////////// -//Basic Statistics -/////////////////////////////// - - ///////////////////////////////////////////////////////////////// - // Hide unselected Basic Statistics tabs (when just BXD strains - // are selected, hide the results for all strains/non-BXD) - ///////////////////////////////////////////////////////////////// - - $('#stats_tabs1').hide(); - $('#stats_tabs2').hide(); - - $('#sectionbody2').find('select[name=stats_mdp]').change(function(){ - selected = $('#sectionbody2').find('select[name=stats_mdp] option:selected').val(); - for (i=0;i<=2;i++){ - $('#stats_tabs'+i).hide(); - } - $('#stats_tabs'+selected).show(); - }); - - //////////////////////////////////////////////////////////////////////// - // Select the same tab across each sample group (when a Box Plot is - // selected for BXD, switching to Non-BXD will also display a Box Plot) - ////////////./////////////////////////////////////////////////////////// - - var $tabs1 = $('#stats_tabs0').tabs(); - var $tabs2 = $('#stats_tabs1').tabs(); - var $tabs3 = $('#stats_tabs2').tabs(); - - $tabs1.tabs({ - show: function(event, ui) { - var selected = $tabs1.tabs('option','selected'); - $tabs2.tabs('select',selected); - $tabs3.tabs('select',selected); - } - }); - $tabs2.tabs({ - show: function(event, ui) { - var selected = $tabs2.tabs('option','selected'); - $tabs1.tabs('select',selected); - $tabs3.tabs('select',selected); - } - }); - $tabs3.tabs({ - show: function(event, ui) { - var selected = $tabs3.tabs('option','selected'); - $tabs1.tabs('select',selected); - $tabs2.tabs('select',selected); - } - }); - - -/////////////////////////////// -//Calculate Correlations -/////////////////////////////// - - $('#sectionbody3').find('input[name="sample_corr"]').click(function() { - dbValue = $('select[name=database1] option:selected').val(); - $('input[name=database]').val(dbValue); - criteriaValue = $('select[name=criteria1] option:selected').val(); - $('input[name=criteria]').val(criteriaValue); - MDPValue = $('select[name=MDPChoice1] option:selected').val(); - $('input[name=MDPChoice]').val(MDPValue); - - methodValue = $('input[name=sample_method]:checked').val(); - - //This simple method can be used now that 'method' is defaulted to None instead of '' - if (methodValue == "1"){ - $('input[name=method]').val('1'); - } - else{ - $('input[name=method]').val('2'); - } - - dataEditingFunc(this.form,'correlation'); - }); - - $('#sectionbody3').find('input[name="lit_corr"]').click(function() { - dbValue = $('select[name=database2] option:selected').val(); - $('input[name=database]').val(dbValue); - criteriaValue = $('select[name=criteria2] option:selected').val(); - $('input[name=criteria]').val(criteriaValue); - MDPValue = $('select[name=MDPChoice2] option:selected').val(); - $('input[name=MDPChoice]').val(MDPValue); - - $('input[name=method]').val('3'); - - dataEditingFunc(this.form,'correlation'); - }); - - $('#sectionbody3').find('input[name="tiss_corr"]').click(function() { - dbValue = $('select[name=database3] option:selected').val(); - $('input[name=database]').val(dbValue); - criteriaValue = $('select[name=criteria3] option:selected').val(); - $('input[name=criteria]').val(criteriaValue); - MDPValue = $('select[name=MDPChoice3] option:selected').val(); - $('input[name=MDPChoice]').val(MDPValue); - - methodValue = $('input[name=tissue_method]:checked').val(); - - if (methodValue == "4"){ - $('input[name=method]').val('4'); - } - else{ - $('input[name=method]').val('5'); - } - dataEditingFunc(this.form,'correlation'); - }); - -/////////////////////////////// -//Mapping Tools -/////////////////////////////// - - $('#sectionbody4').find('input[name=interval]').click(function() { - chrValue = $('select[name=chromosomes1] option:selected').val(); - $('input[name=chromosomes]').val(chrValue); - scaleValue = $('select[name=scale1] option:selected').val(); - $('input[name=scale]').val(scaleValue); - $('input[name=controlLocus]').val(''); - - //Changed the way permValue, bootValue, and parentsValue are acquired; before it was $(____).is(':checked'); - permValue = $('input[name=permCheck1]:checked').val(); - $('input[name=permCheck]').val(permValue); - - bootValue = $('input[name=bootCheck1]:checked').val(); - $('input[name=bootCheck]').val(bootValue); - - if ($('input[name=parentsf14regression1]:checked').length > 0){ - $('input[name=parentsf14regression]').val('on'); - } else { - $('input[name=parentsf14regression]').val('off'); - } - - varValue = $('input[name=applyVarianceSE1]:checked').val(); - $('input[name=applyVarianceSE]').val(varValue); - - dataEditingFunc(this.form,'intervalMap'); - }); - - var tiptext = "e.g., rs12345"; - controlLocus = $('#sectionbody4').find('input[name=controlLocus]'); - - if(controlLocus.val() == '' || controlLocus == tiptext) { - controlLocus.addClass('searchtip').val(tiptext); - } - - controlLocus.focus(function(e) { - if(controlLocus.val() == tiptext) { - controlLocus.val(''); - } - controlLocus.removeClass('searchtip'); - }); - - controlLocus.blur(function(e) { - if(controlLocus.val() == '') { - controlLocus.addClass('searchtip').val(tiptext); - } else if(controlLocus.val() == tiptext) { - controlLocus.addClass('searchtip'); - } else { - controlLocus.removeClass('searchtip'); - } - }); - - $('#sectionbody4').find('input[name=composite]').click(function() { - chrValue = $('select[name=chromosomes2] option:selected').val(); - $('input[name=chromosomes]').val(chrValue); - scaleValue = $('select[name=scale2] option:selected').val(); - $('input[name=scale]').val(scaleValue); - controlValue = controlLocus.val(); - if (controlValue != tiptext){ - controlLocus.val(controlValue); - } - else{ - controlLocus.val(''); - } - - //Changed the way permValue, bootValue, and parentsValue are acquired; before it was $(____).is(':checked'); - permValue = $('input[name=permCheck2]:checked').val(); - $('input[name=permCheck]').val(permValue); - - bootValue = $('input[name=bootCheck2]:checked').val(); - $('input[name=bootCheck]').val(bootValue); - - if ($('input[name=parentsf14regression3]:checked').length > 0){ - $('input[name=parentsf14regression]').val('on'); - } else { - $('input[name=parentsf14regression]').val('off'); - } - - dataEditingFunc(this.form,'intervalMap'); - - }); - - $('#sectionbody4').find('input[name=marker]').click(function() { - //Changed the way parentsValue is acquired; before it was $(____).is(':checked'); - if ($('input[name=parentsf14regression2]:checked').length > 0){ - $('input[name=parentsf14regression]').val('on'); - } else { - $('input[name=parentsf14regression]').val('off'); - } - - varValue = $('input[name=applyVarianceSE2]:checked').val(); - $('input[name=applyVarianceSE]').val(varValue); - - dataEditingFunc(this.form,'markerRegression'); - }); - -/////////////////////////////// -//Review and Edit Data -/////////////////////////////// - - $('input[name=excludeGroup]').click(function(){ - for (i = 1;i <= Math.max(primary_row_count,other_row_count)-1; i++){ - valueExists = 0; - $('#Primary_'+i+',#Other_'+i).children().each(function(){ - if ($(this).text() == exclude_value) { - $('#Primary_'+i+',#Other_'+i).addClass('blocked').find('input[type=text]').val('x'); - valueExists = 1; - return false; - } - }); - } - }); - - $('.update').click(function(){ - windowName = 'formTarget' + (new Date().getTime()); - newWindow = open("",windowName,"menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=0,directories=1,width=900"); - document.dataInput.target = windowName; - document.dataInput.submitID.value = "basicStatistics"; - - primaryData = getTraitData()[0]; - otherData = getTraitData()[1]; - allData = getTraitData()[2]; - - if (otherData[0].length > 0) { - if ($('select[name="stats_mdp"] option:selected').val() == 0) { - document.dataInput.strainNames.value = allData[0].toString(); - document.dataInput.strainVals.value = allData[1].toString(); - document.dataInput.strainVars.value = allData[2].toString(); - } - else if ($('select[name="stats_mdp"] option:selected').val() == 1) { - document.dataInput.strainNames.value = primaryData[0].toString(); - document.dataInput.strainVals.value = primaryData[1].toString(); - document.dataInput.strainVars.value = primaryData[2].toString(); - } - else { - document.dataInput.strainNames.value = otherData[0].toString(); - document.dataInput.strainVals.value = otherData[1].toString(); - document.dataInput.strainVars.value = otherData[2].toString(); - } - } - else { - document.dataInput.strainNames.value = allData[0].toString(); - document.dataInput.strainVals.value = allData[1].toString(); - document.dataInput.strainVars.value = allData[2].toString(); - } - - document.dataInput.submit(); - }); - - $('input[name="export"]').click(function(){ - windowName = 'formTarget' + (new Date().getTime()); - newWindow = open("",windowName,"menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=0,directories=1,width=900"); - document.dataInput.target = windowName; - document.dataInput.submitID.value = "exportData"; - - primaryData = getTraitData()[0]; - otherData = getTraitData()[1]; - - document.dataInput.strainNames.value = primaryData[0].toString(); - document.dataInput.strainVals.value = primaryData[1].toString(); - document.dataInput.strainVars.value = primaryData[2].toString(); - - document.dataInput.otherStrainNames.value = otherData[0].toString(); - document.dataInput.otherStrainVals.value = otherData[1].toString(); - document.dataInput.otherStrainVars.value = otherData[2].toString(); - - attribute_names = new Array(); - $('#primary,#other').find('th.attribute_name').each(function(){ - attribute_names.push($(this).val().toString()); - }); - - primary_attribute_values = ""; //This string will be structured as a dictionary with a set of values for each attribute; it will be parsed in the ExportPage class - other_attribute_values = ""; - - attr_counter = 1; // Counter for each different attribute - row_counter = 1; // Counter for each value for each attribute - while (attr_counter <= attribute_names.length){ - attribute_name = $('#primary,#other').find('th.attribute_name:eq('+ (attr_counter-1).toString() + ')').text(); - primary_row_count = $('#primary').find('tr').length - 1; - other_row_count = $('#other').find('tr').length - 1; - - primary_attribute_values += attribute_name + " : "; - other_attribute_values += attribute_name + " : "; - - primary_value_string = ""; //This string of values (in the format 'a,b,c', etc) will be appended to the primary_attribute_values string - for (row_counter = 1;row_counter <= numPrimaryRows; row_counter++){ - value = $('#primary_attribute'+attr_counter.toString()+'_sample'+row_counter.toString()).text(); - if (row_counter == primary_row_count) { - primary_value_string += (value + " / "); - } - else{ - primary_value_string += (value + ","); - } - } - - primary_attribute_values += primary_value_string; - - other_value_string = ""; //This string of values (in the format 'a,b,c', etc) will be appended to the other_attribute_values string - for (row_counter = 1;row_counter <= numOtherRows; row_counter++){ - value = $('#other_attribute'+attr_counter.toString()+'_sample'+row_counter.toString()).text(); - if (row_counter == other_row_count) { - other_value_string += (value + " / "); - } - else{ - other_value_string += (value + ","); - } - } - other_attribute_values += other_value_string; - attr_counter += 1 - } - - document.dataInput.extra_attributes.value = primary_attribute_values; - document.dataInput.other_extra_attributes.value = other_attribute_values; - - document.dataInput.submit(); - }); - - var thisTable = $('#sortable1,#sortable2'); //ZS: variable representing each table, because it's used often - - thisTable.find('input[name="selectCheck"]').click(function(){ - if($(this).is(':checked')){ - $(this).parent("").parent("").children("td").css("background-color", "yellow"); - } - else{ - if(!($(this).parent().parent().hasClass('outlier'))){ - $(this).parent().parent().children("td").css("background-color", "white"); - } - } - }); - - $('input[name=resetButton]').click(function(){ - - //ZS: Reset "hide no value" and "hide outliers" - $('#showHideOptions').find('input[name=showHideNoValue]').val(' Hide No Value '); - $('#showHideOptions').find('input[name=showHideOutliers]').val(' Hide Outliers '); - noValShown = 1; - outliersShown = 1; - - for (i=1;i<=numPrimaryRows-1;i++){ - var thisRow = $('#Primary_'+i); - if (thisRow.is('.invisible')){ - thisRow.removeClass('invisible'); - } - if (thisRow.is('.blocked')){ - thisRow.removeClass('blocked'); - } - if (thisRow.is(':not(.outlier)')){ - thisRow.css("background-color", "white"); - } - - var thisValueField = thisRow.find('.valueField'); - - var originalValue = thisValueField[0].defaultValue; - var thisClassNames = thisRow.find('input:eq(1)').attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - thisRow.find('input:eq(1)').removeClass(valueClass).addClass(originalValue).val(originalValue); - - if (thisValueField.length > 1){ - var originalValue = thisValueField[1].defaultValue; - var thisClassNames = thisRow.find('input:eq(2)').attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - thisRow.find('input:eq(2)').removeClass(valueClass).addClass(originalValue).val(originalValue); - } - } - for (i=1;i<=numOtherRows-1;i++){ - var thisRow = $('#Other_'+i); - if (thisRow.is('.invisible')){ - thisRow.removeClass('invisible') - } - if (thisRow.is('.blocked')){ - thisRow.removeClass('blocked'); - } - if (thisRow.is(':not(.outlier)')){ - thisRow.css("background-color", "white"); - } - - var thisValueField = thisRow.find('.valueField'); - - var originalValue = thisValueField[0].defaultValue; - var thisClassNames = thisRow.find('input:eq(1)').attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - thisRow.find('input:eq(1)').removeClass(valueClass).addClass(originalValue).val(originalValue); - - if (thisValueField.length > 1){ - var originalValue = thisValueField[1].defaultValue; - var thisClassNames = thisRow.find('input:eq(2)').attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - thisRow.find('input:eq(2)').removeClass(valueClass).addClass(originalValue).val(originalValue); - } - } - }); - - var tiptext2 = "e.g., 4, 6-30, 43"; - var blockField = $('#showHideOptions').find('input[name=removeField]'); //ZS: Field where user inputs the index of the samples he/she wants to block; created variable because it's used often - - if(blockField.val() == '' || blockField.val() == tiptext2) { - blockField.addClass('searchtip'); - blockField.val(tiptext2); - } - - blockField.focus(function(e) { - if(blockField.val() == tiptext2) { - blockField.val(''); - } - blockField.removeClass('searchtip'); - }); - - blockField.blur(function(e) { - if(blockField.val() == '') { - blockField.addClass('searchtip'); - blockField.val(tiptext2); - } else if(blockField.val() == tiptext2) { - blockField.addClass('searchtip'); - } else { - blockField.removeClass('searchtip'); - } - }); - - var noValShown = new Boolean(1); - var outliersShown = new Boolean(1); - - $('#showHideOptions').bind('click', function(e){ - var target = e.target; - $target = $(target); - - if (target.name === 'blockSamples'){ - if (blockField.val() == tiptext2){ - blockField.val('') - } - blockedText = blockField.val(); - blockedTextSplit = new Array(); - blockedItems = new Array(); - - blockedTextSplit = blockedText.split(/\,/); - - for (i=0;i<=blockedTextSplit.length-1;i++) { - var item = blockedTextSplit[i]; - if(item.indexOf('-') != -1){ - subArray = new Array(); - subArray = item.split('-'); - num1 = parseInt(subArray[0]); - num2 = parseInt(subArray[1]); - for (j=num1;j<=num2;j=j+1){ - blockedItems.push(j); - } - } - else if(!(isNaN(item))) { - blockedItems.push(item); - } - } - - for (i=0;i<=blockedItems.length-1;i++) { - item = blockedItems[i]; - if ($('select[name=block_method]').val() == '0') { - var thisRow = $('#Other_'+item); - } - else { - var thisRow = $('#Primary_'+item); - } - - if (thisRow.is('.novalue')) { - continue; - } - else { - thisRow.addClass('blocked').find('input.valueField').val('x'); - } - - //First look at value cell - var thisCell = thisRow.find('input:eq(1)'); - var thisClassNames = thisCell.attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - var header = thisRow.parents('table.tablesorter').find('th.header:contains("Value"):eq(0)'); - if (header.hasClass('headerSortUp')){ - thisCell.removeClass(valueClass).addClass('-9999'); - } else if (header.hasClass('headerSortDown')){ - thisCell.removeClass(valueClass).addClass('9999'); - } else { - thisCell.removeClass(valueClass).addClass('-9999'); - } - - //Check if there is an SE column - if (thisRow.find('input.valueField').length > 1) { - var thisCell = thisRow.find('input:eq(2)'); - var thisClassNames = thisCell.attr('class').split(/\s+/); - var valueClass = thisClassNames[thisClassNames.length-1]; - var header = thisRow.parents('table.tablesorter').find('th.header:contains("SE"):eq(0)'); - if (header.hasClass('headerSortUp')){ - thisCell.removeClass(valueClass).addClass('-9999'); - } else if (header.hasClass('headerSortDown')){ - thisCell.removeClass(valueClass).addClass('9999'); - } else { - thisCell.removeClass(valueClass).addClass('-9999'); - } - } - } - } - - else if (target.name === 'showHideNoValue'){ - if (noValShown) { - $('#showHideOptions').find('input[name=showHideNoValue]').val(' Show No Value '); - for (i=1;i<=Math.max(numPrimaryRows,numOtherRows)-1;i++) { - if (i<=numPrimaryRows-1) { - var thisRow = $('#Primary_'+i); - if (thisRow.is('.novalue:visible') || thisRow.is('.blocked:visible')){ - jQuery(thisRow).addClass('invisible'); - } - } - if (i<=numOtherRows-1){ - var thisOtherRow = $('#Other_'+i); - if (thisOtherRow.is('.novalue:visible') || thisOtherRow.is('.blocked:visible')){ - if (thisOtherRow.is(':visible')){ - jQuery(thisOtherRow).addClass('invisible'); - } - } - } - } - noValShown = 0; - } - else { - $('#showHideOptions').find('input[name=showHideNoValue]').val(' Hide No Value '); - for (i=1;i<=Math.max(numPrimaryRows,numOtherRows)-1;i++) { - if (i<=numPrimaryRows-1) { - var thisRow = $('#Primary_'+i); - if (thisRow.is('.novalue') || thisRow.is('.blocked')){ - jQuery(thisRow).removeClass('invisible'); - if (!(outliersShown)) { - if (thisRow.is('.outlier:visible')){ - jQuery(thisRow).addClass('invisible'); - } - } - } - } - if (i<=numOtherRows-1){ - var thisOtherRow = $('#Other_'+i); - if (thisOtherRow.is('.novalue') || thisOtherRow.is('.blocked')){ - jQuery(thisOtherRow).removeClass('invisible'); - if (!(outliersShown)) { - if (thisOtherRow.is('.outlier:visible')){ - jQuery(thisOtherRow).addClass('invisible'); - } - } - } - } - } - noValShown = 1; - } - } - - else if (target.name === 'showHideOutliers'){ - if (outliersShown){ - $('#showHideOptions').find('input[name=showHideOutliers]').val(' Show Outliers '); - for (i=1;i<=Math.max(numPrimaryRows,numOtherRows)-1;i++) { - if (i<=numPrimaryRows-1) { - thisRow = $('#Primary_'+i); - if (thisRow.is('.outlier:visible') && (!(thisRow.is('.invisible')))) { - thisRow.addClass('invisible') - } - } - if (i<=numOtherRows-1) { - thisOtherRow = $('#Other_'+i); - if (thisOtherRow.is('.outlier:visible') && (!(thisOtherRow.is('.invisible')))) { - thisOtherRow.addClass('invisible') - } - } - } - outliersShown = 0; - } - else { - $('#showHideOptions').find('input[name=showHideOutliers]').val(' Hide Outliers '); - for (i=1;i<=Math.max(numPrimaryRows,numOtherRows)-1;i++) { - if (i<=numPrimaryRows-1) { - thisRow = $('#Primary_'+i); - if (thisRow.is('.outlier') && (!(thisRow.is(':visible')))) { - if (!(noValShown)) { - if (thisRow.is('.blocked')){ - continue; - } - } - jQuery(thisRow).removeClass('invisible') - } - } - if (i<=numOtherRows-1) { - thisOtherRow = $('#Other_'+i); - if (thisOtherRow.is('.outlier') && (!(thisOtherRow.is(':visible')))) { - if (!(noValShown)) { - if (thisOtherRow.is('.blocked')){ - continue; - } - } - jQuery(thisOtherRow).removeClass('invisible') - } - } - } - outliersShown = 1; - } - } - return false; - }); -}); - -function getTraitData(){ - primary_row_count = $('#sortable1').find('tr').length - 1; - other_row_count = $('#sortable2').find('tr').length - 1; - - primaryStrainNames = new Array(); - primaryVals = new Array(); - primaryVars = new Array(); - - allStrainNames = new Array(); - allVals = new Array(); - allVars = new Array(); - - for (i = 1;i <= primary_row_count; i++){ - thisRow = $('#Primary_'+i); - strainName = thisRow.find('span:first').text(); - primaryStrainNames.push(strainName); - allStrainNames.push(strainName); - strainVal = thisRow.find('input:eq(1)').val(); - primaryVals.push(strainVal); - allVals.push(strainVal); - strainVar = ''; // Just to initialize it in case there is no var - strainVar = thisRow.find('input:eq(2)').val(); - primaryVars.push(strainVar); - allVars.push(strainVar); - } - - otherStrainNames = new Array(); - otherVals = new Array(); - otherVars = new Array(); - - for (j = 1;j <= other_row_count; j++){ - thisRow = $('#Other_'+j) - strainName = thisRow.find('span:first').text(); - otherStrainNames.push(strainName); - strainVal = thisRow.find('input:eq(1)').val(); - otherVals.push(strainVal); - strainVar = ''; // Just to initialize it in case there is no var - strainVar = thisRow.find('input:eq(2)').val(); - otherVars.push(strainVar); - - if (jQuery.inArray(strainName, allStrainNames) == -1) { - allStrainNames.push(strainName); - allVals.push(strainVal); - allVars.push(strainVar); - } - } - - primaryData = [primaryStrainNames, primaryVals, primaryVars]; - otherData = [otherStrainNames, otherVals, otherVars]; - allData = [allStrainNames, allVals, allVars]; - - return [primaryData, otherData, allData]; -} + var thisTable = $('#sortable1,#sortable2'); + thisTable.bind("update propertychange keyup input paste", function (e) { -/* -used by networkGraphPageBody.py -*/ + var target = e.target; + $target = $(target); -//Default to plain text + symbol for the "Export Graph File" button -$('input[name=exportGraphFile]').live('click', function() { window.open($('input[name=exportFilename]').val() + "_plain_symbol.txt") }); + if (target.nodeName.toLowerCase() == 'input') { + thisClassNames = $target.attr('class').split(/\s+/); + valueClass = thisClassNames[thisClassNames.length - 1]; + newValue = $target.val(); + thisParent = $target.parent('td'); + thisParentId = thisParent.attr('id'); + + $target.removeClass(valueClass); + + if (newValue == 'x') { + thisParent.parent('tr').addClass('blocked'); + } else { + $('#' + thisParentId).children('input.valueField:eq(0)').addClass(newValue); + } + } + }); + + //////////////////////////////////// + // Initially close tabs + //////////////////////////////////// + thisForm = $('form[name="dataInput"]'); + + $('#sectionbody2').hide(); + $('#sectionbody3').hide(); + $('#sectionbody4').hide(); + + $('#title1').click(function () { + $('#sectionbody1').toggle(); + return false; + }); + $('#title2').click(function () { + $('#sectionbody2').toggle(); + return false; + }); + $('#title3').click(function () { + $('#sectionbody3').toggle(); + return false; + }); + $('#title4').click(function () { + $('#sectionbody4').toggle(); + return false; + }); + $('#title5').click(function () { + $('#sectionbody5').toggle(); + return false; + }); -function changeFormat(graphName){ - var graphFormat = $('#exportFormat').val(); - var traitType = $('#traitType').val(); - $('input[name=exportGraphFile]').die('click'); - if (graphFormat=="xgmml"){ - if (traitType=="symbol"){ - var graphFile = graphName+ "_xgmml_symbol.txt"; - $('input[name=exportGraphFile]').live('click', function() { window.open(graphFile) }); + ////////////////////////////////////////////////////////////// + // Switch out + and - icon when you click each section header + ////////////////////////////////////////////////////////////// + var expand_html = "  \"Expand\""; + var contract_html = "  \"Contract\""; + + $('#title2, #title3, #title4').prepend(expand_html).addClass('1'); + + $('#title1, #title5').prepend(contract_html).addClass('0'); + + for (i = 1; i <= 5; i++) { + $('#title' + i).click(function () { + if ($(this).hasClass('0')) { + $(this).find('span').replaceWith(expand_html); + $(this).removeClass('0'); + $(this).addClass('1'); + } else { + $(this).find('span').replaceWith(contract_html); + $(this).removeClass('1'); + $(this).addClass('0'); + } + }); + } + + // Exclude cases by attributes + $('div.attribute_values:first').css('display', 'inline'); //Display the dropdown menu with the first attribute's distinct values + $('select[name=exclude_menu]').change(function () { + $('div.attribute_values').css('display', 'none'); //clear all other menus when a new attribute is selected + attribute = $(this).val(); + //attribute = $('select[name=exclude_menu]').val(); + menu = $('div.attribute_values').find('[name=\'' + attribute + '\']'); + menu.parent().css('display', 'inline'); + }); + + primary_row_count = $('#primary').find('tr').length - 1; + other_row_count = $('#other').find('tr').length - 1; + + if (primary_row_count >= other_row_count) { + row_count = primary_row_count; + } else { + row_count = other_row_count; + } + + $('div.attribute_values').children('select').change(function () { + exclude_value = $(this).val(); + }); +}); + +$(window).load(function () { + + //ZS: These are needed in a few places; looping through rows by index is faster than doing a "find" search + numPrimaryRows = $('#sortable1').find('tr').length; + numOtherRows = $('#sortable2').find('tr').length; + + + /////////////////////////////// + //Basic Statistics + /////////////////////////////// + ///////////////////////////////////////////////////////////////// + // Hide unselected Basic Statistics tabs (when just BXD strains + // are selected, hide the results for all strains/non-BXD) + ///////////////////////////////////////////////////////////////// + $('#stats_tabs1').hide(); + $('#stats_tabs2').hide(); + + $('#sectionbody2').find('select[name=stats_mdp]').change(function () { + selected = $('#sectionbody2').find('select[name=stats_mdp] option:selected').val(); + for (i = 0; i <= 2; i++) { + $('#stats_tabs' + i).hide(); + } + $('#stats_tabs' + selected).show(); + }); + + //////////////////////////////////////////////////////////////////////// + // Select the same tab across each sample group (when a Box Plot is + // selected for BXD, switching to Non-BXD will also display a Box Plot) + ////////////./////////////////////////////////////////////////////////// + var $tabs1 = $('#stats_tabs0').tabs(); + var $tabs2 = $('#stats_tabs1').tabs(); + var $tabs3 = $('#stats_tabs2').tabs(); + + $tabs1.tabs({ + show: function (event, ui) { + var selected = $tabs1.tabs('option', 'selected'); + $tabs2.tabs('select', selected); + $tabs3.tabs('select', selected); + } + }); + $tabs2.tabs({ + show: function (event, ui) { + var selected = $tabs2.tabs('option', 'selected'); + $tabs1.tabs('select', selected); + $tabs3.tabs('select', selected); + } + }); + $tabs3.tabs({ + show: function (event, ui) { + var selected = $tabs3.tabs('option', 'selected'); + $tabs1.tabs('select', selected); + $tabs2.tabs('select', selected); + } + }); + + + /////////////////////////////// + //Calculate Correlations + /////////////////////////////// + $('#sectionbody3').find('input[name="sample_corr"]').click(function () { + dbValue = $('select[name=database1] option:selected').val(); + $('input[name=database]').val(dbValue); + criteriaValue = $('select[name=criteria1] option:selected').val(); + $('input[name=criteria]').val(criteriaValue); + MDPValue = $('select[name=MDPChoice1] option:selected').val(); + $('input[name=MDPChoice]').val(MDPValue); + + methodValue = $('input[name=sample_method]:checked').val(); + + //This simple method can be used now that 'method' is defaulted to None instead of '' + if (methodValue == "1") { + $('input[name=method]').val('1'); + } else { + $('input[name=method]').val('2'); + } + + dataEditingFunc(this.form, 'correlation'); + }); + + $('#sectionbody3').find('input[name="lit_corr"]').click(function () { + dbValue = $('select[name=database2] option:selected').val(); + $('input[name=database]').val(dbValue); + criteriaValue = $('select[name=criteria2] option:selected').val(); + $('input[name=criteria]').val(criteriaValue); + MDPValue = $('select[name=MDPChoice2] option:selected').val(); + $('input[name=MDPChoice]').val(MDPValue); + + $('input[name=method]').val('3'); + + dataEditingFunc(this.form, 'correlation'); + }); + + $('#sectionbody3').find('input[name="tiss_corr"]').click(function () { + dbValue = $('select[name=database3] option:selected').val(); + $('input[name=database]').val(dbValue); + criteriaValue = $('select[name=criteria3] option:selected').val(); + $('input[name=criteria]').val(criteriaValue); + MDPValue = $('select[name=MDPChoice3] option:selected').val(); + $('input[name=MDPChoice]').val(MDPValue); + + methodValue = $('input[name=tissue_method]:checked').val(); + + if (methodValue == "4") { + $('input[name=method]').val('4'); + } else { + $('input[name=method]').val('5'); + } + dataEditingFunc(this.form, 'correlation'); + }); + + /////////////////////////////// + //Mapping Tools + /////////////////////////////// + $('#sectionbody4').find('input[name=interval]').click(function () { + chrValue = $('select[name=chromosomes1] option:selected').val(); + $('input[name=chromosomes]').val(chrValue); + scaleValue = $('select[name=scale1] option:selected').val(); + $('input[name=scale]').val(scaleValue); + $('input[name=controlLocus]').val(''); + + //Changed the way permValue, bootValue, and parentsValue are acquired; before it was $(____).is(':checked'); + permValue = $('input[name=permCheck1]:checked').val(); + $('input[name=permCheck]').val(permValue); + + bootValue = $('input[name=bootCheck1]:checked').val(); + $('input[name=bootCheck]').val(bootValue); + + if ($('input[name=parentsf14regression1]:checked').length > 0) { + $('input[name=parentsf14regression]').val('on'); + } else { + $('input[name=parentsf14regression]').val('off'); + } + + varValue = $('input[name=applyVarianceSE1]:checked').val(); + $('input[name=applyVarianceSE]').val(varValue); + + dataEditingFunc(this.form, 'intervalMap'); + }); + + var tiptext = "e.g., rs12345"; + controlLocus = $('#sectionbody4').find('input[name=controlLocus]'); + + if (controlLocus.val() == '' || controlLocus == tiptext) { + controlLocus.addClass('searchtip').val(tiptext); + } + + controlLocus.focus(function (e) { + if (controlLocus.val() == tiptext) { + controlLocus.val(''); + } + controlLocus.removeClass('searchtip'); + }); + + controlLocus.blur(function (e) { + if (controlLocus.val() == '') { + controlLocus.addClass('searchtip').val(tiptext); + } else if (controlLocus.val() == tiptext) { + controlLocus.addClass('searchtip'); + } else { + controlLocus.removeClass('searchtip'); + } + }); + + $('#sectionbody4').find('input[name=composite]').click(function () { + chrValue = $('select[name=chromosomes2] option:selected').val(); + $('input[name=chromosomes]').val(chrValue); + scaleValue = $('select[name=scale2] option:selected').val(); + $('input[name=scale]').val(scaleValue); + controlValue = controlLocus.val(); + if (controlValue != tiptext) { + controlLocus.val(controlValue); + } else { + controlLocus.val(''); + } + + //Changed the way permValue, bootValue, and parentsValue are acquired; before it was $(____).is(':checked'); + permValue = $('input[name=permCheck2]:checked').val(); + $('input[name=permCheck]').val(permValue); + + bootValue = $('input[name=bootCheck2]:checked').val(); + $('input[name=bootCheck]').val(bootValue); + + if ($('input[name=parentsf14regression3]:checked').length > 0) { + $('input[name=parentsf14regression]').val('on'); + } else { + $('input[name=parentsf14regression]').val('off'); + } + + dataEditingFunc(this.form, 'intervalMap'); + + }); + + $('#sectionbody4').find('input[name=marker]').click(function () { + //Changed the way parentsValue is acquired; before it was $(____).is(':checked'); + if ($('input[name=parentsf14regression2]:checked').length > 0) { + $('input[name=parentsf14regression]').val('on'); + } else { + $('input[name=parentsf14regression]').val('off'); + } + + varValue = $('input[name=applyVarianceSE2]:checked').val(); + $('input[name=applyVarianceSE]').val(varValue); + + dataEditingFunc(this.form, 'markerRegression'); + }); + + /////////////////////////////// + //Review and Edit Data + /////////////////////////////// + $('input[name=excludeGroup]').click(function () { + for (i = 1; i <= Math.max(primary_row_count, other_row_count) - 1; i++) { + valueExists = 0; + $('#Primary_' + i + ',#Other_' + i).children().each(function () { + if ($(this).text() == exclude_value) { + $('#Primary_' + i + ',#Other_' + i).addClass('blocked').find('input[type=text]').val('x'); + valueExists = 1; + return false; } - else if (traitType=="name"){ - var graphFile = graphName+ "_xgmml_name.txt"; - $('input[name=exportGraphFile]').live('click', function() { window.open(graphFile) }); + }); + } + }); + + $('.update').click(function () { + windowName = 'formTarget' + (new Date().getTime()); + var windowHeight; // windowHeight and windowWidth are used to place the window in the center of the screen + var windowWidth; + windowHeight = (window.screen.height/2) - (350 + 10) + windowWidth = (window.screen.width/2) - (450 + 50) + newWindow = open("",windowName,"menubar=1,toolbar=1,resizable=1,left=" + windowWidth + ",top=" + windowHeight + ",screenX=" + windowWidth + ",screenY=" + windowHeight + ",status=1,scrollbars=0,directories=1"); + + document.dataInput.target = windowName; + document.dataInput.submitID.value = "basicStatistics"; + + primaryData = getTraitData()[0]; + otherData = getTraitData()[1]; + allData = getTraitData()[2]; + + if (otherData[0].length > 0) { + if ($('select[name="stats_mdp"] option:selected').val() == 0) { + document.dataInput.strainNames.value = allData[0].toString(); + document.dataInput.strainVals.value = allData[1].toString(); + document.dataInput.strainVars.value = allData[2].toString(); + } else if ($('select[name="stats_mdp"] option:selected').val() == 1) { + document.dataInput.strainNames.value = primaryData[0].toString(); + document.dataInput.strainVals.value = primaryData[1].toString(); + document.dataInput.strainVars.value = primaryData[2].toString(); + } else { + document.dataInput.strainNames.value = otherData[0].toString(); + document.dataInput.strainVals.value = otherData[1].toString(); + document.dataInput.strainVars.value = otherData[2].toString(); + } + } else { + document.dataInput.strainNames.value = allData[0].toString(); + document.dataInput.strainVals.value = allData[1].toString(); + document.dataInput.strainVars.value = allData[2].toString(); + } + + document.dataInput.submit(); + }); + + $('input[name="export"]').click(function () { + windowName = 'formTarget' + (new Date().getTime()); + newWindow = open("", windowName, "menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=0,directories=1,width=900"); + document.dataInput.target = windowName; + document.dataInput.submitID.value = "exportData"; + + primaryData = getTraitData()[0]; + otherData = getTraitData()[1]; + + document.dataInput.strainNames.value = primaryData[0].toString(); + document.dataInput.strainVals.value = primaryData[1].toString(); + document.dataInput.strainVars.value = primaryData[2].toString(); + + document.dataInput.otherStrainNames.value = otherData[0].toString(); + document.dataInput.otherStrainVals.value = otherData[1].toString(); + document.dataInput.otherStrainVars.value = otherData[2].toString(); + + attribute_names = new Array(); + $('#primary,#other').find('th.attribute_name').each(function () { + attribute_names.push($(this).val().toString()); + }); + + primary_attribute_values = ""; //This string will be structured as a dictionary with a set of values for each attribute; it will be parsed in the ExportPage class + other_attribute_values = ""; + + attr_counter = 1; // Counter for each different attribute + row_counter = 1; // Counter for each value for each attribute + while (attr_counter <= attribute_names.length) { + attribute_name = $('#primary,#other').find('th.attribute_name:eq(' + (attr_counter - 1).toString() + ')').text(); + primary_row_count = $('#primary').find('tr').length - 1; + other_row_count = $('#other').find('tr').length - 1; + + primary_attribute_values += attribute_name + " : "; + other_attribute_values += attribute_name + " : "; + + primary_value_string = ""; //This string of values (in the format 'a,b,c', etc) will be appended to the primary_attribute_values string + for (row_counter = 1; row_counter <= numPrimaryRows; row_counter++) { + value = $('#primary_attribute' + attr_counter.toString() + '_sample' + row_counter.toString()).text(); + if (row_counter == primary_row_count) { + primary_value_string += (value + " / "); + } else { + primary_value_string += (value + ","); } + } + + primary_attribute_values += primary_value_string; + + other_value_string = ""; //This string of values (in the format 'a,b,c', etc) will be appended to the other_attribute_values string + for (row_counter = 1; row_counter <= numOtherRows; row_counter++) { + value = $('#other_attribute' + attr_counter.toString() + '_sample' + row_counter.toString()).text(); + if (row_counter == other_row_count) { + other_value_string += (value + " / "); + } else { + other_value_string += (value + ","); + } + } + other_attribute_values += other_value_string; + attr_counter += 1 + } + + document.dataInput.extra_attributes.value = primary_attribute_values; + document.dataInput.other_extra_attributes.value = other_attribute_values; + + document.dataInput.submit(); + }); + + var thisTable = $('#sortable1,#sortable2'); //ZS: variable representing each table, because it's used often + thisTable.find('input[name="selectCheck"]').click(function () { + if ($(this).is(':checked')) { + $(this).parent("").parent("").children("td").css("background-color", "yellow"); + } else { + if (!($(this).parent().parent().hasClass('outlier'))) { + $(this).parent().parent().children("td").css("background-color", "white"); + } } + }); - else if (graphFormat=="plain"){ - if (traitType=="symbol"){ - var graphFile = graphName+ "_plain_symbol.txt"; - $('input[name=exportGraphFile]').live('click', function() { window.open(graphFile) }); + $('input[name=resetButton]').click(function () { + + //ZS: Reset "hide no value" and "hide outliers" + $('#showHideOptions').find('input[name=showHideNoValue]').val(' Hide No Value '); + $('#showHideOptions').find('input[name=showHideOutliers]').val(' Hide Outliers '); + noValShown = 1; + outliersShown = 1; + + for (i = 1; i <= numPrimaryRows - 1; i++) { + var thisRow = $('#Primary_' + i); + if (thisRow.is('.invisible')) { + thisRow.removeClass('invisible'); + } + if (thisRow.is('.blocked')) { + thisRow.removeClass('blocked'); + } + if (thisRow.is(':not(.outlier)')) { + thisRow.css("background-color", "white"); + } + + var thisValueField = thisRow.find('.valueField'); + + var originalValue = thisValueField[0].defaultValue; + var thisClassNames = thisRow.find('input:eq(1)').attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + thisRow.find('input:eq(1)').removeClass(valueClass).addClass(originalValue).val(originalValue); + + if (thisValueField.length > 1) { + var originalValue = thisValueField[1].defaultValue; + var thisClassNames = thisRow.find('input:eq(2)').attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + thisRow.find('input:eq(2)').removeClass(valueClass).addClass(originalValue).val(originalValue); + } + } + for (i = 1; i <= numOtherRows - 1; i++) { + var thisRow = $('#Other_' + i); + if (thisRow.is('.invisible')) { + thisRow.removeClass('invisible') + } + if (thisRow.is('.blocked')) { + thisRow.removeClass('blocked'); + } + if (thisRow.is(':not(.outlier)')) { + thisRow.css("background-color", "white"); + } + + var thisValueField = thisRow.find('.valueField'); + + var originalValue = thisValueField[0].defaultValue; + var thisClassNames = thisRow.find('input:eq(1)').attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + thisRow.find('input:eq(1)').removeClass(valueClass).addClass(originalValue).val(originalValue); + + if (thisValueField.length > 1) { + var originalValue = thisValueField[1].defaultValue; + var thisClassNames = thisRow.find('input:eq(2)').attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + thisRow.find('input:eq(2)').removeClass(valueClass).addClass(originalValue).val(originalValue); + } + } + }); + + var tiptext2 = "e.g., 4, 6-30, 43"; + var blockField = $('#showHideOptions').find('input[name=removeField]'); //ZS: Field where user inputs the index of the samples he/she wants to block; created variable because it's used often + if (blockField.val() == '' || blockField.val() == tiptext2) { + blockField.addClass('searchtip'); + blockField.val(tiptext2); + } + + blockField.focus(function (e) { + if (blockField.val() == tiptext2) { + blockField.val(''); + } + blockField.removeClass('searchtip'); + }); + + blockField.blur(function (e) { + if (blockField.val() == '') { + blockField.addClass('searchtip'); + blockField.val(tiptext2); + } else if (blockField.val() == tiptext2) { + blockField.addClass('searchtip'); + } else { + blockField.removeClass('searchtip'); + } + }); + + var noValShown = new Boolean(1); + var outliersShown = new Boolean(1); + + $('#showHideOptions').bind('click', function (e) { + var target = e.target; + $target = $(target); + + if (target.name === 'blockSamples') { + if (blockField.val() == tiptext2) { + blockField.val('') + } + blockedText = blockField.val(); + blockedTextSplit = new Array(); + blockedItems = new Array(); + + blockedTextSplit = blockedText.split(/\,/); + + for (i = 0; i <= blockedTextSplit.length - 1; i++) { + var item = blockedTextSplit[i]; + if (item.indexOf('-') != -1) { + subArray = new Array(); + subArray = item.split('-'); + num1 = parseInt(subArray[0]); + num2 = parseInt(subArray[1]); + for (j = num1; j <= num2; j = j + 1) { + blockedItems.push(j); + } + } else if (!(isNaN(item))) { + blockedItems.push(item); + } + } + + for (i = 0; i <= blockedItems.length - 1; i++) { + item = blockedItems[i]; + if ($('select[name=block_method]').val() == '0') { + var thisRow = $('#Other_' + item); + } else { + var thisRow = $('#Primary_' + item); + } + + if (thisRow.is('.novalue')) { + continue; + } else { + thisRow.addClass('blocked').find('input.valueField').val('x'); + } + + //First look at value cell + var thisCell = thisRow.find('input:eq(1)'); + var thisClassNames = thisCell.attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + var header = thisRow.parents('table.tablesorter').find('th.header:contains("Value"):eq(0)'); + if (header.hasClass('headerSortUp')) { + thisCell.removeClass(valueClass).addClass('-9999'); + } else if (header.hasClass('headerSortDown')) { + thisCell.removeClass(valueClass).addClass('9999'); + } else { + thisCell.removeClass(valueClass).addClass('-9999'); + } + + //Check if there is an SE column + if (thisRow.find('input.valueField').length > 1) { + var thisCell = thisRow.find('input:eq(2)'); + var thisClassNames = thisCell.attr('class').split(/\s+/); + var valueClass = thisClassNames[thisClassNames.length - 1]; + var header = thisRow.parents('table.tablesorter').find('th.header:contains("SE"):eq(0)'); + if (header.hasClass('headerSortUp')) { + thisCell.removeClass(valueClass).addClass('-9999'); + } else if (header.hasClass('headerSortDown')) { + thisCell.removeClass(valueClass).addClass('9999'); + } else { + thisCell.removeClass(valueClass).addClass('-9999'); + } + } + } + } else if (target.name === 'showHideNoValue') { + if (noValShown) { + $('#showHideOptions').find('input[name=showHideNoValue]').val(' Show No Value '); + for (i = 1; i <= Math.max(numPrimaryRows, numOtherRows) - 1; i++) { + if (i <= numPrimaryRows - 1) { + var thisRow = $('#Primary_' + i); + if (thisRow.is('.novalue:visible') || thisRow.is('.blocked:visible')) { + jQuery(thisRow).addClass('invisible'); + } + } + if (i <= numOtherRows - 1) { + var thisOtherRow = $('#Other_' + i); + if (thisOtherRow.is('.novalue:visible') || thisOtherRow.is('.blocked:visible')) { + if (thisOtherRow.is(':visible')) { + jQuery(thisOtherRow).addClass('invisible'); + } + } + } + } + noValShown = 0; + } else { + $('#showHideOptions').find('input[name=showHideNoValue]').val(' Hide No Value '); + for (i = 1; i <= Math.max(numPrimaryRows, numOtherRows) - 1; i++) { + if (i <= numPrimaryRows - 1) { + var thisRow = $('#Primary_' + i); + if (thisRow.is('.novalue') || thisRow.is('.blocked')) { + jQuery(thisRow).removeClass('invisible'); + if (!(outliersShown)) { + if (thisRow.is('.outlier:visible')) { + jQuery(thisRow).addClass('invisible'); + } + } + } + } + if (i <= numOtherRows - 1) { + var thisOtherRow = $('#Other_' + i); + if (thisOtherRow.is('.novalue') || thisOtherRow.is('.blocked')) { + jQuery(thisOtherRow).removeClass('invisible'); + if (!(outliersShown)) { + if (thisOtherRow.is('.outlier:visible')) { + jQuery(thisOtherRow).addClass('invisible'); + } + } + } + } } - else if (traitType=="name"){ - var graphFile = graphName+ "_plain_name.txt"; - $('input[name=exportGraphFile]').live('click', function() { window.open(graphFile) }); + noValShown = 1; + } + } else if (target.name === 'showHideOutliers') { + if (outliersShown) { + $('#showHideOptions').find('input[name=showHideOutliers]').val(' Show Outliers '); + for (i = 1; i <= Math.max(numPrimaryRows, numOtherRows) - 1; i++) { + if (i <= numPrimaryRows - 1) { + thisRow = $('#Primary_' + i); + if (thisRow.is('.outlier:visible') && (!(thisRow.is('.invisible')))) { + thisRow.addClass('invisible') + } + } + if (i <= numOtherRows - 1) { + thisOtherRow = $('#Other_' + i); + if (thisOtherRow.is('.outlier:visible') && (!(thisOtherRow.is('.invisible')))) { + thisOtherRow.addClass('invisible') + } + } + } + outliersShown = 0; + } else { + $('#showHideOptions').find('input[name=showHideOutliers]').val(' Hide Outliers '); + for (i = 1; i <= Math.max(numPrimaryRows, numOtherRows) - 1; i++) { + if (i <= numPrimaryRows - 1) { + thisRow = $('#Primary_' + i); + if (thisRow.is('.outlier') && (!(thisRow.is(':visible')))) { + if (!(noValShown)) { + if (thisRow.is('.blocked')) { + continue; + } + } + jQuery(thisRow).removeClass('invisible') + } + } + if (i <= numOtherRows - 1) { + thisOtherRow = $('#Other_' + i); + if (thisOtherRow.is('.outlier') && (!(thisOtherRow.is(':visible')))) { + if (!(noValShown)) { + if (thisOtherRow.is('.blocked')) { + continue; + } + } + jQuery(thisOtherRow).removeClass('invisible') + } + } } + outliersShown = 1; + } + } + return false; + }); +}); + +function getTraitData() { + primary_row_count = $('#sortable1').find('tr').length - 1; + other_row_count = $('#sortable2').find('tr').length - 1; + + primaryStrainNames = new Array(); + primaryVals = new Array(); + primaryVars = new Array(); + + allStrainNames = new Array(); + allVals = new Array(); + allVars = new Array(); + + for (i = 1; i <= primary_row_count; i++) { + thisRow = $('#Primary_' + i); + strainName = thisRow.find('span:first').text(); + primaryStrainNames.push(strainName); + allStrainNames.push(strainName); + strainVal = thisRow.find('input:eq(1)').val(); + primaryVals.push(strainVal); + allVals.push(strainVal); + strainVar = ''; // Just to initialize it in case there is no var + strainVar = thisRow.find('input:eq(2)').val(); + primaryVars.push(strainVar); + allVars.push(strainVar); + } + + otherStrainNames = new Array(); + otherVals = new Array(); + otherVars = new Array(); + + for (j = 1; j <= other_row_count; j++) { + thisRow = $('#Other_' + j) + strainName = thisRow.find('span:first').text(); + otherStrainNames.push(strainName); + strainVal = thisRow.find('input:eq(1)').val(); + otherVals.push(strainVal); + strainVar = ''; // Just to initialize it in case there is no var + strainVar = thisRow.find('input:eq(2)').val(); + otherVars.push(strainVar); + + if (jQuery.inArray(strainName, allStrainNames) == -1) { + allStrainNames.push(strainName); + allVals.push(strainVal); + allVars.push(strainVar); } + } + + primaryData = [primaryStrainNames, primaryVals, primaryVars]; + otherData = [otherStrainNames, otherVals, otherVars]; + allData = [allStrainNames, allVals, allVars]; + + return [primaryData, otherData, allData]; } +/* +used by networkGraphPageBody.py +*/ + +//Default to plain text + symbol for the "Export Graph File" button +$('input[name=exportGraphFile]').live('click', function () { + window.open($('input[name=exportFilename]').val() + "_plain_symbol.txt") +}); + +function changeFormat(graphName) { + var graphFormat = $('#exportFormat').val(); + var traitType = $('#traitType').val(); + + $('input[name=exportGraphFile]').die('click'); + + if (graphFormat == "xgmml") { + if (traitType == "symbol") { + var graphFile = graphName + "_xgmml_symbol.txt"; + $('input[name=exportGraphFile]').live('click', function () { + window.open(graphFile) + }); + } else if (traitType == "name") { + var graphFile = graphName + "_xgmml_name.txt"; + $('input[name=exportGraphFile]').live('click', function () { + window.open(graphFile) + }); + } + } else if (graphFormat == "plain") { + if (traitType == "symbol") { + var graphFile = graphName + "_plain_symbol.txt"; + $('input[name=exportGraphFile]').live('click', function () { + window.open(graphFile) + }); + } else if (traitType == "name") { + var graphFile = graphName + "_plain_name.txt"; + $('input[name=exportGraphFile]').live('click', function () { + window.open(graphFile) + }); + } + } +} \ No newline at end of file diff --git a/web/webqtl/correlation/CorrelationPage.py b/web/webqtl/correlation/CorrelationPage.py index 8ce669cb..1fd16021 100755 --- a/web/webqtl/correlation/CorrelationPage.py +++ b/web/webqtl/correlation/CorrelationPage.py @@ -23,6 +23,9 @@ # Created by GeneNetwork Core Team 2010/08/10 # # Last updated by NL 2011/02/11 +# Last updated by Christian Fernandez 2012/04/07 +# Refactored correlation calculation into smaller functions in preparation of +# separating html from existing code import string from math import * @@ -47,447 +50,324 @@ from dbFunction import webqtlDatabaseFunction import utility.webqtlUtil #this is for parallel computing only. from correlation import correlationFunction +import logging +logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) +_log = logging.getLogger("correlation") -class CorrelationPage(templatePage): +METHOD_SAMPLE_PEARSON = "1" +METHOD_SAMPLE_RANK = "2" +METHOD_LIT = "3" +METHOD_TISSUE_PEARSON = "4" +METHOD_TISSUE_RANK = "5" - corrMinInformative = 4 +TISSUE_METHODS = [METHOD_TISSUE_PEARSON, METHOD_TISSUE_RANK] - def __init__(self, fd): +TISSUE_MOUSE_DB = 1 - #XZ, 01/14/2009: This method is for parallel computing only. - #XZ: It is supposed to be called when "Genetic Correlation, Pearson's r" (method 1) - #XZ: or "Genetic Correlation, Spearman's rho" (method 2) is selected - def compute_corr( input_nnCorr, input_trait, input_list, computing_method): +class AuthException(Exception): pass - allcorrelations = [] - for line in input_list: - tokens = line.split('","') - tokens[-1] = tokens[-1][:-2] #remove the last " - tokens[0] = tokens[0][1:] #remove the first " +class Trait(object): + def __init__(self, name, raw_values = None, lit_corr = None, tissue_corr = None, p_tissue = None): + self.name = name + self.raw_values = raw_values + self.lit_corr = lit_corr + self.tissue_corr = tissue_corr + self.p_tissue = p_tissue + self.correlation = 0 + self.p_value = 0 - traitdataName = tokens[0] - database_trait = tokens[1:] + @staticmethod + def from_csv(line, data_start = 1): + name = line[0] + numbers = line[data_start:] + # _log.info(numbers) + numbers = [ float(number) for number in numbers ] - if computing_method == "1": #XZ: Pearson's r - corr,nOverlap = utility.webqtlUtil.calCorrelationText(input_trait, database_trait, input_nnCorr) - else: #XZ: Spearman's rho - corr,nOverlap = utility.webqtlUtil.calCorrelationRankText(input_trait, database_trait, input_nnCorr) - traitinfo = [traitdataName,corr,nOverlap] - allcorrelations.append(traitinfo) + return Trait(name, raw_values = numbers) - return allcorrelations + def calculate_correlation(self, values, method): + """Calculate the correlation value and p value according to the method specified""" + #ZS: This takes the list of values of the trait our selected trait is being correlated against and removes the values of the samples our trait has no value for + #There's probably a better way of dealing with this, but I'll have to ask Christian + updated_raw_values = [] + updated_values = [] + for i in range(len(values)): + if values[i] != "None": + updated_raw_values.append(self.raw_values[i]) + updated_values.append(values[i]) - templatePage.__init__(self, fd) + self.raw_values = updated_raw_values + values = updated_values - if not self.openMysql(): - return - - if not fd.genotype: - fd.readGenotype() + if method == METHOD_SAMPLE_PEARSON or method == METHOD_LIT or method == METHOD_TISSUE_PEARSON: + corr,nOverlap = webqtlUtil.calCorrelation(self.raw_values, values, len(values)) + else: + corr,nOverlap = webqtlUtil.calCorrelationRank(self.raw_values, values, len(values)) - #XZ, 09/18/2008: get the information such as value, variance of the input strain names from the form. - if fd.allstrainlist: - mdpchoice = fd.formdata.getvalue('MDPChoice') - #XZ, in HTML source code, it is "BXD Only" or "BXH only", and so on - if mdpchoice == "1": - strainlist = fd.f1list + fd.strainlist - #XZ, in HTML source code, it is "MDP Only" - elif mdpchoice == "2": - strainlist = [] - strainlist2 = fd.f1list + fd.strainlist - for strain in fd.allstrainlist: - if strain not in strainlist2: - strainlist.append(strain) - #So called MDP Panel - if strainlist: - strainlist = fd.f1list+fd.parlist+strainlist - #XZ, in HTML source code, it is "All Cases" + self.correlation = corr + self.overlap = nOverlap + + if self.overlap < 3: + self.p_value = 1.0 + else: + #ZS - This is probably the wrong way to deal with this. Correlation values of 1.0 definitely exist (the trait correlated against itself), so zero division needs to br prevented. + if abs(self.correlation) >= 1.0: + self.p_value = 0.0 else: - strainlist = fd.allstrainlist - #XZ, 09/18/2008: put the trait data into dictionary fd.allTraitData - fd.readData(fd.allstrainlist) - else: - mdpchoice = None - strainlist = fd.strainlist - #XZ, 09/18/2008: put the trait data into dictionary fd.allTraitData - fd.readData() + ZValue = 0.5*log((1.0+self.correlation)/(1.0-self.correlation)) + ZValue = ZValue*sqrt(self.overlap-3) + self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue))) - #XZ, 3/16/2010: variable RISet must be pass by the form - RISet = fd.RISet - #XZ, 12/12/2008: get species infomation - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet) + - #XZ, 09/18/2008: get all information about the user selected database. - self.target_db_name = fd.formdata.getvalue('database') +#XZ, 01/14/2009: This method is for parallel computing only. +#XZ: It is supposed to be called when "Genetic Correlation, Pearson's r" (method 1) +#XZ: or "Genetic Correlation, Spearman's rho" (method 2) is selected +def compute_corr( input_nnCorr, input_trait, input_list, computing_method): + + allcorrelations = [] + + for line in input_list: + tokens = line.split('","') + tokens[-1] = tokens[-1][:-2] #remove the last " + tokens[0] = tokens[0][1:] #remove the first " + + traitdataName = tokens[0] + database_trait = tokens[1:] + + if computing_method == "1": #XZ: Pearson's r + corr,nOverlap = utility.webqtlUtil.calCorrelationText(input_trait, database_trait, input_nnCorr) + else: #XZ: Spearman's rho + corr,nOverlap = utility.webqtlUtil.calCorrelationRankText(input_trait, database_trait, input_nnCorr) + traitinfo = [traitdataName,corr,nOverlap] + allcorrelations.append(traitinfo) + + return allcorrelations + +def get_correlation_method_key(form_data): + #XZ, 09/28/2008: if user select "1", then display 1, 3 and 4. + #XZ, 09/28/2008: if user select "2", then display 2, 3 and 5. + #XZ, 09/28/2008: if user select "3", then display 1, 3 and 4. + #XZ, 09/28/2008: if user select "4", then display 1, 3 and 4. + #XZ, 09/28/2008: if user select "5", then display 2, 3 and 5. + + method = form_data.formdata.getvalue("method") + if method not in ["1", "2", "3" ,"4", "5"]: + return "1" + + return method + + +def get_custom_trait(form_data, cursor): + """Pulls the custom trait, if it exists, out of the form data""" + trait_name = form_data.formdata.getvalue('fullname') + + if trait_name: + trait = webqtlTrait(fullname=trait_name, cursor=cursor) + trait.retrieveInfo() + return trait + else: + return None + + +#XZ, 09/18/2008: get the information such as value, variance of the input strain names from the form. +def get_sample_data(form_data): + if form_data.allstrainlist: + mdpchoice = form_data.formdata.getvalue('MDPChoice') + #XZ, in HTML source code, it is "BXD Only" or "BXH only", and so on + if mdpchoice == "1": + strainlist = form_data.f1list + form_data.strainlist + #XZ, in HTML source code, it is "MDP Only" + elif mdpchoice == "2": + strainlist = [] + strainlist2 = form_data.f1list + form_data.strainlist + for strain in form_data.allstrainlist: + if strain not in strainlist2: + strainlist.append(strain) + #So called MDP Panel + if strainlist: + strainlist = form_data.f1list+form_data.parlist+strainlist + #XZ, in HTML source code, it is "All Cases" + else: + strainlist = form_data.allstrainlist + #XZ, 09/18/2008: put the trait data into dictionary form_data.allTraitData + form_data.readData(form_data.allstrainlist) + else: + mdpchoice = None + strainlist = form_data.strainlist + #XZ, 09/18/2008: put the trait data into dictionary form_data.allTraitData + form_data.readData() + + return strainlist + + +def get_mdp_choice(form_data): + if form_data.allstrainlist: + return form_data.formdata.getvalue("MDPChoice") + else: + return None + + +def get_species(fd, cursor): + #XZ, 3/16/2010: variable RISet must be pass by the form + RISet = fd.RISet + #XZ, 12/12/2008: get species infomation + species = webqtlDatabaseFunction.retrieveSpecies(cursor=cursor, RISet=RISet) + return species + + +def sortTraitCorrelations(traits, method="1"): + if method in TISSUE_METHODS: + traits.sort(key=lambda trait: trait.tissue_corr != None and abs(trait.tissue_corr), reverse=True) + elif method == METHOD_LIT: + traits.sort(key=lambda trait: trait.lit_corr != None and abs(trait.lit_corr), reverse=True) + else: + traits.sort(key=lambda trait: trait.correlation != None and abs(trait.correlation), reverse=True) + + return traits + + +def auth_user_for_db(db, cursor, target_db_name, privilege, username): + """Authorize a user for access to a database if that database is + confidential. A db (identified by a record in ProbeSetFreeze) contains a + list of authorized users who may access it, as well as its confidentiality + level. + + If the current user's privilege level is greater than 'user', ie: root or + admin, then they are automatically authed, otherwise, check the + AuthorizedUsers field for the presence of their name.""" + + if db.type == 'ProbeSet': + cursor.execute('SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM ProbeSetFreeze WHERE Name = "%s"' % target_db_name) + indId, indName, indFullName, confidential, AuthorisedUsers = cursor.fetchall()[0] + + if confidential: + authorized = 0 + + #for the dataset that confidentiality is 1 + #1. 'admin' and 'root' can see all of the dataset + #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + if webqtlConfig.USERDICT[privilege] > webqtlConfig.USERDICT['user']: + authorized = 1 + else: + if username in AuthorisedUsers.split(","): + authorized = 1 + + if not authorized: + raise AuthException("The %s database you selected is not open to the public at this time, please go back and select other database." % indFullName) - try: - self.db = webqtlDataset(self.target_db_name, self.cursor) - except: - heading = "Correlation Table" - detail = ["The database you just requested has not been established yet."] - self.error(heading=heading,detail=detail) - return - #XZ, 09/18/2008: check if user has the authority to get access to the database. - if self.db.type == 'ProbeSet': - self.cursor.execute('SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM ProbeSetFreeze WHERE Name = "%s"' % self.target_db_name) - indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] +class CorrelationPage(templatePage): - if confidential == 1: - access_to_confidential_dataset = 0 + corrMinInformative = 4 - #for the dataset that confidentiality is 1 - #1. 'admin' and 'root' can see all of the dataset - #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) - if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: - access_to_confidential_dataset = 1 - else: - AuthorisedUsersList=AuthorisedUsers.split(',') - if AuthorisedUsersList.__contains__(self.userName): - access_to_confidential_dataset = 1 + PAGE_HEADING = "Correlation Table" + CORRELATION_METHODS = {"1" : "Genetic Correlation (Pearson's r)", + "2" : "Genetic Correlation (Spearman's rho)", + "3" : "SGO Literature Correlation", + "4" : "Tissue Correlation (Pearson's r)", + "5" : "Tissue Correlation (Spearman's rho)"} - if not access_to_confidential_dataset: - #Error, Confidential Database - heading = "Correlation Table" - detail = ["The %s database you selected is not open to the public at this time, please go back and select other database." % indFullName] - self.error(heading=heading,detail=detail,error="Confidential Database") - return + RANK_ORDERS = {"1": 0, "2": 1, "3": 0, "4": 0, "5": 1} - #XZ, 09/18/2008: filter out the strains that have no value. - _strains, _vals, _vars, N = fd.informativeStrains(strainlist) - N = len(_strains) + def error(self, message, error="Error", heading = None): + heading = heading or self.PAGE_HEADING + return templatePage.error(heading = heading, detail = [message], error=error) - if N < self.corrMinInformative: - heading = "Correlation Table" - detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corrMinInformative, RISet)] - self.error(heading=heading,detail=detail) + def __init__(self, fd): + + # Call the superclass constructor + templatePage.__init__(self, fd) + + # Connect to the database + if not self.openMysql(): return - #XZ, 09/28/2008: if user select "1", then display 1, 3 and 4. - #XZ, 09/28/2008: if user select "2", then display 2, 3 and 5. - #XZ, 09/28/2008: if user select "3", then display 1, 3 and 4. - #XZ, 09/28/2008: if user select "4", then display 1, 3 and 4. - #XZ, 09/28/2008: if user select "5", then display 2, 3 and 5. - methodDict = {"1":"Genetic Correlation (Pearson's r)","2":"Genetic Correlation (Spearman's rho)","3":"SGO Literature Correlation","4":"Tissue Correlation (Pearson's r)", "5":"Tissue Correlation (Spearman's rho)"} - self.method = fd.formdata.getvalue('method') - if self.method not in ("1","2","3","4","5"): - self.method = "1" + # Read the genotype from a file + if not fd.genotype: + fd.readGenotype() - self.returnNumber = int(fd.formdata.getvalue('criteria')) + sample_list = get_sample_data(fd) + mdp_choice = get_mdp_choice(fd) # No idea what this is yet + self.species = get_species(fd, self.cursor) - myTrait = fd.formdata.getvalue('fullname') - if myTrait: - myTrait = webqtlTrait(fullname=myTrait, cursor=self.cursor) - myTrait.retrieveInfo() + #XZ, 09/18/2008: get all information about the user selected database. + target_db_name = fd.formdata.getvalue('database') + self.target_db_name = target_db_name - # We will not get Literature Correlations if there is no GeneId because there is nothing to look against try: - input_trait_GeneId = int(fd.formdata.getvalue('GeneId')) + self.db = webqtlDataset(target_db_name, self.cursor) except: - input_trait_GeneId = None + detail = ["The database you just requested has not been established yet."] + self.error(detail) + return - # We will not get Tissue Correlations if there is no gene symbol because there is nothing to look against + # Auth if needed try: - input_trait_symbol = myTrait.symbol - except: - input_trait_symbol = None - - - #XZ, 12/12/2008: if the species is rat or human, translate the geneid to mouse geneid - input_trait_mouse_geneid = self.translateToMouseGeneID(species, input_trait_GeneId) - - - #XZ: As of Nov/13/2010, this dataset is 'UTHSC Illumina V6.2 RankInv B6 D2 average CNS GI average (May 08)' - TissueProbeSetFreezeId = 1 - - #XZ, 09/22/2008: If we need search by GeneId, - #XZ, 09/22/2008: we have to check if this GeneId is in the literature or tissue correlation table. - #XZ, 10/15/2008: We also to check if the selected database is probeset type. - if self.method == "3" or self.method == "4" or self.method == "5": - if self.db.type != "ProbeSet": - self.error(heading="Wrong correlation type",detail="It is not possible to compute the %s between your trait and data in this %s database. Please try again after selecting another type of correlation." % (methodDict[self.method],self.db.name),error="Correlation Type Error") - return - - """ - if not input_trait_GeneId: - self.error(heading="No Associated GeneId",detail="This trait has no associated GeneId, so we are not able to show any literature or tissue related information.",error="No GeneId Error") - return - """ - - #XZ: We have checked geneid did exist - - if self.method == "3": - if not input_trait_GeneId or not self.checkForLitInfo(input_trait_mouse_geneid): - self.error(heading="No Literature Info",detail="This gene does not have any associated Literature Information.",error="Literature Correlation Error") - return - - if self.method == "4" or self.method == "5": - if not input_trait_symbol: - self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error") - return - - if not self.checkSymbolForTissueCorr(TissueProbeSetFreezeId, myTrait.symbol): - self.error(heading="No Tissue Correlation Information",detail="This gene does not have any associated Tissue Correlation Information.",error="Tissue Correlation Error") - return - -############################################################################################################################################ - - allcorrelations = [] - nnCorr = len(_vals) - - #XZ: Use the fast method only for probeset dataset, and this dataset must have been created. - #XZ: Otherwise, use original method - - useFastMethod = False - - if self.db.type == "ProbeSet": - - DatabaseFileName = self.getFileName( target_db_name=self.target_db_name ) - DirectoryList = os.listdir(webqtlConfig.TEXTDIR) ### List of existing text files. Used to check if a text file already exists - - if DatabaseFileName in DirectoryList: - useFastMethod = True - - if useFastMethod: - if 1: - #try: - useLit = False - if self.method == "3": - litCorrs = self.fetchLitCorrelations(species=species, GeneId=input_trait_GeneId, db=self.db, returnNumber=self.returnNumber) - useLit = True - - useTissueCorr = False - if self.method == "4" or self.method == "5": - tissueCorrs = self.fetchTissueCorrelations(db=self.db, primaryTraitSymbol=input_trait_symbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=self.method, returnNumber = self.returnNumber) - useTissueCorr = True - - datasetFile = open(webqtlConfig.TEXTDIR+DatabaseFileName,'r') - - #XZ, 01/08/2009: read the first line - line = datasetFile.readline() - dataset_strains = webqtlUtil.readLineCSV(line)[1:] - - #XZ, 01/08/2009: This step is critical. It is necessary for this new method. - #XZ: The original function fetchAllDatabaseData uses all strains stored in variable _strains to - #XZ: retrieve the values of each strain from database in real time. - #XZ: The new method uses all strains stored in variable dataset_strains to create a new variable - #XZ: _newvals. _newvals has the same length as dataset_strains. The items in _newvals is in - #XZ: the same order of items in dataset_strains. The value of each item in _newvals is either - #XZ: the value of correspinding strain in _vals or 'None'. - _newvals = [] - for item in dataset_strains: - if item in _strains: - _newvals.append(_vals[_strains.index(item)]) - else: - _newvals.append('None') - - nnCorr = len(_newvals) - - #XZ, 01/14/2009: If literature corr or tissue corr is selected, - #XZ: there is no need to use parallel computing. - if useLit or useTissueCorr: - for line in datasetFile: - traitdata=webqtlUtil.readLineCSV(line) - traitdataName = traitdata[0] - traitvals = traitdata[1:] - - if useLit: - if not litCorrs.has_key( traitdataName ): - continue - - if useTissueCorr: - if not tissueCorrs.has_key( traitdataName ): - continue - - if self.method == "3" or self.method == "4": - corr,nOverlap = webqtlUtil.calCorrelationText(traitvals,_newvals,nnCorr) - else: - corr,nOverlap = webqtlUtil.calCorrelationRankText(traitvals,_newvals,nnCorr) - - traitinfo = [traitdataName,corr,nOverlap] - - if useLit: - traitinfo.append(litCorrs[traitdataName]) - - if useTissueCorr: - tempCorr, tempPValue = tissueCorrs[traitdataName] - traitinfo.append(tempCorr) - traitinfo.append(tempPValue) - - allcorrelations.append(traitinfo) - #XZ, 01/14/2009: If genetic corr is selected, use parallel computing - else: - input_line_list = datasetFile.readlines() - all_line_number = len(input_line_list) - - step = 1000 - job_number = math.ceil( float(all_line_number)/step ) - - job_input_lists = [] - - for job_index in range( int(job_number) ): - starti = job_index*step - endi = min((job_index+1)*step, all_line_number) - - one_job_input_list = [] - - for i in range( starti, endi ): - one_job_input_list.append( input_line_list[i] ) - - job_input_lists.append( one_job_input_list ) - - ppservers = () - # Creates jobserver with automatically detected number of workers - job_server = pp.Server(ppservers=ppservers) - - jobs = [] - results = [] - - for one_job_input_list in job_input_lists: #pay attention to modules from outside - jobs.append( job_server.submit(func=compute_corr, args=(nnCorr, _newvals, one_job_input_list, self.method), depfuncs=(), modules=("utility.webqtlUtil",)) ) - - for one_job in jobs: - one_result = one_job() - results.append( one_result ) - - for one_result in results: - for one_traitinfo in one_result: - allcorrelations.append( one_traitinfo ) - - datasetFile.close() - totalTraits = len(allcorrelations) - #except: - # useFastMethod = False - # self.error(heading="No computation method",detail="Something is wrong within the try except block in CorrelationPage python module.",error="Computation Error") - # return - - #XZ, 01/08/2009: use the original method to retrieve from database and compute. - if not useFastMethod: - - traitdatabase, dataStartPos = self.fetchAllDatabaseData(species=species, GeneId=input_trait_GeneId, GeneSymbol=input_trait_symbol, strains=_strains, db=self.db, method=self.method, returnNumber=self.returnNumber, tissueProbeSetFreezeId=TissueProbeSetFreezeId) - - totalTraits = len(traitdatabase) #XZ, 09/18/2008: total trait number - - for traitdata in traitdatabase: - traitdataName = traitdata[0] - traitvals = traitdata[dataStartPos:] - if self.method == "1" or self.method == "3" or self.method == "4": - corr,nOverlap = webqtlUtil.calCorrelation(traitvals,_vals,nnCorr) - else: - corr,nOverlap = webqtlUtil.calCorrelationRank(traitvals,_vals,nnCorr) - - traitinfo = [traitdataName,corr,nOverlap] - - #XZ, 09/28/2008: if user select '3', then fetchAllDatabaseData would give us LitCorr in the [1] position - #XZ, 09/28/2008: if user select '4' or '5', then fetchAllDatabaseData would give us Tissue Corr in the [1] position - #XZ, 09/28/2008: and Tissue Corr P Value in the [2] position - if input_trait_GeneId and self.db.type == "ProbeSet": - if self.method == "3": - traitinfo.append( traitdata[1] ) - if self.method == "4" or self.method == "5": - traitinfo.append( traitdata[1] ) - traitinfo.append( traitdata[2] ) - - allcorrelations.append(traitinfo) + auth_user_for_db(self.db, self.cursor, target_db_name, self.privilege, self.userName) + except AuthException, e: + detail = [e.message] + return self.error(detail) + #XZ, 09/18/2008: filter out the strains that have no value. + self.sample_names, vals, vars, N = fd.informativeStrains(sample_list) -############################################################# + #CF - If less than a minimum number of strains/cases in common, don't calculate anything + if len(self.sample_names) < self.corrMinInformative: + detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corrMinInformative, fd.RISet)] + self.error(heading=PAGE_HEADING,detail=detail) - if self.method == "3" and input_trait_GeneId: - allcorrelations.sort(webqtlUtil.cmpLitCorr) - #XZ, 3/31/2010: Theoretically, we should create one function 'comTissueCorr' - #to compare each trait by their tissue corr p values. - #But because the tissue corr p values are generated by permutation test, - #the top ones always have p value 0. So comparing p values actually does nothing. - #In addition, for the tissue data in our database, the N is always the same. - #So it's safe to compare with tissue corr statistic value. - #That's the same as literature corr. - elif self.method in ["4","5"] and input_trait_GeneId: - allcorrelations.sort(webqtlUtil.cmpLitCorr) - else: - allcorrelations.sort(webqtlUtil.cmpCorr) + self.method = get_correlation_method_key(fd) + correlation_method = self.CORRELATION_METHODS[self.method] + rankOrder = self.RANK_ORDERS[self.method] - #XZ, 09/20/2008: we only need the top ones. - self.returnNumber = min(self.returnNumber,len(allcorrelations)) - allcorrelations = allcorrelations[:self.returnNumber] + # CF - Number of results returned + self.returnNumber = int(fd.formdata.getvalue('criteria')) - addLiteratureCorr = False - addTissueCorr = False + self.record_count = 0 - traitList = [] - for item in allcorrelations: - thisTrait = webqtlTrait(db=self.db, name=item[0], cursor=self.cursor) - thisTrait.retrieveInfo( QTL='Yes' ) + myTrait = get_custom_trait(fd, self.cursor) - nOverlap = item[2] - corr = item[1] - #XZ: calculate corrPValue - if nOverlap < 3: - corrPValue = 1.0 - else: - if abs(corr) >= 1.0: - corrPValue = 0.0 - else: - ZValue = 0.5*log((1.0+corr)/(1.0-corr)) - ZValue = ZValue*sqrt(nOverlap-3) - corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - - thisTrait.Name = item[0] - thisTrait.corr = corr - thisTrait.nOverlap = nOverlap - thisTrait.corrPValue = corrPValue - # NL, 07/19/2010 - # js function changed, add a new parameter rankOrder for js function 'showTissueCorrPlot' - rankOrder = 0; - if self.method in ["2","5"]: - rankOrder = 1; - thisTrait.rankOrder =rankOrder - - #XZ, 26/09/2008: Method is 4 or 5. Have fetched tissue corr, but no literature correlation yet. - if len(item) == 5: - thisTrait.tissueCorr = item[3] - thisTrait.tissuePValue = item[4] - addLiteratureCorr = True + # We will not get Literature Correlations if there is no GeneId because there is nothing to look against + self.gene_id = int(fd.formdata.getvalue('GeneId') or 0) - #XZ, 26/09/2008: Method is 3, Have fetched literature corr, but no tissue corr yet. - elif len(item) == 4: - thisTrait.LCorr = item[3] - thisTrait.mouse_geneid = self.translateToMouseGeneID(species, thisTrait.geneid) - addTissueCorr = True + # We will not get Tissue Correlations if there is no gene symbol because there is nothing to look against + self.trait_symbol = myTrait.symbol + - #XZ, 26/09/2008: Method is 1 or 2. Have NOT fetched literature corr and tissue corr yet. - # Phenotype data will not have geneid, and neither will some probes - # we need to handle this because we will get an attribute error - else: - if input_trait_mouse_geneid and self.db.type=="ProbeSet": - addLiteratureCorr = True - if input_trait_symbol and self.db.type=="ProbeSet": - addTissueCorr = True + #XZ, 12/12/2008: if the species is rat or human, translate the geneid to mouse geneid + self.input_trait_mouse_gene_id = self.translateToMouseGeneID(self.species, self.gene_id) - traitList.append(thisTrait) + #XZ: As of Nov/13/2010, this dataset is 'UTHSC Illumina V6.2 RankInv B6 D2 average CNS GI average (May 08)' + self.tissue_probeset_freeze_id = 1 - if addLiteratureCorr: - traitList = self.getLiteratureCorrelationByList(input_trait_mouse_geneid, species, traitList) - if addTissueCorr: - traitList = self.getTissueCorrelationByList( primaryTraitSymbol=input_trait_symbol, traitList=traitList,TissueProbeSetFreezeId =TissueProbeSetFreezeId, method=self.method) + traitList = self.correlate(vals) + + _log.info("Done doing correlation calculation") -######################################################## +############################################################################################################################################ TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') mainfmName = webqtlUtil.genRandStr("fm_") form = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name= mainfmName, submit=HT.Input(type='hidden')) - hddn = {'FormID':'showDatabase', 'ProbeSetID':'_','database':self.target_db_name, 'databaseFull':self.db.fullname, 'CellID':'_', 'RISet':RISet, 'identification':fd.identification} + hddn = {'FormID': 'showDatabase', + 'ProbeSetID': '_', + 'database': self.target_db_name, + 'databaseFull': self.db.fullname, + 'CellID': '_', + 'RISet': fd.RISet, + 'identification': fd.identification} if myTrait: hddn['fullname']=fd.formdata.getvalue('fullname') - if mdpchoice: - hddn['MDPChoice']=mdpchoice + if mdp_choice: + hddn['MDPChoice']=mdp_choice #XZ, 09/18/2008: pass the trait data to next page by hidden parameters. @@ -510,13 +390,13 @@ class CorrelationPage(templatePage): #XZ, 3/11/2010: add one parameter to record if the method is rank order. form.append(HT.Input(name="rankOrder", value="%s" % rankOrder, type='hidden')) - form.append(HT.Input(name="TissueProbeSetFreezeId", value="%s" % TissueProbeSetFreezeId, type='hidden')) + form.append(HT.Input(name="TissueProbeSetFreezeId", value="%s" % self.tissue_probeset_freeze_id, type='hidden')) #################################### # generate the info on top of page # #################################### - info = self.getTopInfo(myTrait=myTrait, method=self.method, db=self.db, target_db_name=self.target_db_name, returnNumber=self.returnNumber, methodDict=methodDict, totalTraits=totalTraits, identification=fd.identification ) + info = self.getTopInfo(myTrait=myTrait, method=self.method, db=self.db, target_db_name=self.target_db_name, returnNumber=self.returnNumber, methodDict=self.CORRELATION_METHODS, totalTraits=traitList, identification=fd.identification ) ############## # Excel file # @@ -536,7 +416,7 @@ class CorrelationPage(templatePage): ##################################################################### - + #Select All, Deselect All, Invert Selection, Add to Collection mintmap = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'showIntMap');" % mainfmName) mintmap_img = HT.Image("/images/multiple_interval_mapping1_final.jpg", name='mintmap', alt="Multiple Interval Mapping", title="Multiple Interval Mapping", style="border:none;") mintmap.append(mintmap_img) @@ -555,10 +435,10 @@ class CorrelationPage(templatePage): partialCorr = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'partialCorrInput');" % mainfmName) partialCorr_img = HT.Image("/images/partial_correlation_final.jpg", name='partialCorr', alt="Partial Correlation", title="Partial Correlation", style="border:none;") partialCorr.append(partialCorr_img) - addselect = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (RISet, mainfmName)) + addselect = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, mainfmName)) addselect_img = HT.Image("/images/add_collection1_final.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") addselect.append(addselect_img) - selectall = HT.Href(url="#redirect", onClick="checkAll(document.getElementsByName('%s')[0]);" % mainfmName) + selectall = HT.Href(url="#redirect", onClick="checkAll(document.getElementsByName('%s')[0]);" % mainfmName) selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;") selectall.append(selectall_img) selectinvert = HT.Href(url="#redirect", onClick = "checkInvert(document.getElementsByName('%s')[0]);" % mainfmName) @@ -575,20 +455,90 @@ class CorrelationPage(templatePage): selectandor.append(('OR','or')) selectandor.selected.append('AND') - pageTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="100%", border=0, align="Left") - containerTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="90%",border=0, align="Left") + #External analysis tools + GCATButton = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GCAT');" % mainfmName) + GCATButton_img = HT.Image("/images/GCAT_logo_final.jpg", name="GCAT", alt="GCAT", title="GCAT", style="border:none") + GCATButton.append(GCATButton_img) + + ODE = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'ODE');" % mainfmName) + ODE_img = HT.Image("/images/ODE_logo_final.jpg", name="ode", alt="ODE", title="ODE", style="border:none") + ODE.append(ODE_img) + + ''' + #XZ, 07/07/2010: I comment out this block of code. + WebGestaltScript = HT.Script(language="Javascript") + WebGestaltScript.append(""" +setTimeout('openWebGestalt()', 2000); +function openWebGestalt(){ +var thisForm = document['WebGestalt']; +makeWebGestaltTree(thisForm, '%s', %d, 'edag_only.php'); +} + """ % (mainfmName, len(traitList))) + ''' + + self.cursor.execute('SELECT GeneChip.GO_tree_value FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % self.db.name) + result = self.cursor.fetchone() + + if result: + GO_tree_value = result[0] + + if GO_tree_value: + + WebGestalt = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GOTree');" % mainfmName) + WebGestalt_img = HT.Image("/images/webgestalt_icon_final.jpg", name="webgestalt", alt="Gene Set Analysis Toolkit", title="Gene Set Analysis Toolkit", style="border:none") + WebGestalt.append(WebGestalt_img) + + hddnWebGestalt = { + 'id_list':'', + 'correlation':'', + 'id_value':'', + 'llid_list':'', + 'id_type':GO_tree_value, + 'idtype':'', + 'species':'', + 'list':'', + 'client':''} + + hddnWebGestalt['ref_type'] = hddnWebGestalt['id_type'] + hddnWebGestalt['cat_type'] = 'GO' + hddnWebGestalt['significancelevel'] = 'Top10' + + if self.species == 'rat': + hddnWebGestalt['org'] = 'Rattus norvegicus' + elif self.species == 'human': + hddnWebGestalt['org'] = 'Homo sapiens' + elif self.species == 'mouse': + hddnWebGestalt['org'] = 'Mus musculus' + else: + hddnWebGestalt['org'] = '' + + for key in hddnWebGestalt.keys(): + form.append(HT.Input(name=key, value=hddnWebGestalt[key], type='hidden')) + - optionsTable = HT.TableLite(cellSpacing=2, cellPadding=0,width="320", height="80", border=0, align="Left") - optionsTable.append(HT.TR(HT.TD(selectall), HT.TD(reset), HT.TD(selectinvert), HT.TD(addselect), align="left")) - optionsTable.append(HT.TR(HT.TD(" "*1,"Select"), HT.TD("Deselect"), HT.TD(" "*1,"Invert"), HT.TD(" "*3,"Add"))) + #Create tables with options, etc + + pageTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="100%", border=0, align="Left") + + containerTable = HT.TableLite(cellSpacing=0,cellPadding=0,width="90%",border=0, align="Left") + + + if not GO_tree_value: + optionsTable = HT.TableLite(cellSpacing=2, cellPadding=0,width="480", height="80", border=0, align="Left") + optionsTable.append(HT.TR(HT.TD(selectall), HT.TD(reset), HT.TD(selectinvert), HT.TD(addselect), HT.TD(GCATButton), HT.TD(ODE), align="left")) + optionsTable.append(HT.TR(HT.TD(" "*1,"Select"), HT.TD("Deselect"), HT.TD(" "*1,"Invert"), HT.TD(" "*3,"Add"), HT.TD("Gene Set"), HT.TD(" "*2,"GCAT"))) + else: + optionsTable = HT.TableLite(cellSpacing=2, cellPadding=0,width="560", height="80", border=0, align="Left") + optionsTable.append(HT.TR(HT.TD(selectall), HT.TD(reset), HT.TD(selectinvert), HT.TD(addselect), HT.TD(GCATButton), HT.TD(ODE), HT.TD(WebGestalt), align="left")) + optionsTable.append(HT.TR(HT.TD(" "*1,"Select"), HT.TD("Deselect"), HT.TD(" "*1,"Invert"), HT.TD(" "*3,"Add"), HT.TD("Gene Set"), HT.TD(" "*2,"GCAT"), HT.TD(" "*3, "ODE"))) containerTable.append(HT.TR(HT.TD(optionsTable))) functionTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="480",height="80", border=0, align="Left") functionRow = HT.TR(HT.TD(networkGraph, width="16.7%"), HT.TD(cormatrix, width="16.7%"), HT.TD(partialCorr, width="16.7%"), HT.TD(mcorr, width="16.7%"), HT.TD(mintmap, width="16.7%"), HT.TD(heatmap), align="left") labelRow = HT.TR(HT.TD(" "*1,HT.Text("Graph")), HT.TD(" "*1,HT.Text("Matrix")), HT.TD(" "*1,HT.Text("Partial")), HT.TD(HT.Text("Compare")), HT.TD(HT.Text("QTL Map")), HT.TD(HT.Text(text="Heat Map"))) functionTable.append(functionRow, labelRow) - containerTable.append(HT.TR(HT.TD(functionTable), HT.BR())) + containerTable.append(HT.TR(HT.TD(functionTable), HT.BR())) #more_options = HT.Image("/images/more_options1_final.jpg", name='more_options', alt="Expand Options", title="Expand Options", style="border:none;", Class="toggleShowHide") @@ -597,12 +547,14 @@ class CorrelationPage(templatePage): moreOptions = HT.Input(type='button',name='options',value='More Options', onClick="",Class="toggle") fewerOptions = HT.Input(type='button',name='options',value='Fewer Options', onClick="",Class="toggle") + """ if (fd.formdata.getvalue('showHideOptions') == 'less'): - containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(fewerOptions, Class="toggleShowHide")))) - containerTable.append(HT.TR(HT.TD(" "))) + containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(fewerOptions, Class="toggleShowHide")))) + containerTable.append(HT.TR(HT.TD(" "))) else: - containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(moreOptions, Class="toggleShowHide")))) - containerTable.append(HT.TR(HT.TD(" "))) + containerTable.append(HT.TR(HT.TD(" "), height="10"), HT.TR(HT.TD(HT.Div(moreOptions, Class="toggleShowHide")))) + containerTable.append(HT.TR(HT.TD(" "))) + """ containerTable.append(HT.TR(HT.TD(HT.Span(selecttraits,' with r > ',selectgt, ' ',selectandor, ' r < ',selectlt,Class="bd1 cbddf fs11")), style="display:none;", Class="extra_options")) @@ -615,9 +567,9 @@ class CorrelationPage(templatePage): if self.db.type=="Geno": - containerTable.append(HT.TR(HT.TD(xlsUrl, height=40))) + containerTable.append(HT.TR(HT.TD(xlsUrl, height=60))) - pageTable.append(HT.TR(HT.TD(containerTable))) + pageTable.append(HT.TR(HT.TD(containerTable))) tblobj['header'], worksheet = self.getTableHeaderForGeno( method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) newrow += 1 @@ -636,9 +588,9 @@ class CorrelationPage(templatePage): div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable") - pageTable.append(HT.TR(HT.TD(div))) + pageTable.append(HT.TR(HT.TD(div))) - form.append(HT.Input(name='ShowStrains',type='hidden', value =1), + form.append(HT.Input(name='ShowStrains',type='hidden', value =1), HT.Input(name='ShowLine',type='hidden', value =1), HT.P(), HT.P(), pageTable) TD_LR.append(corrHeading, info, form, HT.P()) @@ -649,9 +601,9 @@ class CorrelationPage(templatePage): elif self.db.type=="Publish": - containerTable.append(HT.TR(HT.TD(xlsUrl, height=40))) + containerTable.append(HT.TR(HT.TD(xlsUrl, height=40))) - pageTable.append(HT.TR(HT.TD(containerTable))) + pageTable.append(HT.TR(HT.TD(containerTable))) tblobj['header'], worksheet = self.getTableHeaderForPublish(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) newrow += 1 @@ -661,7 +613,7 @@ class CorrelationPage(templatePage): corrScript = HT.Script(language="Javascript") corrScript.append("var corrArray = new Array();") - tblobj['body'], worksheet, corrScript = self.getTableBodyForPublish(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=species) + tblobj['body'], worksheet, corrScript = self.getTableBodyForPublish(traitList=traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=self.species) workbook.close() @@ -671,7 +623,7 @@ class CorrelationPage(templatePage): # NL, 07/27/2010. genTableObj function has been moved from templatePage.py to webqtlUtil.py; div = HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "1"), corrScript, Id="sortable") - pageTable.append(HT.TR(HT.TD(div))) + pageTable.append(HT.TR(HT.TD(div))) form.append( HT.Input(name='ShowStrains',type='hidden', value =1), @@ -685,7 +637,6 @@ class CorrelationPage(templatePage): elif self.db.type=="ProbeSet": - tblobj['header'], worksheet = self.getTableHeaderForProbeSet(method=self.method, worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) newrow += 1 @@ -694,7 +645,7 @@ class CorrelationPage(templatePage): corrScript = HT.Script(language="Javascript") corrScript.append("var corrArray = new Array();") - tblobj['body'], worksheet, corrScript = self.getTableBodyForProbeSet(traitList=traitList, primaryTrait=myTrait, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=species) + tblobj['body'], worksheet, corrScript = self.getTableBodyForProbeSet(traitList=traitList, primaryTrait=myTrait, formName=mainfmName, worksheet=worksheet, newrow=newrow, corrScript=corrScript, species=self.species) workbook.close() objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') @@ -741,95 +692,21 @@ class CorrelationPage(templatePage): #updated by NL. Delete function generateJavaScript, move js files to dhtml.js, webqtl.js and jqueryFunction.js #variables: filename, strainIds and vals are required by getquerystring function - strainIds=self.getStrainIds(species=species, strains=_strains) + strainIds=self.getStrainIds(species=self.species, strains=self.sample_names) var1 = HT.Input(name="filename", value=filename, type='hidden') var2 = HT.Input(name="strainIds", value=strainIds, type='hidden') - var3 = HT.Input(name="vals", value=_vals, type='hidden') + var3 = HT.Input(name="vals", value=vals, type='hidden') customizerButton = HT.Input(type="button", Class="button", value="Add Correlation", onClick = "xmlhttpPost('%smain.py?FormID=AJAX_table', 'sortable', (getquerystring(this.form)))" % webqtlConfig.CGIDIR) containerTable.append(HT.TR(HT.TD(HT.Span(var1,var2,var3,customizerButton, "with", dbCustomizer, Class="bd1 cbddf fs11"), HT.BR(), HT.BR()), style="display:none;", Class="extra_options")) - #outside analysis part - GCATButton = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GCAT');" % mainfmName) - GCATButton_img = HT.Image("/images/GCAT_logo_final.jpg", name="GCAT", alt="GCAT", title="GCAT", style="border:none") - GCATButton.append(GCATButton_img) - - ODE = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'ODE');" % mainfmName) - ODE_img = HT.Image("/images/ODE_logo_final.jpg", name="ode", alt="ODE", title="ODE", style="border:none") - ODE.append(ODE_img) + containerTable.append(HT.TR(HT.TD(xlsUrl, HT.BR(), HT.BR()))) - ''' - #XZ, 07/07/2010: I comment out this block of code. - WebGestaltScript = HT.Script(language="Javascript") - WebGestaltScript.append(""" -setTimeout('openWebGestalt()', 2000); -function openWebGestalt(){ - var thisForm = document['WebGestalt']; - makeWebGestaltTree(thisForm, '%s', %d, 'edag_only.php'); -} - """ % (mainfmName, len(traitList))) - ''' - - self.cursor.execute('SELECT GeneChip.GO_tree_value FROM GeneChip, ProbeFreeze, ProbeSetFreeze WHERE GeneChip.Id = ProbeFreeze.ChipId and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.Name = "%s"' % self.db.name) - result = self.cursor.fetchone() + pageTable.append(HT.TR(HT.TD(containerTable))) - if result: - GO_tree_value = result[0] + pageTable.append(HT.TR(HT.TD(div))) - if GO_tree_value: - - WebGestalt = HT.Href(url="#redirect", onClick="databaseFunc(document.getElementsByName('%s')[0], 'GOTree');" % mainfmName) - WebGestalt_img = HT.Image("/images/webgestalt_icon_final.jpg", name="webgestalt", alt="Gene Set Analysis Toolkit", title="Gene Set Analysis Toolkit", style="border:none") - WebGestalt.append(WebGestalt_img) - - hddnWebGestalt = { - 'id_list':'', - 'correlation':'', - 'id_value':'', - 'llid_list':'', - 'id_type':GO_tree_value, - 'idtype':'', - 'species':'', - 'list':'', - 'client':''} - - hddnWebGestalt['ref_type'] = hddnWebGestalt['id_type'] - hddnWebGestalt['cat_type'] = 'GO' - hddnWebGestalt['significancelevel'] = 'Top10' - - if species == 'rat': - hddnWebGestalt['org'] = 'Rattus norvegicus' - elif species == 'human': - hddnWebGestalt['org'] = 'Homo sapiens' - elif species == 'mouse': - hddnWebGestalt['org'] = 'Mus musculus' - else: - hddnWebGestalt['org'] = '' - - for key in hddnWebGestalt.keys(): - form.append(HT.Input(name=key, value=hddnWebGestalt[key], type='hidden')) - - - LinkOutTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="320",height="80", border=0, align="Left") - - if not GO_tree_value: - LinkOutRow = HT.TR(HT.TD(GCATButton, width="50%"), HT.TD(ODE, width="50%"), align="left") - LinkOutLabels = HT.TR(HT.TD(" ", HT.Text("GCAT"), width="50%"), HT.TD(" ",HT.Text("ODE"), width="50%"), align="left") - else: - LinkOutRow = HT.TR(HT.TD(WebGestalt, width="25%"), HT.TD(GCATButton, width="25%"), HT.TD(ODE, width="25%"), align="left") - LinkOutLabels = HT.TR(HT.TD(HT.Text("Gene Set")), HT.TD(" "*2, HT.Text("GCAT")), HT.TD(" "*3, HT.Text("ODE")), style="display:none;", Class="extra_options") - - LinkOutTable.append(LinkOutRow,LinkOutLabels) - - containerTable.append(HT.TR(HT.TD(LinkOutTable), Class="extra_options", style="display:none;")) - - containerTable.append(HT.TR(HT.TD(xlsUrl, HT.BR(), HT.BR()))) - - pageTable.append(HT.TR(HT.TD(containerTable))) - - pageTable.append(HT.TR(HT.TD(div))) - - if species == 'human': + if self.species == 'human': heatmap = "" form.append(HT.Input(name='ShowStrains',type='hidden', value =1), @@ -1009,7 +886,7 @@ Resorting this table
tempTable = self.getTempLiteratureTable(species=species, input_species_geneid=GeneId, returnNumber=returnNumber) if method == "4" or method == "5": - tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=GeneSymbol, TissueProbeSetFreezeId=tissueProbeSetFreezeId, method=method, returnNumber=returnNumber) + tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=GeneSymbol, TissueProbeSetFreezeId=TISSUE_MOUSE_DB, method=method, returnNumber=returnNumber) for step in range(nnn): temp = [] @@ -1068,18 +945,30 @@ Resorting this table
oridata.append(results) datasize = len(oridata[0]) - traitdatabase = [] - # put all of the seperate data together into a huge list of lists + traits = [] + # put all of the separate data together into a huge list of lists for j in range(datasize): traitdata = list(oridata[0][j]) for i in range(1,nnn): traitdata += list(oridata[i][j][dataStartPos:]) - traitdatabase.append(traitdata) + + trait = Trait(traitdata[0], traitdata[dataStartPos:]) + + if method == METHOD_LIT: + trait.lit_corr = traitdata[1] + + if method in TISSUE_METHODS: + trait.tissue_corr = traitdata[1] + trait.p_tissue = traitdata[2] + + traits.append(trait) if tempTable: self.cursor.execute( 'DROP TEMPORARY TABLE %s' % tempTable ) - return traitdatabase, dataStartPos + return traits + + # XZ, 09/20/2008: This function creates TEMPORARY TABLE tmpTableName_2 and return its name. @@ -1159,7 +1048,7 @@ Resorting this table
except: return 0 - symbolCorrDict, symbolPvalueDict = self.calculateCorrOfAllTissueTrait(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=method) + symbolCorrDict, symbolPvalueDict = self.calculateCorrOfAllTissueTrait(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TISSUE_MOUSE_DB, method=method) symbolCorrList = symbolCorrDict.items() @@ -1216,7 +1105,7 @@ Resorting this table
Returns a dictionary of 'TraitID':(tissueCorr, tissuePValue) for the requested correlation""" - tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TissueProbeSetFreezeId, method=method, returnNumber=returnNumber) + tempTable = self.getTempTissueCorrTable(primaryTraitSymbol=primaryTraitSymbol, TissueProbeSetFreezeId=TISSUE_MOUSE_DB, method=method, returnNumber=returnNumber) query = "SELECT ProbeSet.Name, %s.Correlation, %s.PValue" % (tempTable, tempTable) query += ' FROM (ProbeSet, ProbeSetXRef, ProbeSetFreeze)' @@ -1276,6 +1165,225 @@ Resorting this table
return traitList + def get_trait(self, cached, vals): + + if cached: + _log.info("Using the fast method because the file exists") + lit_corrs = {} + tissue_corrs = {} + use_lit = False + if self.method == METHOD_LIT: + lit_corrs = self.fetchLitCorrelations(species=self.species, GeneId=self.gene_id, db=self.db, returnNumber=self.returnNumber) + use_lit = True + + use_tissue_corr = False + if self.method in TISSUE_METHODS: + tissue_corrs = self.fetchTissueCorrelations(db=self.db, primaryTraitSymbol=self.trait_symbol, TissueProbeSetFreezeId=TISSUE_MOUSE_DB, method=self.method, returnNumber = self.returnNumber) + use_tissue_corr = True + + DatabaseFileName = self.getFileName( target_db_name=self.target_db_name ) + datasetFile = open(webqtlConfig.TEXTDIR+DatabaseFileName,'r') + + #XZ, 01/08/2009: read the first line + line = datasetFile.readline() + cached_sample_names = webqtlUtil.readLineCSV(line)[1:] + + #XZ, 01/08/2009: This step is critical. It is necessary for this new method. + #XZ: The original function fetchAllDatabaseData uses all strains stored in variable _strains to + #XZ: retrieve the values of each strain from database in real time. + #XZ: The new method uses all strains stored in variable dataset_strains to create a new variable + #XZ: _newvals. _newvals has the same length as dataset_strains. The items in _newvals is in + #XZ: the same order of items in dataset_strains. The value of each item in _newvals is either + #XZ: the value of correspinding strain in _vals or 'None'. + new_vals = [] + for name in cached_sample_names: + if name in self.sample_names: + new_vals.append(float(vals[self.sample_names.index(name)])) + else: + new_vals.append('None') + + nnCorr = len(new_vals) + + #XZ, 01/14/2009: If literature corr or tissue corr is selected, + #XZ: there is no need to use parallel computing. + + traits = [] + data_start = 1 + for line in datasetFile: + raw_trait = webqtlUtil.readLineCSV(line) + trait = Trait.from_csv(raw_trait, data_start) + trait.lit_corr = lit_corrs.get(trait.name) + trait.tissue_corr, trait.p_tissue = tissue_corrs.get(trait.name, (None, None)) + traits.append(trait) + + return traits, new_vals + + else: + _log.info("Using the slow method for correlation") + + _log.info("Fetching from database") + traits = self.fetchAllDatabaseData(species=self.species, GeneId=self.gene_id, GeneSymbol=self.trait_symbol, strains=self.sample_names, db=self.db, method=self.method, returnNumber=self.returnNumber, tissueProbeSetFreezeId= self.tissue_probeset_freeze_id) + _log.info("Done fetching from database") + totalTraits = len(traits) #XZ, 09/18/2008: total trait number + + return traits, vals + + + def do_parallel_correlation(self): + _log.info("Invoking parallel computing") + input_line_list = datasetFile.readlines() + _log.info("Read lines from the file") + all_line_number = len(input_line_list) + + step = 1000 + job_number = math.ceil( float(all_line_number)/step ) + + job_input_lists = [] + + _log.info("Configuring jobs") + + for job_index in range( int(job_number) ): + starti = job_index*step + endi = min((job_index+1)*step, all_line_number) + + one_job_input_list = [] + + for i in range( starti, endi ): + one_job_input_list.append( input_line_list[i] ) + + job_input_lists.append( one_job_input_list ) + + _log.info("Creating pp servers") + + ppservers = () + # Creates jobserver with automatically detected number of workers + job_server = pp.Server(ppservers=ppservers) + + _log.info("Done creating servers") + + jobs = [] + results = [] + + _log.info("Starting parallel computation, submitting jobs") + for one_job_input_list in job_input_lists: #pay attention to modules from outside + jobs.append( job_server.submit(func=compute_corr, args=(nnCorr, _newvals, one_job_input_list, self.method), depfuncs=(), modules=("utility.webqtlUtil",)) ) + _log.info("Done submitting jobs") + + for one_job in jobs: + one_result = one_job() + results.append( one_result ) + + _log.info("Acquiring results") + + for one_result in results: + for one_traitinfo in one_result: + allcorrelations.append( one_traitinfo ) + + _log.info("Appending the results") + + datasetFile.close() + totalTraits = len(allcorrelations) + _log.info("Done correlating using the fast method") + + + def correlate(self, vals): + + correlations = [] + + #XZ: Use the fast method only for probeset dataset, and this dataset must have been created. + #XZ: Otherwise, use original method + _log.info("Entering correlation") + + db_filename = self.getFileName( target_db_name=self.target_db_name ) + + cache_available = db_filename in os.listdir(webqtlConfig.TEXTDIR) + + # If the cache file exists, do a cached correlation for probeset data + if self.db.type == "ProbeSet": +# if self.method in [METHOD_SAMPLE_PEARSON, METHOD_SAMPLE_RANK] and cache_available: +# traits = do_parallel_correlation() +# +# else: + + (traits, vals) = self.get_trait(cache_available, vals) + + for trait in traits: + trait.calculate_correlation(vals, self.method) + + self.record_count = len(traits) #ZS: This isn't a good way to get this value, so I need to change it later + + #XZ, 3/31/2010: Theoretically, we should create one function 'comTissueCorr' + #to compare each trait by their tissue corr p values. + #But because the tissue corr p values are generated by permutation test, + #the top ones always have p value 0. So comparing p values actually does nothing. + #In addition, for the tissue data in our database, the N is always the same. + #So it's safe to compare with tissue corr statistic value. + #That's the same as literature corr. + #if self.method in [METHOD_LIT, METHOD_TISSUE_PEARSON, METHOD_TISSUE_RANK] and self.gene_id: + # traits.sort(webqtlUtil.cmpLitCorr) + #else: + #if self.method in TISSUE_METHODS: + # sort(traits, key=lambda A: math.fabs(A.tissue_corr)) + #elif self.method == METHOD_LIT: + # traits.sort(traits, key=lambda A: math.fabs(A.lit_corr)) + #else: + traits = sortTraitCorrelations(traits, self.method) + + # Strip to the top N correlations + traits = traits[:min(self.returnNumber, len(traits))] + + addLiteratureCorr = False + addTissueCorr = False + + trait_list = [] + for trait in traits: + db_trait = webqtlTrait(db=self.db, name=trait.name, cursor=self.cursor) + db_trait.retrieveInfo( QTL='Yes' ) + + db_trait.Name = trait.name + db_trait.corr = trait.correlation + db_trait.nOverlap = trait.overlap + db_trait.corrPValue = trait.p_value + + # NL, 07/19/2010 + # js function changed, add a new parameter rankOrder for js function 'showTissueCorrPlot' + db_trait.RANK_ORDER = self.RANK_ORDERS[self.method] + + #XZ, 26/09/2008: Method is 4 or 5. Have fetched tissue corr, but no literature correlation yet. + if self.method in TISSUE_METHODS: + db_trait.tissueCorr = trait.tissue_corr + db_trait.tissuePValue = trait.p_tissue + addTissueCorr = True + + + #XZ, 26/09/2008: Method is 3, Have fetched literature corr, but no tissue corr yet. + elif self.method == METHOD_LIT: + db_trait.LCorr = trait.lit_corr + db_trait.mouse_geneid = self.translateToMouseGeneID(self.species, db_trait.geneid) + addLiteratureCorr = True + + #XZ, 26/09/2008: Method is 1 or 2. Have NOT fetched literature corr and tissue corr yet. + # Phenotype data will not have geneid, and neither will some probes + # we need to handle this because we will get an attribute error + else: + if self.input_trait_mouse_gene_id and self.db.type=="ProbeSet": + addLiteratureCorr = True + if self.trait_symbol and self.db.type=="ProbeSet": + addTissueCorr = True + + trait_list.append(db_trait) + + if addLiteratureCorr: + trait_list = self.getLiteratureCorrelationByList(self.input_trait_mouse_gene_id, + self.species, trait_list) + if addTissueCorr: + trait_list = self.getTissueCorrelationByList( + primaryTraitSymbol = self.trait_symbol, + traitList = trait_list, + TissueProbeSetFreezeId = TISSUE_MOUSE_DB, + method=self.method) + + return trait_list def calculateCorrOfAllTissueTrait(self, primaryTraitSymbol=None, TissueProbeSetFreezeId=None, method=None): @@ -1283,10 +1391,10 @@ Resorting this table
symbolCorrDict = {} symbolPvalueDict = {} - primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TissueProbeSetFreezeId) + primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TISSUE_MOUSE_DB) primaryTraitValue = primaryTraitSymbolValueDict.values()[0] - SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[], TissueProbeSetFreezeId=TissueProbeSetFreezeId) + SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[], TissueProbeSetFreezeId=TISSUE_MOUSE_DB) if method in ["2","5"]: symbolCorrDict, symbolPvalueDict = correlationFunction.batchCalTissueCorr(primaryTraitValue,SymbolValueDict,method='spearman') @@ -1301,7 +1409,7 @@ Resorting this table
#XZ, 10/13/2010 def getTissueCorrelationByList(self, primaryTraitSymbol=None, traitList=None, TissueProbeSetFreezeId=None, method=None): - primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TissueProbeSetFreezeId) + primaryTraitSymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=[primaryTraitSymbol], TissueProbeSetFreezeId=TISSUE_MOUSE_DB) if primaryTraitSymbol.lower() in primaryTraitSymbolValueDict: primaryTraitValue = primaryTraitSymbolValueDict[primaryTraitSymbol.lower()] @@ -1312,7 +1420,7 @@ Resorting this table
if hasattr(thisTrait, 'symbol'): geneSymbolList.append(thisTrait.symbol) - SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=geneSymbolList, TissueProbeSetFreezeId=TissueProbeSetFreezeId) + SymbolValueDict = correlationFunction.getGeneSymbolTissueValueDictForTrait(cursor=self.cursor, GeneNameLst=geneSymbolList, TissueProbeSetFreezeId=TISSUE_MOUSE_DB) for thisTrait in traitList: if hasattr(thisTrait, 'symbol') and thisTrait.symbol and thisTrait.symbol.lower() in SymbolValueDict: @@ -1339,7 +1447,7 @@ Resorting this table
if myTrait: if method in ["1","2"]: #genetic correlation info = HT.Paragraph("Values of Record %s in the " % myTrait.getGivenName(), HT.Href(text=myTrait.db.fullname,url=webqtlConfig.INFOPAGEHREF % myTrait.db.name,target="_blank", Class="fwn"), - " database were compared to all %d records in the " % totalTraits, HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank", Class="fwn"), + " database were compared to all %d records in the " % self.record_count, HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank", Class="fwn"), ' database. The top %d correlations ranked by the %s are displayed.' % (returnNumber,methodDict[method]), ' You can resort this list using the small arrowheads in the top row.') else: @@ -1359,7 +1467,7 @@ Resorting this table
' You can resort this list using the small arrowheads in the top row.' ) elif identification: - info = HT.Paragraph('Values of %s were compared to all %d traits in ' % (identification, totalTraits), + info = HT.Paragraph('Values of %s were compared to all %d traits in ' % (identification, self.record_count), HT.Href(text=db.fullname,url=webqtlConfig.INFOPAGEHREF % target_db_name,target="_blank",Class="fwn"), ' database. The TOP %d correlations ranked by the %s are displayed.' % (returnNumber,methodDict[method]), ' You can resort this list using the small arrowheads in the top row.') @@ -1934,7 +2042,7 @@ Resorting this table
TCorr = thisTrait.tissueCorr TCorrStr = "%2.3f" % thisTrait.tissueCorr # NL, 07/19/2010: add a new parameter rankOrder for js function 'showTissueCorrPlot' - rankOrder = thisTrait.rankOrder + rankOrder = self.RANK_ORDERS[self.method] TCorrPlotURL = "javascript:showTissueCorrPlot('%s','%s','%s',%d)" %(formName, primaryTrait.symbol, thisTrait.symbol,rankOrder) tr.append(TDCell(HT.TD(HT.Href(text=TCorrStr, url=TCorrPlotURL, Class="fs12 fwn ff1"), Class="fs12 fwn ff1 b1 c222", align='right'), TCorrStr, abs(TCorr))) else: diff --git a/web/webqtl/showTrait/DataEditingPage.py b/web/webqtl/showTrait/DataEditingPage.py old mode 100644 new mode 100755 index f38b9880..974b2ed5 --- a/web/webqtl/showTrait/DataEditingPage.py +++ b/web/webqtl/showTrait/DataEditingPage.py @@ -416,13 +416,15 @@ class DataEditingPage(templatePage): UTHSC_BLAT_URL = "" if UCSC_BLAT_URL: - verifyButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % UCSC_BLAT_URL) - verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="addselect", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") + verifyButton = HT.Href(url="#") + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", + title=" Check probe locations at UCSC ", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL, style="border:none;") verifyButton.append(verifyButtonImg) verifyText = 'Verify' if UTHSC_BLAT_URL: - rnaseqButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) - rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="addselect", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButton = HT.Href(url="#") + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", + title=" View probes, SNPs, and RNA-seq at UTHSC ", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL, style="border:none;") rnaseqButton.append(rnaseqButtonImg) rnaseqText = 'RNA-seq' tSpan.append(HT.BR()) @@ -590,10 +592,24 @@ class DataEditingPage(templatePage): url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ % thisTrait.symbol,Class="fs14 fwn", \ title="Protein interactions: known and inferred"), style=linkStyle), " "*2) - if thisTrait.geneid: + if thisTrait.symbol: + #ZS: The "species scientific" converts the plain English species names we're using to their scientific names, which are needed for PANTHER's input + #We should probably use the scientific name along with the English name (if not instead of) elsewhere as well, given potential non-English speaking users + if _Species == "mouse": + species_scientific = "Mus%20musculus" + elif _Species == "rat": + species_scientific = "Rattus%20norvegicus" + elif _Species == "human": + species_scientific = "Homo%20sapiens" + elif _Species == "drosophila": + species_scientific = "Drosophila%20melanogaster" + else: + species_scientific = "all" + + species_scientific tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ - url="http://www.pantherdb.org/genes/gene.do?acc=%s" \ - % thisTrait.geneid,Class="fs14 fwn", \ + url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ + % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) else: pass @@ -755,11 +771,12 @@ class DataEditingPage(templatePage): UCSC_BLAT_URL = "" UTHSC_BLAT_URL = "" if UCSC_BLAT_URL: - verifyButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % UCSC_BLAT_URL) + #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) + verifyButton = HT.Href(url="#") verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="addselect", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") verifyButton.append(verifyButtonImg) verifyText = "Verify" - rnaseqButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) + rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="addselect", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") rnaseqButton.append(rnaseqButtonImg) rnaseqText = "RNA-seq" -- cgit v1.2.3 From 63297d5f4eb61541cb98dcbca668410f6550257a Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Fri, 1 Jun 2012 02:03:02 -0400 Subject: Views and templates modified to allow template analysis --- web/javascript/webqtl.js | 184 +++++++++++----------- wqflask/runserver.py | 6 + wqflask/wqflask/search_results.py | 6 +- wqflask/wqflask/templates/search_result_page.html | 5 +- wqflask/wqflask/views.py | 4 + 5 files changed, 111 insertions(+), 94 deletions(-) diff --git a/web/javascript/webqtl.js b/web/javascript/webqtl.js index 19ecf3b7..536e7d26 100755 --- a/web/javascript/webqtl.js +++ b/web/javascript/webqtl.js @@ -38,16 +38,16 @@ function makeTree(thisForm, nnn){ j += 1; } } - + var windowName = 'formTarget' + (new Date().getTime()); var newWindow = open("", windowName,"width=900,menubar=0,toolbar=1,resizable=1,status=1,scrollbars=1"); var html = ""; if (j > 0) - { + { var waithtml1 ="
Your list of "+j+" transcripts is being exported to the Gene Ontology Tree Machine for analysis. This window will soon be replaced with the main GOTM results.
"; } else - { + { var waithtml1 ="
Your should select at least one transcript to export to the Gene Ontology Tree Machine for analysis.
"; } html += waithtml1; @@ -152,7 +152,11 @@ function showDatabase3(formName, Database,ProbeSetID,CellID){ document[formName].database.value = Database; document[formName].ProbeSetID.value = ProbeSetID; document[formName].CellID.value = CellID; - document[formName].submit(); + console.log("formName:", formName) + console.log("document[formName]:", document[formName]) + console.log("submit turned off for debugging") + console.log("showDatabase3 is deprecated for the flask version of this site") + //document[formName].submit(); } @@ -188,10 +192,10 @@ function showTrait(fmName){ var thisForm = getForm(fmName); if (thisForm == null || showTrait.arguments.length < 2) return; - + windowName = genNewWin(); thisForm.target = windowName; - + thisForm.FormID.value = "showDatabase"; thisForm.ProbeSetID.value = showTrait.arguments[1]; if (showTrait.arguments.length > 2) @@ -205,10 +209,10 @@ function showCateGraph(fmName){ var thisForm = getForm(fmName); if (thisForm == null || showCateGraph.arguments.length < 2) return; - + windowName = genNewWin(); thisForm.target = windowName; - + thisForm.FormID.value = "showCategoryGraph"; thisForm.interval1.value = showCateGraph.arguments[1]; thisForm.interval2.value = showCateGraph.arguments[2]; @@ -219,22 +223,22 @@ function showCorrPlot(fmName){ var thisForm = getForm(fmName); if (thisForm == null || showCorrPlot.arguments.length < 2) return; - + windowName = genNewWin(); thisForm.target = windowName; - + thisForm.FormID.value = "showCorrelationPlot"; thisForm.ProbeSetID.value = showCorrPlot.arguments[1]; if (showCorrPlot.arguments.length > 2) thisForm.CellID.value = showCorrPlot.arguments[2]; else thisForm.CellID.value = ""; - + thisForm.X_geneSymbol.value = null; thisForm.Y_geneSymbol.value = null; thisForm.submit(); - + } @@ -242,12 +246,12 @@ function showCorrPlotThird(fmName){ var thisForm = getForm(fmName); if (thisForm == null || showCorrPlotThird.arguments.length < 3) return; - + windowName = genNewWin(); thisForm.target = windowName; - + var olddb = thisForm.database.value; - + thisForm.FormID.value = "showCorrelationPlot"; thisForm.database.value = showCorrPlotThird.arguments[1]; thisForm.ProbeSetID.value = showCorrPlotThird.arguments[2]; @@ -284,15 +288,15 @@ function ODE(thisForm, script){ var windowName = 'formTarget' + (new Date().getTime()); var newWindow = open("", windowName, "width=900,menubar=0,toolbar=1,resizable=1,status=1,scrollbars=1"); var html = ""; - if (j == 0){ + if (j == 0){ j = length; trait_list2 = trait_list_all; correlation2 = correlation_all; llid_list2 = llid_list_all; } - + var waithtml1 ="
Your list of "+j+" transcripts is being exported to the ODE for analysis. This window will soon be replaced with the results.
"; - + html += waithtml1; newWindow.document.write(html); newWindow.document.close(); @@ -302,14 +306,14 @@ function ODE(thisForm, script){ thisForm.correlation.value = correlation2.join(','); thisForm.id_value.value = thisForm.correlation.value; thisForm.llid_list.value = llid_list2.join(','); - + // ODE - + thisForm.idtype.value = thisForm.id_type.value; thisForm.species.value = thisForm.org.value; thisForm.list.value = thisForm.id_list.value; thisForm.client.value = "genenetwork"; - + thisForm.target = windowName; var oldaction = thisForm.action; thisForm.action = script; @@ -318,13 +322,13 @@ function ODE(thisForm, script){ } } */ -// 02/12/2009 +// 02/12/2009 // Lei Yan /*scripts in the Dataediting form*/ function dataEditingFunc(thisForm,submitIdValue){ - + windowName = 'formTarget' + (new Date().getTime()); if (thisForm.FormID.value!='secondRegression'){ @@ -336,7 +340,7 @@ function dataEditingFunc(thisForm,submitIdValue){ } else if (submitIdValue == "addRecord"){ - windowName = thisForm.RISet.value; + windowName = thisForm.RISet.value; var name = thisForm.identification.value; if (name != ""){ } @@ -352,7 +356,7 @@ function dataEditingFunc(thisForm,submitIdValue){ newWindow = open("",windowName,"menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=1,directories=1,width=900"); thisForm.target = windowName; - newWindow.focus(); + newWindow.focus(); thisForm.submitID.value = submitIdValue; thisForm.submit(); } @@ -394,7 +398,7 @@ function addRmvSelection(windowName, thisForm, addORrmv){ thisForm.target = windowName; thisForm.FormID.value = addORrmv; thisForm.submit(); - newWindow.focus(); + newWindow.focus(); } function batchSelection(thisForm){ @@ -424,7 +428,7 @@ function showTop10(formName, submitIdValue){ if ((submitIdValue == "markerRegression")||(submitIdValue == "compositeRegression")){ thisForm.topten.value = "topten"; } - + thisForm.submitID.value = submitIdValue; thisForm.submit(); } @@ -441,12 +445,12 @@ function showIndividualChromosome(formName, submitIdValue, ii){ } if (match == 0) return; - + windowName = 'formTarget' + (new Date().getTime()); newWindow = open("",windowName,"menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=1,directories=1,width=900"); newWindow.focus(); thisForm.target = windowName; - + if (submitIdValue == "showIntMap"){ thisForm.chromosomes.value = ii; } @@ -529,10 +533,10 @@ function dataWindow(form){ } -function xchange() { +function xchange() { var select = document.crossChoice.RISet; var value = select.options[select.selectedIndex].value; - + if (value !="BDAI") return; document.crossChoice.variance.checked = false; } @@ -580,97 +584,97 @@ function crossinfo2(){ function checkWidth(){ var width = document.getElementsByName('plotSize')[0].value - + if (width < 600) { alert("Plot size is too small - setting size to 600") document.getElementsByName('plotSize')[0].value = 600 - } + } } function changeLineColor(){ var lineColor = document.getElementsByName('lineColorSel')[0].value - + document.getElementsByName('lineColor')[0].value = lineColor } function changeLineSize(){ var lineSize = document.getElementsByName('lineSizeSel')[0].value - + document.getElementsByName('lineSize')[0].value = lineSize } function changeIdColor(){ var idColor = document.getElementsByName('idColorSel')[0].value - + document.getElementsByName('idColor')[0].value = idColor } function changeIdFont(){ var idFont = document.getElementsByName('idFontSel')[0].value - + document.getElementsByName('idFont')[0].value = idFont } function changeIdSize(){ var idSize = document.getElementsByName('idSizeSel')[0].value - + document.getElementsByName('idSize')[0].value = idSize } function changeSymbolColor(){ var symbolColor = document.getElementsByName('colorSel')[0].value - + document.getElementsByName('symbolColor')[0].value = symbolColor } function changeSymbol(){ var symbol = document.getElementsByName('symbolSel')[0].value - + document.getElementsByName('symbol')[0].value = symbol } function changeFilled(){ var filled = document.getElementsByName('fillSel')[0].value - + document.getElementsByName('filled')[0].value = filled } function changeSize(){ var symbolSize = document.getElementsByName('sizeSel')[0].value - + document.getElementsByName('symbolSize')[0].value = symbolSize } -function checkAll(thisForm){ +function checkAll(thisForm){ var length = thisForm.searchResult.length; for(var i = 0; i < length; i++) { thisForm.searchResult[i].checked = true; highlight(thisForm.searchResult[i]); } -} +} -function checkNone(thisForm){ +function checkNone(thisForm){ var length = thisForm.searchResult.length; for(var i = 0; i < length; i++) { thisForm.searchResult[i].checked = false; highlight(thisForm.searchResult[i]); } -} +} -function checkInvert(thisForm){ +function checkInvert(thisForm){ var length = thisForm.searchResult.length; for(var i = 0; i < length; i++) { thisForm.searchResult[i].checked = !(thisForm.searchResult[i].checked); highlight(thisForm.searchResult[i]); } -} +} /*Not used anymore*/ -function checkTraits2(thisForm){ +function checkTraits2(thisForm){ var length = thisForm.searchResult.length; var category = thisForm.selectmenu.value; for(var i = 0; i < length; i++) @@ -720,18 +724,18 @@ function checkTraits2(thisForm){ else {} } -} +} function checkNumeric(field,limit,resetvalue,compares,fdname) { - pattern = /^-?[0-9]*\.?[0-9]*$/; + pattern = /^-?[0-9]*\.?[0-9]*$/; if(pattern.test(field.value)==false) { alert("Not numeric in " + fdname); field.value = resetvalue; } - else + else { if (compares == 'gthan') { if(field.value > limit) @@ -748,7 +752,7 @@ function checkNumeric(field,limit,resetvalue,compares,fdname) } } -function checkTraits(thisForm){ +function checkTraits(thisForm){ var length = thisForm.searchResult.length; var andor = thisForm.selectandor.value; var gthan = parseFloat(thisForm.selectgt.value); @@ -780,7 +784,7 @@ function checkTraits(thisForm){ } -function checkPM(thisForm){ +function checkPM(thisForm){ var length = thisForm.searchResult.length; for(var i = 0; i < length; i++) { @@ -792,8 +796,8 @@ function checkPM(thisForm){ {thisForm.searchResult[i].checked = false;} highlight(thisForm.searchResult[i]); } -} -function checkMM(thisForm){ +} +function checkMM(thisForm){ var length = thisForm.searchResult.length; for(var i = 0; i < length; i++) { @@ -804,14 +808,14 @@ function checkMM(thisForm){ {thisForm.searchResult[i].checked = false;} highlight(thisForm.searchResult[i]); } -} +} -function directPermuAlert(thisForm){ - if (thisForm.directPermuCheckbox.checked){ - alert("Interaction permutation will take long time to compute.\n Check this box only when necessary."); +function directPermuAlert(thisForm){ + if (thisForm.directPermuCheckbox.checked){ + alert("Interaction permutation will take long time to compute.\n Check this box only when necessary."); } -} +} function cliqueDatabase(pid){ var windowName = 'clique'; @@ -869,7 +873,7 @@ function snpbrowser_function_refresh() { for (var i=1; i - {{ thisTrait.name.upper() }} + - + + {{ thisTrait.name.upper() }} + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 88a6f6a1..b128f425 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -17,3 +17,7 @@ def index_page(): def search(): the_search = search_results.SearchResultPage(request.args) return render_template("search_result_page.html", **the_search.__dict__) + +@app.route("/showDatabaseBXD") +def showDatabaseBXD(): + return None -- cgit v1.2.3 From e03be38427b6fcb64a567e345c96fc2a6ee99d60 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 1 Jun 2012 15:03:29 -0500 Subject: added scrollable tab areas for the updated basic statistics output --- .../basicStatistics/updatedBasicStatisticsPage.py | 54 +++++++++++----------- web/webqtl/showTrait/DataEditingPage.py | 22 ++++----- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py b/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py index 156dafe7..ab7ed07d 100755 --- a/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py +++ b/web/webqtl/basicStatistics/updatedBasicStatisticsPage.py @@ -63,9 +63,9 @@ class updatedBasicStatisticsPage(templatePage): thisValFull = [strain_names[i], this_strain_val, this_strain_var] vals.append(thisValFull) - stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"), + stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-2", Class="stats_tab"), HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), - HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")] + HT.Href(text="Box Plot", url="#statstabs-5", Class="stats_tab")] stats_tabs = HT.List(stats_tab_list) stats_container = HT.Div(id="stats_tabs", Class="ui-tabs") @@ -73,7 +73,7 @@ class updatedBasicStatisticsPage(templatePage): stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" #Javascript enabling tabs - table_div = HT.Div(id="statstabs-1") + table_div = HT.Div(id="statstabs-1", style="height:320px;width:740px;overflow:scroll;") table_container = HT.Paragraph() statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") @@ -86,16 +86,21 @@ class updatedBasicStatisticsPage(templatePage): table_div.append(table_container) stats_container.append(table_div) - boxplot_div = HT.Div(id="statstabs-2") - boxplot_container = HT.Paragraph() - boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) - boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) - boxplot_container.append(boxplot) - boxplot_div.append(boxplot_container) - stats_container.append(boxplot_div) + normalplot_div = HT.Div(id="statstabs-2", style="height:540px;width:740px;overflow:scroll;") + normalplot_container = HT.Paragraph() + normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + plotTitle = fd.formdata.getvalue("normalPlotTitle","") + normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + normalplot.append(HT.TR(HT.TD(normalplot_img))) + normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + normalplot_container.append(normalplot) + normalplot_div.append(normalplot_container) + stats_container.append(normalplot_div) - barName_div = HT.Div(id="statstabs-3") + barName_div = HT.Div(id="statstabs-3", style="height:540px;width:740px;overflow:scroll;") barName_container = HT.Paragraph() barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") @@ -104,7 +109,7 @@ class updatedBasicStatisticsPage(templatePage): barName_div.append(barName_container) stats_container.append(barName_div) - barRank_div = HT.Div(id="statstabs-4") + barRank_div = HT.Div(id="statstabs-4", style="height:540px;width:740px;overflow:scroll;") barRank_container = HT.Paragraph() barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") @@ -112,20 +117,15 @@ class updatedBasicStatisticsPage(templatePage): barRank_container.append(barRank) barRank_div.append(barRank_container) stats_container.append(barRank_div) - - normalplot_div = HT.Div(id="statstabs-5") - normalplot_container = HT.Paragraph() - normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - plotTitle = fd.formdata.getvalue("normalPlotTitle","") - normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) - normalplot.append(HT.TR(HT.TD(normalplot_img))) - normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ - normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), - "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", - target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) - normalplot_container.append(normalplot) - normalplot_div.append(normalplot_container) - stats_container.append(normalplot_div) + + boxplot_div = HT.Div(id="statstabs-5", style="height:540px;width:740px;overflow:scroll;") + boxplot_container = HT.Paragraph() + boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + boxplot_container.append(boxplot) + boxplot_div.append(boxplot_container) + stats_container.append(boxplot_div) stats_cell.append(stats_container) stats_script.append(stats_script_text) diff --git a/web/webqtl/showTrait/DataEditingPage.py b/web/webqtl/showTrait/DataEditingPage.py index 974b2ed5..c240d8a0 100755 --- a/web/webqtl/showTrait/DataEditingPage.py +++ b/web/webqtl/showTrait/DataEditingPage.py @@ -280,13 +280,13 @@ class DataEditingPage(templatePage): if snpurl: snpBrowserButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % snpurl) - snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="addselect", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") + snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="snpbrowser", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") snpBrowserButton.append(snpBrowserButton_img) snpBrowserText = "SNPs" #XZ: Show GeneWiki for all species geneWikiButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % thisTrait.symbol)) - geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="addselect", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") + geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="genewiki", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") geneWikiButton.append(geneWikiButton_img) geneWikiText = 'GeneWiki' @@ -295,7 +295,7 @@ class DataEditingPage(templatePage): if _Species in ("mouse", "rat", "human"): similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) - similarButton_img = HT.Image("/images/find_icon.jpg", name="addselect", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") + similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") similarButton.append(similarButton_img) similarText = "Find" else: @@ -416,15 +416,15 @@ class DataEditingPage(templatePage): UTHSC_BLAT_URL = "" if UCSC_BLAT_URL: - verifyButton = HT.Href(url="#") + verifyButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL) verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", - title=" Check probe locations at UCSC ", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL, style="border:none;") + title=" Check probe locations at UCSC ", style="border:none;") verifyButton.append(verifyButtonImg) verifyText = 'Verify' if UTHSC_BLAT_URL: - rnaseqButton = HT.Href(url="#") + rnaseqButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL) rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", - title=" View probes, SNPs, and RNA-seq at UTHSC ", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL, style="border:none;") + title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") rnaseqButton.append(rnaseqButtonImg) rnaseqText = 'RNA-seq' tSpan.append(HT.BR()) @@ -444,8 +444,8 @@ class DataEditingPage(templatePage): if probeResult[0] > 0: probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&RISet=%s&incparentsf1=ON" \ % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.db, thisTrait.name, thisTrait.cellid, fd.RISet) - probeButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % probeurl) - probeButton_img = HT.Image("/images/probe_icon.jpg", name="addselect", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") + probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) + probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") probeButton.append(probeButton_img) probeText = "Probes" @@ -773,11 +773,11 @@ class DataEditingPage(templatePage): if UCSC_BLAT_URL: #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) verifyButton = HT.Href(url="#") - verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="addselect", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") verifyButton.append(verifyButtonImg) verifyText = "Verify" rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) - rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="addselect", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") rnaseqButton.append(rnaseqButtonImg) rnaseqText = "RNA-seq" -- cgit v1.2.3 From d75bdd01bc43c8db62dc38af52fa4d811d408645 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 01:28:39 -0400 Subject: Changes before attempting merge --- wqflask/wqflask/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index b128f425..3e1c2729 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -20,4 +20,4 @@ def search(): @app.route("/showDatabaseBXD") def showDatabaseBXD(): - return None + return render_template("trait_data_and_analysis.html") -- cgit v1.2.3 From 6d84254834930be914d9174528f687a1976a9e34 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 02:11:49 -0400 Subject: Added .orig extension to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5767fde7..dbbb76f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # gitignore *.pyc +*.orig -- cgit v1.2.3 From 3de34936fcbdc5f252dcacdf4e0da63a7714436a Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 03:21:01 -0400 Subject: Adding in show trait files --- .../wqflask/templates/trait_data_and_analysis.html | 6267 ++++++++++++++++---- 1 file changed, 5008 insertions(+), 1259 deletions(-) diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 0e91b474..1325e4b0 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -1,1259 +1,5008 @@ -{% extends "base.html" %} -{% block title %}Trait Data and Analysis{% endblock %} -{% block content %} - - - - - - - - -

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Trait Data and Analysis  for Record ID 1441186_at

  Details and Links

Gene Symbol: Sall3
Aliases: B130022O04Rik, Msal, Msal-1, Sal, Salt, Spalt
Description: sal-like 3 (Drosophila)
Location: Chr 18 @ 81.163175 Mb on the minus strand
Target Score: BLAT specificity: 12.0   Score: 240  
Species and Group: Mouse, BXD
Database: Hippocampus Consortium M430v2 (Jun06) PDNN
Resource Links: Gene  UniGene  GenBank  HomoloGene  
UCSC  BioGPS  STRING  PANTHER  Gemma  SynDB  ABA  

Add To Collection Find similar expression data  Check probe locations at UCSC  Write or review comments about this gene  View SNPs and Indels  View probes, SNPs, and RNA-seq at UTHSC  Check sequence of probes
AddFindVerifyGeneWikiSNPsRNA-seqProbes

  Basic Statistics

Include: -

-

-

StatisticValue
N of Samples99
Mean6.129
Median6.105
Standard Error (SE)0.018
Standard Deviation (SD)0.182
Minimum5.782
Maximum6.579
Range (log2)0.797
Range (fold)1.74
Interquartile Range1.18

nP_OE9u7BSx.gif


This plot evaluates whether data are normally distributed. Different symbols represent different groups.

More about Normal Probability Plots and more about interpreting these plots from the glossary

Box_gUFtEOVI.gif -

-More about Box Plots

Bar_y7L2rYlL.gif

Bar_1Z4GjYFq.gif

-

StatisticValue
N of Samples71
Mean6.109
Median6.084
Standard Error (SE)0.022
Standard Deviation (SD)0.187
Minimum5.782
Maximum6.579
Range (log2)0.797
Range (fold)1.74
Interquartile Range1.13

nP_eSYO7ZQg.gif


This plot evaluates whether data are normally distributed. Different symbols represent different groups.

More about Normal Probability Plots and more about interpreting these plots from the glossary

Box_PWNWQMfj.gif -

-More about Box Plots

Bar_VuPqYbR6.gif

Bar_9PbdvXZ9.gif

-

StatisticValue
N of Samples32
Mean6.176
Median6.170
Standard Error (SE)0.027
Standard Deviation (SD)0.150
Minimum5.906
Maximum6.485
Range (log2)0.579
Range (fold)1.49
Interquartile Range1.15

nP_swDAFlJy.gif


This plot evaluates whether data are normally distributed. Different symbols represent different groups.

More about Normal Probability Plots and more about interpreting these plots from the glossary

Box_6sQJ8xhK.gif -

-More about Box Plots

Bar_QMWE2VEp.gif

Bar_X07QmgsX.gif

  Calculate Correlations

-
-
Database: -
Return: -
Samples: -

Pearson -   Spearman Rank -

-

The Sample Correlation is computed between trait data and any
other traits in the sample database selected above. Use Spearman Rank
when the sample size is small (<20) or when there are influential outliers.
-
Database: -
Return: -
Samples: -

-

The Literature Correlation (Lit r) between this gene and all other genes is computed
using the Semantic Gene Organizer and human, rat, and mouse data from PubMed.
Values are ranked by Lit r, but Sample r and Tissue r are also displayed.

More on using Lit r
-
Database: -
Return: -
Samples: -

Pearson -   Spearman Rank -

-

The Tissue Correlation (Tissue r) estimates the similarity of expression of two genes
or transcripts across different cells, tissues, or organs (glossary). Tissue correlations
are generated by analyzing expression in multiple samples usually taken from single cases.
Pearson and Spearman Rank correlations have been computed for all pairs of genes
using data from mouse samples.

  Mapping Tools

-
Chromosome: -
Mapping Scale: -

-Permutation Test (n=2000)
-Bootstrap Test (n=2000)
-Use Parents
-Use Weighted

-

Interval Mapping computes linkage maps for the entire genome or single
chromosomes. The Permutation Test estimates suggestive and significant
linkage scores. The Bootstrap Test estimates the precision of the QTL location.

Display LRS greater than: -
- Display all LRS
- Use Parents
- Use Weighted

-

Marker regression computes and displays LRS values for individual markers.
This function also lists additive effects (phenotype units per allele) and
dominance deviations for some datasets.

Chromosome: -
Mapping Scale: -
Control Locus: -

-Permutation Test (n=2000)
-Bootstrap Test (n=2000)
-Use Parents

-

Composite Interval Mapping allows you to control for a single marker as
a cofactor. To find a control marker, run the Marker Regression function.

Sort by: -
Return: -

-Permutation Test (n=500)

-

Pair-Scan searches for pairs of chromosomal regions that are
involved in two-locus epistatic interactions.

  Review and Edit Data

Edit or delete values in the Trait Data boxes, and use the Reset option as needed.

  Block samples by index:     -    -    -
  Options:      -      -      -      -


  Outliers highlighted in  yellow  can be hidden using the Hide Outliers button,
  and samples with no value (x) can be hidden by clicking Hide No Value .


IndexSampleValue SE
1 -B6D2F1 -± -
2 -D2B6F1 -± -
3 -C57BL/6J -± -
4 -DBA/2J -± -
5 -BXD1 -± -
6 -BXD2 -± -
7 -BXD5 -± -
8 -BXD6 -± -
9 -BXD8 -± -
10 -BXD9 -± -
11 -BXD11 -± -
12 -BXD12 -± -
13 -BXD13 -± -
14 -BXD14 -± -
15 -BXD15 -± -
16 -BXD16 -± -
17 -BXD18 -± -
18 -BXD19 -± -
19 -BXD20 -± -
20 -BXD21 -± -
21 -BXD22 -± -
22 -BXD23 -± -
23 -BXD24a -± -
24 -BXD24 -± -
25 -BXD25 -± -
26 -BXD27 -± -
27 -BXD28 -± -
28 -BXD29 -± -
29 -BXD30 -± -
30 -BXD31 -± -
31 -BXD32 -± -
32 -BXD33 -± -
33 -BXD34 -± -
34 -BXD35 -± -
35 -BXD36 -± -
36 -BXD37 -± -
37 -BXD38 -± -
38 -BXD39 -± -
39 -BXD40 -± -
40 -BXD41 -± -
41 -BXD42 -± -
42 -BXD43 -± -
43 -BXD44 -± -
44 -BXD45 -± -
45 -BXD48 -± -
46 -BXD49 -± -
47 -BXD50 -± -
48 -BXD51 -± -
49 -BXD52 -± -
50 -BXD53 -± -
51 -BXD54 -± -
52 -BXD55 -± -
53 -BXD56 -± -
54 -BXD59 -± -
55 -BXD60 -± -
56 -BXD61 -± -
57 -BXD62 -± -
58 -BXD63 -± -
59 -BXD64 -± -
60 -BXD65 -± -
61 -BXD66 -± -
62 -BXD67 -± -
63 -BXD68 -± -
64 -BXD69 -± -
65 -BXD70 -± -
66 -BXD71 -± -
67 -BXD72 -± -
68 -BXD73 -± -
69 -BXD74 -± -
70 -BXD75 -± -
71 -BXD76 -± -
72 -BXD77 -± -
73 -BXD78 -± -
74 -BXD79 -± -
75 -BXD80 -± -
76 -BXD81 -± -
77 -BXD83 -± -
78 -BXD84 -± -
79 -BXD85 -± -
80 -BXD86 -± -
81 -BXD87 -± -
82 -BXD88 -± -
83 -BXD89 -± -
84 -BXD90 -± -
85 -BXD91 -± -
86 -BXD92 -± -
87 -BXD93 -± -
88 -BXD94 -± -
89 -BXD95 -± -
90 -BXD96 -± -
91 -BXD97 -± -
92 -BXD98 -± -
93 -BXD99 -± -
94 -BXD100 -± -
95 -BXD101 -± -
96 -BXD102 -± -
97 -BXD103 -± -
 
IndexSampleValue SE
1 -B6D2F1 -± -
2 -D2B6F1 -± -
3 -C57BL/6J -± -
4 -DBA/2J -± -
5 -129S1/SvImJ -± -
6 -A/J -± -
7 -AKR/J -± -
8 -BALB/cByJ -± -
9 -BALB/cJ -± -
10 -C3H/HeJ -± -
11 -C57BL/6ByJ -± -
12 -CAST/EiJ -± -
13 -CXB1 -± -
14 -CXB10 -± -
15 -CXB11 -± -
16 -CXB12 -± -
17 -CXB13 -± -
18 -CXB2 -± -
19 -CXB3 -± -
20 -CXB4 -± -
21 -CXB5 -± -
22 -CXB6 -± -
23 -CXB7 -± -
24 -CXB8 -± -
25 -CXB9 -± -
26 -KK/HlJ -± -
27 -LG/J -± -
28 -NOD/ShiLtJ -± -
29 -NZO/HlLtJ -± -
30 -PWD/PhJ -± -
31 -PWK/PhJ -± -
32 -WSB/EiJ -± -

- -
-

- - - - - -{% endblock %} + + {% extends "base.html" %} + {% block title %}Trait Data and Analysis{% endblock %} + {% block content %} + + + + + + + +
+
+ + + + + + + + +
+
+ Trait Data and Analysis  for Record ID 1441186_at +
+
+ +

  Details and Links

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Gene Symbol:Sall3
Aliases:B130022O04Rik, Msal, Msal-1, Sal, Salt, Spalt
Description:sal-like 3 (Drosophila)
Location:Chr 18 @ 81.163175 Mb on the minus strand
Target Score:BLAT specificity: 12.0   Score: 240  
Species and Group:Mouse, BXD
Database:Hippocampus Consortium M430v2 (Jun06) + PDNN
Resource Links:Gene  UniGene  GenBank  HomoloGene  
UCSC  BioGPS  STRING  PANTHER  Gemma  SynDB  ABA  

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
++ +  Check probe locations at UCSC  Write or review comments about this gene +  View SNPs and Indels +  View probes, SNPs, and RNA-seq at UTHSC +  Check sequence of probes
AddFindVerifyGeneWikiSNPsRNA-seqProbes
+ +

  Basic Statistics

+ +

Include:
+
+
+
+ + + + + + +
+
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StatisticValue
N of Samples99
Mean6.129
Median6.105
Standard Error (SE)0.018
Standard Deviation (SD)0.182
Minimum5.782
Maximum6.579
Range (log2)0.797
Range (fold)1.74
Interquartile Range1.18
+
+
+ +
+ + + + + + + + +
nP_OE9u7BSx.gif

+
+ This plot evaluates whether data are normally distributed. Different symbols represent different groups.
+
+ More about Normal Probability Plots and more + about interpreting these plots from the glossary
+
+ +
+ + + + +
+ Box_gUFtEOVI.gif + +

More about Box Plots

+
+
+ +
+ + + + +
Bar_y7L2rYlL.gif
+
+ +
+ + + + +
Bar_1Z4GjYFq.gif
+
+
+ +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StatisticValue
N of Samples71
Mean6.109
Median6.084
Standard Error (SE)0.022
Standard Deviation (SD)0.187
Minimum5.782
Maximum6.579
Range (log2)0.797
Range (fold)1.74
Interquartile Range1.13
+
+
+ +
+ + + + + + + + +
nP_eSYO7ZQg.gif

+
+ This plot evaluates whether data are normally distributed. Different symbols represent different groups.
+
+ More about Normal Probability Plots and more + about interpreting these plots from the glossary
+
+ +
+ + + + +
+ Box_PWNWQMfj.gif + +

More about Box Plots

+
+
+ +
+ + + + +
Bar_VuPqYbR6.gif
+
+ +
+ + + + +
Bar_9PbdvXZ9.gif
+
+
+ +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StatisticValue
N of Samples32
Mean6.176
Median6.170
Standard Error (SE)0.027
Standard Deviation (SD)0.150
Minimum5.906
Maximum6.485
Range (log2)0.579
Range (fold)1.49
Interquartile Range1.15
+
+
+ +
+ + + + + + + + +
nP_swDAFlJy.gif

+
+ This plot evaluates whether data are normally distributed. Different symbols represent different groups.
+
+ More about Normal Probability Plots and more + about interpreting these plots from the glossary
+
+ +
+ + + + +
+ Box_6sQJ8xhK.gif + +

More about Box Plots

+
+
+ +
+ + + + +
Bar_QMWE2VEp.gif
+
+ +
+ + + + +
Bar_X07QmgsX.gif
+
+
+
+ +

  Calculate Correlations

+ +

+ + + + + +
+
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + +
Database:
Return:
Samples:

+ Pearson    Spearman Rank
+
+
+
+ The Sample Correlation is computed + between trait data and any
+ other traits in the sample database selected above. Use Spearman + Rank
+ when the sample size is small (<20) or when there are influential outliers.
+
+
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + +
Database:
Return:
Samples:

+
+
+ The Literature Correlation (Lit r) between this + gene and all other genes is computed
+ using the Semantic Gene Organizer and human, rat, and + mouse data from PubMed.
+ Values are ranked by Lit r, but Sample r and Tissue r are also displayed.
+
+ More on using Lit r
+
+
+ +
+ + + + +
+ + + + + + + + + + + + + + + + + + + + +
Database:
Return:
Samples:

+ Pearson    Spearman Rank
+
+
+
+ The Tissue Correlation (Tissue r) + estimates the similarity of expression of two genes
+ or transcripts across different cells, tissues, or organs (glossary). Tissue correlations
+ are generated by analyzing expression in multiple samples usually taken from single cases.
+ Pearson and Spearman Rank correlations have been computed for all pairs of genes
+ using data from mouse samples.
+
+
+
+
+ +

  Mapping Tools

+ +

+ + + + + +
+
+ + +
+ + + + + + + + +
+ + + + + + + + + + + + +
Chromosome:
Mapping Scale:

+ Permutation Test (n=2000)
+ Bootstrap Test (n=2000)
+ Use Parents
+ Use Weighted
+
+
+
+
Interval Mapping computes linkage maps + for the entire genome or single
+ chromosomes. The Permutation Test estimates suggestive and + significant
+ linkage scores. The Bootstrap Test estimates the precision of the QTL + location.

+
+ +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Display LRS greater than:
Display all LRS
Use Parents
Use Weighted

+
+
+
Marker regression computes and displays LRS + values for individual markers.
+ This function also lists additive effects (phenotype units per allele) and
+ dominance deviations for some datasets.

+
+ +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + +
Chromosome:
Mapping Scale:
Control Locus:

+ Permutation Test (n=2000)
+ Bootstrap Test (n=2000)
+ Use Parents
+
+
+
+
Composite Interval Mapping allows you to control + for a single marker as
+ a cofactor. To find a control marker, run the Marker Regression function.

+
+ +
+ + + + + + + + +
+ + + + + + + + + + + + +
Sort by:
Return:

+ Permutation Test + (n=500)
+
+
+
+
Pair-Scan searches for pairs of chromosomal regions + that are
+ involved in two-locus epistatic interactions.

+
+
+
+ +

  Review and Edit Data

+ +

+ + + + + +
+
+

Edit or delete values in the Trait Data boxes, and use the Reset option as + needed.

+ +
+   Block samples by index:     +        
+   Options:                       

+
+   Outliers highlighted in  yellow  can be hidden using + the Hide Outliers button,
+   and samples with no value (x) can be hidden by clicking Hide No Value .

+

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IndexSampleValue SE
1 B6D2F1±
2 D2B6F1±
3 C57BL/6J±
4 DBA/2J±
5 BXD1±
6 BXD2±
7 BXD5±
8 BXD6±
9 BXD8±
10 BXD9±
11 BXD11±
12 BXD12±
13 BXD13±
14 BXD14±
15 BXD15±
16 BXD16±
17 BXD18±
18 BXD19±
19 BXD20±
20 BXD21±
21 BXD22±
22 BXD23±
23 BXD24a±
24 BXD24±
25 BXD25±
26 BXD27±
27 BXD28±
28 BXD29±
29 BXD30±
30 BXD31±
31 BXD32±
32 BXD33±
33 BXD34±
34 BXD35±
35 BXD36±
36 BXD37±
37 BXD38±
38 BXD39±
39 BXD40±
40 BXD41±
41 BXD42±
42 BXD43±
43 BXD44±
44 BXD45±
45 BXD48±
46 BXD49±
47 BXD50±
48 BXD51±
49 BXD52±
50 BXD53±
51 BXD54±
52 BXD55±
53 BXD56±
54 BXD59±
55 BXD60±
56 BXD61±
57 BXD62±
58 BXD63±
59 BXD64±
60 BXD65±
61 BXD66±
62 BXD67±
63 BXD68±
64 BXD69±
65 BXD70±
66 BXD71±
67 BXD72±
68 BXD73±
69 BXD74±
70 BXD75±
71 BXD76±
72 BXD77±
73 BXD78±
74 BXD79±
75 BXD80±
76 BXD81±
77 BXD83±
78 BXD84±
79 BXD85±
80 BXD86±
81 BXD87±
82 BXD88±
83 BXD89±
84 BXD90±
85 BXD91±
86 BXD92±
87 BXD93±
88 BXD94±
89 BXD95±
90 BXD96±
91 BXD97±
92 BXD98±
93 BXD99±
94 BXD100±
95 BXD101±
96 BXD102±
97 BXD103±
+
+ +
+   +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IndexSampleValue SE
1 B6D2F1±
2 D2B6F1±
3 C57BL/6J±
4 DBA/2J±
5 129S1/SvImJ±
6 A/J±
7 AKR/J±
8 BALB/cByJ±
9 BALB/cJ±
10 C3H/HeJ±
11 C57BL/6ByJ±
12 CAST/EiJ±
13 CXB1±
14 CXB10±
15 CXB11±
16 CXB12±
17 CXB13±
18 CXB2±
19 CXB3±
20 CXB4±
21 CXB5±
22 CXB6±
23 CXB7±
24 CXB8±
25 CXB9±
26 KK/HlJ±
27 LG/J±
28 NOD/ShiLtJ±
29 NZO/HlLtJ±
30 PWD/PhJ±
31 PWK/PhJ±
32 WSB/EiJ±
+
+
+
+
+
+ + + {% endblock %} + -- cgit v1.2.3 From 50a1242c3ba087b6b4e6e64375ea6690339edf34 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 03:21:24 -0400 Subject: Adding in show trait files (this time for real) --- wqflask/wqflask/show_trait/ShowTraitPage.py | 170 ++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 wqflask/wqflask/show_trait/ShowTraitPage.py diff --git a/wqflask/wqflask/show_trait/ShowTraitPage.py b/wqflask/wqflask/show_trait/ShowTraitPage.py new file mode 100644 index 00000000..82511228 --- /dev/null +++ b/wqflask/wqflask/show_trait/ShowTraitPage.py @@ -0,0 +1,170 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig +from utility import webqtlUtil +from base.webqtlTrait import webqtlTrait +from base.templatePage import templatePage +from DataEditingPage import DataEditingPage + + + +class ShowTraitPage(DataEditingPage): + + def __init__(self, fd, traitInfos = []): + + templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + if traitInfos: + database,ProbeSetID,CellID = traitInfos + else: + database = fd.formdata.getfirst('database') + ProbeSetID = fd.formdata.getfirst('ProbeSetID') + CellID = fd.formdata.getfirst('CellID') + try: + thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) + except: + heading = "Trait Data and Analysis Form" + detail = ["The trait isn't available currently."] + self.error(heading=heading,detail=detail,error="Error") + return + + if thisTrait.db.type == "ProbeSet": + + self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers + FROM ProbeSetFreeze WHERE Name = "%s"''' % database) + + indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] + + if confidential == 1: + access_to_confidential_dataset = 0 + + #for the dataset that confidentiality is 1 + #1. 'admin' and 'root' can see all of the dataset + #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: + access_to_confidential_dataset = 1 + else: + AuthorisedUsersList=AuthorisedUsers.split(',') + if AuthorisedUsersList.__contains__(self.userName): + access_to_confidential_dataset = 1 + + if not access_to_confidential_dataset: + #Error, Confidential Database + heading = "Show Database" + detail = ["The %s database you selected is not open to the public \ + at this time, please go back and select other database." % indFullName] + self.error(heading=heading,detail=detail,error="Confidential Database") + return + + user_ip = fd.remote_ip + query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ + UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" + self.cursor.execute(query,user_ip) + daycount = self.cursor.fetchall() + if daycount: + daycount = daycount[0][0] + if daycount > webqtlConfig.DAILYMAXIMUM: + heading = "Retrieve Data" + detail = ['For security reasons, the maximum access to a database is \ + %d times per day per ip address. You have reached the limit, please \ + try it again tomorrow.' % webqtlConfig.DAILYMAXIMUM] + self.error(heading=heading,detail=detail) + return + else: + pass + else: + pass + + if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: + heading = "Retrieve Data" + detail = ['The Record you requested doesn\'t exist!'] + self.error(heading=heading,detail=detail) + return + + #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore + # check if animal information are available + """ + self.cursor.execute(''' + SELECT + SampleXRef.ProbeFreezeId + FROM + SampleXRef, ProbeSetFreeze + WHERE + SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % thisTrait.db.name) + + sampleId = self.cursor.fetchall() + if sampleId: + thisTrait.strainInfo = 1 + else: + thisTrait.strainInfo = None + """ + + ##identification, etc. + fd.identification = '%s : %s'%(thisTrait.db.shortname,ProbeSetID) + thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ + &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database,ProbeSetID,fd.RISet) + + if CellID: + fd.identification = '%s/%s'%(fd.identification, CellID) + thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) + + #retrieve trait information + try: + thisTrait.retrieveInfo() + thisTrait.retrieveData() + self.updMysql() + self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)" ,user_ip) + self.openMysql() + except: + heading = "Retrieve Data" + detail = ["The information you requested is not avaiable at this time."] + self.error(heading=heading,detail=detail) + return + + ##read genotype file + fd.RISet = thisTrait.riset + fd.readGenotype() + + if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): + fd.displayVariance = 1 + fd.varianceDispName = 'SE' + fd.formID = 'varianceChoice' + + self.dict['body']= thisTrait + DataEditingPage.__init__(self, fd, thisTrait) + self.dict['title'] = '%s: Display Trait' % fd.identification + + -- cgit v1.2.3 From f7c2c6ff903f835ddef2daffa368ae1aa26e136a Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 03:21:57 -0400 Subject: Renamed file --- wqflask/wqflask/show_trait/ShowTraitPage.py | 170 -------------------------- wqflask/wqflask/show_trait/show_trait_page.py | 170 ++++++++++++++++++++++++++ 2 files changed, 170 insertions(+), 170 deletions(-) delete mode 100644 wqflask/wqflask/show_trait/ShowTraitPage.py create mode 100644 wqflask/wqflask/show_trait/show_trait_page.py diff --git a/wqflask/wqflask/show_trait/ShowTraitPage.py b/wqflask/wqflask/show_trait/ShowTraitPage.py deleted file mode 100644 index 82511228..00000000 --- a/wqflask/wqflask/show_trait/ShowTraitPage.py +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from htmlgen import HTMLgen2 as HT - -from base import webqtlConfig -from utility import webqtlUtil -from base.webqtlTrait import webqtlTrait -from base.templatePage import templatePage -from DataEditingPage import DataEditingPage - - - -class ShowTraitPage(DataEditingPage): - - def __init__(self, fd, traitInfos = []): - - templatePage.__init__(self, fd) - - if not self.openMysql(): - return - - TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - - if traitInfos: - database,ProbeSetID,CellID = traitInfos - else: - database = fd.formdata.getfirst('database') - ProbeSetID = fd.formdata.getfirst('ProbeSetID') - CellID = fd.formdata.getfirst('CellID') - try: - thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) - except: - heading = "Trait Data and Analysis Form" - detail = ["The trait isn't available currently."] - self.error(heading=heading,detail=detail,error="Error") - return - - if thisTrait.db.type == "ProbeSet": - - self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers - FROM ProbeSetFreeze WHERE Name = "%s"''' % database) - - indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] - - if confidential == 1: - access_to_confidential_dataset = 0 - - #for the dataset that confidentiality is 1 - #1. 'admin' and 'root' can see all of the dataset - #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) - if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: - access_to_confidential_dataset = 1 - else: - AuthorisedUsersList=AuthorisedUsers.split(',') - if AuthorisedUsersList.__contains__(self.userName): - access_to_confidential_dataset = 1 - - if not access_to_confidential_dataset: - #Error, Confidential Database - heading = "Show Database" - detail = ["The %s database you selected is not open to the public \ - at this time, please go back and select other database." % indFullName] - self.error(heading=heading,detail=detail,error="Confidential Database") - return - - user_ip = fd.remote_ip - query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ - UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" - self.cursor.execute(query,user_ip) - daycount = self.cursor.fetchall() - if daycount: - daycount = daycount[0][0] - if daycount > webqtlConfig.DAILYMAXIMUM: - heading = "Retrieve Data" - detail = ['For security reasons, the maximum access to a database is \ - %d times per day per ip address. You have reached the limit, please \ - try it again tomorrow.' % webqtlConfig.DAILYMAXIMUM] - self.error(heading=heading,detail=detail) - return - else: - pass - else: - pass - - if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: - heading = "Retrieve Data" - detail = ['The Record you requested doesn\'t exist!'] - self.error(heading=heading,detail=detail) - return - - #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore - # check if animal information are available - """ - self.cursor.execute(''' - SELECT - SampleXRef.ProbeFreezeId - FROM - SampleXRef, ProbeSetFreeze - WHERE - SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % thisTrait.db.name) - - sampleId = self.cursor.fetchall() - if sampleId: - thisTrait.strainInfo = 1 - else: - thisTrait.strainInfo = None - """ - - ##identification, etc. - fd.identification = '%s : %s'%(thisTrait.db.shortname,ProbeSetID) - thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database,ProbeSetID,fd.RISet) - - if CellID: - fd.identification = '%s/%s'%(fd.identification, CellID) - thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) - - #retrieve trait information - try: - thisTrait.retrieveInfo() - thisTrait.retrieveData() - self.updMysql() - self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)" ,user_ip) - self.openMysql() - except: - heading = "Retrieve Data" - detail = ["The information you requested is not avaiable at this time."] - self.error(heading=heading,detail=detail) - return - - ##read genotype file - fd.RISet = thisTrait.riset - fd.readGenotype() - - if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): - fd.displayVariance = 1 - fd.varianceDispName = 'SE' - fd.formID = 'varianceChoice' - - self.dict['body']= thisTrait - DataEditingPage.__init__(self, fd, thisTrait) - self.dict['title'] = '%s: Display Trait' % fd.identification - - diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py new file mode 100644 index 00000000..82511228 --- /dev/null +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -0,0 +1,170 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig +from utility import webqtlUtil +from base.webqtlTrait import webqtlTrait +from base.templatePage import templatePage +from DataEditingPage import DataEditingPage + + + +class ShowTraitPage(DataEditingPage): + + def __init__(self, fd, traitInfos = []): + + templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + if traitInfos: + database,ProbeSetID,CellID = traitInfos + else: + database = fd.formdata.getfirst('database') + ProbeSetID = fd.formdata.getfirst('ProbeSetID') + CellID = fd.formdata.getfirst('CellID') + try: + thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) + except: + heading = "Trait Data and Analysis Form" + detail = ["The trait isn't available currently."] + self.error(heading=heading,detail=detail,error="Error") + return + + if thisTrait.db.type == "ProbeSet": + + self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers + FROM ProbeSetFreeze WHERE Name = "%s"''' % database) + + indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] + + if confidential == 1: + access_to_confidential_dataset = 0 + + #for the dataset that confidentiality is 1 + #1. 'admin' and 'root' can see all of the dataset + #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: + access_to_confidential_dataset = 1 + else: + AuthorisedUsersList=AuthorisedUsers.split(',') + if AuthorisedUsersList.__contains__(self.userName): + access_to_confidential_dataset = 1 + + if not access_to_confidential_dataset: + #Error, Confidential Database + heading = "Show Database" + detail = ["The %s database you selected is not open to the public \ + at this time, please go back and select other database." % indFullName] + self.error(heading=heading,detail=detail,error="Confidential Database") + return + + user_ip = fd.remote_ip + query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ + UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" + self.cursor.execute(query,user_ip) + daycount = self.cursor.fetchall() + if daycount: + daycount = daycount[0][0] + if daycount > webqtlConfig.DAILYMAXIMUM: + heading = "Retrieve Data" + detail = ['For security reasons, the maximum access to a database is \ + %d times per day per ip address. You have reached the limit, please \ + try it again tomorrow.' % webqtlConfig.DAILYMAXIMUM] + self.error(heading=heading,detail=detail) + return + else: + pass + else: + pass + + if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: + heading = "Retrieve Data" + detail = ['The Record you requested doesn\'t exist!'] + self.error(heading=heading,detail=detail) + return + + #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore + # check if animal information are available + """ + self.cursor.execute(''' + SELECT + SampleXRef.ProbeFreezeId + FROM + SampleXRef, ProbeSetFreeze + WHERE + SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % thisTrait.db.name) + + sampleId = self.cursor.fetchall() + if sampleId: + thisTrait.strainInfo = 1 + else: + thisTrait.strainInfo = None + """ + + ##identification, etc. + fd.identification = '%s : %s'%(thisTrait.db.shortname,ProbeSetID) + thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ + &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database,ProbeSetID,fd.RISet) + + if CellID: + fd.identification = '%s/%s'%(fd.identification, CellID) + thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) + + #retrieve trait information + try: + thisTrait.retrieveInfo() + thisTrait.retrieveData() + self.updMysql() + self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)" ,user_ip) + self.openMysql() + except: + heading = "Retrieve Data" + detail = ["The information you requested is not avaiable at this time."] + self.error(heading=heading,detail=detail) + return + + ##read genotype file + fd.RISet = thisTrait.riset + fd.readGenotype() + + if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): + fd.displayVariance = 1 + fd.varianceDispName = 'SE' + fd.formID = 'varianceChoice' + + self.dict['body']= thisTrait + DataEditingPage.__init__(self, fd, thisTrait) + self.dict['title'] = '%s: Display Trait' % fd.identification + + -- cgit v1.2.3 From 93fdf06d57770c985e0ca8169977c210a891e262 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sat, 2 Jun 2012 04:43:31 -0400 Subject: Coming along in trying to get trait page working --- wqflask/utility/Plot.py | 334 +++++++++++++------------- wqflask/wqflask/show_trait/show_trait_page.py | 40 ++- wqflask/wqflask/views.py | 2 + 3 files changed, 188 insertions(+), 188 deletions(-) diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 2401c85c..e00b8e9e 100755 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -24,7 +24,7 @@ # # Last updated by GeneNetwork Core Team 2010/10/20 -import piddle as pid +#import piddle as pid from math import * import random import sys, os @@ -41,7 +41,7 @@ from base import webqtlConfig def cformat(d, rank=0): 'custom string format' strD = "%2.6f" % d - + if rank == 0: while strD[-1] in ('0','.'): if strD[-1] == '0' and strD[-2] == '.' and len(strD) <= 4: @@ -51,29 +51,29 @@ def cformat(d, rank=0): break else: strD = strD[:-1] - + else: - strD = strD.split(".")[0] + strD = strD.split(".")[0] if strD == '-0.0': strD = '0.0' return strD - -def frange(start, end=None, inc=1.0): - "A faster range-like function that does accept float increments..." - if end == None: - end = start + 0.0 - start = 0.0 - else: - start += 0.0 # force it to be a float - count = int((end - start) / inc) - if start + count * inc != end: - # Need to adjust the count. AFAICT, it always comes up one short. - count += 1 - L = [start] * count - for i in xrange(1, count): - L[i] = start + i * inc - return L + +def frange(start, end=None, inc=1.0): + "A faster range-like function that does accept float increments..." + if end == None: + end = start + 0.0 + start = 0.0 + else: + start += 0.0 # force it to be a float + count = int((end - start) / inc) + if start + count * inc != end: + # Need to adjust the count. AFAICT, it always comes up one short. + count += 1 + L = [start] * count + for i in xrange(1, count): + L[i] = start + i * inc + return L def gammln(xx): @@ -85,15 +85,15 @@ def gammln(xx): for item in cof: x+=1.0 ser+=item/x - + return -tmp+log(2.50662827465*ser) - + def gser(a,x): gln=gammln(a) ITMAX=100 EPS=3.0e-7 - + if x<=0.0: gamser=0.0 return [gamser,gln] @@ -109,7 +109,7 @@ def gser(a,x): gamser=sum*exp(-x+a*log(x)-gln) return [gamser,gln] return None - + def gcf(a,x): ITMAX=100 EPS=3.0e-7 @@ -119,7 +119,7 @@ def gcf(a,x): b0=0.0 a0=1.0 gln=gammln(a) - + a1=x for n in range(1,ITMAX+1): an=n+0.0 @@ -137,7 +137,7 @@ def gcf(a,x): return [gammcf,gln] gold=g return None - + def gammp(a,x): if x<0.0 or a<=0.0: return None @@ -155,7 +155,7 @@ def U(n): m.append(a) m.append(x) return m - + def erf(x): if x<0.0: return -gammp(0.5,x*x) @@ -170,7 +170,7 @@ def erfcc(x): return ans else: return 2.0-ans - + def calMeanVar(data): n=len(data) if n<2: @@ -187,7 +187,7 @@ def calMeanVar(data): for i in range(n): z[i]=z[i]/variance return z - + def inverseCumul(p): #Coefficients in rational approximations. a = [-3.969683028665376e+01,2.209460984245205e+02,-2.759285104469687e+02,1.383577518672690e+02,-3.066479806614716e+01,2.506628277459239e+00] @@ -227,7 +227,7 @@ def inverseCumul(p): return None if p>0 and p < 1: - e = 0.5 * erfcc(-x/sqrt(2)) - p + e = 0.5 * erfcc(-x/sqrt(2)) - p u = e * sqrt(2*pi) * exp(x*x/2) x = x - u/(1 + x*u/2) return x @@ -252,7 +252,7 @@ def gmedian(lst2): return (lst[N/2]+lst[(N-2)/2])/2.0 else: return lst[(N-1)/2] - + def gpercentile(lst2, np): lst = lst2[:] N = len(lst) @@ -269,21 +269,21 @@ def gpercentile(lst2, np): return lst[N-1] else: return lst[k-1] + d*(lst[k] - lst[k-1]) - + def findOutliers(vals): - + valsOnly = [] dataXZ = vals[:] for i in range(len(dataXZ)): valsOnly.append(dataXZ[i][1]) - - data = [('', valsOnly[:])] - + + data = [('', valsOnly[:])] + for item in data: itemvalue = item[1] nValue = len(itemvalue) catValue = [] - + for item2 in itemvalue: try: tstrain, tvalue = item2 @@ -293,18 +293,18 @@ def findOutliers(vals): continue else: catValue.append(tvalue) - + if catValue != []: lowHinge = gpercentile(catValue, 25) upHinge = gpercentile(catValue, 75) Hstep = 1.5*(upHinge - lowHinge) - + outlier = [] extreme = [] - + upperBound = upHinge + Hstep lowerBound = lowHinge - Hstep - + for item in catValue: if item >= upHinge + 2*Hstep: extreme.append(item) @@ -312,7 +312,7 @@ def findOutliers(vals): outlier.append(item) else: pass - + for item in catValue: if item <= lowHinge - 2*Hstep: extreme.append(item) @@ -323,10 +323,10 @@ def findOutliers(vals): else: upperBound = 1000 lowerBound = -1000 - + return upperBound, lowerBound - - + + def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabel="Value"): xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset @@ -338,8 +338,8 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe iValues.append(item2[1]) except: iValues.append(item2) - - #draw frame + + #draw frame max_Y = max(iValues) min_Y = min(iValues) scaleY = detScale(min_Y, max_Y) @@ -349,7 +349,7 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe stepY = (Yur - Yll)/nStep stepYPixel = plotHeight/(nStep) canvas.drawRect(plotWidth+xLeftOffset, plotHeight + yTopOffset, xLeftOffset, yTopOffset) - + ##draw Y Scale YYY = Yll YCoord = plotHeight + yTopOffset @@ -361,7 +361,7 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe canvas.drawString(strY, xLeftOffset -30,YCoord +5,font=scaleFont) YYY += stepY YCoord -= stepYPixel - + ##draw X Scale stepX = plotWidth/len(data) XCoord = xLeftOffset + 0.5*stepX @@ -373,7 +373,7 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe canvas.drawLine(XCoord, YCoord,XCoord, YCoord+5, color=pid.black) canvas.drawString(itemname, XCoord - canvas.stringWidth(itemname,font=labelFont)/2.0,\ YCoord +20,font=labelFont) - + nValue = len(itemvalue) catValue = [] for item2 in itemvalue: @@ -391,10 +391,10 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe lowHinge = gpercentile(catValue, 25) upHinge = gpercentile(catValue, 75) Hstep = 1.5*(upHinge - lowHinge) - + outlier = [] extrem = [] - + upperAdj = None for item in catValue: if item >= upHinge + 2*Hstep: @@ -431,7 +431,7 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe XCoord, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll), \ XCoord+20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) - + outlierFont = pid.Font(ttf="cour",size=12,bold=0) if outlier != []: for item in outlier: @@ -443,14 +443,14 @@ def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabe yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) canvas.drawString('*', XCoord-3, yc+6, font=outlierFont, color=pid.red) - + canvas.drawCross(XCoord, plotHeight + yTopOffset - (catMean-Yll)*plotHeight/(Yur - Yll), \ color=pid.blue,size=3) #print (catMean, catMedian, cat25per, cat75per) pass - + XCoord += stepX - + labelFont=pid.Font(ttf="verdana",size=18,bold=0) canvas.drawString(XLabel, xLeftOffset + (plotWidth -canvas.stringWidth(XLabel,font=labelFont))/2.0, \ YCoord +40, font=labelFont) @@ -465,48 +465,48 @@ def plotSecurity(canvas, text="12345"): plotHeight = canvas.size[1] if plotHeight<=0 or plotWidth<=0: return - + bgColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) canvas.drawRect(0,0,plotWidth,plotHeight, edgeColor=bgColor, fillColor=bgColor) - + for i in range(30): randomColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) scaleFont=pid.Font(ttf="cour",size=random.choice(range(20, 50))) - canvas.drawString(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), - int(random.random()*plotWidth), int(random.random()*plotHeight), font=scaleFont, + canvas.drawString(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), + int(random.random()*plotWidth), int(random.random()*plotHeight), font=scaleFont, color=randomColor, angle=random.choice(range(-45, 50))) - + step = (plotWidth-20)/len(text) startX = 20 for item in text: randomColor = pid.Color(0.6*random.random(),0.6*random.random(), 0.6*random.random()) scaleFont=pid.Font(ttf="verdana",size=random.choice(range(50, 60)),bold=1) - canvas.drawString(item, startX, plotHeight/2-10, font=scaleFont, + canvas.drawString(item, startX, plotHeight/2-10, font=scaleFont, color=randomColor, angle=random.choice(range(-45, 50))) startX += step - + # parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py) -# or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) +# or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): - + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset if plotHeight<=0 or plotWidth<=0: return - + if len(data) < 2: return - + max_D = max(data) min_D = min(data) #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: max_D=webqtlConfig.MAXLRS #maximum LRS value - + xLow, xTop, stepX = detScale(min_D, max_D) - + #reduce data step = ceil((xTop-xLow)/50.0) j = xLow @@ -515,27 +515,27 @@ def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid while j <= xTop: dataXY.append(j) Count.append(0) - j += step - + j += step + for i, item in enumerate(data): if item == float('inf') or item>webqtlConfig.MAXLRS: item = webqtlConfig.MAXLRS #maximum LRS value j = int((item-xLow)/step) - Count[j] += 1 - + Count[j] += 1 + yLow, yTop, stepY=detScale(0,max(Count)) - + #draw data xScale = plotWidth/(xTop-xLow) yScale = plotHeight/(yTop-yLow) barWidth = xScale*step - + for i, count in enumerate(Count): if count: xc = (dataXY[i]-xLow)*xScale+xLeftOffset yc =-(count-yLow)*yScale+yTopOffset+plotHeight canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) - + #draw drawing region canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) @@ -548,7 +548,7 @@ def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid strX = cformat(d=x, rank=0) canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) x+= (xTop - xLow)/stepX - + y=yLow for i in range(stepY+1): yc=yTopOffset+plotHeight-(y-yLow)*yScale @@ -556,13 +556,13 @@ def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid strY = "%d" %y canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) y+= (yTop - yLow)/stepY - + #draw label labelFont=pid.Font(ttf="tahoma",size=17,bold=0) if XLabel: canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) - + if YLabel: canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, font=labelFont,color=labelColor,angle=90) @@ -578,34 +578,34 @@ def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor plotHeight = canvas.size[1] - yTopOffset - yBottomOffset if plotHeight<=0 or plotWidth<=0: return - + NNN = len(data) if NNN < 2 or NNN != len(label): return if variance and len(variance)!=NNN: variance = [] - + Y2 = data[:] if variance: for i in range(NNN): if variance[i]: Y2 += [data[i]-variance[i]] - + #Y axis YLow, YTop, stepY = detScale(min(Y2), max(Y2)) YScale = plotHeight/(YTop - YLow) - + if YLow < 0 and YTop > 0: drawZero = 1 else: drawZero = 0 - + #X axis X = range(NNN) - Xll= 0 + Xll= 0 Xur= NNN-1 - - + + if drawZero: YZero = yTopOffset+plotHeight-YScale*(0-YLow) canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) @@ -616,9 +616,9 @@ def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor if spaceWidth < 1: spaceWidth = 1 barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) - + xc= xLeftOffset - scaleFont=pid.Font(ttf="verdana",size=11,bold=0) + scaleFont=pid.Font(ttf="verdana",size=11,bold=0) for i in range(NNN): yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) @@ -633,13 +633,13 @@ def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) strX = label[i] canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) - xc += barWidth + spaceWidth - + xc += barWidth + spaceWidth + #draw drawing region canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) - + #draw Y scale - scaleFont=pid.Font(ttf="cour",size=16,bold=1) + scaleFont=pid.Font(ttf="cour",size=16,bold=1) y=YLow for i in range(stepY+1): yc=yTopOffset+plotHeight-(y-YLow)*YScale @@ -647,35 +647,35 @@ def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor strY = cformat(d=y, rank=0) canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) y+= (YTop - YLow)/stepY - + #draw label labelFont=pid.Font(ttf="verdana",size=17,bold=0) if XLabel: canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) - + if YLabel: canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) - + labelFont=pid.Font(ttf="verdana",size=18,bold=0) if title: canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) - + return - + def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, axesColor=pid.black, labelColor=pid.black, lineSize="thin", lineColor=pid.grey, idFont="arial", idColor=pid.blue, idSize="14", symbolColor=pid.black, symbolType="circle", filled="yes", symbolSize="tiny", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1, bufferSpace = 15): 'displayR : correlation scatter plot, loadings : loading plot' - + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) - + #get ID font size - idFontSize = int(idSize) - + idFontSize = int(idSize) + #If filled is yes, set fill color if filled == "yes": fillColor = symbolColor else: - fillColor = None - + fillColor = None + if symbolSize == "large": sizeModifier = 7 fontModifier = 12 @@ -687,8 +687,8 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax fontModifier = 3 else: sizeModifier = 1 - fontModifier = -1 - + fontModifier = -1 + if rank == 0: # Pearson correlation bufferSpace = 0 dataXPrimary = dataX @@ -700,7 +700,7 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax dataYPrimary = dataYRanked dataXAlt = dataX #Values used just for printing the other corr type to the graph image dataYAlt = dataY #Values used just for printing the other corr type to the graph image - + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = canvas.size[0] - xLeftOffset - xRightOffset plotHeight = canvas.size[1] - yTopOffset - yBottomOffset @@ -708,29 +708,29 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax return if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): return - + max_X=max(dataXPrimary) min_X=min(dataXPrimary) max_Y=max(dataYPrimary) min_Y=min(dataYPrimary) - + #for some reason I forgot why I need to do this if loadingPlot: min_X = min(-0.1,min_X) max_X = max(0.1,max_X) min_Y = min(-0.1,min_Y) max_Y = max(0.1,max_Y) - + xLow, xTop, stepX=detScale(min_X,max_X) yLow, yTop, stepY=detScale(min_Y,max_Y) xScale = plotWidth/(xTop-xLow) yScale = plotHeight/(yTop-yLow) - + #draw drawing region canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) - #calculate data points + #calculate data points data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) @@ -767,12 +767,12 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax elif (symbolType == "diamond" and filled != "yes"): canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) elif (symbolType == "diamond" and filled == "yes"): - canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) + canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) elif symbolType == "4-star": - canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) elif symbolType == "3-star": - canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) - else: + canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + else: canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) if showLabel and dataLabel: @@ -784,10 +784,10 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax labelGap = 11 canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) - + #draw scale scaleFont=pid.Font(ttf="cour",size=16,bold=1) - + x=xLow for i in range(stepX+1): @@ -795,14 +795,14 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax if ((x == 0) & (rank == 1)): pass else: - canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) + canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) strX = cformat(d=x, rank=rank) if ((strX == "0") & (rank == 1)): pass else: canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) x+= (xTop - xLow)/stepX - + y=yLow for i in range(stepY+1): yc=yTopOffset+plotHeight-(y-yLow)*yScale @@ -816,23 +816,23 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax else: canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) y+= (yTop - yLow)/stepY - + #draw label labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) - + if (rank == 1 and not title): canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, 25,font=titleFont,color=labelColor) elif (rank == 0 and not title): canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, 25,font=titleFont,color=labelColor) - + if XLabel: canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) - + if YLabel: canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, font=labelFont,color=labelColor,angle=90) @@ -841,7 +841,7 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax if title: canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, 20,font=labelFont,color=labelColor) - + if fitcurve: import sys sys.argv = [ "mod_python" ] @@ -852,9 +852,9 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax AA = dot(fitXX,swapaxes(fitXX,0,1)) BB = dot(fitXX,fitYY) bb = la.linear_least_squares(AA,BB)[0] - + xc1 = xLeftOffset - yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale if yc1 > yTopOffset+plotHeight: yc1 = yTopOffset+plotHeight xc1 = (yLow-bb[0])/bb[1] @@ -865,8 +865,8 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax xc1=(xc1-xLow)*xScale+xLeftOffset else: pass - - xc2 = xLeftOffset + plotWidth + + xc2 = xLeftOffset + plotWidth yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale if yc2 > yTopOffset+plotHeight: yc2 = yTopOffset+plotHeight @@ -885,8 +885,8 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax if lineSize == "thick": canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) - - + + if displayR: labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) NNN = len(dataX) @@ -901,7 +901,7 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax ZValue = 0.5*log((1.0+corr)/(1.0-corr)) ZValue = ZValue*sqrt(NNN-3) corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - + NStr = "N = %d" % NNN strLenN = canvas.stringWidth(NStr,font=labelFont) @@ -924,24 +924,24 @@ def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, ax def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black", axesColor="black", labelColor="black", symbolColor="red", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1): 'displayR : correlation scatter plot, loadings : loading plot' - + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) - - # Switching Ranked and Unranked X and Y values if a Spearman Rank Correlation + + # Switching Ranked and Unranked X and Y values if a Spearman Rank Correlation if rank == 0: dataXPrimary = dataX dataYPrimary = dataY dataXAlt = dataXRanked - dataYAlt = dataYRanked - - else: + dataYAlt = dataYRanked + + else: dataXPrimary = dataXRanked dataYPrimary = dataYRanked dataXAlt = dataX dataYAlt = dataY - + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset plotWidth = drawSpace.attributes['width'] - xLeftOffset - xRightOffset plotHeight = drawSpace.attributes['height'] - yTopOffset - yBottomOffset @@ -949,34 +949,34 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" return if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): return - + max_X=max(dataXPrimary) min_X=min(dataXPrimary) max_Y=max(dataYPrimary) min_Y=min(dataYPrimary) - + #for some reason I forgot why I need to do this if loadingPlot: min_X = min(-0.1,min_X) max_X = max(0.1,max_X) min_Y = min(-0.1,min_Y) max_Y = max(0.1,max_Y) - + xLow, xTop, stepX=detScale(min_X,max_X) yLow, yTop, stepY=detScale(min_Y,max_Y) xScale = plotWidth/(xTop-xLow) yScale = plotHeight/(yTop-yLow) - + #draw drawing region r = svg.rect(xLeftOffset, yTopOffset, plotWidth, plotHeight, 'none', axesColor, 1) drawSpace.addElement(r) - - #calculate data points + + #calculate data points data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) labelFontF = "verdana" labelFontS = 11 - + if loadingPlot: xZero = -xLow*xScale+xLeftOffset yZero = yTopOffset+plotHeight+yLow*yScale @@ -988,7 +988,7 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" #drawSpace.drawPolygon(xCoord,edgeColor=plotColor,closed=0) else: pass - + for i, item in enumerate(xCoord): if dataLabel and dataLabel[i] in specialCases: drawSpace.addElement(svg.rect(item[0]-3, item[1]-3, 6, 6, "none", "green", 0.5)) @@ -998,11 +998,11 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" drawSpace.addElement(svg.line(item[0]+5,item[1],item[0]-5,item[1],symbolColor,1)) if showLabel and dataLabel: pass - drawSpace.addElement(svg.text(item[0], item[1]+14, dataLabel[i], labelFontS, + drawSpace.addElement(svg.text(item[0], item[1]+14, dataLabel[i], labelFontS, labelFontF, text_anchor="middle", style="stroke:blue;stroke-width:0.5;")) #canvas.drawString(, item[0]- canvas.stringWidth(dataLabel[i], # font=labelFont)/2, item[1]+14, font=labelFont, color=pid.blue) - + #draw scale #scaleFont=pid.Font(ttf="cour",size=14,bold=1) x=xLow @@ -1012,7 +1012,7 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" strX = cformat(d=x, rank=rank) drawSpace.addElement(svg.text(xc,yTopOffset+plotHeight+20,strX,13, "courier", text_anchor="middle")) x+= (xTop - xLow)/stepX - + y=yLow for i in range(stepY+1): yc=yTopOffset+plotHeight-(y-yLow)*yScale @@ -1020,7 +1020,7 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" strY = cformat(d=y, rank=rank) drawSpace.addElement(svg.text(xLeftOffset-10,yc+5,strY,13, "courier", text_anchor="end")) y+= (yTop - yLow)/stepY - + #draw label labelFontF = "verdana" labelFontS = 17 @@ -1028,7 +1028,7 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" drawSpace.addElement(svg.text(xLeftOffset+plotWidth/2.0, yTopOffset+plotHeight+yBottomOffset-10,XLabel, labelFontS, labelFontF, text_anchor="middle")) - + if YLabel: drawSpace.addElement(svg.text(xLeftOffset-50, yTopOffset+plotHeight/2,YLabel, @@ -1046,9 +1046,9 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" AA = dot(fitXX,swapaxes(fitXX,0,1)) BB = dot(fitXX,fitYY) bb = la.linear_least_squares(AA,BB)[0] - + xc1 = xLeftOffset - yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale if yc1 > yTopOffset+plotHeight: yc1 = yTopOffset+plotHeight xc1 = (yLow-bb[0])/bb[1] @@ -1059,8 +1059,8 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" xc1=(xc1-xLow)*xScale+xLeftOffset else: pass - - xc2 = xLeftOffset + plotWidth + + xc2 = xLeftOffset + plotWidth yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale if yc2 > yTopOffset+plotHeight: yc2 = yTopOffset+plotHeight @@ -1074,8 +1074,8 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" pass drawSpace.addElement(svg.line(xc1,yc1,xc2,yc2,"green", 1)) - - if displayR: + + if displayR: labelFontF = "trebuc" labelFontS = 14 NNN = len(dataX) @@ -1091,24 +1091,24 @@ def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black" ZValue = 0.5*log((1.0+corr)/(1.0-corr)) ZValue = ZValue*sqrt(NNN-3) corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - + NStr = "N of Cases=%d" % NNN - + if rank == 1: corrStr = "Spearman's r=%1.3f P=%3.2E" % (corr, corrPValue) else: corrStr = "Pearson's r=%1.3f P=%3.2E" % (corr, corrPValue) - + drawSpace.addElement(svg.text(xLeftOffset,yTopOffset-10,NStr, labelFontS, labelFontF, text_anchor="start")) drawSpace.addElement(svg.text(xLeftOffset+plotWidth,yTopOffset-25,corrStr, labelFontS, labelFontF, text_anchor="end")) - """ + """ """ return -# This function determines the scale of the plot +# This function determines the scale of the plot def detScaleOld(min,max): if min>=max: return None @@ -1205,8 +1205,8 @@ def colorSpectrumOld(n): colors.append(pid.Color(red,green,blue)) i += 1 return colors - - + + def bluefunc(x): @@ -1273,7 +1273,7 @@ def BWSpectrum(n=100): return [pid.Color(0,0,0),pid.Color(1,1,1)] elif n == 3: return [pid.Color(0,0,0),pid.Color(0.5,0.5,0.5),pid.Color(1,1,1)] - + step = 1.0/n x = 0.0 out = [] diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index 82511228..03f8b9b3 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -42,9 +42,9 @@ class ShowTraitPage(DataEditingPage): if not self.openMysql(): return - + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - + if traitInfos: database,ProbeSetID,CellID = traitInfos else: @@ -61,7 +61,7 @@ class ShowTraitPage(DataEditingPage): if thisTrait.db.type == "ProbeSet": - self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers + self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM ProbeSetFreeze WHERE Name = "%s"''' % database) indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] @@ -86,7 +86,7 @@ class ShowTraitPage(DataEditingPage): at this time, please go back and select other database." % indFullName] self.error(heading=heading,detail=detail,error="Confidential Database") return - + user_ip = fd.remote_ip query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" @@ -105,26 +105,26 @@ class ShowTraitPage(DataEditingPage): pass else: pass - + if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: heading = "Retrieve Data" detail = ['The Record you requested doesn\'t exist!'] self.error(heading=heading,detail=detail) return - #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore + #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore # check if animal information are available """ self.cursor.execute(''' - SELECT - SampleXRef.ProbeFreezeId - FROM - SampleXRef, ProbeSetFreeze - WHERE + SELECT + SampleXRef.ProbeFreezeId + FROM + SampleXRef, ProbeSetFreeze + WHERE SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND ProbeSetFreeze.Name = "%s" - ''' % thisTrait.db.name) - + ''' % thisTrait.db.name) + sampleId = self.cursor.fetchall() if sampleId: thisTrait.strainInfo = 1 @@ -136,12 +136,12 @@ class ShowTraitPage(DataEditingPage): fd.identification = '%s : %s'%(thisTrait.db.shortname,ProbeSetID) thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database,ProbeSetID,fd.RISet) - + if CellID: fd.identification = '%s/%s'%(fd.identification, CellID) thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) - - #retrieve trait information + + #retrieve trait information try: thisTrait.retrieveInfo() thisTrait.retrieveData() @@ -153,18 +153,16 @@ class ShowTraitPage(DataEditingPage): detail = ["The information you requested is not avaiable at this time."] self.error(heading=heading,detail=detail) return - + ##read genotype file fd.RISet = thisTrait.riset fd.readGenotype() - + if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): fd.displayVariance = 1 fd.varianceDispName = 'SE' fd.formID = 'varianceChoice' - + self.dict['body']= thisTrait DataEditingPage.__init__(self, fd, thisTrait) self.dict['title'] = '%s: Display Trait' % fd.identification - - diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3e1c2729..611cc05b 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -5,6 +5,7 @@ from wqflask import app from flask import render_template, request from wqflask import search_results +from wqflask.show_trait import show_trait_page from pprint import pformat as pf @@ -20,4 +21,5 @@ def search(): @app.route("/showDatabaseBXD") def showDatabaseBXD(): + template_vars = show_trait_page.ShowTraitPage(request.args) return render_template("trait_data_and_analysis.html") -- cgit v1.2.3 From c1432f41d243047e767a4ec1dc423b9fd0055e0f Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 3 Jun 2012 04:08:15 -0400 Subject: Cleaning up trait stuff in flask --- wqflask/base/webqtlTrait.py | 228 ++++++++++++++------------ wqflask/wqflask/show_trait/show_trait_page.py | 42 +++-- 2 files changed, 145 insertions(+), 125 deletions(-) diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index f5051e45..c3c0cded 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -1,3 +1,5 @@ +from __future__ import division, print_function + import string from htmlgen import HTMLgen2 as HT @@ -8,14 +10,18 @@ from webqtlDataset import webqtlDataset from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil +from pprint import pformat as pf + class webqtlTrait: """ - Trait class defines a trait in webqtl, can be either Microarray, + Trait class defines a trait in webqtl, can be either Microarray, Published phenotype, genotype, or user input trait + """ def __init__(self, cursor = None, **kw): + print("in webqtlTrait") self.cursor = cursor self.db = None # database object self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. @@ -25,6 +31,9 @@ class webqtlTrait: self.haveinfo = 0 self.sequence = '' # Blat sequence, available for ProbeSet self.data = {} + print("foo") + print("kw in webqtlTrait are:", pf(kw)) + print("printed\n\n") for name, value in kw.items(): if self.__dict__.has_key(name): setattr(self, name, value) @@ -35,28 +44,29 @@ class webqtlTrait: elif len(name2) == 3: self.db, self.name, self.cellid = name2 else: - raise KeyError, `value` + ' parameter format error.' + raise KeyError, repr(value) + ' parameter format error.' else: - raise KeyError, `name`+' not a valid parameter for this class.' - - if self.db and type(self.db) == type("1"): - assert self.cursor + raise KeyError, repr(name) + ' not a valid parameter for this class.' + + if self.db and isinstance(self.db, basestring): + assert self.cursor, "Don't have a cursor" self.db = webqtlDataset(self.db, self.cursor) #if self.db == None, not from a database + print("self.db is:", self.db, type(self.db)) if self.db: if self.db.type == "Temp": self.cursor.execute(''' - SELECT - InbredSet.Name - FROM - InbredSet, Temp - WHERE - Temp.InbredSetId = InbredSet.Id AND + SELECT + InbredSet.Name + FROM + InbredSet, Temp + WHERE + Temp.InbredSetId = InbredSet.Id AND Temp.Name = "%s" - ''' % self.name) + ''', self.name) self.riset = self.cursor.fetchone()[0] - else: + else: self.riset = self.db.getRISet() # @@ -73,8 +83,9 @@ class webqtlTrait: if self.db: if self.db.type == 'ProbeSet': + print("Doing ProbeSet Query") query = ''' - SELECT + SELECT ProbeSet.BlatSeq FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef @@ -84,10 +95,11 @@ class webqtlTrait: ProbeSet.Name = "%s" and ProbeSetFreeze.Name = "%s" ''' % (self.name, self.db.name) + print("query is:", query) self.cursor.execute(query) self.sequence = self.cursor.fetchone()[0] - + def getName(self): str = "" if self.db and self.name: @@ -98,12 +110,12 @@ class webqtlTrait: str = self.description return str - # + # # when user enter a trait or GN generate a trait, user want show the name # not the name that generated by GN randomly, the two follow function are - # used to give the real name and the database. displayName() will show the - # database also, getGivenName() just show the name. - # For other trait, displayName() as same as getName(), getGivenName() as + # used to give the real name and the database. displayName() will show the + # database also, getGivenName() just show the name. + # For other trait, displayName() as same as getName(), getGivenName() as # same as self.name # # Hongqiang 11/29/07 @@ -137,10 +149,10 @@ class webqtlTrait: str += "::" + self.cellid else: str = self.description - + return str - + #def __str__(self): # #return "%s %s" % (self.getName(), self.riset) # return self.getName() @@ -166,7 +178,7 @@ class webqtlTrait: else: result.append(None) return result - + def exportInformative(self, incVar=0): """ export informative strain @@ -195,7 +207,7 @@ class webqtlTrait: assert self.cursor if self.db.type == 'ProbeSet': query = ''' - SELECT + SELECT ProbeSet.BlatSeq FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef @@ -209,40 +221,40 @@ class webqtlTrait: results = self.fetchone() return results[0] - - - + + + def retrieveData(self, strainlist=[]): assert self.db and self.cursor if self.db.type == 'Temp': query = ''' - SELECT - Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id - FROM - TempData, Temp, Strain - WHERE - TempData.StrainId = Strain.Id AND - TempData.Id = Temp.DataId AND + SELECT + Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id + FROM + TempData, Temp, Strain + WHERE + TempData.StrainId = Strain.Id AND + TempData.Id = Temp.DataId AND Temp.name = '%s' Order BY Strain.Name ''' % self.name #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE - elif self.db.type == 'Publish': + elif self.db.type == 'Publish': query = ''' - SELECT - Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id - FROM + SELECT + Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + FROM (PublishData, Strain, PublishXRef, PublishFreeze) - left join PublishSE on + left join PublishSE on (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) - left join NStrain on - (NStrain.DataId = PublishData.Id AND - NStrain.StrainId = PublishData.StrainId) - WHERE - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND + left join NStrain on + (NStrain.DataId = PublishData.Id AND + NStrain.StrainId = PublishData.StrainId) + WHERE + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id Order BY Strain.Name @@ -252,21 +264,21 @@ class webqtlTrait: elif self.cellid: #Probe Data query = ''' - SELECT - Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id - FROM - (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, + SELECT + Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id + FROM + (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, Strain, Probe, ProbeSet) - left join ProbeSE on + left join ProbeSE on (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) - WHERE - Probe.Name = '%s' AND ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id AND - ProbeXRef.ProbeId = Probe.Id AND - ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeXRef.DataId = ProbeData.Id AND + WHERE + Probe.Name = '%s' AND ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id AND + ProbeXRef.ProbeId = Probe.Id AND + ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeXRef.DataId = ProbeData.Id AND ProbeData.StrainId = Strain.Id Order BY Strain.Name @@ -295,23 +307,23 @@ class webqtlTrait: #Geno Data #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. query = ''' - SELECT - Strain.Name, GenoData.value, GenoSE.error, GenoData.Id - FROM + SELECT + Strain.Name, GenoData.value, GenoSE.error, GenoData.Id + FROM (GenoData, GenoFreeze, Strain, Geno, GenoXRef) left join GenoSE on (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) - WHERE + WHERE Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoFreeze.Name = '%s' AND - GenoXRef.DataId = GenoData.Id AND + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoFreeze.Name = '%s' AND + GenoXRef.DataId = GenoData.Id AND GenoData.StrainId = Strain.Id Order BY Strain.Name ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name) - + self.cursor.execute(query) results = self.cursor.fetchall() self.data.clear() @@ -328,7 +340,7 @@ class webqtlTrait: ndata = item[3] self.data[item[0]] = webqtlCaseData(val, var, ndata) #end for - else: + else: for item in results: val = item[1] if val != None: @@ -341,16 +353,16 @@ class webqtlTrait: #end if else: pass - + def keys(self): return self.__dict__.keys() - + def has_key(self, key): return self.__dict__.has_key(key) - + def items(self): return self.__dict__.items() - + def retrieveInfo(self, QTL = None): assert self.db and self.cursor if self.db.type == 'Publish': @@ -358,22 +370,22 @@ class webqtlTrait: # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ # 'Units', 'comments'] query = ''' - SELECT - PublishXRef.Id, Publication.PubMed_ID, - Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, - Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, + SELECT + PublishXRef.Id, Publication.PubMed_ID, + Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, + Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, - Publication.Authors, Publication.Title, Publication.Abstract, - Publication.Journal, Publication.Volume, Publication.Pages, - Publication.Month, Publication.Year, PublishXRef.Sequence, - Phenotype.Units, PublishXRef.comments - FROM - PublishXRef, Publication, Phenotype, PublishFreeze - WHERE - PublishXRef.Id = %s AND - Phenotype.Id = PublishXRef.PhenotypeId AND - Publication.Id = PublishXRef.PublicationId AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + Publication.Authors, Publication.Title, Publication.Abstract, + Publication.Journal, Publication.Volume, Publication.Pages, + Publication.Month, Publication.Year, PublishXRef.Sequence, + Phenotype.Units, PublishXRef.comments + FROM + PublishXRef, Publication, Phenotype, PublishFreeze + WHERE + PublishXRef.Id = %s AND + Phenotype.Id = PublishXRef.PhenotypeId AND + Publication.Id = PublishXRef.PublicationId AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND PublishFreeze.Id =%s ''' % (self.name, self.db.id) #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name @@ -382,7 +394,7 @@ class webqtlTrait: disfieldString = string.join(self.db.disfield,',ProbeSet.') disfieldString = 'ProbeSet.' + disfieldString query = """ - SELECT %s + SELECT %s FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND @@ -396,7 +408,7 @@ class webqtlTrait: disfieldString = string.join(self.db.disfield,',Geno.') disfieldString = 'Geno.' + disfieldString query = """ - SELECT %s + SELECT %s FROM Geno, GenoFreeze, GenoXRef WHERE GenoXRef.GenoFreezeId = GenoFreeze.Id AND @@ -408,7 +420,7 @@ class webqtlTrait: query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ (string.join(self.db.disfield,','), self.db.type, self.name) - + self.cursor.execute(query) traitInfo = self.cursor.fetchone() if traitInfo: @@ -457,12 +469,12 @@ class webqtlTrait: if QTL: if self.db.type == 'ProbeSet' and not self.cellid: query = ''' - SELECT - ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean - FROM + SELECT + ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean + FROM ProbeSetXRef, ProbeSet - WHERE - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + WHERE + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSet.Name = "%s" AND ProbeSetXRef.ProbeSetFreezeId =%s ''' % (self.name, self.db.id) @@ -491,11 +503,11 @@ class webqtlTrait: self.locus = self.lrs = "" else: raise KeyError, `self.name`+' information is not found in the database.' - + def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): if not self.haveinfo: self.retrieveInfo() - + if self.db.type == 'Publish': PubMedLink = "" if self.pubmed_id: @@ -503,14 +515,14 @@ class webqtlTrait: target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) else: PubMedLink = HT.Span("Unpublished : ", Class="fs15") - + if formName: - setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % + setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name, self.name), Class = "fs14") else: - setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % + setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), Class = "fs14") - + if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) else: @@ -526,12 +538,12 @@ class webqtlTrait: setDescription2.append(' by ') setDescription2.append(HT.Italic('%s, and colleagues' % a1)) setDescription = HT.Span(PubMedLink, setDescription2) - + elif self.db.type == 'Temp': setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ ('%s','%s','')" % (self.db.name,self.name), Class = "fs14") setDescription = HT.Span(setDescription) - + elif self.db.type == 'Geno': # Genome DB only available for single search if formName: setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ @@ -541,16 +553,16 @@ class webqtlTrait: setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ (self.db.name,self.name), Class = "fs14") - + setDescription = HT.Span(setDescription) - + else: if self.cellid: - if formName: + if formName: setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \ Class = "fs14") - else: + else: setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \ Class = "fs14") @@ -572,10 +584,8 @@ class webqtlTrait: if self.probe_target_description: setDescription.append('; %s' % self.probe_target_description) setDescription = HT.Span(setDescription) - + if self.db.type != 'Temp' and dispFromDatabase: setDescription.append( ' --- FROM : ') setDescription.append(self.db.genHTML(Class='cori')) return setDescription - - diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index 03f8b9b3..c7d6618e 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -36,29 +36,39 @@ from DataEditingPage import DataEditingPage class ShowTraitPage(DataEditingPage): - def __init__(self, fd, traitInfos = []): + def __init__(self, fd, traitInfos = None): - templatePage.__init__(self, fd) + #templatePage.__init__(self, fd) if not self.openMysql(): return - TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - + #TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + print("j2") + # When is traitInfos used? if traitInfos: - database,ProbeSetID,CellID = traitInfos + print("j2.2") + database, ProbeSetID, CellID = traitInfos else: - database = fd.formdata.getfirst('database') - ProbeSetID = fd.formdata.getfirst('ProbeSetID') - CellID = fd.formdata.getfirst('CellID') - try: - thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) - except: - heading = "Trait Data and Analysis Form" - detail = ["The trait isn't available currently."] - self.error(heading=heading,detail=detail,error="Error") - return - + print("j2.3") + print("fd is:", fd) + database = fd['database'] + ProbeSetID = fd['ProbeSetID'] + print("j2.4") + CellID = fd.get('CellID') + print("j2.6") + + # We're no longer wrapping this in an exception. If we fail, let's fail hard + # Log it and fix it + #try: + print("j3") + thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) + #except: + # heading = "Trait Data and Analysis Form" + # detail = ["The trait isn't available currently."] + # self.error(heading=heading,detail=detail,error="Error") + # return + print("j4") if thisTrait.db.type == "ProbeSet": self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers -- cgit v1.2.3 From f44a9e0425cf9d364604c62893100c0cdb0a6f8f Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 3 Jun 2012 04:08:57 -0400 Subject: Added files --- .../basicStatistics/BasicStatisticsFunctions.py | 174 ++ .../basicStatistics/BasicStatisticsPage_alpha.py | 348 ++++ wqflask/basicStatistics/__init__.py | 0 .../basicStatistics/updatedBasicStatisticsPage.py | 150 ++ wqflask/wqflask/show_trait/DataEditingPage.py | 1898 ++++++++++++++++++++ wqflask/wqflask/show_trait/__init__.py | 0 6 files changed, 2570 insertions(+) create mode 100755 wqflask/basicStatistics/BasicStatisticsFunctions.py create mode 100755 wqflask/basicStatistics/BasicStatisticsPage_alpha.py create mode 100755 wqflask/basicStatistics/__init__.py create mode 100755 wqflask/basicStatistics/updatedBasicStatisticsPage.py create mode 100755 wqflask/wqflask/show_trait/DataEditingPage.py create mode 100644 wqflask/wqflask/show_trait/__init__.py diff --git a/wqflask/basicStatistics/BasicStatisticsFunctions.py b/wqflask/basicStatistics/BasicStatisticsFunctions.py new file mode 100755 index 00000000..5cbbb145 --- /dev/null +++ b/wqflask/basicStatistics/BasicStatisticsFunctions.py @@ -0,0 +1,174 @@ +#import string +from math import * +#import piddle as pid +#import os + +#import reaper +from htmlgen import HTMLgen2 as HT + +#from utility import Plot +from utility import webqtlUtil +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction + +def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None): + + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) + + traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future + + tbl = HT.TableLite(cellpadding=20, cellspacing=0) + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180), + HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60))) + tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"), + HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + #tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + # HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222"))) + tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + if (trait_type != None and trait_type == 'ProbeSet'): + #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") + #IRQuest.append(HT.BR()) + #IRQuest.append(" (fold difference)") + tbl.append(HT.TR(HT.TD("Range (log2)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD(HT.Span(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold")), align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + + #XZ, 04/01/2009: don't try to get H2 value for probe. + if cellid: + pass + else: + if heritability: + tbl.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + else: + pass + # Lei Yan + # 2008/12/19 + + return tbl + +def plotNormalProbability(vals=None, RISet='', title=None, showstrains=0, specialStrains=[None], size=(750,500)): + + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + dataLabel = [] + dataX = map(lambda X: X[1], dataXZ) + + showLabel = showstrains + if len(dataXZ) > 50: + showLabel = 0 + for item in dataXZ: + strainName = webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=item[0]) + dataLabel.append(strainName) + + dataY=Plot.U(len(dataX)) + dataZ=map(Plot.inverseCumul,dataY) + c = pid.PILCanvas(size=(750,500)) + Plot.plotXY(c, dataZ, dataX, dataLabel = dataLabel, XLabel='Expected Z score', connectdot=0, YLabel='Trait value', title=title, specialCases=specialStrains, showLabel = showLabel) + + filename= webqtlUtil.genRandStr("nP_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + + img=HT.Image('/image/'+filename+'.gif',border=0) + + return img + +def plotBoxPlot(vals): + + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) + + plotHeight = 320 + plotWidth = 220 + xLeftOffset = 60 + xRightOffset = 40 + yTopOffset = 40 + yBottomOffset = 60 + + canvasHeight = plotHeight + yTopOffset + yBottomOffset + canvasWidth = plotWidth + xLeftOffset + xRightOffset + canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) + XXX = [('', valsOnly[:])] + + Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") + filename= webqtlUtil.genRandStr("Box_") + canvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) + + plotLink = HT.Span("More about ", HT.Href(text="Box Plots", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs13")) + + return img, plotLink + +def plotBarGraph(identification='', RISet='', vals=None, type="name"): + + this_identification = "unnamed trait" + if identification: + this_identification = identification + + if type=="rank": + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + title='%s' % this_identification + else: + dataXZ = vals[:] + title='%s' % this_identification + + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + nnStrain = len(tnames) + + sLabel = 1 + + ###determine bar width and space width + if nnStrain < 20: + sw = 4 + elif nnStrain < 40: + sw = 3 + else: + sw = 2 + + ### 700 is the default plot width minus Xoffsets for 40 strains + defaultWidth = 650 + if nnStrain > 40: + defaultWidth += (nnStrain-40)*10 + defaultOffset = 100 + bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) + if bw < 10: + bw = 10 + + plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset + plotHeight = 500 + #print [plotWidth, plotHeight, bw, sw, nnStrain] + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title=title, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) + + return img diff --git a/wqflask/basicStatistics/BasicStatisticsPage_alpha.py b/wqflask/basicStatistics/BasicStatisticsPage_alpha.py new file mode 100755 index 00000000..4ba9d54a --- /dev/null +++ b/wqflask/basicStatistics/BasicStatisticsPage_alpha.py @@ -0,0 +1,348 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import string +from math import * +import piddle as pid +import os + +from htmlgen import HTMLgen2 as HT +import reaper + +from utility import Plot +from base.webqtlTrait import webqtlTrait +from base.templatePage import templatePage +from utility import webqtlUtil +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction + + + +class BasicStatisticsPage_alpha(templatePage): + + plotMinInformative = 4 + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + if not fd.genotype: + fd.readGenotype() + strainlist2 = fd.strainlist + + if fd.allstrainlist: + strainlist2 = fd.allstrainlist + + fd.readData(strainlist2) + + specialStrains = [] + setStrains = [] + for item in strainlist2: + if item not in fd.strainlist and item.find('F1') < 0: + specialStrains.append(item) + else: + setStrains.append(item) + specialStrains.sort() + #So called MDP Panel + if specialStrains: + specialStrains = fd.f1list+fd.parlist+specialStrains + + self.plotType = fd.formdata.getvalue('ptype', '0') + plotStrains = strainlist2 + if specialStrains: + if self.plotType == '1': + plotStrains = setStrains + if self.plotType == '2': + plotStrains = specialStrains + + self.dict['title'] = 'Basic Statistics' + if not self.openMysql(): + return + + self.showstrains = 1 + self.identification = "unnamed trait" + + self.fullname = fd.formdata.getvalue('fullname', '') + if self.fullname: + self.Trait = webqtlTrait(fullname=self.fullname, cursor=self.cursor) + self.Trait.retrieveInfo() + else: + self.Trait = None + + if fd.identification: + self.identification = fd.identification + self.dict['title'] = self.identification + ' / '+self.dict['title'] + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + ##should not display Variance, but cannot convert Variance to SE + #print plotStrains, fd.allTraitData.keys() + if len(fd.allTraitData) > 0: + vals=[] + InformData = [] + for _strain in plotStrains: + if fd.allTraitData.has_key(_strain): + _val, _var = fd.allTraitData[_strain].val, fd.allTraitData[_strain].var + if _val != None: + vals.append([_strain, _val, _var]) + InformData.append(_val) + + if len(vals) >= self.plotMinInformative: + supertable2 = HT.TableLite(border=0, cellspacing=0, cellpadding=5,width="800") + + staIntro1 = HT.Paragraph("The table and plots below list the basic statistical analysis result of trait",HT.Strong(" %s" % self.identification)) + + ##### + #anova + ##### + traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(InformData) + TDStatis = HT.TD(width="360", valign="top") + tbl2 = HT.TableLite(cellpadding=5, cellspacing=0, Class="collap") + dataXZ = vals[:] + dataXZ.sort(self.cmpValue) + tbl2.append(HT.TR(HT.TD("Statistic",align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 200), + HT.TD("Value", align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 140))) + tbl2.append(HT.TR(HT.TD("N of Cases",align="center", Class="fs13 b1 cbw c222"), + HT.TD(N,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Mean",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmean,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Median",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmedian,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + #tbl2.append(HT.TR(HT.TD("Variance",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + # HT.TD("%2.3f" % traitvar,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("SEM",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitsem,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("SD",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitstdev,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Minimum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[0][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Maximum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[-1][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + if self.Trait and self.Trait.db.type == 'ProbeSet': + #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") + #IRQuest.append(HT.BR()) + #IRQuest.append(" (fold difference)") + tbl2.append(HT.TR(HT.TD("Range (log2)",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD(HT.Span("Quartile Range",HT.BR()," (fold difference)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + + # (Lei Yan) + # 2008/12/19 + self.Trait.retrieveData() + #XZ, 04/01/2009: don't try to get H2 value for probe. + if self.Trait.cellid: + pass + else: + self.cursor.execute("SELECT DataId, h2 from ProbeSetXRef WHERE DataId = %d" % self.Trait.mysqlid) + dataid, heritability = self.cursor.fetchone() + if heritability: + tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + else: + tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("NaN", nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + + # Lei Yan + # 2008/12/19 + + TDStatis.append(tbl2) + + plotHeight = 220 + plotWidth = 120 + xLeftOffset = 60 + xRightOffset = 25 + yTopOffset = 20 + yBottomOffset = 53 + + canvasHeight = plotHeight + yTopOffset + yBottomOffset + canvasWidth = plotWidth + xLeftOffset + xRightOffset + canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) + XXX = [('', InformData[:])] + + Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") + filename= webqtlUtil.genRandStr("Box_") + canvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) + + #supertable2.append(HT.TR(HT.TD(staIntro1, colspan=3 ))) + tb = HT.TableLite(border=0, cellspacing=0, cellpadding=0) + tb.append(HT.TR(HT.TD(img, align="left", style="border: 1px solid #999999; padding:0px;"))) + supertable2.append(HT.TR(TDStatis, HT.TD(tb))) + + dataXZ = vals[:] + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + nnStrain = len(tnames) + + sLabel = 1 + + ###determine bar width and space width + if nnStrain < 20: + sw = 4 + elif nnStrain < 40: + sw = 3 + else: + sw = 2 + + ### 700 is the default plot width minus Xoffsets for 40 strains + defaultWidth = 650 + if nnStrain > 40: + defaultWidth += (nnStrain-40)*10 + defaultOffset = 100 + bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) + if bw < 10: + bw = 10 + + plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset + plotHeight = 500 + #print [plotWidth, plotHeight, bw, sw, nnStrain] + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (sorted by name)' % self.identification, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img0=HT.Image('/image/'+filename+'.gif',border=0) + + dataXZ = vals[:] + dataXZ.sort(self.cmpValue) + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (ranked)' % self.identification, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img1=HT.Image('/image/'+filename+'.gif',border=0) + + # Lei Yan + # 05/18/2009 + # report + + title = HT.Paragraph('REPORT on the variation of Shh (or PCA Composite Trait XXXX) (sonic hedgehog) in the (insert Data set name) of (insert Species informal name, e.g., Mouse, Rat, Human, Barley, Arabidopsis)', Class="title") + header = HT.Paragraph('''This report was generated by GeneNetwork on May 11, 2009, at 11.20 AM using the Basic Statistics module (v 1.0) and data from the Hippocampus Consortium M430v2 (Jun06) PDNN data set. For more details and updates on this data set please link to URL:get Basic Statistics''') + hr = HT.HR() + p1 = HT.Paragraph('''Trait values for Shh were taken from the (insert Database name, Hippocampus Consortium M430v2 (Jun06) PDNN). GeneNetwork contains data for NN (e.g., 99) cases. In general, data are averages for each case. A summary of mean, median, and the range of these data are provided in Table 1 and in the box plot (Figure 1). Data for individual cases are provided in Figure 2A and 2B, often with error bars (SEM). ''') + p2 = HT.Paragraph('''Trait values for Shh range 5.1-fold: from a low of 8.2 (please round value) in 129S1/SvImJ to a high of 10.6 (please round value) in BXD9. The interquartile range (the difference between values closest to the 25% and 75% levels) is a more modest 1.8-fold. The mean value is XX. ''') + t1 = HT.Paragraph('''Table 1. Summary of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + f1 = HT.Paragraph('''Figure 1. ''') + f1.append(HT.Href(text="Box plot", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs14")) + f1.append(HT.Text(''' of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''')) + f2A = HT.Paragraph('''Figure 2A: Bar chart of Shh data ordered by case from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + f2B = HT.Paragraph('''Figure 2B: Bar chart of Shh values ordered by from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + TD_LR.append(HT.Blockquote(title, HT.P(), header, hr, p1, HT.P(), p2, HT.P(), supertable2, t1, f1, HT.P(), img0, f2A, HT.P(), img1, f2B)) + self.dict['body'] = str(TD_LR) + else: + heading = "Basic Statistics" + detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = "Basic Statistics" + detail = ['Empty data set, please check your data.'] + self.error(heading=heading,detail=detail) + return + + def traitInfo(self, fd, specialStrains = None): + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + heading2 = HT.Paragraph(HT.Strong('Population: '), "%s %s" % (species.title(), fd.RISet) , HT.BR()) + if self.Trait: + trait_url = HT.Href(text=self.Trait.name, url = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + \ + "?FormID=showDatabase&incparentsf1=1&database=%s&ProbeSetID=%s" % (self.Trait.db.name, self.Trait.name), \ + target='_blank', Class="fs13 fwn") + heading2.append(HT.Strong("Database: "), + HT.Href(text=self.Trait.db.fullname, url = webqtlConfig.INFOPAGEHREF % self.Trait.db.name , + target='_blank',Class="fs13 fwn"),HT.BR()) + if self.Trait.db.type == 'ProbeSet': + heading2.append(HT.Strong('Trait ID: '), trait_url, HT.BR(), + HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.symbol,id="green"),HT.BR()) + if self.Trait.chr and self.Trait.mb: + heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) + elif self.Trait.db.type == 'Geno': + heading2.append(HT.Strong('Locus : '), trait_url, HT.BR()) + #heading2.append(HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.Symbol,id="green"),HT.BR()) + if self.Trait.chr and self.Trait.mb: + heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) + elif self.Trait.db.type == 'Publish': + heading2.append(HT.Strong('Record ID: '), trait_url, HT.BR()) + heading2.append(HT.Strong('Phenotype: '), self.Trait.phenotype, HT.BR()) + heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) + elif self.Trait.db.type == 'Temp': + heading2.append(HT.Strong('Description: '), self.Trait.description, HT.BR()) + #heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) + else: + pass + else: + heading2.append(HT.Strong("Trait Name: "), fd.identification) + + if specialStrains: + mdpform = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='MDP_Form',submit=HT.Input(type='hidden')) + mdphddn = {'FormID':'dataEditing', 'submitID':'basicStatistics','RISet':fd.RISet, "allstrainlist":string.join(fd.allstrainlist, " "), "ptype":self.plotType, 'identification':fd.identification, "incparentsf1":1} + if self.fullname: mdphddn['fullname'] = self.fullname + webqtlUtil.exportData(mdphddn, fd.allTraitData) + for key in mdphddn.keys(): + mdpform.append(HT.Input(name=key, value=mdphddn[key], type='hidden')) + btn0 = HT.Input(type='button' ,name='',value='All Cases',onClick="this.form.ptype.value=0;submit();", Class="button") + btn1 = HT.Input(type='button' ,name='',value='%s Only' % fd.RISet,onClick="this.form.ptype.value=1;submit();", Class="button") + btn2 = HT.Input(type='button' ,name='',value='MDP Only', onClick="this.form.ptype.value=2;submit();", Class="button") + mdpform.append(btn0) + mdpform.append(btn1) + mdpform.append(btn2) + heading2.append(HT.P(), mdpform) + + return HT.Span(heading2) + + def calSD(self,var): + try: + return sqrt(abs(var)) + except: + return None + + + def cmpValue(self,A,B): + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 + + + + diff --git a/wqflask/basicStatistics/__init__.py b/wqflask/basicStatistics/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/basicStatistics/updatedBasicStatisticsPage.py b/wqflask/basicStatistics/updatedBasicStatisticsPage.py new file mode 100755 index 00000000..ab7ed07d --- /dev/null +++ b/wqflask/basicStatistics/updatedBasicStatisticsPage.py @@ -0,0 +1,150 @@ +from htmlgen import HTMLgen2 as HT + +from base.templatePage import templatePage +from dbFunction import webqtlDatabaseFunction +import BasicStatisticsFunctions + +#Window generated from the Trait Data and Analysis page (DataEditingPage.py) with updated stats figures; takes the page's values that can bed edited by the user +class updatedBasicStatisticsPage(templatePage): + + plotMinInformative = 4 + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + if not fd.genotype: + fd.readGenotype() + this_strainlist = fd.strainlist + + if fd.allstrainlist: + this_strainlist = fd.allstrainlist + + fd.readData(this_strainlist) + + specialStrains = [] #This appears to be the "other/non-RISet strainlist" without parents/f1 strains; not sure what to name it + setStrains = [] + for item in this_strainlist: + if item not in fd.strainlist and item.find('F1') < 0: + specialStrains.append(item) + else: + continue + + specialStrains.sort() + if specialStrains: + specialStrains = fd.f1list+fd.parlist+specialStrains + + self.dict['title'] = 'Basic Statistics' + TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") + + stats_row = HT.TR() + stats_cell = HT.TD() + stats_script = HT.Script(language="Javascript") + + #Get strain names, values, and variances + strain_names = fd.formdata.getvalue('strainNames').split(',') + strain_vals = fd.formdata.getvalue('strainVals').split(',') + strain_vars = fd.formdata.getvalue('strainVars').split(',') + + vals = [] + if (len(strain_names) > 0): + if (len(strain_names) > 3): + #Need to create "vals" object + for i in range(len(strain_names)): + try: + this_strain_val = float(strain_vals[i]) + except: + continue + try: + this_strain_var = float(strain_vars[i]) + except: + this_strain_var = None + + thisValFull = [strain_names[i], this_strain_val, this_strain_var] + vals.append(thisValFull) + + stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-2", Class="stats_tab"), + HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), + HT.Href(text="Box Plot", url="#statstabs-5", Class="stats_tab")] + stats_tabs = HT.List(stats_tab_list) + + stats_container = HT.Div(id="stats_tabs", Class="ui-tabs") + stats_container.append(stats_tabs) + + stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" #Javascript enabling tabs + + table_div = HT.Div(id="statstabs-1", style="height:320px;width:740px;overflow:scroll;") + table_container = HT.Paragraph() + + statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + this_trait_type = fd.formdata.getvalue('trait_type', None) + this_cellid = fd.formdata.getvalue('cellid', None) + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait_type, cellid=this_cellid) + statsTable.append(HT.TR(HT.TD(statsTableCell))) + + table_container.append(statsTable) + table_div.append(table_container) + stats_container.append(table_div) + + normalplot_div = HT.Div(id="statstabs-2", style="height:540px;width:740px;overflow:scroll;") + normalplot_container = HT.Paragraph() + normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + plotTitle = fd.formdata.getvalue("normalPlotTitle","") + normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + normalplot.append(HT.TR(HT.TD(normalplot_img))) + normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + normalplot_container.append(normalplot) + normalplot_div.append(normalplot_container) + stats_container.append(normalplot_div) + + barName_div = HT.Div(id="statstabs-3", style="height:540px;width:740px;overflow:scroll;") + barName_container = HT.Paragraph() + barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + barName.append(HT.TR(HT.TD(barName_img))) + barName_container.append(barName) + barName_div.append(barName_container) + stats_container.append(barName_div) + + barRank_div = HT.Div(id="statstabs-4", style="height:540px;width:740px;overflow:scroll;") + barRank_container = HT.Paragraph() + barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + barRank.append(HT.TR(HT.TD(barRank_img))) + barRank_container.append(barRank) + barRank_div.append(barRank_container) + stats_container.append(barRank_div) + + boxplot_div = HT.Div(id="statstabs-5", style="height:540px;width:740px;overflow:scroll;") + boxplot_container = HT.Paragraph() + boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + boxplot_container.append(boxplot) + boxplot_div.append(boxplot_container) + stats_container.append(boxplot_div) + + stats_cell.append(stats_container) + stats_script.append(stats_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + stats_row.append(stats_cell) + + submitTable.append(stats_row) + submitTable.append(stats_script) + + TD_LR.append(submitTable) + self.dict['body'] = str(TD_LR) + else: + heading = "Basic Statistics" + detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = "Basic Statistics" + detail = ['Empty data set, please check your data.'] + self.error(heading=heading,detail=detail) + return \ No newline at end of file diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py new file mode 100755 index 00000000..c2e1c37f --- /dev/null +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -0,0 +1,1898 @@ +import string +import os +import cPickle +#import pyXLWriter as xl + +from htmlgen import HTMLgen2 as HT + +from base import webqtlConfig +from utility import webqtlUtil #, Plot +from base.webqtlTrait import webqtlTrait +from dbFunction import webqtlDatabaseFunction +from base.templatePage import templatePage +from basicStatistics import BasicStatisticsFunctions + + +######################################### +# DataEditingPage +######################################### +class DataEditingPage(templatePage): + + def __init__(self, fd, thisTrait=None): + + templatePage.__init__(self, fd) + + self.dict['title'] = 'Data Editing' + TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") + + if not self.openMysql(): + return + if not fd.genotype: + fd.readData(incf1=1) + + ############################# + # determine data editing page format + ############################# + varianceDataPage = 0 + if fd.formID == 'varianceChoice': + varianceDataPage = 1 + + if varianceDataPage: + fmID='dataEditing' + nCols = 6 + else: + if fd.enablevariance: + fmID='pre_dataEditing' + nCols = 4 + else: + fmID='dataEditing' + nCols = 4 + + ############################# + ## titles, etc. + ############################# + + titleTop = HT.Div() + + title1 = HT.Paragraph("  Details and Links", style="border-radius: 5px;", Id="title1", Class="sectionheader") + title1Body = HT.Paragraph(Id="sectionbody1") + + if fd.enablevariance and not varianceDataPage: + title2 = HT.Paragraph("  Submit Variance", style="border-radius: 5px;", Id="title2", Class="sectionheader") + else: + title2 = HT.Paragraph("  Basic Statistics", style="border-radius: 5px;", Id="title2", Class="sectionheader") + title2Body = HT.Paragraph(Id="sectionbody2") + + title3 = HT.Paragraph("  Calculate Correlations", style="border-radius: 5px;", Id="title3", Class="sectionheader") + title3Body = HT.Paragraph(Id="sectionbody3") + + title4 = HT.Paragraph("  Mapping Tools", style="border-radius: 5px;", Id="title4", Class="sectionheader") + title4Body = HT.Paragraph(Id="sectionbody4") + + title5 = HT.Paragraph("  Review and Edit Data", style="border-radius: 5px;", Id="title5", Class="sectionheader") + title5Body = HT.Paragraph(Id="sectionbody5") + + ############################# + ## Hidden field + ############################# + + # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery + hddn = {'FormID':fmID, 'RISet':fd.RISet, 'submitID':'', 'scale':'physic', 'additiveCheck':'ON', 'showSNP':'ON', 'showGenes':'ON', 'method':None,\ + 'parentsf14regression':'OFF', 'stats_method':'1', 'chromosomes':'-1', 'topten':'', 'viewLegend':'ON', 'intervalAnalystCheck':'ON', 'valsHidden':'OFF',\ + 'database':'', 'criteria':None, 'MDPChoice':None, 'bootCheck':None, 'permCheck':None, 'applyVarianceSE':None, 'strainNames':'_', 'strainVals':'_',\ + 'strainVars':'_', 'otherStrainNames':'_', 'otherStrainVals':'_', 'otherStrainVars':'_', 'extra_attributes':'_', 'other_extra_attributes':'_'} + + if fd.enablevariance: + hddn['enablevariance']='ON' + if fd.incparentsf1: + hddn['incparentsf1']='ON' + + if thisTrait: + hddn['fullname'] = str(thisTrait) + try: + hddn['normalPlotTitle'] = thisTrait.symbol + hddn['normalPlotTitle'] += ": " + hddn['normalPlotTitle'] += thisTrait.name + except: + hddn['normalPlotTitle'] = str(thisTrait.name) + hddn['fromDataEditingPage'] = 1 + if thisTrait.db and thisTrait.db.type and thisTrait.db.type == 'ProbeSet': + hddn['trait_type'] = thisTrait.db.type + if thisTrait.cellid: + hddn['cellid'] = thisTrait.cellid + else: + self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % thisTrait.mysqlid) + heritability = self.cursor.fetchone() + hddn['heritability'] = heritability + + hddn['attribute_names'] = "" + + hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, groupName=fd.RISet) + + ############################# + ## Display Trait Information + ############################# + + headSpan = self.dispHeader(fd,thisTrait) #Draw header + + titleTop.append(headSpan) + + if fd.identification: + hddn['identification'] = fd.identification + + else: + hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named + + self.dispTraitInformation(fd, title1Body, hddn, thisTrait) #Display trait information + function buttons + + ############################# + ## Generate form and buttons + ############################# + + mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), + name='dataInput', submit=HT.Input(type='hidden')) + + next=HT.Input(type='submit', name='submit',value='Next',Class="button") + reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + correlationMenus = [] + + if thisTrait == None: + thisTrait = webqtlTrait(data=fd.allTraitData, db=None) + + # Variance submit page only + if fd.enablevariance and not varianceDataPage: + title2Body.append("Click the next button to go to the variance submission form.", + HT.Center(next,reset)) + else: + self.dispBasicStatistics(fd, title2Body, thisTrait) + self.dispCorrelationTools(fd, title3Body, thisTrait) + self.dispMappingTools(fd, title4Body, thisTrait) + + ############################# + ## Trait Value Table + ############################# + + self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) + + if fd.allstrainlist: + hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') + for key in hddn.keys(): + mainForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + if fd.enablevariance and not varianceDataPage: + #pre dataediting page, need to submit variance + mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + else: + mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + TD_LR.append(HT.Paragraph(mainForm)) + self.dict['body'] = str(TD_LR) + + ########################################## + ## Function to display header + ########################################## + def dispHeader(self, fd, thisTrait): + headSpan = HT.Div(style="font-size:14px;") + + #If trait, use trait name; otherwise, use identification value + if thisTrait: + if thisTrait.cellid: + headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Probe ID ', thisTrait.cellid) + else: + headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Record ID ', thisTrait.name) + else: + if fd.identification: + headSpan.append(HT.Strong('Trait ID ', style='font-size:16px;'),fd.identification) + else: + headSpan.append(HT.Strong('Un-named Trait', style='font-size:16px;')) + + return headSpan + + ########################################## + ## Function to display trait infos + ########################################## + def dispTraitInformation(self, fd, title1Body, hddn, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") + + reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + + #XZ, August 02, 2011: The display of icons is decided by the trait type (if trait exists), along with user log-in status. Note that the new submitted trait might not be trait object. + addSelectionButton = "" + verifyButton = "" + rnaseqButton = "" + geneWikiButton = "" + probeButton = "" + similarButton = "" + snpBrowserButton = "" + updateButton = "" + + addSelectionText = "" + verifyText = "" + rnaseqText = "" + geneWikiText = "" + probeText = "" + similarText = "" + snpBrowserText = "" + updateText = "" + + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: + + if thisTrait==None or thisTrait.db.type=='Temp': + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + elif thisTrait.db.type != 'Temp': + if thisTrait.db.type == 'Publish' and thisTrait.confidential: #XZ: confidential phenotype trait + if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + else: + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + else: + pass + + self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.RISet) + if thisTrait: + addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, 'dataInput')) + addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") + addSelectionButton.append(addSelectionButton_img) + addSelectionText = "Add" + elif self.cursor.fetchall(): + addSelectionButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('%s')[0], 'addRecord');" % ('dataInput')) + addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="", alt="Add To Collection", title="Add To Collection", style="border:none;") + addSelectionButton.append(addSelectionButton_img) + addSelectionText = "Add" + else: + pass + + + # Microarray database information to display + if thisTrait and thisTrait.db and thisTrait.db.type == 'ProbeSet': #before, this line was only reached if thisTrait != 0, but now we need to check + try: + hddn['GeneId'] = int(string.strip(thisTrait.geneid)) + except: + pass + + Info2Disp = HT.Paragraph() + + #XZ: Gene Symbol + if thisTrait.symbol: + #XZ: Show SNP Browser only for mouse + if _Species == 'mouse': + self.cursor.execute("select geneSymbol from GeneList where geneSymbol = %s", thisTrait.symbol) + geneName = self.cursor.fetchone() + if geneName: + snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + "&geneName=%s" % geneName[0] + else: + if thisTrait.chr and thisTrait.mb: + snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + \ + "&chr=%s&start=%2.6f&end=%2.6f" % (thisTrait.chr, thisTrait.mb-0.002, thisTrait.mb+0.002) + else: + snpurl = "" + + if snpurl: + snpBrowserButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % snpurl) + snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="snpbrowser", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") + snpBrowserButton.append(snpBrowserButton_img) + snpBrowserText = "SNPs" + + #XZ: Show GeneWiki for all species + geneWikiButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % thisTrait.symbol)) + geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="genewiki", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") + geneWikiButton.append(geneWikiButton_img) + geneWikiText = 'GeneWiki' + + #XZ: display similar traits in other selected datasets + if thisTrait and thisTrait.db and thisTrait.db.type=="ProbeSet" and thisTrait.symbol: + if _Species in ("mouse", "rat", "human"): + similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) + similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) + similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") + similarButton.append(similarButton_img) + similarText = "Find" + else: + pass + tbl.append(HT.TR( + HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('%s' % thisTrait.symbol, valign="top", Class="fs13 fsI"), valign="top", width=740) + )) + else: + tbl.append(HT.TR( + HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('Not available', Class="fs13 fsI"), valign="top") + )) + + #XZ: Gene Alias + if thisTrait.alias: + alias = string.replace(thisTrait.alias, ";", " ") + alias = string.join(string.split(alias), ", ") + tbl.append(HT.TR( + HT.TD('Aliases: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(alias, Class="fs13 fsI"), valign="top") + )) + + #XZ: Description + if thisTrait.description: + tSpan = HT.Span(thisTrait.description, Class="fs13") + if thisTrait.probe_target_description: + tSpan.append('; ', thisTrait.probe_target_description) + else: + tSpan = HT.Span('Not available', Class="fs13") + tbl.append(HT.TR( + HT.TD('Description: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + #XZ: Location + + #XZ: deal with Chr and Mb + if thisTrait.chr and thisTrait.mb: + tSpan = HT.Span('Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb),Class="fs13") + elif (thisTrait.chr): + tSpan = HT.Span('Chr %s @ Unknown position' % (thisTrait.chr), Class="fs13") + else: + tSpan = HT.Span('Not available', Class="fs13") + + #XZ: deal with direction + if thisTrait.strand_probe == '+': + tSpan.append(' on the plus strand ') + elif thisTrait.strand_probe == '-': + tSpan.append(' on the minus strand ') + else: + pass + + tbl.append(HT.TR( + HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + ##display Verify Location button + try: + blatsequence = thisTrait.blatseq + if not blatsequence: + #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. + self.cursor.execute("""SELECT Probe.Sequence, Probe.Name + FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) + seqs = self.cursor.fetchall() + if not seqs: + raise ValueError + else: + blatsequence = '' + for seqt in seqs: + if int(seqt[1][-1]) % 2 == 1: + blatsequence += string.strip(seqt[0]) + + #--------Hongqiang add this part in order to not only blat ProbeSet, but also blat Probe + blatsequence = '%3E'+thisTrait.name+'%0A'+blatsequence+'%0A' + #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. + self.cursor.execute("""SELECT Probe.Sequence, Probe.Name + FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) + + seqs = self.cursor.fetchall() + for seqt in seqs: + if int(seqt[1][-1]) %2 == 1: + blatsequence += '%3EProbe_'+string.strip(seqt[1])+'%0A'+string.strip(seqt[0])+'%0A' + #-------- + #XZ, 07/16/2009: targetsequence is not used, so I comment out this block + #targetsequence = thisTrait.targetseq + #if targetsequence==None: + # targetsequence = "" + + #XZ: Pay attention to the parameter of version (rn, mm, hg). They need to be changed if necessary. + if _Species == "rat": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', blatsequence) + UTHSC_BLAT_URL = "" + elif _Species == "mouse": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', blatsequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', blatsequence) + elif _Species == "human": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) + UTHSC_BLAT_URL = "" + else: + UCSC_BLAT_URL = "" + UTHSC_BLAT_URL = "" + + if UCSC_BLAT_URL: + verifyButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL) + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", + title=" Check probe locations at UCSC ", style="border:none;") + verifyButton.append(verifyButtonImg) + verifyText = 'Verify' + if UTHSC_BLAT_URL: + rnaseqButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL) + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", + title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButton.append(rnaseqButtonImg) + rnaseqText = 'RNA-seq' + tSpan.append(HT.BR()) + except: + pass + + #Display probe information (if any) + if thisTrait.db.name.find('Liver') >= 0 and thisTrait.db.name.find('F2') < 0: + pass + else: + #query database for number of probes associated with trait; if count > 0, set probe tool button and text + self.cursor.execute("""SELECT count(*) + FROM Probe, ProbeSet + WHERE ProbeSet.Name = '%s' AND Probe.ProbeSetId = ProbeSet.Id""" % (thisTrait.name)) + + probeResult = self.cursor.fetchone() + if probeResult[0] > 0: + probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&RISet=%s&incparentsf1=ON" \ + % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.db, thisTrait.name, thisTrait.cellid, fd.RISet) + probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) + probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") + probeButton.append(probeButton_img) + probeText = "Probes" + + tSpan = HT.Span(Class="fs13") + + #XZ: deal with blat score and blat specificity. + if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: + if thisTrait.probe_set_specificity: + tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) + if thisTrait.probe_set_blat_score: + tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) + + onClick="openNewWin('/blatInfo.html')" + + tbl.append(HT.TR( + HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + tSpan = HT.Span(Class="fs13") + tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) + + tbl.append(HT.TR( + HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + if thisTrait.cellid: + self.cursor.execute(""" + select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze + where + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Id = %d""" % thisTrait.db.id) + probeDBName = self.cursor.fetchone()[0] + tbl.append(HT.TR( + HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") + )) + else: + tbl.append(HT.TR( + HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, + target='_blank', Class="fs13 fwn non_bold"), valign="top") + )) + + #XZ: ID links + if thisTrait.genbankid or thisTrait.geneid or thisTrait.unigeneid or thisTrait.omim or thisTrait.homologeneid: + idStyle = "background:#dddddd;padding:2" + tSpan = HT.Span(Class="fs13") + if thisTrait.geneid: + gurl = HT.Href(text= 'Gene', target='_blank',\ + url=webqtlConfig.NCBI_LOCUSID % thisTrait.geneid, Class="fs14 fwn", title="Info from NCBI Entrez Gene") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.omim: + gurl = HT.Href(text= 'OMIM', target='_blank', \ + url= webqtlConfig.OMIM_ID % thisTrait.omim,Class="fs14 fwn", title="Summary from On Mendelian Inheritance in Man") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.unigeneid: + try: + gurl = HT.Href(text= 'UniGene',target='_blank',\ + url= webqtlConfig.UNIGEN_ID % tuple(string.split(thisTrait.unigeneid,'.')[:2]),Class="fs14 fwn", title="UniGene ID") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + except: + pass + if thisTrait.genbankid: + thisTrait.genbankid = '|'.join(thisTrait.genbankid.split('|')[0:10]) + if thisTrait.genbankid[-1]=='|': + thisTrait.genbankid=thisTrait.genbankid[0:-1] + gurl = HT.Href(text= 'GenBank', target='_blank', \ + url= webqtlConfig.GENBANK_ID % thisTrait.genbankid,Class="fs14 fwn", title="Find the original GenBank sequence used to design the probes") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.homologeneid: + hurl = HT.Href(text= 'HomoloGene', target='_blank',\ + url=webqtlConfig.HOMOLOGENE_ID % thisTrait.homologeneid, Class="fs14 fwn", title="Find similar genes in other species") + tSpan.append(HT.Span(hurl, style=idStyle), " "*2) + + tbl.append( + HT.TR(HT.TD(colspan=3,height=6)), + HT.TR( + HT.TD('Resource Links: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + #XZ: Resource Links: + if thisTrait.symbol: + linkStyle = "background:#dddddd;padding:2" + tSpan = HT.Span(style="font-family:verdana,serif;font-size:13px") + + #XZ,12/26/2008: Gene symbol may contain single quotation mark. + #For example, Affymetrix, mouse430v2, 1440338_at, the symbol is 2'-Pde (geneid 211948) + #I debug this by using double quotation marks. + if _Species == "rat": + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #symatlas_species = "Rattus norvegicus" + + #self.cursor.execute("SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = '%s'" % thisTrait.symbol) + self.cursor.execute('SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = "%s"' % thisTrait.symbol) + try: + kgId, chr, txst, txen = self.cursor.fetchall()[0] + if chr and txst and txen and kgId: + txst = int(txst*1000000) + txen = int(txen*1000000) + tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('rn3',kgId,chr,txst,txen),Class="fs14 fwn"), style=linkStyle) + , " "*2) + except: + pass + if _Species == "mouse": + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #symatlas_species = "Mus musculus" + + #self.cursor.execute("SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = '%s'" % thisTrait.symbol) + self.cursor.execute('SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = "%s"' % thisTrait.symbol) + try: + chr, txst, txen = self.cursor.fetchall()[0] + if chr and txst and txen and thisTrait.refseq_transcriptid : + txst = int(txst*1000000) + txen = int(txen*1000000) + tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('mm9',thisTrait.refseq_transcriptid,chr,txst,txen), + Class="fs14 fwn"), style=linkStyle) + , " "*2) + except: + pass + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #tSpan.append(HT.Span(HT.Href(text= 'SymAtlas',target="mainFrame",\ + # url="http://symatlas.gnf.org/SymAtlas/bioentry?querytext=%s&query=14&species=%s&type=Expression" \ + # % (thisTrait.symbol,symatlas_species),Class="fs14 fwn", \ + # title="Expression across many tissues and cell types"), style=linkStyle), " "*2) + if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): + tSpan.append(HT.Span(HT.Href(text= 'BioGPS',target="mainFrame",\ + url="http://biogps.gnf.org/?org=%s#goto=genereport&id=%s" \ + % (_Species, thisTrait.geneid),Class="fs14 fwn", \ + title="Expression across many tissues and cell types"), style=linkStyle), " "*2) + tSpan.append(HT.Span(HT.Href(text= 'STRING',target="mainFrame",\ + url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ + % thisTrait.symbol,Class="fs14 fwn", \ + title="Protein interactions: known and inferred"), style=linkStyle), " "*2) + if thisTrait.symbol: + #ZS: The "species scientific" converts the plain English species names we're using to their scientific names, which are needed for PANTHER's input + #We should probably use the scientific name along with the English name (if not instead of) elsewhere as well, given potential non-English speaking users + if _Species == "mouse": + species_scientific = "Mus%20musculus" + elif _Species == "rat": + species_scientific = "Rattus%20norvegicus" + elif _Species == "human": + species_scientific = "Homo%20sapiens" + elif _Species == "drosophila": + species_scientific = "Drosophila%20melanogaster" + else: + species_scientific = "all" + + species_scientific + tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ + url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ + % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ + title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) + else: + pass + #tSpan.append(HT.Span(HT.Href(text= 'BIND',target="mainFrame",\ + # url="http://bind.ca/?textquery=%s" \ + # % thisTrait.symbol,Class="fs14 fwn", \ + # title="Protein interactions"), style=linkStyle), " "*2) + if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): + tSpan.append(HT.Span(HT.Href(text= 'Gemma',target="mainFrame",\ + url="http://www.chibi.ubc.ca/Gemma/gene/showGene.html?ncbiid=%s" \ + % thisTrait.geneid, Class="fs14 fwn", \ + title="Meta-analysis of gene expression data"), style=linkStyle), " "*2) + tSpan.append(HT.Span(HT.Href(text= 'SynDB',target="mainFrame",\ + url="http://lily.uthsc.edu:8080/20091027_GNInterfaces/20091027_redirectSynDB.jsp?query=%s" \ + % thisTrait.symbol, Class="fs14 fwn", \ + title="Brain synapse database"), style=linkStyle), " "*2) + if _Species == "mouse": + tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + url="http://mouse.brain-map.org/brain/%s.html" \ + % thisTrait.symbol, Class="fs14 fwn", \ + title="Allen Brain Atlas"), style=linkStyle), " "*2) + + if thisTrait.geneid: + #if _Species == "mouse": + # tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + # url="http://www.brain-map.org/search.do?queryText=egeneid=%s" \ + # % thisTrait.geneid, Class="fs14 fwn", \ + # title="Allen Brain Atlas"), style=linkStyle), " "*2) + if _Species == "human": + tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + url="http://humancortex.alleninstitute.org/has/human/imageseries/search/1.html?searchSym=t&searchAlt=t&searchName=t&gene_term=&entrez_term=%s" \ + % thisTrait.geneid, Class="fs14 fwn", \ + title="Allen Brain Atlas"), style=linkStyle), " "*2) + tbl.append( + HT.TR(HT.TD(colspan=3,height=6)), + HT.TR( + HT.TD(' '), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top"))) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="620", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(similarButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(geneWikiButton, align="center"),HT.TD(snpBrowserButton, align="center"),HT.TD(rnaseqButton, align="center"),HT.TD(probeButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(similarText, align="center"),HT.TD(verifyText, align="center"),HT.TD(geneWikiText, align="center"),HT.TD(snpBrowserText, align="center"),HT.TD(rnaseqText, align="center"),HT.TD(probeText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + + #for zhou mi's cliques, need to be removed + #if self.database[:6] == 'BXDMic' and self.ProbeSetID in cliqueID: + # Info2Disp.append(HT.Strong('Clique Search: '),HT.Href(text='Search',\ + # url ="http://compbio1.utmem.edu/clique_go/results.php?pid=%s&pval_1=0&pval_2=0.001" \ + # % self.ProbeSetID,target='_blank',Class="normalsize"),HT.BR()) + + #linkTable.append(HT.TR(linkTD)) + #Info2Disp.append(linkTable) + title1Body.append(tbl, HT.BR(), menuTable) + + elif thisTrait and thisTrait.db and thisTrait.db.type =='Publish': #Check if trait is phenotype + + if thisTrait.confidential: + tbl.append(HT.TR( + HT.TD('Pre-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.pre_publication_description, Class="fs13"), valign="top", width=740) + )) + if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): + tbl.append(HT.TR( + HT.TD('Post-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Pre-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.pre_publication_abbreviation, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Post-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_abbreviation, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Lab code: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.lab_code, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Owner: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.owner, Class="fs13"), valign="top", width=740) + )) + else: + tbl.append(HT.TR( + HT.TD('Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Authors: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.authors, Class="fs13"), + valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Title: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.title, Class="fs13"), + valign="top", width=740) + )) + if thisTrait.journal: + journal = thisTrait.journal + if thisTrait.year: + journal = thisTrait.journal + " (%s)" % thisTrait.year + + tbl.append(HT.TR( + HT.TD('Journal: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(journal, Class="fs13"), + valign="top", width=740) + )) + PubMedLink = "" + if thisTrait.pubmed_id: + PubMedLink = webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id + if PubMedLink: + tbl.append(HT.TR( + HT.TD('Link: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(HT.Href(url=PubMedLink, text="PubMed",target='_blank',Class="fs14 fwn"), + style = "background:#cddcff;padding:2"), valign="top", width=740) + )) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + elif thisTrait and thisTrait.db and thisTrait.db.type == 'Geno': #Check if trait is genotype + + GenoInfo = HT.Paragraph() + if thisTrait.chr and thisTrait.mb: + location = ' Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb) + else: + location = "not available" + + if thisTrait.sequence and len(thisTrait.sequence) > 100: + if _Species == "rat": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', thisTrait.sequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('rat', 'rn3', thisTrait.sequence) + elif _Species == "mouse": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) + elif _Species == "human": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('human', 'hg19', thisTrait.sequence) + else: + UCSC_BLAT_URL = "" + UTHSC_BLAT_URL = "" + if UCSC_BLAT_URL: + #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) + verifyButton = HT.Href(url="#") + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") + verifyButton.append(verifyButtonImg) + verifyText = "Verify" + rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButton.append(rnaseqButtonImg) + rnaseqText = "RNA-seq" + + tbl.append(HT.TR( + HT.TD('Location: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(location, Class="fs13"), valign="top", width=740) + ), + HT.TR( + HT.TD('SNP Search: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Href("http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=snp&cmd=search&term=%s" % thisTrait.name, 'NCBI',Class="fs13"), + valign="top", width=740) + )) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + elif (thisTrait == None or thisTrait.db.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) + + TempInfo = HT.Paragraph() + if thisTrait != None: + if thisTrait.description: + tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),' %s ' % thisTrait.description,HT.BR()), colspan=3, height=15)) + else: + tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),'not available',HT.BR(),HT.BR()), colspan=3, height=15)) + + if (updateText == "Edit"): + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") + else: + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="80", id="target1") + + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="right"),HT.TD(updateButton, align="right"), colspan=3, height=50, style="vertical-align:bottom;") ) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + else: + pass + + + ########################################## + ## Function to display analysis tools + ########################################## + def dispBasicStatistics(self, fd, title2Body, thisTrait): + + #XZ, June 22, 2011: The definition and usage of primary_strains, other_strains, specialStrains, all_strains are not clear and hard to understand. But since they are only used in this function for draw graph purpose, they will not hurt the business logic outside. As of June 21, 2011, this function seems work fine, so no hurry to clean up. These parameters and code in this function should be cleaned along with fd.f1list, fd.parlist, fd.strainlist later. + stats_row = HT.TR() + stats_cell = HT.TD() + + if fd.genotype.type == "riset": + strainlist = fd.f1list + fd.strainlist + else: + strainlist = fd.f1list + fd.parlist + fd.strainlist + + other_strains = [] #XZ: strain that is not of primary group + specialStrains = [] #XZ: This might be replaced by other_strains / ZS: It is just other strains without parent/f1 strains. + all_strains = [] + primary_strains = [] #XZ: strain of primary group, e.g., BXD, LXS + + MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') + + for strain in thisTrait.data.keys(): + strainName = strain.replace("_2nd_", "") + if strain not in strainlist: + if (thisTrait.data[strainName].val != None): + if strain.find('F1') < 0: + specialStrains.append(strain) + if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): + other_strains.append(strain) #XZ: at current stage, other_strains doesn't include parent strains and F1 strains of primary group + else: + if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): + primary_strains.append(strain) #XZ: at current stage, the primary_strains is the same as fd.strainlist / ZS: I tried defining primary_strains as fd.strainlist instead, but in some cases it ended up including the parent strains (1436869_at BXD) + + if len(other_strains) > 3: + other_strains.sort(key=webqtlUtil.natsort_key) + primary_strains.sort(key=webqtlUtil.natsort_key) + primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains #XZ: note that fd.f1list and fd.parlist are added. + all_strains = primary_strains + other_strains + other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #XZ: note that fd.f1list and fd.parlist are added. + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet,'1')) + MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + stats_row.append("Include: ", MDP_menu, HT.BR(), HT.BR()) + else: + if (len(other_strains) > 0) and (len(primary_strains) + len(other_strains) > 3): + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet,'1')) + MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + stats_row.append("Include: ", MDP_menu, " "*3) + all_strains = primary_strains + all_strains.sort(key=webqtlUtil.natsort_key) + all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains + primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains + else: + all_strains = strainlist + + other_strains.sort(key=webqtlUtil.natsort_key) + all_strains = all_strains + other_strains + pass + + update_button = HT.Input(type='button',value=' Update Figures ', Class="button update") #This is used to reload the page and update the Basic Statistics figures with user-edited data + stats_row.append(update_button, HT.BR(), HT.BR()) + + if (len(other_strains)) > 0 and (len(primary_strains) + len(other_strains) > 4): + #One set of vals for all, selected strain only, and non-selected only + vals1 = [] + vals2 = [] + vals3 = [] + + #Using all strains/cases for values + for i, strainNameOrig in enumerate(all_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals1.append(thisValFull) + + #Using just the RISet strain + for i, strainNameOrig in enumerate(primary_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals2.append(thisValFull) + + #Using all non-RISet strains only + for i, strainNameOrig in enumerate(other_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals3.append(thisValFull) + + vals_set = [vals1,vals2,vals3] + + else: + vals = [] + + #Using all strains/cases for values + for i, strainNameOrig in enumerate(all_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals.append(thisValFull) + + vals_set = [vals] + + stats_script = HT.Script(language="Javascript") #script needed for tabs + + for i, vals in enumerate(vals_set): + if i == 0 and len(vals) < 4: + stats_container = HT.Div(id="stats_tabs", style="padding:10px;", Class="ui-tabs") #Needed for tabs; notice the "stats_script_text" below referring to this element + stats_container.append(HT.Div(HT.Italic("Fewer than 4 case data were entered. No statistical analysis has been attempted."))) + stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" + stats_cell.append(stats_container) + break + elif (i == 1 and len(primary_strains) < 4): + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_container.append(HT.Div(HT.Italic("Fewer than 4 " + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + elif (i == 2 and len(other_strains) < 4): + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" + else: + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" + if len(vals) > 4: + stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"), + HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), + HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")] + stats_tabs = HT.List(stats_tab_list) + stats_container.append(stats_tabs) + + table_div = HT.Div(id="statstabs-1") + table_container = HT.Paragraph() + + statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + + if thisTrait.db: + if thisTrait.cellid: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type, cellid=thisTrait.cellid) + else: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type) + else: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals) + + statsTable.append(HT.TR(HT.TD(statsTableCell))) + + table_container.append(statsTable) + table_div.append(table_container) + stats_container.append(table_div) + + normalplot_div = HT.Div(id="statstabs-5") + normalplot_container = HT.Paragraph() + normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + + try: + plotTitle = thisTrait.symbol + plotTitle += ": " + plotTitle += thisTrait.name + except: + plotTitle = str(thisTrait.name) + + normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + normalplot.append(HT.TR(HT.TD(normalplot_img))) + normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + normalplot_container.append(normalplot) + normalplot_div.append(normalplot_container) + stats_container.append(normalplot_div) + + boxplot_div = HT.Div(id="statstabs-2") + boxplot_container = HT.Paragraph() + boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + boxplot_container.append(boxplot) + boxplot_div.append(boxplot_container) + stats_container.append(boxplot_div) + + + barName_div = HT.Div(id="statstabs-3") + barName_container = HT.Paragraph() + barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + barName.append(HT.TR(HT.TD(barName_img))) + barName_container.append(barName) + barName_div.append(barName_container) + stats_container.append(barName_div) + + barRank_div = HT.Div(id="statstabs-4") + barRank_container = HT.Paragraph() + barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + barRank.append(HT.TR(HT.TD(barRank_img))) + barRank_container.append(barRank) + barRank_div.append(barRank_container) + stats_container.append(barRank_div) + + stats_cell.append(stats_container) + + stats_script.append(stats_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") + stats_row.append(stats_cell) + + submitTable.append(stats_row) + submitTable.append(stats_script) + + title2Body.append(submitTable) + + + def dispCorrelationTools(self, fd, title3Body, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + RISetgp = fd.RISet + if RISetgp[:3] == 'BXD': + RISetgp = 'BXD' + + if RISetgp: + sample_correlation = HT.Input(type='button',name='sample_corr', value=' Compute ', Class="button sample_corr") + lit_correlation = HT.Input(type='button',name='lit_corr', value=' Compute ', Class="button lit_corr") + tissue_correlation = HT.Input(type='button',name='tiss_corr', value=' Compute ', Class="button tiss_corr") + methodText = HT.Span("Calculate:", Class="ffl fwb fs12") + + databaseText = HT.Span("Database:", Class="ffl fwb fs12") + databaseMenu1 = HT.Select(name='database1') + databaseMenu2 = HT.Select(name='database2') + databaseMenu3 = HT.Select(name='database3') + + nmenu = 0 + self.cursor.execute('SELECT PublishFreeze.FullName,PublishFreeze.Name FROM \ + PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id \ + and InbredSet.Name = "%s" and PublishFreeze.public > %d' % \ + (RISetgp,webqtlConfig.PUBLICTHRESH)) + for item in self.cursor.fetchall(): + databaseMenu1.append(item) + databaseMenu2.append(item) + databaseMenu3.append(item) + nmenu += 1 + self.cursor.execute('SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze,\ + InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = \ + "%s" and GenoFreeze.public > %d' % (RISetgp,webqtlConfig.PUBLICTHRESH)) + for item in self.cursor.fetchall(): + databaseMenu1.append(item) + databaseMenu2.append(item) + databaseMenu3.append(item) + nmenu += 1 + #03/09/2009: Xiaodong changed the SQL query to order by Name as requested by Rob. + self.cursor.execute('SELECT Id, Name FROM Tissue order by Name') + for item in self.cursor.fetchall(): + TId, TName = item + databaseMenuSub = HT.Optgroup(label = '%s ------' % TName) + self.cursor.execute('SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, \ + InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %d and \ + ProbeSetFreeze.public > %d and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like "%s%%" \ + order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ' % (TId,webqtlConfig.PUBLICTHRESH, RISetgp)) + for item2 in self.cursor.fetchall(): + databaseMenuSub.append(item2) + nmenu += 1 + databaseMenu1.append(databaseMenuSub) + databaseMenu2.append(databaseMenuSub) + databaseMenu3.append(databaseMenuSub) + if nmenu: + if thisTrait and thisTrait.db != None: + databaseMenu1.selected.append(thisTrait.db.fullname) + databaseMenu2.selected.append(thisTrait.db.fullname) + databaseMenu3.selected.append(thisTrait.db.fullname) + + criteriaText = HT.Span("Return:", Class="ffl fwb fs12") + + criteriaMenu1 = HT.Select(name='criteria1', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu1.append(('top 100','100')) + criteriaMenu1.append(('top 200','200')) + criteriaMenu1.append(('top 500','500')) + criteriaMenu1.append(('top 1000','1000')) + criteriaMenu1.append(('top 2000','2000')) + criteriaMenu1.append(('top 5000','5000')) + criteriaMenu1.append(('top 10000','10000')) + criteriaMenu1.append(('top 15000','15000')) + criteriaMenu1.append(('top 20000','20000')) + + criteriaMenu2 = HT.Select(name='criteria2', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu2.append(('top 100','100')) + criteriaMenu2.append(('top 200','200')) + criteriaMenu2.append(('top 500','500')) + criteriaMenu2.append(('top 1000','1000')) + criteriaMenu2.append(('top 2000','2000')) + criteriaMenu2.append(('top 5000','5000')) + criteriaMenu2.append(('top 10000','10000')) + criteriaMenu2.append(('top 15000','15000')) + criteriaMenu2.append(('top 20000','20000')) + + criteriaMenu3 = HT.Select(name='criteria3', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu3.append(('top 100','100')) + criteriaMenu3.append(('top 200','200')) + criteriaMenu3.append(('top 500','500')) + criteriaMenu3.append(('top 1000','1000')) + criteriaMenu3.append(('top 2000','2000')) + criteriaMenu3.append(('top 5000','5000')) + criteriaMenu3.append(('top 10000','10000')) + criteriaMenu3.append(('top 15000','15000')) + criteriaMenu3.append(('top 20000','20000')) + + + self.MDPRow1 = HT.TR(Class='mdp1') + self.MDPRow2 = HT.TR(Class='mdp2') + self.MDPRow3 = HT.TR(Class='mdp3') + + correlationMenus1 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu1, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu1)), + self.MDPRow1, cellspacing=0, width="619px", cellpadding=2) + correlationMenus1.append(HT.Input(name='orderBy', value='2', type='hidden')) # to replace the orderBy menu + correlationMenus2 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu2, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu2)), + self.MDPRow2, cellspacing=0, width="619px", cellpadding=2) + correlationMenus2.append(HT.Input(name='orderBy', value='2', type='hidden')) + correlationMenus3 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu3, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu3)), + self.MDPRow3, cellspacing=0, width="619px", cellpadding=2) + correlationMenus3.append(HT.Input(name='orderBy', value='2', type='hidden')) + + else: + correlationMenus = "" + + + corr_row = HT.TR() + corr_container = HT.Div(id="corr_tabs", Class="ui-tabs") + + if (thisTrait.db != None and thisTrait.db.type =='ProbeSet'): + corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1"), HT.Href(text='Literature r', url="#corrtabs-2"), HT.Href(text='Tissue r', url="#corrtabs-3")] + else: + corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1")] + + corr_tabs = HT.List(corr_tab_list) + corr_container.append(corr_tabs) + + if correlationMenus1 or correlationMenus2 or correlationMenus3: + sample_div = HT.Div(id="corrtabs-1") + sample_container = HT.Span() + + sample_type = HT.Input(type="radio", name="sample_method", value="1", checked="checked") + sample_type2 = HT.Input(type="radio", name="sample_method", value="2") + + sampleTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + sampleTD = HT.TD(correlationMenus1, HT.BR(), + "Pearson", sample_type, " "*3, "Spearman Rank", sample_type2, HT.BR(), HT.BR(), + sample_correlation, HT.BR(), HT.BR()) + + sampleTD.append(HT.Span("The ",HT.Href(url="/correlationAnnotation.html#sample_r", target="_blank", text="Sample Correlation")," is computed between trait data and", + " any ",HT.BR()," other traits in the sample database selected above. Use ", + HT.Href(url="/glossary.html#Correlations", target="_blank", text="Spearman Rank"), + HT.BR(),"when the sample size is small (<20) or when there are influential \ + outliers.", HT.BR(),Class="fs12")) + + sampleTable.append(sampleTD) + + sample_container.append(sampleTable) + sample_div.append(sample_container) + corr_container.append(sample_div) + + literature_div = HT.Div(id="corrtabs-2") + literature_container = HT.Span() + + literatureTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + literatureTD = HT.TD(correlationMenus2,HT.BR(),lit_correlation, HT.BR(), HT.BR()) + literatureTD.append(HT.Span("The ", HT.Href(url="/correlationAnnotation.html", target="_blank",text="Literature Correlation"), " (Lit r) between this gene and all other genes is computed",HT.BR(), + "using the ", HT.Href(url="https://grits.eecs.utk.edu/sgo/sgo.html", target="_blank", text="Semantic Gene Organizer"), + " and human, rat, and mouse data from PubMed. ", HT.BR(),"Values are ranked by Lit r, \ + but Sample r and Tissue r are also displayed.", HT.BR(), HT.BR(), + HT.Href(url="/glossary.html#Literature", target="_blank", text="More on using Lit r"), Class="fs12")) + literatureTable.append(literatureTD) + + literature_container.append(literatureTable) + literature_div.append(literature_container) + + if thisTrait.db != None: + if (thisTrait.db.type =='ProbeSet'): + corr_container.append(literature_div) + + tissue_div = HT.Div(id="corrtabs-3") + tissue_container = HT.Span() + + tissue_type = HT.Input(type="radio", name="tissue_method", value="4", checked="checked") + tissue_type2 = HT.Input(type="radio", name="tissue_method", value="5") + + tissueTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + tissueTD = HT.TD(correlationMenus3,HT.BR(), + "Pearson", tissue_type, " "*3, "Spearman Rank", tissue_type2, HT.BR(), HT.BR(), + tissue_correlation, HT.BR(), HT.BR()) + tissueTD.append(HT.Span("The ", HT.Href(url="/webqtl/main.py?FormID=tissueCorrelation", target="_blank", text="Tissue Correlation"), + " (Tissue r) estimates the similarity of expression of two genes",HT.BR()," or \ + transcripts across different cells, tissues, or organs (",HT.Href(url="/correlationAnnotation.html#tissue_r", target="_blank", text="glossary"),"). \ + Tissue correlations",HT.BR()," are generated by analyzing expression in multiple samples usually taken from \ + single cases.",HT.BR(),HT.Bold("Pearson")," and ",HT.Bold("Spearman Rank")," correlations have been computed for all pairs \ + of genes",HT.BR()," using data from mouse samples.", + HT.BR(), Class="fs12")) + tissueTable.append(tissueTD) + + tissue_container.append(tissueTable) + tissue_div.append(tissue_container) + if thisTrait.db != None: + if (thisTrait.db.type =='ProbeSet'): + corr_container.append(tissue_div) + + corr_row.append(HT.TD(corr_container)) + + corr_script = HT.Script(language="Javascript") + corr_script_text = """$(function() { $("#corr_tabs").tabs(); });""" + corr_script.append(corr_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target4") + submitTable.append(corr_row) + submitTable.append(corr_script) + + title3Body.append(submitTable) + + + def dispMappingTools(self, fd, title4Body, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + RISetgp = fd.RISet + if RISetgp[:3] == 'BXD': + RISetgp = 'BXD' + + #check boxes - one for regular interval mapping, the other for composite + permCheck1= HT.Input(type='checkbox', Class='checkbox', name='permCheck1',checked="on") + bootCheck1= HT.Input(type='checkbox', Class='checkbox', name='bootCheck1',checked=0) + permCheck2= HT.Input(type='checkbox', Class='checkbox', name='permCheck2',checked="on") + bootCheck2= HT.Input(type='checkbox', Class='checkbox', name='bootCheck2',checked=0) + optionbox1 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression1',checked=0) + optionbox2 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression2',checked=0) + optionbox3 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression3',checked=0) + applyVariance1 = HT.Input(name='applyVarianceSE1',type='checkbox', Class='checkbox') + applyVariance2 = HT.Input(name='applyVarianceSE2',type='checkbox', Class='checkbox') + + IntervalMappingButton=HT.Input(type='button' ,name='interval',value=' Compute ', Class="button") + CompositeMappingButton=HT.Input(type='button' ,name='composite',value=' Compute ', Class="button") + MarkerRegressionButton=HT.Input(type='button',name='marker', value=' Compute ', Class="button") + + chrText = HT.Span("Chromosome:", Class="ffl fwb fs12") + + # updated by NL 5-28-2010 + # Interval Mapping + chrMenu = HT.Select(name='chromosomes1') + chrMenu.append(tuple(["All",-1])) + for i in range(len(fd.genotype)): + if len(fd.genotype[i]) > 1: + chrMenu.append(tuple([fd.genotype[i].name,i])) + + #Menu for Composite Interval Mapping + chrMenu2 = HT.Select(name='chromosomes2') + chrMenu2.append(tuple(["All",-1])) + for i in range(len(fd.genotype)): + if len(fd.genotype[i]) > 1: + chrMenu2.append(tuple([fd.genotype[i].name,i])) + + if fd.genotype.Mbmap: + scaleText = HT.Span("Mapping Scale:", Class="ffl fwb fs12") + scaleMenu1 = HT.Select(name='scale1', onChange="checkUncheck(window.document.dataInput.scale1.value, window.document.dataInput.permCheck1, window.document.dataInput.bootCheck1)") + scaleMenu1.append(("Megabase",'physic')) + scaleMenu1.append(("Centimorgan",'morgan')) + scaleMenu2 = HT.Select(name='scale2', onChange="checkUncheck(window.document.dataInput.scale2.value, window.document.dataInput.permCheck2, window.document.dataInput.bootCheck2)") + scaleMenu2.append(("Megabase",'physic')) + scaleMenu2.append(("Centimorgan",'morgan')) + + controlText = HT.Span("Control Locus:", Class="ffl fwb fs12") + controlMenu = HT.Input(type="text", name="controlLocus", Class="controlLocus") + + if fd.genotype.Mbmap: + intMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), + HT.TR(HT.TD(scaleText), HT.TD(scaleMenu1)), + cellspacing=0, width="263px", cellpadding=2) + compMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), + HT.TR(HT.TD(scaleText), HT.TD(scaleMenu2)), + HT.TR(HT.TD(controlText), HT.TD(controlMenu)), + cellspacing=0, width="325px", cellpadding=2) + else: + intMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), + cellspacing=0, width="263px", cellpadding=2) + compMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), + HT.TR(HT.TD(controlText), HT.TD(controlMenu)), + cellspacing=0, width="325px", cellpadding=2) + + directPlotButton = "" + directPlotButton = HT.Input(type='button',name='', value=' Compute ',\ + onClick="dataEditingFunc(this.form,'directPlot');",Class="button") + directPlotSortText = HT.Span(HT.Bold("Sort by: "), Class="ffl fwb fs12") + directPlotSortMenu = HT.Select(name='graphSort') + directPlotSortMenu.append(('LRS Full',0)) + directPlotSortMenu.append(('LRS Interact',1)) + directPlotPermuText = HT.Span("Permutation Test (n=500)", Class="ffl fs12") + directPlotPermu = HT.Input(type='checkbox', Class='checkbox',name='directPermuCheckbox', checked="on") + pairScanReturnText = HT.Span(HT.Bold("Return: "), Class="ffl fwb fs12") + pairScanReturnMenu = HT.Select(name='pairScanReturn') + pairScanReturnMenu.append(('top 50','50')) + pairScanReturnMenu.append(('top 100','100')) + pairScanReturnMenu.append(('top 200','200')) + pairScanReturnMenu.append(('top 500','500')) + + pairScanMenus = HT.TableLite( + HT.TR(HT.TD(directPlotSortText), HT.TD(directPlotSortMenu)), + HT.TR(HT.TD(pairScanReturnText), HT.TD(pairScanReturnMenu)), + cellspacing=0, width="232px", cellpadding=2) + + markerSuggestiveText = HT.Span(HT.Bold("Display LRS greater than:"), Class="ffl fwb fs12") + markerSuggestive = HT.Input(name='suggestive', size=5, maxlength=8) + displayAllText = HT.Span(" Display all LRS ", Class="ffl fs12") + displayAll = HT.Input(name='displayAllLRS', type="checkbox", Class='checkbox') + useParentsText = HT.Span(" Use Parents ", Class="ffl fs12") + useParents = optionbox2 + applyVarianceText = HT.Span(" Use Weighted ", Class="ffl fs12") + + markerMenu = HT.TableLite( + HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive)), + HT.TR(HT.TD(displayAll,displayAllText)), + HT.TR(HT.TD(useParents,useParentsText)), + HT.TR(HT.TD(applyVariance2,applyVarianceText)), + cellspacing=0, width="263px", cellpadding=2) + + + mapping_row = HT.TR() + mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") + + mapping_tab_list = [HT.Href(text="Interval", url="#mappingtabs-1"), HT.Href(text="Marker Regression", url="#mappingtabs-2"), HT.Href(text="Composite", url="#mappingtabs-3"), HT.Href(text="Pair-Scan", url="#mappingtabs-4")] + mapping_tabs = HT.List(mapping_tab_list) + mapping_container.append(mapping_tabs) + + interval_div = HT.Div(id="mappingtabs-1") + interval_container = HT.Span() + + intervalTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + intTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + intTD.append(intMappingMenu,HT.BR()) + + intTD.append(permCheck1,'Permutation Test (n=2000)',HT.BR(), + bootCheck1,'Bootstrap Test (n=2000)', HT.BR(), optionbox1, 'Use Parents', HT.BR(), + applyVariance1,'Use Weighted', HT.BR(), HT.BR(),IntervalMappingButton, HT.BR(), HT.BR()) + intervalTable.append(HT.TR(intTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#intmap', target='_blank', text='Interval Mapping'), + ' computes linkage maps for the entire genome or single',HT.BR(),' chromosomes.', + ' The ',HT.Href(url='/glossary.html#permutation', target='_blank', text='Permutation Test'),' estimates suggestive and significant ',HT.BR(),' linkage scores. \ + The ',HT.Href(url='/glossary.html#bootstrap', target='_blank', text='Bootstrap Test'), ' estimates the precision of the QTL location.' + ,Class="fs12"), HT.BR(), valign="top"))) + + interval_container.append(intervalTable) + interval_div.append(interval_container) + mapping_container.append(interval_div) + + # Marker Regression + + marker_div = HT.Div(id="mappingtabs-2") + marker_container = HT.Span() + + markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + markerTD.append(markerMenu,HT.BR()) + + markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) + + markerTable.append(HT.TR(markerTD),HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#',target='_blank',text='Marker regression'), + ' computes and displays LRS values for individual markers.',HT.BR(), + 'This function also lists additive effects (phenotype units per allele) and', HT.BR(), + 'dominance deviations for some datasets.', HT.BR(),Class="fs12"), HT.BR(), valign="top"))) + + marker_container.append(markerTable) + marker_div.append(marker_container) + mapping_container.append(marker_div) + + # Composite interval mapping + composite_div = HT.Div(id="mappingtabs-3") + composite_container = HT.Span() + + compositeTable = HT.TableLite(cellspacing=0, cellpadding=3, width="100%") + compTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + compTD.append(compMappingMenu,HT.BR()) + + compTD.append(permCheck2, 'Permutation Test (n=2000)',HT.BR(), + bootCheck2,'Bootstrap Test (n=2000)', HT.BR(), + optionbox3, 'Use Parents', HT.BR(), HT.BR(), CompositeMappingButton, HT.BR(), HT.BR()) + compositeTable.append(HT.TR(compTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Composite',target='_blank',text='Composite Interval Mapping'), + " allows you to control for a single marker as",HT.BR()," a cofactor. ", + "To find a control marker, run the ",HT.Bold("Marker Regression")," function."), + HT.BR(), valign="top"))) + + composite_container.append(compositeTable) + composite_div.append(composite_container) + mapping_container.append(composite_div) + + # Pair Scan + + pairscan_div = HT.Div(id="mappingtabs-4") + pairscan_container = HT.Span() + + pairScanTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + pairScanTD = HT.TD(NOWRAP='ON', Class="fs12 fwn") + pairScanTD.append(pairScanMenus,HT.BR()) + pairScanTD.append(directPlotPermu, directPlotPermuText, HT.BR(), HT.BR(), + directPlotButton,HT.BR(),HT.BR()) + pairScanTable.append(HT.TR(pairScanTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Pair_Scan', target="_blank", text='Pair-Scan'), + ' searches for pairs of chromosomal regions that are',HT.BR(), + 'involved in two-locus epistatic interactions.'), HT.BR(), valign="top"))) + + pairscan_container.append(pairScanTable) + pairscan_div.append(pairscan_container) + mapping_container.append(pairscan_div) + + mapping_row.append(HT.TD(mapping_container)) + + # Treat Interval Mapping and Marker Regression and Pair Scan as a group for displaying + #disable Interval Mapping and Marker Regression and Pair Scan for human and the dataset doesn't have genotype file + mappingMethodId = webqtlDatabaseFunction.getMappingMethod(cursor=self.cursor, groupName=RISetgp) + + mapping_script = HT.Script(language="Javascript") + mapping_script_text = """$(function() { $("#mapping_tabs").tabs(); });""" + mapping_script.append(mapping_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") + + if mappingMethodId != None: + if int(mappingMethodId) == 1: + submitTable.append(mapping_row) + submitTable.append(mapping_script) + elif int(mappingMethodId) == 4: + # NL; 09-26-2011 testing for Human Genome Association function + mapping_row=HT.TR() + mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") + + mapping_tab_list = [HT.Href(text="Genome Association", url="#mappingtabs-1")] + mapping_tabs = HT.List(mapping_tab_list) + mapping_container.append(mapping_tabs) + + # Genome Association + markerSuggestiveText = HT.Span(HT.Bold("P Value:"), Class="ffl fwb fs12") + + markerSuggestive = HT.Input(name='pValue', value='0.001', size=10, maxlength=20,onClick="this.value='';",onBlur="if(this.value==''){this.value='0.001'};") + markerMenu = HT.TableLite(HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive),HT.TD(HT.Italic('   (e.g. 0.001 or 1e-3 or 1E-3 or 3)'))),cellspacing=0, width="400px", cellpadding=2) + MarkerRegressionButton=HT.Input(type='button',name='computePlink', value='  Compute Using PLINK  ', onClick= "validatePvalue(this.form);", Class="button") + + marker_div = HT.Div(id="mappingtabs-1") + marker_container = HT.Span() + markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + markerTD.append(markerMenu,HT.BR()) + markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) + markerTable.append(HT.TR(markerTD)) + + marker_container.append(markerTable) + marker_div.append(marker_container) + + mapping_container.append(marker_div) + mapping_row.append(HT.TD(mapping_container)) + submitTable.append(mapping_row) + submitTable.append(mapping_script) + else: + submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("mappingMethodId %s has not been implemented for this dataset yet." % mappingMethodId), id="mapping_tabs", Class="ui-tabs")))) + submitTable.append(mapping_script) + + else: + submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("Mapping options are disabled for data not matched with genotypes."), id="mapping_tabs", Class="ui-tabs")))) + submitTable.append(mapping_script) + + title4Body.append(submitTable) + + + def natural_sort(strain_list): + + sorted = [] + for strain in strain_list: + try: + strain = int(strain) + try: sorted[-1] = sorted[-1] * 10 + strain + except: sorted.append(strain) + except: + sorted.append(strain) + return sorted + + ########################################## + ## Function to display trait tables + ########################################## + def dispTraitValues(self, fd , title5Body, varianceDataPage, nCols, mainForm, thisTrait): + traitTableOptions = HT.Div(style="border: 3px solid #EEEEEE; -moz-border-radius: 10px; -webkit-border-radius: 10px; width: 625px; padding: 5px 5px 10px 8px; font-size: 12px; background: #DDDDDD;") + resetButton = HT.Input(type='button',name='resetButton',value=' Reset ',Class="button") + blockSamplesField = HT.Input(type="text",style="background-color:white;border: 1px solid black;font-size: 14px;", name="removeField") + blockSamplesButton = HT.Input(type='button',value=' Block ', name='blockSamples', Class="button") + showHideNoValue = HT.Input(type='button', name='showHideNoValue', value=' Hide No Value ',Class='button') + blockMenuSpan = HT.Span(Id="blockMenuSpan") + blockMenu = HT.Select(name='block_method') + + if fd.genotype.type == "riset": + allstrainlist_neworder = fd.f1list + fd.strainlist + else: + allstrainlist_neworder = fd.f1list + fd.parlist + fd.strainlist + + attribute_ids = [] + attribute_names = [] + try: + #ZS: Id values for this trait's extra attributes; used to create "Exclude" dropdown and query for attribute values and create + self.cursor.execute("""SELECT CaseAttribute.Id, CaseAttribute.Name + FROM CaseAttribute, CaseAttributeXRef + WHERE CaseAttributeXRef.ProbeSetFreezeId = '%s' AND + CaseAttribute.Id = CaseAttributeXRef.CaseAttributeId + group by CaseAttributeXRef.CaseAttributeId""" % (str(thisTrait.db.id))) + + exclude_menu = HT.Select(name="exclude_menu") + dropdown_menus = [] #ZS: list of dropdown menus with the distinct values of each attribute (contained in DIVs so the style parameter can be edited and they can be hidden) + + for attribute in self.cursor.fetchall(): + attribute_ids.append(attribute[0]) + attribute_names.append(attribute[1]) + for this_attr_name in attribute_names: + exclude_menu.append((this_attr_name.capitalize(), this_attr_name)) + self.cursor.execute("""SELECT DISTINCT CaseAttributeXRef.Value + FROM CaseAttribute, CaseAttributeXRef + WHERE CaseAttribute.Name = '%s' AND + CaseAttributeXRef.CaseAttributeId = CaseAttribute.Id""" % (this_attr_name)) + try: + distinct_values = self.cursor.fetchall() + attr_value_menu_div = HT.Div(style="display:none;", Class="attribute_values") #container used to show/hide dropdown menus + attr_value_menu = HT.Select(name=this_attr_name) + attr_value_menu.append(("None", "show_all")) + for value in distinct_values: + attr_value_menu.append((str(value[0]), value[0])) + attr_value_menu_div.append(attr_value_menu) + dropdown_menus.append(attr_value_menu_div) + except: + pass + except: + pass + + other_strains = [] + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + other_strains.append(strain) + + if other_strains: + blockMenu.append(('%s Only' % fd.RISet,'1')) + blockMenu.append(('Non-%s Only' % fd.RISet,'0')) + blockMenuSpan.append(blockMenu) + else: + pass + + showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') + showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") + if other_strains: + showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) + else: + showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) + + exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') + if len(attribute_names) > 0: + excludeButton = HT.Input(type='button', name='excludeGroup', value=' Block ', Class='button') + showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) + for menu in dropdown_menus: + showHideMenuOptions.append(menu) + showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) + showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) + + traitTableOptions.append(showHideMenuOptions,HT.BR(),HT.BR()) + traitTableOptions.append(HT.Span("  Outliers highlighted in ", HT.Bold(" yellow ", style="background-color:yellow;"), " can be hidden using the ", + HT.Strong(" Hide Outliers "), " button,",HT.BR(),"  and samples with no value (x) can be hidden by clicking ", + HT.Strong(" Hide No Value "), "."), HT.BR()) + + + dispintro = HT.Paragraph("Edit or delete values in the Trait Data boxes, and use the ", HT.Strong("Reset"), " option as needed.",Class="fs12", style="margin-left:20px;") + + table = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target5") #Everything needs to be inside this table object in order for the toggle to work + container = HT.Div() #This will contain everything and be put into a cell of the table defined above + + container.append(dispintro, traitTableOptions, HT.BR()) + + primary_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable1", Class="tablesorter") + primary_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for primary table object + + other_strainsExist = False + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + other_strainsExist = True + break + + primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') + + primary_table.append(primary_header) + for i in range(len(primary_body)): + primary_table.append(primary_body[i]) + + other_strains = [] + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + allstrainlist_neworder.append(strain) + other_strains.append(strain) + + if other_strains: + other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits + other_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for other table object; same function is used as the one used for the primary table, since the header is the same + other_strains.sort() #Sort other strains + other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #Append F1 and parent strains to the beginning of the sorted list of other strains + + MDPText = HT.Span("Samples:", Class="ffl fwb fs12") + MDPMenu1 = HT.Select(name='MDPChoice1') + MDPMenu2 = HT.Select(name='MDPChoice2') + MDPMenu3 = HT.Select(name='MDPChoice3') + MDPMenu1.append(('%s Only' % fd.RISet,'1')) + MDPMenu2.append(('%s Only' % fd.RISet,'1')) + MDPMenu3.append(('%s Only' % fd.RISet,'1')) + MDPMenu1.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu2.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu3.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu1.append(('All Cases','0')) + MDPMenu2.append(('All Cases','0')) + MDPMenu3.append(('All Cases','0')) + self.MDPRow1.append(HT.TD(MDPText),HT.TD(MDPMenu1)) + self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) + self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) + + other_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') + + other_table.append(other_header) + for i in range(len(other_body)): + other_table.append(other_body[i]) + else: + pass + + if other_strains or (fd.f1list and thisTrait.data.has_key(fd.f1list[0])) \ + or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): + fd.allstrainlist = allstrainlist_neworder + + if nCols == 6 and fd.varianceDispName != 'Variance': + mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) + + primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values + container.append(primary_div) + + if other_strains: + other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values + container.append(HT.Div(' ', height=30)) + container.append(other_div) + + table.append(HT.TR(HT.TD(container))) + title5Body.append(table) + + def addTrait2Table(self, fd, varianceDataPage, strainlist, mainForm, thisTrait, other_strainsExist=None, attribute_ids=[], attribute_names=[], strains='primary'): + #XZ, Aug 23, 2010: I commented the code related to the display of animal case + #strainInfo = thisTrait.has_key('strainInfo') and thisTrait.strainInfo + + table_body = [] + vals = [] + + for i, strainNameOrig in enumerate(strainlist): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals.append(thisValFull) + + upperBound, lowerBound = Plot.findOutliers(vals) # ZS: Values greater than upperBound or less than lowerBound are considered outliers. + + for i, strainNameOrig in enumerate(strainlist): + + trId = strainNameOrig + selectCheck = HT.Input(type="checkbox", name="selectCheck", value=trId, Class="checkbox", onClick="highlight(this)") + + strainName = strainNameOrig.replace("_2nd_", "") + strainNameAdd = '' + if fd.RISet == 'AXBXA' and strainName in ('AXB18/19/20','AXB13/14','BXA8/17'): + strainNameAdd = HT.Href(url='/mouseCross.html#AXB/BXA', text=HT.Sup('#'), Class='fs12', target="_blank") + + try: + thisval, thisvar, thisNP = thisTrait.data[strainName].val, thisTrait.data[strainName].var, thisTrait.data[strainName].N + if thisNP: + mainForm.append(HT.Input(name='N'+strainName, value=thisNP, type='hidden')) + else: + pass + except: + thisval = thisvar = 'x' + + try: + traitVal = thisval + dispVal = "%2.3f" % thisval + except: + traitVal = '' + dispVal = 'x' + + strainNameDisp = HT.Span(strainName, Class='fs14 fwn ffl') + + if varianceDataPage: + try: + traitVar = thisvar + dispVar = "%2.3f" % thisvar + except: + traitVar = '' + dispVar = 'x' + + if thisval == 'x': + traitVar = '' #ZS: Used to be 0, but it doesn't seem like a good idea for values of 0 to *always* be at the bottom when you sort; it makes more sense to put "nothing" + + className = 'fs13 b1 c222 ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = 'novalue ' + else: + if (thisval >= upperBound) or (thisval <= lowerBound): + className = 'fs13 b1 c222 outlier ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = 'outlier' + else: + className = 'fs13 b1 c222 ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = ' ' + + if varianceDataPage: + varClassName = valueClassName + str(traitVar) + valueClassName += str(traitVal) + + if strainNameOrig == strainName: + if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): + ######################################################################################################################################################## + # ZS: Append value and variance to the value and variance input fields' list of classes; this is so the javascript can update the value when the user + # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. + ######################################################################################################################################################### + + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, + onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + else: + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) + else: + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, + onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + + if (strains == 'primary'): + table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) + else: + table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) + + if varianceDataPage: + table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + table_row.append(HT.TD("±", width=20, align='center', Class=className)) + table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) + else: + table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + + if thisTrait and thisTrait.db and thisTrait.db.type =='ProbeSet': + if len(attribute_ids) > 0: + + #ZS: Get StrainId value for the next query + self.cursor.execute("""SELECT Strain.Id + FROM Strain, StrainXRef, InbredSet + WHERE Strain.Name = '%s' and + StrainXRef.StrainId = Strain.Id and + InbredSet.Id = StrainXRef.InbredSetId and + InbredSet.Name = '%s'""" % (strainName, fd.RISet)) + + strain_id = self.cursor.fetchone()[0] + + attr_counter = 1 # This is needed so the javascript can know which attribute type to associate this value with for the exported excel sheet (each attribute type being a column). + for attribute_id in attribute_ids: + + #ZS: Add extra case attribute values (if any) + self.cursor.execute("""SELECT Value + FROM CaseAttributeXRef + WHERE ProbeSetFreezeId = '%s' AND + StrainId = '%s' AND + CaseAttributeId = '%s' + group by CaseAttributeXRef.CaseAttributeId""" % (thisTrait.db.id, strain_id, str(attribute_id))) + + attributeValue = self.cursor.fetchone()[0] #Trait-specific attributes, if any + + #ZS: If it's an int, turn it into one for sorting (for example, 101 would be lower than 80 if they're strings instead of ints) + try: + attributeValue = int(attributeValue) + except: + pass + + span_Id = strains+"_attribute"+str(attr_counter)+"_sample"+str(i+1) + attr_container = HT.Span(attributeValue, Id=span_Id) + attr_className = str(attributeValue) + " " + className + table_row.append(HT.TD(attr_container, align='right', Class=attr_className)) + attr_counter += 1 + + table_body.append(table_row) + return table_body + + def getTableHeader(self, fd, thisTrait, nCols, attribute_names): + + table_header = HT.TR() + + col_class = "fs13 fwb ff1 b1 cw cbrb" + + if nCols == 6: + try: + if fd.varianceDispName: + pass + except: + fd.varianceDispName = 'Variance' + + table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), + HT.TH('Sample', align='right', width=100, Class=col_class), + HT.TH('Value', align='right', width=70, Class=col_class), + HT.TH(' ', width=20, Class=col_class), + HT.TH(fd.varianceDispName, align='right', width=80, Class=col_class)) + + elif nCols == 4: + table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), + HT.TH('Sample', align='right', width=100, Class=col_class), + HT.TH('Value', align='right', width=70, Class=col_class)) + + else: + pass + + if len(attribute_names) > 0: + i=0 + for attribute in attribute_names: + char_count = len(attribute) + cell_width = char_count * 14 + table_header.append(HT.TH(attribute, align='right', width=cell_width, Class="attribute_name " + col_class)) + i+=1 + + return table_header + + + def getSortByValue(self): + + sortby = ("", "") + + return sortby diff --git a/wqflask/wqflask/show_trait/__init__.py b/wqflask/wqflask/show_trait/__init__.py new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From 3d6be932e5185e4dd7170b3ea740591de01341a0 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 3 Jun 2012 05:47:07 -0400 Subject: Before changing fd for trait analysis into a webQTLFormData object --- wqflask/base/webqtlTrait.py | 17 +++++++++-------- wqflask/wqflask/show_trait/show_trait_page.py | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index c3c0cded..88226894 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -92,12 +92,13 @@ class webqtlTrait: WHERE ProbeSet.Id=ProbeSetXRef.ProbeSetId and ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - ProbeSet.Name = "%s" and - ProbeSetFreeze.Name = "%s" - ''' % (self.name, self.db.name) + ProbeSet.Name = %s and + ProbeSetFreeze.Name = %s + ''', (self.name, self.db.name) print("query is:", query) - self.cursor.execute(query) + self.cursor.execute(*query) self.sequence = self.cursor.fetchone()[0] + print("self.sequence is:", self.sequence) def getName(self): @@ -124,7 +125,7 @@ class webqtlTrait: str = self.name if self.db and self.name: if self.db.type=='Temp': - self.cursor.execute('SELECT description FROM Temp WHERE Name=%s',self.name) + self.cursor.execute('SELECT description FROM Temp WHERE Name=%s', self.name) desc = self.cursor.fetchone()[0] if desc.__contains__('PCA'): desc = desc[desc.rindex(':')+1:].strip() @@ -206,7 +207,7 @@ class webqtlTrait: def getSequence(self): assert self.cursor if self.db.type == 'ProbeSet': - query = ''' + self.cursor.execute(''' SELECT ProbeSet.BlatSeq FROM @@ -216,8 +217,8 @@ class webqtlTrait: ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and ProbeSet.Name = %s ProbeSetFreeze.Name = %s - ''' , (self.name, self.db.name) - self.cursor.execute(query) + ''', self.name, self.db.name) + #self.cursor.execute(query) results = self.fetchone() return results[0] diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index c7d6618e..a34c20cf 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -24,6 +24,10 @@ # # Last updated by GeneNetwork Core Team 2010/10/20 +from __future__ import division, print_function + +from flask import request + from htmlgen import HTMLgen2 as HT from base import webqtlConfig @@ -96,8 +100,12 @@ class ShowTraitPage(DataEditingPage): at this time, please go back and select other database." % indFullName] self.error(heading=heading,detail=detail,error="Confidential Database") return + print("environ:", request.environ) - user_ip = fd.remote_ip + # Becuase of proxying remote_addr is probably localhost, so we first try for + # HTTP_X_FORWARDED_FOR + user_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.remote_addr # in old app was fd.remote_ip + print("user_ip is:", user_ip) query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" self.cursor.execute(query,user_ip) @@ -143,9 +151,9 @@ class ShowTraitPage(DataEditingPage): """ ##identification, etc. - fd.identification = '%s : %s'%(thisTrait.db.shortname,ProbeSetID) + fd.identification = '%s : %s' % (thisTrait.db.shortname,ProbeSetID) thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database,ProbeSetID,fd.RISet) + &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database, ProbeSetID, fd['RISet']) if CellID: fd.identification = '%s/%s'%(fd.identification, CellID) @@ -156,12 +164,13 @@ class ShowTraitPage(DataEditingPage): thisTrait.retrieveInfo() thisTrait.retrieveData() self.updMysql() - self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)" ,user_ip) + self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)", user_ip) self.openMysql() - except: + except Exception as why: + print("Got an exception:", why) heading = "Retrieve Data" detail = ["The information you requested is not avaiable at this time."] - self.error(heading=heading,detail=detail) + self.error(heading=heading, detail=detail) return ##read genotype file -- cgit v1.2.3 From b2240d137c4d81110994bc8e2e9004bd7a01fe5b Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 3 Jun 2012 06:20:36 -0400 Subject: Now using modified webqtlformdata for trait analysis --- wqflask/base/webqtlFormData.py | 119 ++++++++++++++------------ wqflask/wqflask/show_trait/show_trait_page.py | 4 +- wqflask/wqflask/views.py | 6 +- 3 files changed, 72 insertions(+), 57 deletions(-) diff --git a/wqflask/base/webqtlFormData.py b/wqflask/base/webqtlFormData.py index 84e41cae..c94dbe53 100755 --- a/wqflask/base/webqtlFormData.py +++ b/wqflask/base/webqtlFormData.py @@ -24,7 +24,7 @@ # # Last updated by GeneNetwork Core Team 2010/10/20 -from mod_python import Cookie +#from mod_python import Cookie import string import os @@ -47,7 +47,9 @@ class webqtlFormData: #XZ: Attention! All attribute values must be picklable! - def __init__(self, req = None, mod_python_session=None, FieldStorage_formdata=None): + def __init__(self, start_vars = None, req = None, mod_python_session=None, FieldStorage_formdata=None): + + self.__dict__.update(start_vars) for item in self.attrs: setattr(self,item, None) @@ -62,34 +64,35 @@ class webqtlFormData: else: self.refURL = None + # For now let's just comment all this out - Sam - self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie. - - #XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable. - self.input_session_data = sessionData.sessionData( mod_python_session ) - - #XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data. - self.formdata = cgiData( FieldStorage_formdata ) - - #get Form ID - self.formID = self.formdata.getfirst('FormID') + #self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie. + # + ##XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable. + #self.input_session_data = sessionData.sessionData( mod_python_session ) + # + ##XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data. + #self.formdata = cgiData( FieldStorage_formdata ) + # + ##get Form ID + #self.formID = self.formdata.getfirst('FormID') + # + ##get rest of the attributes + #if self.formID: + # for item in self.attrs: + # value = self.formdata.getfirst(item) + # if value != None: + # setattr(self,item,string.strip(value)) - #get rest of the attributes - if self.formID: - for item in self.attrs: - value = self.formdata.getfirst(item) - if value != None: - setattr(self,item,string.strip(value)) - self.ppolar = "" self.mpolar = "" if self.RISet: try: - # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; f1, f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet] except: f1 = f12 = self.mpolar = self.ppolar = None - + try: self.nperm = int(self.nperm) self.nboot = int(self.nboot) @@ -101,12 +104,21 @@ class webqtlFormData: self.allstrainlist = map(string.strip, string.split(self.allstrainlist)) #self.readGenotype() #self.readData() - + if self.RISet == 'BXD300': self.RISet = 'BXD' else: pass - + + def __getitem__(self, key): + return self.__dict__[key] + + def get(self, key, default=None): + if key in self.__dict__: + return self.__dict__[key] + else: + return default + def __str__(self): rstr = '' for item in self.attrs: @@ -114,7 +126,7 @@ class webqtlFormData: rstr += '%s:%s\n' % (item,str(getattr(self,item))) return rstr - + def readGenotype(self): 'read genotype from .geno file' if self.RISet == 'BXD300': @@ -127,15 +139,15 @@ class webqtlFormData: self.genotype_1 = reaper.Dataset() self.genotype_1.read(os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno')) try: - # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] except: _f1 = _f12 = _mat = _pat = None - + self.genotype_2 =self.genotype_1 if self.genotype_1.type == "riset" and _mat and _pat: self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) - + #determine default genotype object if self.incparentsf1 and self.genotype_1.type != "intercross": self.genotype = self.genotype_2 @@ -148,7 +160,7 @@ class webqtlFormData: self.f1list = [_f1, _f12] if _mat and _pat: self.parlist = [_mat, _pat] - + def readData(self, strainlst=[], incf1=[]): 'read user input data or from trait data and analysis form' @@ -158,16 +170,16 @@ class webqtlFormData: if incf1: strainlst = self.f1list + self.strainlist else: - strainlst = self.strainlist - - + strainlst = self.strainlist + + traitfiledata = self.formdata.getfirst('traitfile') traitpastedata = self.formdata.getfirst('traitpaste') variancefiledata = self.formdata.getfirst('variancefile') variancepastedata = self.formdata.getfirst('variancepaste') Nfiledata = self.formdata.getfirst('Nfile') - + if traitfiledata: tt = string.split(traitfiledata) vals = map(webqtlUtil.StringAsFloat, tt) @@ -183,8 +195,8 @@ class webqtlFormData: vals = vals[:len(strainlst)] else: pass - - + + if variancefiledata: tt = string.split(variancefiledata) vars = map(webqtlUtil.StringAsFloat, tt) @@ -200,7 +212,7 @@ class webqtlFormData: vars = vars[:len(strainlst)] else: pass - + if Nfiledata: tt = string.split(Nfiledata) nstrains = map(webqtlUtil.IntAsFloat, tt) @@ -208,14 +220,14 @@ class webqtlFormData: nstrains += [None]*(len(strainlst) - len(nstrains)) else: nstrains = map(self.FormNAsFloat, strainlst) - + ##vals, vars, nstrains is obsolete self.allTraitData = {} for i, _strain in enumerate(strainlst): if vals[i] != None: self.allTraitData[_strain] = webqtlCaseData(vals[i], vars[i], nstrains[i]) - + def informativeStrains(self, strainlst=[], incVars = 0): '''if readData was called, use this to output the informative strains @@ -241,26 +253,26 @@ class webqtlFormData: return strains, vals, vars, len(strains) - + def FormDataAsFloat(self, key): try: return float(self.formdata.getfirst(key)) except: return None - + def FormVarianceAsFloat(self, key): try: return float(self.formdata.getfirst('V' + key)) except: return None - + def FormNAsFloat(self, key): try: return int(self.formdata.getfirst('N' + key)) except: return None - + def Sample(self): 'Create some dummy data for testing' self.RISet = 'BXD' @@ -273,17 +285,16 @@ class webqtlFormData: #self.genotype.ReadMM('AXBXAforQTL') #self.strainlist = map((lambda x, y='': '%s%s' % (y,x)), self.genotype.prgy) #self.strainlist.sort() - self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2), - 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2), - 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4), - 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2), - 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3), - 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3), - 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2), - 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4), - 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4), - 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1), - 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4), - 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4), + self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2), + 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2), + 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4), + 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2), + 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3), + 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3), + 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2), + 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4), + 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4), + 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1), + 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4), + 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4), 'BXD42': webqtlCaseData(4), 'BXD40': webqtlCaseData(3)} - diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index a34c20cf..d4019fd5 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -56,8 +56,8 @@ class ShowTraitPage(DataEditingPage): else: print("j2.3") print("fd is:", fd) - database = fd['database'] - ProbeSetID = fd['ProbeSetID'] + database = fd['database'][0] + ProbeSetID = fd['ProbeSetID'][0] print("j2.4") CellID = fd.get('CellID') print("j2.6") diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 611cc05b..3457f0ff 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -7,6 +7,8 @@ from flask import render_template, request from wqflask import search_results from wqflask.show_trait import show_trait_page +from base import webqtlFormData + from pprint import pformat as pf @app.route("/") @@ -21,5 +23,7 @@ def search(): @app.route("/showDatabaseBXD") def showDatabaseBXD(): - template_vars = show_trait_page.ShowTraitPage(request.args) + # Here it's currently too complicated not to use an fd that is a webqtlFormData + fd = webqtlFormData.webqtlFormData(request.args) + template_vars = show_trait_page.ShowTraitPage(fd) return render_template("trait_data_and_analysis.html") -- cgit v1.2.3 From cad0bdf26b325c7d5fa1757e44db8721a9d86cca Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 4 Jun 2012 22:45:24 -0400 Subject: Checkpoint along modifying for data trait and analysis --- wqflask/base/templatePage.py | 44 ++++++++-------- wqflask/wqflask/show_trait/DataEditingPage.py | 73 ++++++++++++++++++--------- wqflask/wqflask/show_trait/show_trait_page.py | 4 +- 3 files changed, 74 insertions(+), 47 deletions(-) diff --git a/wqflask/base/templatePage.py b/wqflask/base/templatePage.py index 4dece24a..821c6181 100755 --- a/wqflask/base/templatePage.py +++ b/wqflask/base/templatePage.py @@ -70,13 +70,13 @@ class templatePage: self.starttime = time.time() self.dict = {} self.template = template - + for item in self.contents: self.dict[item] = "" - + self.dict['basehref'] = "" #webqtlConfig.BASEHREF self.cursor = None - + self.cookie = [] #XZ: list to hold cookies (myCookie object) being changed self.content_type = 'text/html' self.content_disposition = '' @@ -89,11 +89,13 @@ class templatePage: self.userName = 'Guest' self.privilege = 'guest' - if fd.input_session_data.has_key('user'): - self.userName = fd.input_session_data['user'] - if fd.input_session_data.has_key('privilege'): - self.privilege = fd.input_session_data['privilege'] - + + # Commenting this out for flask - we'll have to reimplement later - Sam + #if fd.input_session_data.has_key('user'): + # self.userName = fd.input_session_data['user'] + #if fd.input_session_data.has_key('privilege'): + # self.privilege = fd.input_session_data['privilege'] + def __str__(self): #XZ: default setting @@ -126,20 +128,20 @@ class templatePage: def __del__(self): if self.cursor: self.cursor.close() - + def write(self): 'return string representation of this object' if self.cursor: self.cursor.close() - return str(self) - + return str(self) + def writeFile(self, filename): 'save string representation of this object into a file' if self.cursor: self.cursor.close() - + try: 'it could take a long time to generate the file, save to .tmp first' fp = open(os.path.join(webqtlConfig.TMPDIR, filename+'.tmp'), 'wb') @@ -147,9 +149,9 @@ class templatePage: fp.close() path_tmp = os.path.join(webqtlConfig.TMPDIR, filename+'.tmp') path_html = os.path.join(webqtlConfig.TMPDIR, filename) - shutil.move(path_tmp,path_html) + shutil.move(path_tmp,path_html) except: - pass + pass def openMysql(self): try: @@ -176,12 +178,12 @@ class templatePage: The server may be down at this time "] self.error(heading=heading,detail=detail,error="Error 2003") return 0 - + def error(self,heading="",intro=[],detail=[],title="Error",error="Error"): 'generating a WebQTL style error page' Heading = HT.Paragraph(heading) Heading.__setattr__("class","title") - + Intro = HT.Blockquote() if intro: for item in intro: @@ -190,7 +192,7 @@ class templatePage: Intro.append(HT.Strong('Sorry!'),' Error occurred while processing\ your request.', HT.P(),'The nature of the error generated is as\ follows:') - + Detail = HT.Blockquote() Detail.append(HT.Span("%s : " % error,Class="fwb cr")) if detail: @@ -198,7 +200,7 @@ class templatePage: for item in detail: Detail2.append(item) Detail.append(HT.Italic(Detail2)) - + #Detail.__setattr__("class","subtitle") TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") TD_LR.append(Heading,Intro,Detail) @@ -210,13 +212,11 @@ class templatePage: self.filename = webqtlUtil.generate_session() self.dict['title'] = mytitle self.dict['basehref'] = webqtlConfig.REFRESHSTR % (webqtlConfig.CGIDIR, self.filename) + "" #webqtlConfig.BASEHREF - + TD_LR = HT.TD(align="center", valign="middle", height=200,width="100%", bgColor='#eeeeee') Heading = HT.Paragraph(myHeading, Class="fwb fs16 cr") - # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py; + # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py; TD_LR.append(Heading, HT.BR(), webqtlUtil.PROGRESSBAR) self.dict['body'] = TD_LR self.writeFile(self.filename + '.html') return self.filename - - diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index c2e1c37f..1186fa03 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -52,35 +52,62 @@ class DataEditingPage(templatePage): ## titles, etc. ############################# - titleTop = HT.Div() - - title1 = HT.Paragraph("  Details and Links", style="border-radius: 5px;", Id="title1", Class="sectionheader") - title1Body = HT.Paragraph(Id="sectionbody1") - - if fd.enablevariance and not varianceDataPage: - title2 = HT.Paragraph("  Submit Variance", style="border-radius: 5px;", Id="title2", Class="sectionheader") - else: - title2 = HT.Paragraph("  Basic Statistics", style="border-radius: 5px;", Id="title2", Class="sectionheader") - title2Body = HT.Paragraph(Id="sectionbody2") - - title3 = HT.Paragraph("  Calculate Correlations", style="border-radius: 5px;", Id="title3", Class="sectionheader") - title3Body = HT.Paragraph(Id="sectionbody3") - - title4 = HT.Paragraph("  Mapping Tools", style="border-radius: 5px;", Id="title4", Class="sectionheader") - title4Body = HT.Paragraph(Id="sectionbody4") - - title5 = HT.Paragraph("  Review and Edit Data", style="border-radius: 5px;", Id="title5", Class="sectionheader") - title5Body = HT.Paragraph(Id="sectionbody5") + #titleTop = HT.Div() + # + #title1 = HT.Paragraph("  Details and Links", style="border-radius: 5px;", Id="title1", Class="sectionheader") + #title1Body = HT.Paragraph(Id="sectionbody1") + # + #if fd.enablevariance and not varianceDataPage: + # title2 = HT.Paragraph("  Submit Variance", style="border-radius: 5px;", Id="title2", Class="sectionheader") + #else: + # title2 = HT.Paragraph("  Basic Statistics", style="border-radius: 5px;", Id="title2", Class="sectionheader") + #title2Body = HT.Paragraph(Id="sectionbody2") + # + #title3 = HT.Paragraph("  Calculate Correlations", style="border-radius: 5px;", Id="title3", Class="sectionheader") + #title3Body = HT.Paragraph(Id="sectionbody3") + # + #title4 = HT.Paragraph("  Mapping Tools", style="border-radius: 5px;", Id="title4", Class="sectionheader") + #title4Body = HT.Paragraph(Id="sectionbody4") + # + #title5 = HT.Paragraph("  Review and Edit Data", style="border-radius: 5px;", Id="title5", Class="sectionheader") + #title5Body = HT.Paragraph(Id="sectionbody5") ############################# ## Hidden field ############################# # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery - hddn = {'FormID':fmID, 'RISet':fd.RISet, 'submitID':'', 'scale':'physic', 'additiveCheck':'ON', 'showSNP':'ON', 'showGenes':'ON', 'method':None,\ - 'parentsf14regression':'OFF', 'stats_method':'1', 'chromosomes':'-1', 'topten':'', 'viewLegend':'ON', 'intervalAnalystCheck':'ON', 'valsHidden':'OFF',\ - 'database':'', 'criteria':None, 'MDPChoice':None, 'bootCheck':None, 'permCheck':None, 'applyVarianceSE':None, 'strainNames':'_', 'strainVals':'_',\ - 'strainVars':'_', 'otherStrainNames':'_', 'otherStrainVals':'_', 'otherStrainVars':'_', 'extra_attributes':'_', 'other_extra_attributes':'_'} + hddn = { + 'FormID':fmID, + 'RISet':fd.RISet, + 'submitID':'', + 'scale':'physic', + 'additiveCheck':'ON', + 'showSNP':'ON', + 'showGenes':'ON', + 'method':None, + 'parentsf14regression':'OFF', + 'stats_method':'1', + 'chromosomes':'-1', + 'topten':'', + 'viewLegend':'ON', + 'intervalAnalystCheck':'ON', + 'valsHidden':'OFF', + 'database':'', + 'criteria':None, + 'MDPChoice':None, + 'bootCheck':None, + 'permCheck':None, + 'applyVarianceSE':None, + 'strainNames':'_', + 'strainVals':'_', + 'strainVars':'_', + 'otherStrainNames':'_', + 'otherStrainVals':'_', + 'otherStrainVars':'_', + 'extra_attributes':'_', + 'other_extra_attributes':'_' + } if fd.enablevariance: hddn['enablevariance']='ON' diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index d4019fd5..a63071c3 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -182,6 +182,6 @@ class ShowTraitPage(DataEditingPage): fd.varianceDispName = 'SE' fd.formID = 'varianceChoice' - self.dict['body']= thisTrait + #self.dict['body']= thisTrait DataEditingPage.__init__(self, fd, thisTrait) - self.dict['title'] = '%s: Display Trait' % fd.identification + #self.dict['title'] = '%s: Display Trait' % fd.identification -- cgit v1.2.3 From 9dfc78ec131f6198c503e62d9486b71313ab2d20 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 4 Jun 2012 22:56:54 -0400 Subject: Before wholesale turning tabs into spaces on DataEditingPage --- wqflask/wqflask/show_trait/DataEditingPage.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 1186fa03..b50428fc 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -140,9 +140,9 @@ class DataEditingPage(templatePage): ## Display Trait Information ############################# - headSpan = self.dispHeader(fd,thisTrait) #Draw header - - titleTop.append(headSpan) + #headSpan = self.dispHeader(fd,thisTrait) #Draw header + # + #titleTop.append(headSpan) if fd.identification: hddn['identification'] = fd.identification @@ -150,7 +150,7 @@ class DataEditingPage(templatePage): else: hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named - self.dispTraitInformation(fd, title1Body, hddn, thisTrait) #Display trait information + function buttons + self.dispTraitInformation(fd, "", hddn, thisTrait) #Display trait information + function buttons ############################# ## Generate form and buttons @@ -221,9 +221,9 @@ class DataEditingPage(templatePage): _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) - tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") + #tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") - reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + #reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") #XZ, August 02, 2011: The display of icons is decided by the trait type (if trait exists), along with user log-in status. Note that the new submitted trait might not be trait object. addSelectionButton = "" @@ -270,12 +270,12 @@ class DataEditingPage(templatePage): if thisTrait: addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, 'dataInput')) addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") - addSelectionButton.append(addSelectionButton_img) + #addSelectionButton.append(addSelectionButton_img) addSelectionText = "Add" elif self.cursor.fetchall(): addSelectionButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('%s')[0], 'addRecord');" % ('dataInput')) addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="", alt="Add To Collection", title="Add To Collection", style="border:none;") - addSelectionButton.append(addSelectionButton_img) + #addSelectionButton.append(addSelectionButton_img) addSelectionText = "Add" else: pass @@ -288,7 +288,7 @@ class DataEditingPage(templatePage): except: pass - Info2Disp = HT.Paragraph() + #Info2Disp = HT.Paragraph() #XZ: Gene Symbol if thisTrait.symbol: @@ -319,14 +319,14 @@ class DataEditingPage(templatePage): #XZ: display similar traits in other selected datasets if thisTrait and thisTrait.db and thisTrait.db.type=="ProbeSet" and thisTrait.symbol: - if _Species in ("mouse", "rat", "human"): + if _Species in ("mouse", "rat", "human"): similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") similarButton.append(similarButton_img) similarText = "Find" else: - pass + pass tbl.append(HT.TR( HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), HT.TD(width=10, valign="top"), -- cgit v1.2.3 From 8abd879e71f492ce61e0b8d3eab53fcb43c34681 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 4 Jun 2012 23:05:33 -0400 Subject: Added flies ending in ~ to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dbbb76f9..8bc78454 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ # gitignore *.pyc *.orig +*~ -- cgit v1.2.3 From 8ac39ead1014953c634e85d0ce340497ecfe2934 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Tue, 5 Jun 2012 00:24:44 -0400 Subject: Ran reindent.py recursively on wqflask directory --- .gitignore | 2 + wqflask/base/GeneralObject.py | 77 +- wqflask/base/admin.py | 32 +- wqflask/base/cgiData.py | 60 +- wqflask/base/cookieData.py | 27 +- wqflask/base/header.py | 2 +- wqflask/base/indexBody.py | 414 +-- wqflask/base/myCookie.py | 38 +- wqflask/base/sessionData.py | 27 +- wqflask/base/template.py | 74 +- wqflask/base/templatePage.py | 318 +- wqflask/base/webqtlCaseData.py | 43 +- wqflask/base/webqtlDataset.py | 249 +- wqflask/base/webqtlFormData.py | 516 +-- wqflask/base/webqtlTrait.py | 1152 +++--- .../basicStatistics/BasicStatisticsFunctions.py | 280 +- .../basicStatistics/BasicStatisticsPage_alpha.py | 602 ++-- .../basicStatistics/updatedBasicStatisticsPage.py | 284 +- wqflask/dbFunction/webqtlDatabaseFunction.py | 293 +- wqflask/utility/AJAX_table.py | 224 +- wqflask/utility/Plot.py | 2304 ++++++------ wqflask/utility/TDCell.py | 15 +- wqflask/utility/THCell.py | 16 +- wqflask/utility/svg.py | 133 +- wqflask/utility/webqtlUtil.py | 1459 ++++---- wqflask/wqflask/show_trait/DataEditingPage.py | 3810 ++++++++++---------- wqflask/wqflask/show_trait/show_trait_page.py | 290 +- 27 files changed, 6353 insertions(+), 6388 deletions(-) diff --git a/.gitignore b/.gitignore index 8bc78454..fc051245 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ # gitignore *.pyc *.orig +*.bak *~ + diff --git a/wqflask/base/GeneralObject.py b/wqflask/base/GeneralObject.py index 311c9e22..53d1357b 100755 --- a/wqflask/base/GeneralObject.py +++ b/wqflask/base/GeneralObject.py @@ -25,47 +25,44 @@ # Last updated by GeneNetwork Core Team 2010/10/20 class GeneralObject: - """ - Base class to define an Object. - a = [Spam(1, 4), Spam(9, 3), Spam(4,6)] - a.sort(lambda x, y: cmp(x.eggs, y.eggs)) - """ + """ + Base class to define an Object. + a = [Spam(1, 4), Spam(9, 3), Spam(4,6)] + a.sort(lambda x, y: cmp(x.eggs, y.eggs)) + """ - def __init__(self, *args, **kw): - self.contents = list(args) - for name, value in kw.items(): - setattr(self, name, value) - - def __setitem__(self, key, value): - setattr(self, key, value) - - def __getitem__(self, key): - return getattr(self, key) - - def __getattr__(self, key): - if key in self.__dict__.keys(): - return self.__dict__[key] - else: - return eval("self.__dict__.%s" % key) - - def __len__(self): - return len(self.__dict__) - 1 - - def __str__(self): - s = '' - for key in self.__dict__.keys(): - if key != 'contents': - s += '%s = %s\n' % (key,self.__dict__[key]) - return s - - def __repr__(self): - s = '' - for key in self.__dict__.keys(): - s += '%s = %s\n' % (key,self.__dict__[key]) - return s - - def __cmp__(self,other): - return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys())) + def __init__(self, *args, **kw): + self.contents = list(args) + for name, value in kw.items(): + setattr(self, name, value) + def __setitem__(self, key, value): + setattr(self, key, value) + def __getitem__(self, key): + return getattr(self, key) + def __getattr__(self, key): + if key in self.__dict__.keys(): + return self.__dict__[key] + else: + return eval("self.__dict__.%s" % key) + + def __len__(self): + return len(self.__dict__) - 1 + + def __str__(self): + s = '' + for key in self.__dict__.keys(): + if key != 'contents': + s += '%s = %s\n' % (key,self.__dict__[key]) + return s + + def __repr__(self): + s = '' + for key in self.__dict__.keys(): + s += '%s = %s\n' % (key,self.__dict__[key]) + return s + + def __cmp__(self,other): + return len(self.__dict__.keys()).__cmp__(len(other.__dict__.keys())) diff --git a/wqflask/base/admin.py b/wqflask/base/admin.py index a04df2da..1ba75117 100755 --- a/wqflask/base/admin.py +++ b/wqflask/base/admin.py @@ -35,18 +35,18 @@ ADMIN_search_dbs = { - 'rat': {'PERITONEAL FAT': ['FT_2A_0605_Rz'], + 'rat': {'PERITONEAL FAT': ['FT_2A_0605_Rz'], 'KIDNEY': ['KI_2A_0405_Rz'], 'ADRENAL GLAND': ['HXB_Adrenal_1208'], 'HEART': ['HXB_Heart_1208'] }, - 'mouse': {'CEREBELLUM': ['CB_M_0305_R'], + 'mouse': {'CEREBELLUM': ['CB_M_0305_R'], 'STRIATUM': ['SA_M2_0905_R', 'SA_M2_0405_RC', 'UTHSC_1107_RankInv', 'Striatum_Exon_0209'], - 'HIPPOCAMPUS': ['HC_M2_0606_R', 'UMUTAffyExon_0209_RMA'], - 'WHOLE BRAIN': ['BR_M2_1106_R', 'IBR_M_0106_R', 'BRF2_M_0805_R', 'UCLA_BHF2_BRAIN_0605'], - 'LIVER': ['LV_G_0106_B', 'UCLA_BHF2_LIVER_0605'], - 'EYE': ['Eye_M2_0908_R'], - 'HEMATOPOIETIC STEM CELLS': ['HC_U_0304_R'], + 'HIPPOCAMPUS': ['HC_M2_0606_R', 'UMUTAffyExon_0209_RMA'], + 'WHOLE BRAIN': ['BR_M2_1106_R', 'IBR_M_0106_R', 'BRF2_M_0805_R', 'UCLA_BHF2_BRAIN_0605'], + 'LIVER': ['LV_G_0106_B', 'UCLA_BHF2_LIVER_0605'], + 'EYE': ['Eye_M2_0908_R'], + 'HEMATOPOIETIC STEM CELLS': ['HC_U_0304_R'], 'KIDNEY': ['MA_M2_0806_R'], 'MAMMARY TUMORS': ['MA_M_0704_R', 'NCI_Agil_Mam_Tum_RMA_0409'], 'PREFRONTAL CORTEX': ['VCUSal_1206_R'], @@ -65,14 +65,14 @@ ADMIN_search_dbs = { ###LIST of tissue alias -ADMIN_tissue_alias = {'CEREBELLUM': ['Cb'], - 'STRIATUM': ['Str'], - 'HIPPOCAMPUS': ['Hip'], - 'WHOLE BRAIN': ['Brn'], - 'LIVER': ['Liv'], - 'EYE': ['Eye'], - 'PERITONEAL FAT': ['Fat'], - 'HEMATOPOIETIC STEM CELLS': ['Hsc'], +ADMIN_tissue_alias = {'CEREBELLUM': ['Cb'], + 'STRIATUM': ['Str'], + 'HIPPOCAMPUS': ['Hip'], + 'WHOLE BRAIN': ['Brn'], + 'LIVER': ['Liv'], + 'EYE': ['Eye'], + 'PERITONEAL FAT': ['Fat'], + 'HEMATOPOIETIC STEM CELLS': ['Hsc'], 'KIDNEY': ['Kid'], 'ADRENAL GLAND': ['Adr'], 'HEART': ['Hea'], @@ -84,5 +84,3 @@ ADMIN_tissue_alias = {'CEREBELLUM': ['Cb'], 'ADIPOSE': ['Wfat'], 'RETINA': ['Ret'] } - - diff --git a/wqflask/base/cgiData.py b/wqflask/base/cgiData.py index 57416060..155b3ec3 100755 --- a/wqflask/base/cgiData.py +++ b/wqflask/base/cgiData.py @@ -30,41 +30,37 @@ ######################################### class cgiData(dict): - '''convert Field storage object to Dict object - Filed storage object cannot be properly dumped - ''' + '''convert Field storage object to Dict object + Filed storage object cannot be properly dumped + ''' - def __init__(self, field_storage=None): + def __init__(self, field_storage=None): - if not field_storage: - field_storage={} - - for key in field_storage.keys(): - temp = field_storage.getlist(key) - if len(temp) > 1: - temp = map(self.toValue, temp) - elif len(temp) == 1: - temp = self.toValue(temp[0]) - else: - temp = None - self[key]= temp - - def toValue(self, obj): - '''fieldstorge returns different type of objects, \ - need to convert to string or None''' - try: - return obj.value - except: - return "" - - def getvalue(self, k, default= None): - try: - return self[k] - except: - return default - - getfirst = getvalue + if not field_storage: + field_storage={} + for key in field_storage.keys(): + temp = field_storage.getlist(key) + if len(temp) > 1: + temp = map(self.toValue, temp) + elif len(temp) == 1: + temp = self.toValue(temp[0]) + else: + temp = None + self[key]= temp + def toValue(self, obj): + '''fieldstorge returns different type of objects, \ + need to convert to string or None''' + try: + return obj.value + except: + return "" + def getvalue(self, k, default= None): + try: + return self[k] + except: + return default + getfirst = getvalue diff --git a/wqflask/base/cookieData.py b/wqflask/base/cookieData.py index 4b7c9046..eeb7c0cf 100755 --- a/wqflask/base/cookieData.py +++ b/wqflask/base/cookieData.py @@ -30,23 +30,20 @@ ######################################### class cookieData(dict): - 'convert mod python Cookie object to Dict object' + 'convert mod python Cookie object to Dict object' - def __init__(self, cookies=None): + def __init__(self, cookies=None): - if not cookies: - cookies={} - - for key in cookies.keys(): - self[key.lower()]= cookies[key].value - - def getvalue(self, k, default= None): - try: - return self[k.lower()] - except: - return default - - getfirst = getvalue + if not cookies: + cookies={} + for key in cookies.keys(): + self[key.lower()]= cookies[key].value + def getvalue(self, k, default= None): + try: + return self[k.lower()] + except: + return default + getfirst = getvalue diff --git a/wqflask/base/header.py b/wqflask/base/header.py index b6136b51..ec15e174 100755 --- a/wqflask/base/header.py +++ b/wqflask/base/header.py @@ -3,4 +3,4 @@ import webqtlConfig header_string = open(webqtlConfig.HTMLPATH + 'header.html', 'r').read() header_string = header_string.replace("\\'", "'") header_string = header_string.replace('%"','%%"') -header_string = header_string.replace('', '%s') \ No newline at end of file +header_string = header_string.replace('', '%s') diff --git a/wqflask/base/indexBody.py b/wqflask/base/indexBody.py index aa67dffa..a5bc4c17 100755 --- a/wqflask/base/indexBody.py +++ b/wqflask/base/indexBody.py @@ -1,174 +1,174 @@ index_body_string = """ -

Select and Search -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +

Select and Search + + +

- Species: - - - -
- Group: - - - -
- Type: - - - -
- Database: - - - - -
- - -

    Databases marked with ** suffix are not public yet. -
    Access requires user login.

-
- Get Any: - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - + - + + - - + + - + - - + + - - - - + + + - -
+ Species: + + + +
+ Group: + + + +
+ Type: + + + +
+ Database: + + + + +
+ + +

    Databases marked with ** suffix are not public yet. +
    Access requires user login.

+
+ Get Any: + + + + +
- +
+ - -

    Enter terms, genes, ID numbers in the Get Any field. -
    Use * or ? wildcards (Cyp*a?, synap*). -
    Use Combined for terms such as tyrosine kinase.

+
+

    Enter terms, genes, ID numbers in the Get Any field. +
    Use * or ? wildcards (Cyp*a?, synap*). +
    Use Combined for terms such as tyrosine kinase.

-
- Combined: -
+ Combined: + - + - - -
+ + +
- - -      -      - +
+ + +      +      + -
- - - -
- + + + + + + + + @@ -185,7 +185,7 @@ Quick HELP Examples and User's Guide

-  You can also use advanced commands. Copy these simple examples +  You can also use advanced commands. Copy these simple examples
  into the Get Any or Combined search fields:
    @@ -206,85 +206,85 @@ Quick HELP Examples and
  • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
    in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS scores between 9 and 999. -
+ - + -

Websites Affiliated with GeneNetwork

-

-

-

-

____________________________ - -

Getting Started   

-
    -
  1. Select Species (or select All) -
  2. Select Group (a specific sample) -
  3. Select Type of data: -
      -
    • Phenotype (traits) -
    • Genotype (markers) -
    • Expression (mRNAs) -
    -
  4. Select a Database -
  5. Enter search terms in the Get Any or Combined field: words, genes, ID numbers, probes, advanced search commands -
  6. Click on the Search button -
  7. Optional: Use the Make Default button to save your preferences -
- -

____________________________ +

Websites Affiliated with GeneNetwork

+

+

+

+

____________________________ + +

Getting Started   

+
    +
  1. Select Species (or select All) +
  2. Select Group (a specific sample) +
  3. Select Type of data: +
      +
    • Phenotype (traits) +
    • Genotype (markers) +
    • Expression (mRNAs) +
    +
  4. Select a Database +
  5. Enter search terms in the Get Any or Combined field: words, genes, ID numbers, probes, advanced search commands +
  6. Click on the Search button +
  7. Optional: Use the Make Default button to save your preferences +
+ +

____________________________

How to Use GeneNetwork -

-

Take a 20-40 minute GeneNetwork Tour that includes screen shots and typical steps in the analysis.

-
-
-

For information about resources and methods, select the INFO buttons.

+
+

Take a 20-40 minute GeneNetwork Tour that includes screen shots and typical steps in the analysis.

+
+
+

For information about resources and methods, select the INFO buttons.

+ + - -

Try the Workstation site to explore data and features that are being implemented.

-

Review the Conditions and Contacts pages for information on the status of data sets and advice on their use and citation.

+

Review the Conditions and Contacts pages for information on the status of data sets and advice on their use and citation.

+ +
-
- -

Mirror and Development Sites

+

Mirror and Development Sites

- + -

History and Archive +

History and Archive -

-

GeneNetwork's Time Machine links to earlier versions that correspond to specific publication dates.

+
+

GeneNetwork's Time Machine links to earlier versions that correspond to specific publication dates.

-
+

- + """ diff --git a/wqflask/base/myCookie.py b/wqflask/base/myCookie.py index db5320df..add7e6ea 100755 --- a/wqflask/base/myCookie.py +++ b/wqflask/base/myCookie.py @@ -25,31 +25,27 @@ # Last updated by GeneNetwork Core Team 2010/10/20 ######################################### -## python cookie and mod python cookie are +## python cookie and mod python cookie are ## not compatible ######################################### class myCookie(dict): - 'define my own cookie' - - def __init__(self, name="", value="", expire = None, path="/"): - self['name']= name - self['value']= value - self['expire']= expire - self['path']= path - - def __getattr__(self, key): - if key in self.keys(): - return self[key] - else: - return None - - def __nonzero__ (self): - if self['name']: - return 1 - else: - return 0 - + 'define my own cookie' + def __init__(self, name="", value="", expire = None, path="/"): + self['name']= name + self['value']= value + self['expire']= expire + self['path']= path + def __getattr__(self, key): + if key in self.keys(): + return self[key] + else: + return None + def __nonzero__ (self): + if self['name']: + return 1 + else: + return 0 diff --git a/wqflask/base/sessionData.py b/wqflask/base/sessionData.py index 01555f87..4b23060f 100755 --- a/wqflask/base/sessionData.py +++ b/wqflask/base/sessionData.py @@ -30,24 +30,21 @@ ######################################### class sessionData(dict): - 'convert mod python Session object to Dict object' + 'convert mod python Session object to Dict object' - def __init__(self, mod_python_session=None): - - if not mod_python_session: - mod_python_session = {} + def __init__(self, mod_python_session=None): - for key in mod_python_session.keys(): - self[key]= mod_python_session[key] - - - def getvalue(self, k, default= None): - try: - return self[k] - except: - return default + if not mod_python_session: + mod_python_session = {} - getfirst = getvalue + for key in mod_python_session.keys(): + self[key]= mod_python_session[key] + def getvalue(self, k, default= None): + try: + return self[k] + except: + return default + getfirst = getvalue diff --git a/wqflask/base/template.py b/wqflask/base/template.py index 85bd86df..aa8f90dc 100755 --- a/wqflask/base/template.py +++ b/wqflask/base/template.py @@ -68,32 +68,32 @@ template = """ %s - - - - %s - - + + + + %s + + - - - - - + + + + + - - - - + + + +
- - - %s - -
-
+ + + %s + +
+
- %s
-
+ %s
+
@@ -103,20 +103,20 @@ template = """ diff --git a/wqflask/base/templatePage.py b/wqflask/base/templatePage.py index 821c6181..7ef58a72 100755 --- a/wqflask/base/templatePage.py +++ b/wqflask/base/templatePage.py @@ -61,162 +61,162 @@ from utility import webqtlUtil class templatePage: - contents = ['title','basehref','js1','js2', 'layer', 'header', 'body', 'footer'] - - # you can pass in another template here if you want - def __init__(self, fd=None, template=template.template): - - # initiate dictionary - self.starttime = time.time() - self.dict = {} - self.template = template - - for item in self.contents: - self.dict[item] = "" - - self.dict['basehref'] = "" #webqtlConfig.BASEHREF - self.cursor = None - - self.cookie = [] #XZ: list to hold cookies (myCookie object) being changed - self.content_type = 'text/html' - self.content_disposition = '' - self.redirection = '' - self.debug = '' - self.attachment = '' - - #XZ: Holding data (new data or existing data being changed) that should be saved to session. The data must be picklable!!! - self.session_data_changed = {} - - self.userName = 'Guest' - self.privilege = 'guest' - - # Commenting this out for flask - we'll have to reimplement later - Sam - #if fd.input_session_data.has_key('user'): - # self.userName = fd.input_session_data['user'] - #if fd.input_session_data.has_key('privilege'): - # self.privilege = fd.input_session_data['privilege'] - - def __str__(self): - - #XZ: default setting - thisUserName = self.userName - thisPrivilege = self.privilege - #XZ: user may just go through login or logoff page - if self.session_data_changed.has_key('user'): - thisUserName = self.session_data_changed['user'] - if self.session_data_changed.has_key('privilege'): - thisPrivilege = self.session_data_changed['privilege'] - - if thisUserName == 'Guest': - userInfo = 'Welcome! Login' - else: - userInfo = 'Hi, %s! Logout' % thisUserName - - reload(header) - self.dict['header'] = header.header_string % userInfo - - serverInfo = "It took %2.3f second(s) for %s to generate this page" % (time.time()-self.starttime, socket.getfqdn()) - reload(footer) - self.dict['footer'] = footer.footer_string % serverInfo - - slist = [] - for item in self.contents: - slist.append(self.dict[item]) - return self.template % tuple(slist) - - - def __del__(self): - if self.cursor: - self.cursor.close() - - def write(self): - 'return string representation of this object' - - if self.cursor: - self.cursor.close() - - return str(self) - - def writeFile(self, filename): - 'save string representation of this object into a file' - if self.cursor: - self.cursor.close() - - try: - 'it could take a long time to generate the file, save to .tmp first' - fp = open(os.path.join(webqtlConfig.TMPDIR, filename+'.tmp'), 'wb') - fp.write(str(self)) - fp.close() - path_tmp = os.path.join(webqtlConfig.TMPDIR, filename+'.tmp') - path_html = os.path.join(webqtlConfig.TMPDIR, filename) - shutil.move(path_tmp,path_html) - except: - pass - - def openMysql(self): - try: - self.con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \ - user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) - self.cursor = self.con.cursor() - return 1 - except: - heading = "Connect MySQL Server" - detail = ["Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_SERVER+"':100061. \ - The server may be down at this time"] - self.error(heading=heading,detail=detail,error="Error 2003") - return 0 - - def updMysql(self): - try: - self.con = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \ - user=webqtlConfig.DB_UPDUSER,passwd=webqtlConfig.DB_UPDPASSWD) - self.cursor = self.con.cursor() - return 1 - except: - heading = "Connect MySQL Server" - detail = ["update: Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_UPDSERVER+"':100061. \ - The server may be down at this time "] - self.error(heading=heading,detail=detail,error="Error 2003") - return 0 - - def error(self,heading="",intro=[],detail=[],title="Error",error="Error"): - 'generating a WebQTL style error page' - Heading = HT.Paragraph(heading) - Heading.__setattr__("class","title") - - Intro = HT.Blockquote() - if intro: - for item in intro: - Intro.append(item) - else: - Intro.append(HT.Strong('Sorry!'),' Error occurred while processing\ - your request.', HT.P(),'The nature of the error generated is as\ - follows:') - - Detail = HT.Blockquote() - Detail.append(HT.Span("%s : " % error,Class="fwb cr")) - if detail: - Detail2 = HT.Blockquote() - for item in detail: - Detail2.append(item) - Detail.append(HT.Italic(Detail2)) - - #Detail.__setattr__("class","subtitle") - TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") - TD_LR.append(Heading,Intro,Detail) - self.dict['body'] = str(TD_LR) - self.dict['title'] = title - - def session(self,mytitle="",myHeading=""): - 'generate a auto-refreshing temporary html file(waiting page)' - self.filename = webqtlUtil.generate_session() - self.dict['title'] = mytitle - self.dict['basehref'] = webqtlConfig.REFRESHSTR % (webqtlConfig.CGIDIR, self.filename) + "" #webqtlConfig.BASEHREF - - TD_LR = HT.TD(align="center", valign="middle", height=200,width="100%", bgColor='#eeeeee') - Heading = HT.Paragraph(myHeading, Class="fwb fs16 cr") - # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py; - TD_LR.append(Heading, HT.BR(), webqtlUtil.PROGRESSBAR) - self.dict['body'] = TD_LR - self.writeFile(self.filename + '.html') - return self.filename + contents = ['title','basehref','js1','js2', 'layer', 'header', 'body', 'footer'] + + # you can pass in another template here if you want + def __init__(self, fd=None, template=template.template): + + # initiate dictionary + self.starttime = time.time() + self.dict = {} + self.template = template + + for item in self.contents: + self.dict[item] = "" + + self.dict['basehref'] = "" #webqtlConfig.BASEHREF + self.cursor = None + + self.cookie = [] #XZ: list to hold cookies (myCookie object) being changed + self.content_type = 'text/html' + self.content_disposition = '' + self.redirection = '' + self.debug = '' + self.attachment = '' + + #XZ: Holding data (new data or existing data being changed) that should be saved to session. The data must be picklable!!! + self.session_data_changed = {} + + self.userName = 'Guest' + self.privilege = 'guest' + + # Commenting this out for flask - we'll have to reimplement later - Sam + #if fd.input_session_data.has_key('user'): + # self.userName = fd.input_session_data['user'] + #if fd.input_session_data.has_key('privilege'): + # self.privilege = fd.input_session_data['privilege'] + + def __str__(self): + + #XZ: default setting + thisUserName = self.userName + thisPrivilege = self.privilege + #XZ: user may just go through login or logoff page + if self.session_data_changed.has_key('user'): + thisUserName = self.session_data_changed['user'] + if self.session_data_changed.has_key('privilege'): + thisPrivilege = self.session_data_changed['privilege'] + + if thisUserName == 'Guest': + userInfo = 'Welcome! Login' + else: + userInfo = 'Hi, %s! Logout' % thisUserName + + reload(header) + self.dict['header'] = header.header_string % userInfo + + serverInfo = "It took %2.3f second(s) for %s to generate this page" % (time.time()-self.starttime, socket.getfqdn()) + reload(footer) + self.dict['footer'] = footer.footer_string % serverInfo + + slist = [] + for item in self.contents: + slist.append(self.dict[item]) + return self.template % tuple(slist) + + + def __del__(self): + if self.cursor: + self.cursor.close() + + def write(self): + 'return string representation of this object' + + if self.cursor: + self.cursor.close() + + return str(self) + + def writeFile(self, filename): + 'save string representation of this object into a file' + if self.cursor: + self.cursor.close() + + try: + 'it could take a long time to generate the file, save to .tmp first' + fp = open(os.path.join(webqtlConfig.TMPDIR, filename+'.tmp'), 'wb') + fp.write(str(self)) + fp.close() + path_tmp = os.path.join(webqtlConfig.TMPDIR, filename+'.tmp') + path_html = os.path.join(webqtlConfig.TMPDIR, filename) + shutil.move(path_tmp,path_html) + except: + pass + + def openMysql(self): + try: + self.con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \ + user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) + self.cursor = self.con.cursor() + return 1 + except: + heading = "Connect MySQL Server" + detail = ["Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_SERVER+"':100061. \ + The server may be down at this time"] + self.error(heading=heading,detail=detail,error="Error 2003") + return 0 + + def updMysql(self): + try: + self.con = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \ + user=webqtlConfig.DB_UPDUSER,passwd=webqtlConfig.DB_UPDPASSWD) + self.cursor = self.con.cursor() + return 1 + except: + heading = "Connect MySQL Server" + detail = ["update: Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_UPDSERVER+"':100061. \ + The server may be down at this time "] + self.error(heading=heading,detail=detail,error="Error 2003") + return 0 + + def error(self,heading="",intro=[],detail=[],title="Error",error="Error"): + 'generating a WebQTL style error page' + Heading = HT.Paragraph(heading) + Heading.__setattr__("class","title") + + Intro = HT.Blockquote() + if intro: + for item in intro: + Intro.append(item) + else: + Intro.append(HT.Strong('Sorry!'),' Error occurred while processing\ + your request.', HT.P(),'The nature of the error generated is as\ + follows:') + + Detail = HT.Blockquote() + Detail.append(HT.Span("%s : " % error,Class="fwb cr")) + if detail: + Detail2 = HT.Blockquote() + for item in detail: + Detail2.append(item) + Detail.append(HT.Italic(Detail2)) + + #Detail.__setattr__("class","subtitle") + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee',valign="top") + TD_LR.append(Heading,Intro,Detail) + self.dict['body'] = str(TD_LR) + self.dict['title'] = title + + def session(self,mytitle="",myHeading=""): + 'generate a auto-refreshing temporary html file(waiting page)' + self.filename = webqtlUtil.generate_session() + self.dict['title'] = mytitle + self.dict['basehref'] = webqtlConfig.REFRESHSTR % (webqtlConfig.CGIDIR, self.filename) + "" #webqtlConfig.BASEHREF + + TD_LR = HT.TD(align="center", valign="middle", height=200,width="100%", bgColor='#eeeeee') + Heading = HT.Paragraph(myHeading, Class="fwb fs16 cr") + # NL, 07/27/2010. variable 'PROGRESSBAR' has been moved from templatePage.py to webqtlUtil.py; + TD_LR.append(Heading, HT.BR(), webqtlUtil.PROGRESSBAR) + self.dict['body'] = TD_LR + self.writeFile(self.filename + '.html') + return self.filename diff --git a/wqflask/base/webqtlCaseData.py b/wqflask/base/webqtlCaseData.py index 4df32ca4..f68354be 100755 --- a/wqflask/base/webqtlCaseData.py +++ b/wqflask/base/webqtlCaseData.py @@ -25,30 +25,27 @@ # Last updated by GeneNetwork Core Team 2010/10/20 class webqtlCaseData: - """ - one case data in one trait - """ + """ + one case data in one trait + """ - val = None #Trait Value - var = None #Trait Variance - N = None #Number of individuals - - def __init__(self, val=val, var=var, N=N): - self.val = val - self.var = var - self.N = N - - def __str__(self): - str = "" - if self.val != None: - str += "value=%2.3f" % self.val - if self.var != None: - str += " variance=%2.3f" % self.var - if self.N != None: - str += " ndata=%d" % self.N - return str - - __repr__ = __str__ + val = None #Trait Value + var = None #Trait Variance + N = None #Number of individuals + def __init__(self, val=val, var=var, N=N): + self.val = val + self.var = var + self.N = N + def __str__(self): + str = "" + if self.val != None: + str += "value=%2.3f" % self.val + if self.var != None: + str += " variance=%2.3f" % self.var + if self.N != None: + str += " ndata=%d" % self.N + return str + __repr__ = __str__ diff --git a/wqflask/base/webqtlDataset.py b/wqflask/base/webqtlDataset.py index da1b8601..f8491bb1 100755 --- a/wqflask/base/webqtlDataset.py +++ b/wqflask/base/webqtlDataset.py @@ -31,130 +31,125 @@ import webqtlConfig class webqtlDataset: - """ - Database class defines a database in webqtl, can be either Microarray, - Published phenotype, genotype, or user input database(temp) - """ - - def __init__(self, dbName, cursor=None): - - assert dbName - self.id = 0 - self.name = '' - self.type = '' - self.riset = '' - self.cursor = cursor - - #temporary storage - if dbName.find('Temp') >= 0: - self.searchfield = ['name','description'] - self.disfield = ['name','description'] - self.type = 'Temp' - self.id = 1 - self.fullname = 'Temporary Storage' - self.shortname = 'Temp' - elif dbName.find('Publish') >= 0: - self.searchfield = ['name','post_publication_description','abstract','title','authors'] - self.disfield = ['name','pubmed_id', - 'pre_publication_description', 'post_publication_description', 'original_description', - 'pre_publication_abbreviation', 'post_publication_abbreviation', - 'lab_code', 'submitter', 'owner', 'authorized_users', - 'authors','title','abstract', 'journal','volume','pages','month', - 'year','sequence', 'units', 'comments'] - self.type = 'Publish' - elif dbName.find('Geno') >= 0: - self.searchfield = ['name','chr'] - self.disfield = ['name','chr','mb', 'source2', 'sequence'] - self.type = 'Geno' - else: #ProbeSet - self.searchfield = ['name','description','probe_target_description', - 'symbol','alias','genbankid','unigeneid','omim', - 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] - self.disfield = ['name','symbol','description','probe_target_description', - 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', - 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', - 'strand_probe','strand_gene','probe_set_target_region', - 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', - 'probe_set_blat_mb_end', 'probe_set_strand', - 'probe_set_note_by_rw', 'flag'] - self.type = 'ProbeSet' - self.name = dbName - if self.cursor and self.id == 0: - self.retrieveName() - - def __str__(self): - return self.name - - __repr__ = __str__ - - - def getRISet(self): - assert self.cursor - if self.type == 'Publish': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, PublishFreeze - WHERE - PublishFreeze.InbredSetId = InbredSet.Id AND - PublishFreeze.Name = "%s" - ''' % self.name - elif self.type == 'Geno': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, GenoFreeze - WHERE - GenoFreeze.InbredSetId = InbredSet.Id AND - GenoFreeze.Name = "%s" - ''' % self.name - elif self.type == 'ProbeSet': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, ProbeSetFreeze, ProbeFreeze - WHERE - ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % self.name - else: - return "" - self.cursor.execute(query) - RISet, RIID = self.cursor.fetchone() - if RISet == 'BXD300': - RISet = "BXD" - self.riset = RISet - self.risetid = RIID - return RISet - - - def retrieveName(self): - assert self.id == 0 and self.cursor - query = ''' - SELECT - Id, Name, FullName, ShortName - FROM - %sFreeze - WHERE - public > %d AND - (Name = "%s" OR FullName = "%s" OR ShortName = "%s") - '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) - try: - self.cursor.execute(query) - self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() - except: - raise KeyError, `self.name`+' doesn\'t exist.' - - - def genHTML(self, Class='c0dd'): - return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), - url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") - - - - - + """ + Database class defines a database in webqtl, can be either Microarray, + Published phenotype, genotype, or user input database(temp) + """ + + def __init__(self, dbName, cursor=None): + + assert dbName + self.id = 0 + self.name = '' + self.type = '' + self.riset = '' + self.cursor = cursor + + #temporary storage + if dbName.find('Temp') >= 0: + self.searchfield = ['name','description'] + self.disfield = ['name','description'] + self.type = 'Temp' + self.id = 1 + self.fullname = 'Temporary Storage' + self.shortname = 'Temp' + elif dbName.find('Publish') >= 0: + self.searchfield = ['name','post_publication_description','abstract','title','authors'] + self.disfield = ['name','pubmed_id', + 'pre_publication_description', 'post_publication_description', 'original_description', + 'pre_publication_abbreviation', 'post_publication_abbreviation', + 'lab_code', 'submitter', 'owner', 'authorized_users', + 'authors','title','abstract', 'journal','volume','pages','month', + 'year','sequence', 'units', 'comments'] + self.type = 'Publish' + elif dbName.find('Geno') >= 0: + self.searchfield = ['name','chr'] + self.disfield = ['name','chr','mb', 'source2', 'sequence'] + self.type = 'Geno' + else: #ProbeSet + self.searchfield = ['name','description','probe_target_description', + 'symbol','alias','genbankid','unigeneid','omim', + 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] + self.disfield = ['name','symbol','description','probe_target_description', + 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', + 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', + 'strand_probe','strand_gene','probe_set_target_region', + 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', + 'probe_set_blat_mb_end', 'probe_set_strand', + 'probe_set_note_by_rw', 'flag'] + self.type = 'ProbeSet' + self.name = dbName + if self.cursor and self.id == 0: + self.retrieveName() + + def __str__(self): + return self.name + + __repr__ = __str__ + + + def getRISet(self): + assert self.cursor + if self.type == 'Publish': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, PublishFreeze + WHERE + PublishFreeze.InbredSetId = InbredSet.Id AND + PublishFreeze.Name = "%s" + ''' % self.name + elif self.type == 'Geno': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, GenoFreeze + WHERE + GenoFreeze.InbredSetId = InbredSet.Id AND + GenoFreeze.Name = "%s" + ''' % self.name + elif self.type == 'ProbeSet': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, ProbeSetFreeze, ProbeFreeze + WHERE + ProbeFreeze.InbredSetId = InbredSet.Id AND + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % self.name + else: + return "" + self.cursor.execute(query) + RISet, RIID = self.cursor.fetchone() + if RISet == 'BXD300': + RISet = "BXD" + self.riset = RISet + self.risetid = RIID + return RISet + + + def retrieveName(self): + assert self.id == 0 and self.cursor + query = ''' + SELECT + Id, Name, FullName, ShortName + FROM + %sFreeze + WHERE + public > %d AND + (Name = "%s" OR FullName = "%s" OR ShortName = "%s") + '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) + try: + self.cursor.execute(query) + self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() + except: + raise KeyError, `self.name`+' doesn\'t exist.' + + + def genHTML(self, Class='c0dd'): + return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), + url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") diff --git a/wqflask/base/webqtlFormData.py b/wqflask/base/webqtlFormData.py index c94dbe53..06faacc0 100755 --- a/wqflask/base/webqtlFormData.py +++ b/wqflask/base/webqtlFormData.py @@ -40,261 +40,261 @@ from utility import webqtlUtil class webqtlFormData: - 'Represents data from a WebQTL form page, needed to generate the next page' - attrs = ('formID','RISet','genotype','strainlist','allstrainlist', - 'suggestive','significance','submitID','identification', 'enablevariance', - 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo') - - #XZ: Attention! All attribute values must be picklable! - - def __init__(self, start_vars = None, req = None, mod_python_session=None, FieldStorage_formdata=None): - - self.__dict__.update(start_vars) - - for item in self.attrs: - setattr(self,item, None) - - try: - self.remote_ip = req.connection.remote_ip - except: - self.remote_ip = '1.2.3.4' - - if req and req.headers_in.has_key('referer'): - self.refURL = req.headers_in['referer'] - else: - self.refURL = None - - # For now let's just comment all this out - Sam - - #self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie. - # - ##XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable. - #self.input_session_data = sessionData.sessionData( mod_python_session ) - # - ##XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data. - #self.formdata = cgiData( FieldStorage_formdata ) - # - ##get Form ID - #self.formID = self.formdata.getfirst('FormID') - # - ##get rest of the attributes - #if self.formID: - # for item in self.attrs: - # value = self.formdata.getfirst(item) - # if value != None: - # setattr(self,item,string.strip(value)) - - self.ppolar = "" - self.mpolar = "" - if self.RISet: - try: - # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; - f1, f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet] - except: - f1 = f12 = self.mpolar = self.ppolar = None - - try: - self.nperm = int(self.nperm) - self.nboot = int(self.nboot) - except: - self.nperm = 2000 #XZ: Rob asked to change the default value to 2000 - self.nboot = 2000 #XZ: Rob asked to change the default value to 2000 - - if self.allstrainlist: - self.allstrainlist = map(string.strip, string.split(self.allstrainlist)) - #self.readGenotype() - #self.readData() - - if self.RISet == 'BXD300': - self.RISet = 'BXD' - else: - pass - - def __getitem__(self, key): - return self.__dict__[key] - - def get(self, key, default=None): - if key in self.__dict__: - return self.__dict__[key] - else: - return default - - def __str__(self): - rstr = '' - for item in self.attrs: - if item != 'genotype': - rstr += '%s:%s\n' % (item,str(getattr(self,item))) - return rstr - - - def readGenotype(self): - 'read genotype from .geno file' - if self.RISet == 'BXD300': - self.RISet = 'BXD' - else: - pass - assert self.RISet - #genotype_1 is Dataset Object without parents and f1 - #genotype_2 is Dataset Object with parents and f1 (not for intercross) - self.genotype_1 = reaper.Dataset() - self.genotype_1.read(os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno')) - try: - # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; - _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] - except: - _f1 = _f12 = _mat = _pat = None - - self.genotype_2 =self.genotype_1 - if self.genotype_1.type == "riset" and _mat and _pat: - self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) - - #determine default genotype object - if self.incparentsf1 and self.genotype_1.type != "intercross": - self.genotype = self.genotype_2 - else: - self.incparentsf1 = 0 - self.genotype = self.genotype_1 - self.strainlist = list(self.genotype.prgy) - self.f1list = self.parlist = [] - if _f1 and _f12: - self.f1list = [_f1, _f12] - if _mat and _pat: - self.parlist = [_mat, _pat] - - def readData(self, strainlst=[], incf1=[]): - 'read user input data or from trait data and analysis form' - - if not self.genotype: - self.readGenotype() - if not strainlst: - if incf1: - strainlst = self.f1list + self.strainlist - else: - strainlst = self.strainlist - - - traitfiledata = self.formdata.getfirst('traitfile') - traitpastedata = self.formdata.getfirst('traitpaste') - variancefiledata = self.formdata.getfirst('variancefile') - variancepastedata = self.formdata.getfirst('variancepaste') - Nfiledata = self.formdata.getfirst('Nfile') - - - if traitfiledata: - tt = string.split(traitfiledata) - vals = map(webqtlUtil.StringAsFloat, tt) - elif traitpastedata: - tt = string.split(traitpastedata) - vals = map(webqtlUtil.StringAsFloat, tt) - else: - vals = map(self.FormDataAsFloat, strainlst) - - if len(vals) < len(strainlst): - vals += [None]*(len(strainlst) - len(vals)) - elif len(vals) > len(strainlst): - vals = vals[:len(strainlst)] - else: - pass - - - if variancefiledata: - tt = string.split(variancefiledata) - vars = map(webqtlUtil.StringAsFloat, tt) - elif variancepastedata: - tt = string.split(variancepastedata) - vars = map(webqtlUtil.StringAsFloat, tt) - else: - vars = map(self.FormVarianceAsFloat, strainlst) - - if len(vars) < len(strainlst): - vars += [None]*(len(strainlst) - len(vars)) - elif len(vars) > len(strainlst): - vars = vars[:len(strainlst)] - else: - pass - - if Nfiledata: - tt = string.split(Nfiledata) - nstrains = map(webqtlUtil.IntAsFloat, tt) - if len(nstrains) < len(strainlst): - nstrains += [None]*(len(strainlst) - len(nstrains)) - else: - nstrains = map(self.FormNAsFloat, strainlst) - - ##vals, vars, nstrains is obsolete - self.allTraitData = {} - for i, _strain in enumerate(strainlst): - if vals[i] != None: - self.allTraitData[_strain] = webqtlCaseData(vals[i], vars[i], nstrains[i]) - - - - def informativeStrains(self, strainlst=[], incVars = 0): - '''if readData was called, use this to output the informative strains - (strain with values)''' - if not strainlst: - strainlst = self.strainlist - strains = [] - vals = [] - vars = [] - for _strain in strainlst: - if self.allTraitData.has_key(_strain): - _val, _var = self.allTraitData[_strain].val, self.allTraitData[_strain].var - if _val != None: - if incVars: - if _var != None: - strains.append(_strain) - vals.append(_val) - vars.append(_var) - else: - strains.append(_strain) - vals.append(_val) - vars.append(None) - return strains, vals, vars, len(strains) - - - - def FormDataAsFloat(self, key): - try: - return float(self.formdata.getfirst(key)) - except: - return None - - - def FormVarianceAsFloat(self, key): - try: - return float(self.formdata.getfirst('V' + key)) - except: - return None - - def FormNAsFloat(self, key): - try: - return int(self.formdata.getfirst('N' + key)) - except: - return None - - def Sample(self): - 'Create some dummy data for testing' - self.RISet = 'BXD' - self.incparentsf1 = 'on' - #self.display = 9.2 - #self.significance = 16.1 - self.readGenotype() - self.identification = 'BXD : Coat color example by Lu Lu, et al' - #self.readGenotype() - #self.genotype.ReadMM('AXBXAforQTL') - #self.strainlist = map((lambda x, y='': '%s%s' % (y,x)), self.genotype.prgy) - #self.strainlist.sort() - self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2), - 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2), - 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4), - 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2), - 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3), - 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3), - 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2), - 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4), - 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4), - 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1), - 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4), - 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4), - 'BXD42': webqtlCaseData(4), 'BXD40': webqtlCaseData(3)} + 'Represents data from a WebQTL form page, needed to generate the next page' + attrs = ('formID','RISet','genotype','strainlist','allstrainlist', + 'suggestive','significance','submitID','identification', 'enablevariance', + 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo') + + #XZ: Attention! All attribute values must be picklable! + + def __init__(self, start_vars = None, req = None, mod_python_session=None, FieldStorage_formdata=None): + + self.__dict__.update(start_vars) + + for item in self.attrs: + setattr(self,item, None) + + try: + self.remote_ip = req.connection.remote_ip + except: + self.remote_ip = '1.2.3.4' + + if req and req.headers_in.has_key('referer'): + self.refURL = req.headers_in['referer'] + else: + self.refURL = None + + # For now let's just comment all this out - Sam + + #self.cookies = cookieData.cookieData(Cookie.get_cookies(req)) #XZ: dictionary type. To hold values transfered from mod_python Cookie. + # + ##XZ: dictionary type. To hold values transfered from mod_python Session object. We assume that it is always picklable. + #self.input_session_data = sessionData.sessionData( mod_python_session ) + # + ##XZ: FieldStorage_formdata may contain item that can't be pickled. Must convert to picklable data. + #self.formdata = cgiData( FieldStorage_formdata ) + # + ##get Form ID + #self.formID = self.formdata.getfirst('FormID') + # + ##get rest of the attributes + #if self.formID: + # for item in self.attrs: + # value = self.formdata.getfirst(item) + # if value != None: + # setattr(self,item,string.strip(value)) + + self.ppolar = "" + self.mpolar = "" + if self.RISet: + try: + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + f1, f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet] + except: + f1 = f12 = self.mpolar = self.ppolar = None + + try: + self.nperm = int(self.nperm) + self.nboot = int(self.nboot) + except: + self.nperm = 2000 #XZ: Rob asked to change the default value to 2000 + self.nboot = 2000 #XZ: Rob asked to change the default value to 2000 + + if self.allstrainlist: + self.allstrainlist = map(string.strip, string.split(self.allstrainlist)) + #self.readGenotype() + #self.readData() + + if self.RISet == 'BXD300': + self.RISet = 'BXD' + else: + pass + + def __getitem__(self, key): + return self.__dict__[key] + + def get(self, key, default=None): + if key in self.__dict__: + return self.__dict__[key] + else: + return default + + def __str__(self): + rstr = '' + for item in self.attrs: + if item != 'genotype': + rstr += '%s:%s\n' % (item,str(getattr(self,item))) + return rstr + + + def readGenotype(self): + 'read genotype from .geno file' + if self.RISet == 'BXD300': + self.RISet = 'BXD' + else: + pass + assert self.RISet + #genotype_1 is Dataset Object without parents and f1 + #genotype_2 is Dataset Object with parents and f1 (not for intercross) + self.genotype_1 = reaper.Dataset() + self.genotype_1.read(os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno')) + try: + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] + except: + _f1 = _f12 = _mat = _pat = None + + self.genotype_2 =self.genotype_1 + if self.genotype_1.type == "riset" and _mat and _pat: + self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) + + #determine default genotype object + if self.incparentsf1 and self.genotype_1.type != "intercross": + self.genotype = self.genotype_2 + else: + self.incparentsf1 = 0 + self.genotype = self.genotype_1 + self.strainlist = list(self.genotype.prgy) + self.f1list = self.parlist = [] + if _f1 and _f12: + self.f1list = [_f1, _f12] + if _mat and _pat: + self.parlist = [_mat, _pat] + + def readData(self, strainlst=[], incf1=[]): + 'read user input data or from trait data and analysis form' + + if not self.genotype: + self.readGenotype() + if not strainlst: + if incf1: + strainlst = self.f1list + self.strainlist + else: + strainlst = self.strainlist + + + traitfiledata = self.formdata.getfirst('traitfile') + traitpastedata = self.formdata.getfirst('traitpaste') + variancefiledata = self.formdata.getfirst('variancefile') + variancepastedata = self.formdata.getfirst('variancepaste') + Nfiledata = self.formdata.getfirst('Nfile') + + + if traitfiledata: + tt = string.split(traitfiledata) + vals = map(webqtlUtil.StringAsFloat, tt) + elif traitpastedata: + tt = string.split(traitpastedata) + vals = map(webqtlUtil.StringAsFloat, tt) + else: + vals = map(self.FormDataAsFloat, strainlst) + + if len(vals) < len(strainlst): + vals += [None]*(len(strainlst) - len(vals)) + elif len(vals) > len(strainlst): + vals = vals[:len(strainlst)] + else: + pass + + + if variancefiledata: + tt = string.split(variancefiledata) + vars = map(webqtlUtil.StringAsFloat, tt) + elif variancepastedata: + tt = string.split(variancepastedata) + vars = map(webqtlUtil.StringAsFloat, tt) + else: + vars = map(self.FormVarianceAsFloat, strainlst) + + if len(vars) < len(strainlst): + vars += [None]*(len(strainlst) - len(vars)) + elif len(vars) > len(strainlst): + vars = vars[:len(strainlst)] + else: + pass + + if Nfiledata: + tt = string.split(Nfiledata) + nstrains = map(webqtlUtil.IntAsFloat, tt) + if len(nstrains) < len(strainlst): + nstrains += [None]*(len(strainlst) - len(nstrains)) + else: + nstrains = map(self.FormNAsFloat, strainlst) + + ##vals, vars, nstrains is obsolete + self.allTraitData = {} + for i, _strain in enumerate(strainlst): + if vals[i] != None: + self.allTraitData[_strain] = webqtlCaseData(vals[i], vars[i], nstrains[i]) + + + + def informativeStrains(self, strainlst=[], incVars = 0): + '''if readData was called, use this to output the informative strains + (strain with values)''' + if not strainlst: + strainlst = self.strainlist + strains = [] + vals = [] + vars = [] + for _strain in strainlst: + if self.allTraitData.has_key(_strain): + _val, _var = self.allTraitData[_strain].val, self.allTraitData[_strain].var + if _val != None: + if incVars: + if _var != None: + strains.append(_strain) + vals.append(_val) + vars.append(_var) + else: + strains.append(_strain) + vals.append(_val) + vars.append(None) + return strains, vals, vars, len(strains) + + + + def FormDataAsFloat(self, key): + try: + return float(self.formdata.getfirst(key)) + except: + return None + + + def FormVarianceAsFloat(self, key): + try: + return float(self.formdata.getfirst('V' + key)) + except: + return None + + def FormNAsFloat(self, key): + try: + return int(self.formdata.getfirst('N' + key)) + except: + return None + + def Sample(self): + 'Create some dummy data for testing' + self.RISet = 'BXD' + self.incparentsf1 = 'on' + #self.display = 9.2 + #self.significance = 16.1 + self.readGenotype() + self.identification = 'BXD : Coat color example by Lu Lu, et al' + #self.readGenotype() + #self.genotype.ReadMM('AXBXAforQTL') + #self.strainlist = map((lambda x, y='': '%s%s' % (y,x)), self.genotype.prgy) + #self.strainlist.sort() + self.allTraitData = {'BXD29': webqtlCaseData(3), 'BXD28': webqtlCaseData(2), + 'BXD25': webqtlCaseData(2), 'BXD24': webqtlCaseData(2), 'BXD27': webqtlCaseData(2), + 'BXD21': webqtlCaseData(1), 'BXD20': webqtlCaseData(4), 'BXD23': webqtlCaseData(4), + 'BXD22': webqtlCaseData(3), 'BXD14': webqtlCaseData(4), 'BXD15': webqtlCaseData(2), + 'BXD16': webqtlCaseData(3), 'BXD11': webqtlCaseData(4), 'BXD12': webqtlCaseData(3), + 'BXD13': webqtlCaseData(2), 'BXD18': webqtlCaseData(3), 'BXD19': webqtlCaseData(3), + 'BXD38': webqtlCaseData(3), 'BXD39': webqtlCaseData(3), 'BXD36': webqtlCaseData(2), + 'BXD34': webqtlCaseData(4), 'BXD35': webqtlCaseData(4), 'BXD32': webqtlCaseData(4), + 'BXD33': webqtlCaseData(3), 'BXD30': webqtlCaseData(1), 'BXD31': webqtlCaseData(4), + 'DBA/2J': webqtlCaseData(1), 'BXD8': webqtlCaseData(3), 'BXD9': webqtlCaseData(1), + 'BXD6': webqtlCaseData(3), 'BXD5': webqtlCaseData(3), 'BXD2': webqtlCaseData(4), + 'BXD1': webqtlCaseData(1), 'C57BL/6J': webqtlCaseData(4), 'B6D2F1': webqtlCaseData(4), + 'BXD42': webqtlCaseData(4), 'BXD40': webqtlCaseData(3)} diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 88226894..812d112a 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -14,579 +14,579 @@ from pprint import pformat as pf class webqtlTrait: - """ - Trait class defines a trait in webqtl, can be either Microarray, - Published phenotype, genotype, or user input trait - - """ - - def __init__(self, cursor = None, **kw): - print("in webqtlTrait") - self.cursor = cursor - self.db = None # database object - self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. - self.cellid = '' - self.identification = 'un-named trait' - self.riset = '' - self.haveinfo = 0 - self.sequence = '' # Blat sequence, available for ProbeSet - self.data = {} - print("foo") - print("kw in webqtlTrait are:", pf(kw)) - print("printed\n\n") - for name, value in kw.items(): - if self.__dict__.has_key(name): - setattr(self, name, value) - elif name == 'fullname': - name2 = value.split("::") - if len(name2) == 2: - self.db, self.name = name2 - elif len(name2) == 3: - self.db, self.name, self.cellid = name2 - else: - raise KeyError, repr(value) + ' parameter format error.' - else: - raise KeyError, repr(name) + ' not a valid parameter for this class.' - - if self.db and isinstance(self.db, basestring): - assert self.cursor, "Don't have a cursor" - self.db = webqtlDataset(self.db, self.cursor) - - #if self.db == None, not from a database - print("self.db is:", self.db, type(self.db)) - if self.db: - if self.db.type == "Temp": - self.cursor.execute(''' - SELECT - InbredSet.Name - FROM - InbredSet, Temp - WHERE - Temp.InbredSetId = InbredSet.Id AND - Temp.Name = "%s" - ''', self.name) - self.riset = self.cursor.fetchone()[0] - else: - self.riset = self.db.getRISet() - - # - # In ProbeSet, there are maybe several annotations match one sequence - # so we need use sequence(BlatSeq) as the identification, when we update - # one annotation, we update the others who match the sequence also. - # - # Hongqiang Li, 3/3/2008 - # - - #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. - # The variable self.sequence should be changed to self.BlatSeq - # It also should be changed in other places where it are used. - - if self.db: - if self.db.type == 'ProbeSet': - print("Doing ProbeSet Query") - query = ''' - SELECT - ProbeSet.BlatSeq - FROM - ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - ProbeSet.Name = %s and - ProbeSetFreeze.Name = %s - ''', (self.name, self.db.name) - print("query is:", query) - self.cursor.execute(*query) - self.sequence = self.cursor.fetchone()[0] - print("self.sequence is:", self.sequence) - - - def getName(self): - str = "" - if self.db and self.name: - str = "%s::%s" % (self.db, self.name) - if self.cellid: - str += "::" + self.cellid - else: - str = self.description - return str - - # - # when user enter a trait or GN generate a trait, user want show the name - # not the name that generated by GN randomly, the two follow function are - # used to give the real name and the database. displayName() will show the - # database also, getGivenName() just show the name. - # For other trait, displayName() as same as getName(), getGivenName() as - # same as self.name - # - # Hongqiang 11/29/07 - # - def getGivenName(self): - str = self.name - if self.db and self.name: - if self.db.type=='Temp': - self.cursor.execute('SELECT description FROM Temp WHERE Name=%s', self.name) - desc = self.cursor.fetchone()[0] - if desc.__contains__('PCA'): - desc = desc[desc.rindex(':')+1:].strip() - else: - desc = desc[:desc.index('entered')].strip() - str = desc - return str - - def displayName(self): - str = "" - if self.db and self.name: - if self.db.type=='Temp': - desc = self.description - if desc.__contains__('PCA'): - desc = desc[desc.rindex(':')+1:].strip() - else: - desc = desc[:desc.index('entered')].strip() - str = "%s::%s" % (self.db, desc) - else: - str = "%s::%s" % (self.db, self.name) - if self.cellid: - str += "::" + self.cellid - else: - str = self.description - - return str - - - #def __str__(self): - # #return "%s %s" % (self.getName(), self.riset) - # return self.getName() - __str__ = getName - __repr__ = __str__ - - def exportData(self, strainlist, type="val"): - """ - export data according to strainlist - mostly used in calculating correlation - """ - result = [] - for strain in strainlist: - if self.data.has_key(strain): - if type=='val': - result.append(self.data[strain].val) - elif type=='var': - result.append(self.data[strain].var) - elif type=='N': - result.append(self.data[strain].N) - else: - raise KeyError, `type`+' type is incorrect.' - else: - result.append(None) - return result - - def exportInformative(self, incVar=0): - """ - export informative strain - mostly used in qtl regression - """ - strains = [] - vals = [] - vars = [] - for strain, value in self.data.items(): - if value.val != None: - if not incVar or value.var != None: - strains.append(strain) - vals.append(value.val) - vars.append(value.var) - return strains, vals, vars - - - # - # In ProbeSet, there are maybe several annotations match one sequence - # so we need use sequence(BlatSeq) as the identification, when we update - # one annotation, we update the others who match the sequence also. - # - # Hongqiang Li, 3/3/2008 - # - def getSequence(self): - assert self.cursor - if self.db.type == 'ProbeSet': - self.cursor.execute(''' - SELECT - ProbeSet.BlatSeq - FROM - ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and - ProbeSet.Name = %s - ProbeSetFreeze.Name = %s - ''', self.name, self.db.name) - #self.cursor.execute(query) - results = self.fetchone() - - return results[0] - - - - def retrieveData(self, strainlist=[]): - assert self.db and self.cursor - - if self.db.type == 'Temp': - query = ''' - SELECT - Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id - FROM - TempData, Temp, Strain - WHERE - TempData.StrainId = Strain.Id AND - TempData.Id = Temp.DataId AND - Temp.name = '%s' - Order BY - Strain.Name - ''' % self.name - #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE - elif self.db.type == 'Publish': - query = ''' - SELECT - Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id - FROM - (PublishData, Strain, PublishXRef, PublishFreeze) - left join PublishSE on - (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) - left join NStrain on - (NStrain.DataId = PublishData.Id AND - NStrain.StrainId = PublishData.StrainId) - WHERE - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND - PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.name, self.db.id) - - #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE - elif self.cellid: - #Probe Data - query = ''' - SELECT - Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id - FROM - (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, - Strain, Probe, ProbeSet) - left join ProbeSE on - (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) - WHERE - Probe.Name = '%s' AND ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id AND - ProbeXRef.ProbeId = Probe.Id AND - ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeXRef.DataId = ProbeData.Id AND - ProbeData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.cellid, self.name, self.db.name) - #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE - elif self.db.type == 'ProbeSet': - #ProbeSet Data - query = ''' - SELECT - Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id - FROM - (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) - left join ProbeSetSE on - (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) - WHERE - ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSetXRef.DataId = ProbeSetData.Id AND - ProbeSetData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.name, self.db.name) - #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE - else: - #Geno Data - #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. - query = ''' - SELECT - Strain.Name, GenoData.value, GenoSE.error, GenoData.Id - FROM - (GenoData, GenoFreeze, Strain, Geno, GenoXRef) - left join GenoSE on - (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) - WHERE - Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoFreeze.Name = '%s' AND - GenoXRef.DataId = GenoData.Id AND - GenoData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name) - - - self.cursor.execute(query) - results = self.cursor.fetchall() - self.data.clear() - if results: - self.mysqlid = results[0][-1] - if strainlist: - for item in results: - if item[0] in strainlist: - val = item[1] - if val != None: - var = item[2] - ndata = None - if self.db.type in ('Publish', 'Temp'): - ndata = item[3] - self.data[item[0]] = webqtlCaseData(val, var, ndata) - #end for - else: - for item in results: - val = item[1] - if val != None: - var = item[2] - ndata = None - if self.db.type in ('Publish', 'Temp'): - ndata = item[3] - self.data[item[0]] = webqtlCaseData(val, var, ndata) - #end for - #end if - else: - pass - - def keys(self): - return self.__dict__.keys() - - def has_key(self, key): - return self.__dict__.has_key(key) - - def items(self): - return self.__dict__.items() - - def retrieveInfo(self, QTL = None): - assert self.db and self.cursor - if self.db.type == 'Publish': - #self.db.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ - # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ - # 'Units', 'comments'] - query = ''' - SELECT - PublishXRef.Id, Publication.PubMed_ID, - Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, - Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, - Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, - Publication.Authors, Publication.Title, Publication.Abstract, - Publication.Journal, Publication.Volume, Publication.Pages, - Publication.Month, Publication.Year, PublishXRef.Sequence, - Phenotype.Units, PublishXRef.comments - FROM - PublishXRef, Publication, Phenotype, PublishFreeze - WHERE - PublishXRef.Id = %s AND - Phenotype.Id = PublishXRef.PhenotypeId AND - Publication.Id = PublishXRef.PublicationId AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishFreeze.Id =%s - ''' % (self.name, self.db.id) - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name - #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. - elif self.db.type == 'ProbeSet': - disfieldString = string.join(self.db.disfield,',ProbeSet.') - disfieldString = 'ProbeSet.' + disfieldString - query = """ - SELECT %s - FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' - """ % (disfieldString, self.db.name, self.name) - #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name - # to avoid the problem of same marker name from different species. - elif self.db.type == 'Geno': - disfieldString = string.join(self.db.disfield,',Geno.') - disfieldString = 'Geno.' + disfieldString - query = """ - SELECT %s - FROM Geno, GenoFreeze, GenoXRef - WHERE - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoXRef.GenoId = Geno.Id AND - GenoFreeze.Name = '%s' AND - Geno.Name = '%s' - """ % (disfieldString, self.db.name, self.name) - else: #Temp type - query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ - (string.join(self.db.disfield,','), self.db.type, self.name) - - - self.cursor.execute(query) - traitInfo = self.cursor.fetchone() - if traitInfo: - self.haveinfo = 1 - - #XZ: assign SQL query result to trait attributes. - for i, field in enumerate(self.db.disfield): - setattr(self, field, traitInfo[i]) - - if self.db.type == 'Publish': - self.confidential = 0 - if self.pre_publication_description and not self.pubmed_id: - self.confidential = 1 - - self.homologeneid = None - if self.db.type == 'ProbeSet' and self.riset and self.geneid: - #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. - #XZ: So I have to test if geneid is number before execute the query. - #XZ: The geneid values in database should be cleaned up. - try: - junk = float(self.geneid) - geneidIsNumber = 1 - except: - geneidIsNumber = 0 - - if geneidIsNumber: - query = """ - SELECT - HomologeneId - FROM - Homologene, Species, InbredSet - WHERE - Homologene.GeneId =%s AND - InbredSet.Name = '%s' AND - InbredSet.SpeciesId = Species.Id AND - Species.TaxonomyId = Homologene.TaxonomyId - """ % (self.geneid, self.riset) - self.cursor.execute(query) - result = self.cursor.fetchone() - else: - result = None - - if result: - self.homologeneid = result[0] - - if QTL: - if self.db.type == 'ProbeSet' and not self.cellid: - query = ''' - SELECT - ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean - FROM - ProbeSetXRef, ProbeSet - WHERE - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSet.Name = "%s" AND - ProbeSetXRef.ProbeSetFreezeId =%s - ''' % (self.name, self.db.id) - self.cursor.execute(query) - traitQTL = self.cursor.fetchone() - if traitQTL: - self.locus, self.lrs, self.pvalue, self.mean = traitQTL - else: - self.locus = self.lrs = self.pvalue = self.mean = "" - if self.db.type == 'Publish': - query = ''' - SELECT - PublishXRef.Locus, PublishXRef.LRS - FROM - PublishXRef, PublishFreeze - WHERE - PublishXRef.Id = %s AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishFreeze.Id =%s - ''' % (self.name, self.db.id) - self.cursor.execute(query) - traitQTL = self.cursor.fetchone() - if traitQTL: - self.locus, self.lrs = traitQTL - else: - self.locus = self.lrs = "" - else: - raise KeyError, `self.name`+' information is not found in the database.' - - def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): - if not self.haveinfo: - self.retrieveInfo() - - if self.db.type == 'Publish': - PubMedLink = "" - if self.pubmed_id: - PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, - target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) - else: - PubMedLink = HT.Span("Unpublished : ", Class="fs15") - - if formName: - setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % - (formName, self.db.name, self.name), Class = "fs14") - else: - setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % - (self.db.name,self.name), Class = "fs14") - - if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): - setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) - else: - setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description)) - - #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1. - #if self.sequence > 1: - # setDescription2.append(' btach %d' % self.sequence) - if self.authors: - a1 = string.split(self.authors,',')[0] - while a1[0] == '"' or a1[0] == "'" : - a1 = a1[1:] - setDescription2.append(' by ') - setDescription2.append(HT.Italic('%s, and colleagues' % a1)) - setDescription = HT.Span(PubMedLink, setDescription2) - - elif self.db.type == 'Temp': - setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ - ('%s','%s','')" % (self.db.name,self.name), Class = "fs14") - setDescription = HT.Span(setDescription) - - elif self.db.type == 'Geno': # Genome DB only available for single search - if formName: - setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ - '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ - (formName, self.db.name, self.name), Class = "fs14") - else: - setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ - '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ - (self.db.name,self.name), Class = "fs14") - - setDescription = HT.Span(setDescription) - - else: - if self.cellid: - if formName: - setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ - "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \ - Class = "fs14") - else: - setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ - "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \ - Class = "fs14") - else: - if formName: - setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name,self.name), \ - Class = "fs14") - else: - setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), \ - Class = "fs14") - if self.symbol and self.chr and self.mb: - setDescription.append(' [') - setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb")) - setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb)) - if self.description: - setDescription.append(': %s' % self.description) - if self.probe_target_description: - setDescription.append('; %s' % self.probe_target_description) - setDescription = HT.Span(setDescription) - - if self.db.type != 'Temp' and dispFromDatabase: - setDescription.append( ' --- FROM : ') - setDescription.append(self.db.genHTML(Class='cori')) - return setDescription + """ + Trait class defines a trait in webqtl, can be either Microarray, + Published phenotype, genotype, or user input trait + + """ + + def __init__(self, cursor = None, **kw): + print("in webqtlTrait") + self.cursor = cursor + self.db = None # database object + self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. + self.cellid = '' + self.identification = 'un-named trait' + self.riset = '' + self.haveinfo = 0 + self.sequence = '' # Blat sequence, available for ProbeSet + self.data = {} + print("foo") + print("kw in webqtlTrait are:", pf(kw)) + print("printed\n\n") + for name, value in kw.items(): + if self.__dict__.has_key(name): + setattr(self, name, value) + elif name == 'fullname': + name2 = value.split("::") + if len(name2) == 2: + self.db, self.name = name2 + elif len(name2) == 3: + self.db, self.name, self.cellid = name2 + else: + raise KeyError, repr(value) + ' parameter format error.' + else: + raise KeyError, repr(name) + ' not a valid parameter for this class.' + + if self.db and isinstance(self.db, basestring): + assert self.cursor, "Don't have a cursor" + self.db = webqtlDataset(self.db, self.cursor) + + #if self.db == None, not from a database + print("self.db is:", self.db, type(self.db)) + if self.db: + if self.db.type == "Temp": + self.cursor.execute(''' + SELECT + InbredSet.Name + FROM + InbredSet, Temp + WHERE + Temp.InbredSetId = InbredSet.Id AND + Temp.Name = "%s" + ''', self.name) + self.riset = self.cursor.fetchone()[0] + else: + self.riset = self.db.getRISet() + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + + #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. + # The variable self.sequence should be changed to self.BlatSeq + # It also should be changed in other places where it are used. + + if self.db: + if self.db.type == 'ProbeSet': + print("Doing ProbeSet Query") + query = ''' + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and + ProbeSet.Name = %s and + ProbeSetFreeze.Name = %s + ''', (self.name, self.db.name) + print("query is:", query) + self.cursor.execute(*query) + self.sequence = self.cursor.fetchone()[0] + print("self.sequence is:", self.sequence) + + + def getName(self): + str = "" + if self.db and self.name: + str = "%s::%s" % (self.db, self.name) + if self.cellid: + str += "::" + self.cellid + else: + str = self.description + return str + + # + # when user enter a trait or GN generate a trait, user want show the name + # not the name that generated by GN randomly, the two follow function are + # used to give the real name and the database. displayName() will show the + # database also, getGivenName() just show the name. + # For other trait, displayName() as same as getName(), getGivenName() as + # same as self.name + # + # Hongqiang 11/29/07 + # + def getGivenName(self): + str = self.name + if self.db and self.name: + if self.db.type=='Temp': + self.cursor.execute('SELECT description FROM Temp WHERE Name=%s', self.name) + desc = self.cursor.fetchone()[0] + if desc.__contains__('PCA'): + desc = desc[desc.rindex(':')+1:].strip() + else: + desc = desc[:desc.index('entered')].strip() + str = desc + return str + + def displayName(self): + str = "" + if self.db and self.name: + if self.db.type=='Temp': + desc = self.description + if desc.__contains__('PCA'): + desc = desc[desc.rindex(':')+1:].strip() + else: + desc = desc[:desc.index('entered')].strip() + str = "%s::%s" % (self.db, desc) + else: + str = "%s::%s" % (self.db, self.name) + if self.cellid: + str += "::" + self.cellid + else: + str = self.description + + return str + + + #def __str__(self): + # #return "%s %s" % (self.getName(), self.riset) + # return self.getName() + __str__ = getName + __repr__ = __str__ + + def exportData(self, strainlist, type="val"): + """ + export data according to strainlist + mostly used in calculating correlation + """ + result = [] + for strain in strainlist: + if self.data.has_key(strain): + if type=='val': + result.append(self.data[strain].val) + elif type=='var': + result.append(self.data[strain].var) + elif type=='N': + result.append(self.data[strain].N) + else: + raise KeyError, `type`+' type is incorrect.' + else: + result.append(None) + return result + + def exportInformative(self, incVar=0): + """ + export informative strain + mostly used in qtl regression + """ + strains = [] + vals = [] + vars = [] + for strain, value in self.data.items(): + if value.val != None: + if not incVar or value.var != None: + strains.append(strain) + vals.append(value.val) + vars.append(value.var) + return strains, vals, vars + + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + def getSequence(self): + assert self.cursor + if self.db.type == 'ProbeSet': + self.cursor.execute(''' + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and + ProbeSet.Name = %s + ProbeSetFreeze.Name = %s + ''', self.name, self.db.name) + #self.cursor.execute(query) + results = self.fetchone() + + return results[0] + + + + def retrieveData(self, strainlist=[]): + assert self.db and self.cursor + + if self.db.type == 'Temp': + query = ''' + SELECT + Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id + FROM + TempData, Temp, Strain + WHERE + TempData.StrainId = Strain.Id AND + TempData.Id = Temp.DataId AND + Temp.name = '%s' + Order BY + Strain.Name + ''' % self.name + #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE + elif self.db.type == 'Publish': + query = ''' + SELECT + Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + FROM + (PublishData, Strain, PublishXRef, PublishFreeze) + left join PublishSE on + (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) + left join NStrain on + (NStrain.DataId = PublishData.Id AND + NStrain.StrainId = PublishData.StrainId) + WHERE + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND + PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.name, self.db.id) + + #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE + elif self.cellid: + #Probe Data + query = ''' + SELECT + Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id + FROM + (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, + Strain, Probe, ProbeSet) + left join ProbeSE on + (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) + WHERE + Probe.Name = '%s' AND ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id AND + ProbeXRef.ProbeId = Probe.Id AND + ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeXRef.DataId = ProbeData.Id AND + ProbeData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.cellid, self.name, self.db.name) + #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE + elif self.db.type == 'ProbeSet': + #ProbeSet Data + query = ''' + SELECT + Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id + FROM + (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) + left join ProbeSetSE on + (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) + WHERE + ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSetXRef.DataId = ProbeSetData.Id AND + ProbeSetData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (self.name, self.db.name) + #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE + else: + #Geno Data + #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. + query = ''' + SELECT + Strain.Name, GenoData.value, GenoSE.error, GenoData.Id + FROM + (GenoData, GenoFreeze, Strain, Geno, GenoXRef) + left join GenoSE on + (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) + WHERE + Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoFreeze.Name = '%s' AND + GenoXRef.DataId = GenoData.Id AND + GenoData.StrainId = Strain.Id + Order BY + Strain.Name + ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name) + + + self.cursor.execute(query) + results = self.cursor.fetchall() + self.data.clear() + if results: + self.mysqlid = results[0][-1] + if strainlist: + for item in results: + if item[0] in strainlist: + val = item[1] + if val != None: + var = item[2] + ndata = None + if self.db.type in ('Publish', 'Temp'): + ndata = item[3] + self.data[item[0]] = webqtlCaseData(val, var, ndata) + #end for + else: + for item in results: + val = item[1] + if val != None: + var = item[2] + ndata = None + if self.db.type in ('Publish', 'Temp'): + ndata = item[3] + self.data[item[0]] = webqtlCaseData(val, var, ndata) + #end for + #end if + else: + pass + + def keys(self): + return self.__dict__.keys() + + def has_key(self, key): + return self.__dict__.has_key(key) + + def items(self): + return self.__dict__.items() + + def retrieveInfo(self, QTL = None): + assert self.db and self.cursor + if self.db.type == 'Publish': + #self.db.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ + # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ + # 'Units', 'comments'] + query = ''' + SELECT + PublishXRef.Id, Publication.PubMed_ID, + Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, + Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, + Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, + Publication.Authors, Publication.Title, Publication.Abstract, + Publication.Journal, Publication.Volume, Publication.Pages, + Publication.Month, Publication.Year, PublishXRef.Sequence, + Phenotype.Units, PublishXRef.comments + FROM + PublishXRef, Publication, Phenotype, PublishFreeze + WHERE + PublishXRef.Id = %s AND + Phenotype.Id = PublishXRef.PhenotypeId AND + Publication.Id = PublishXRef.PublicationId AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id =%s + ''' % (self.name, self.db.id) + #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name + #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + elif self.db.type == 'ProbeSet': + disfieldString = string.join(self.db.disfield,',ProbeSet.') + disfieldString = 'ProbeSet.' + disfieldString + query = """ + SELECT %s + FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' + """ % (disfieldString, self.db.name, self.name) + #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name + # to avoid the problem of same marker name from different species. + elif self.db.type == 'Geno': + disfieldString = string.join(self.db.disfield,',Geno.') + disfieldString = 'Geno.' + disfieldString + query = """ + SELECT %s + FROM Geno, GenoFreeze, GenoXRef + WHERE + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoXRef.GenoId = Geno.Id AND + GenoFreeze.Name = '%s' AND + Geno.Name = '%s' + """ % (disfieldString, self.db.name, self.name) + else: #Temp type + query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ + (string.join(self.db.disfield,','), self.db.type, self.name) + + + self.cursor.execute(query) + traitInfo = self.cursor.fetchone() + if traitInfo: + self.haveinfo = 1 + + #XZ: assign SQL query result to trait attributes. + for i, field in enumerate(self.db.disfield): + setattr(self, field, traitInfo[i]) + + if self.db.type == 'Publish': + self.confidential = 0 + if self.pre_publication_description and not self.pubmed_id: + self.confidential = 1 + + self.homologeneid = None + if self.db.type == 'ProbeSet' and self.riset and self.geneid: + #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. + #XZ: So I have to test if geneid is number before execute the query. + #XZ: The geneid values in database should be cleaned up. + try: + junk = float(self.geneid) + geneidIsNumber = 1 + except: + geneidIsNumber = 0 + + if geneidIsNumber: + query = """ + SELECT + HomologeneId + FROM + Homologene, Species, InbredSet + WHERE + Homologene.GeneId =%s AND + InbredSet.Name = '%s' AND + InbredSet.SpeciesId = Species.Id AND + Species.TaxonomyId = Homologene.TaxonomyId + """ % (self.geneid, self.riset) + self.cursor.execute(query) + result = self.cursor.fetchone() + else: + result = None + + if result: + self.homologeneid = result[0] + + if QTL: + if self.db.type == 'ProbeSet' and not self.cellid: + query = ''' + SELECT + ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean + FROM + ProbeSetXRef, ProbeSet + WHERE + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSet.Name = "%s" AND + ProbeSetXRef.ProbeSetFreezeId =%s + ''' % (self.name, self.db.id) + self.cursor.execute(query) + traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs, self.pvalue, self.mean = traitQTL + else: + self.locus = self.lrs = self.pvalue = self.mean = "" + if self.db.type == 'Publish': + query = ''' + SELECT + PublishXRef.Locus, PublishXRef.LRS + FROM + PublishXRef, PublishFreeze + WHERE + PublishXRef.Id = %s AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id =%s + ''' % (self.name, self.db.id) + self.cursor.execute(query) + traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs = traitQTL + else: + self.locus = self.lrs = "" + else: + raise KeyError, `self.name`+' information is not found in the database.' + + def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): + if not self.haveinfo: + self.retrieveInfo() + + if self.db.type == 'Publish': + PubMedLink = "" + if self.pubmed_id: + PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, + target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) + else: + PubMedLink = HT.Span("Unpublished : ", Class="fs15") + + if formName: + setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % + (formName, self.db.name, self.name), Class = "fs14") + else: + setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % + (self.db.name,self.name), Class = "fs14") + + if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): + setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) + else: + setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description)) + + #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1. + #if self.sequence > 1: + # setDescription2.append(' btach %d' % self.sequence) + if self.authors: + a1 = string.split(self.authors,',')[0] + while a1[0] == '"' or a1[0] == "'" : + a1 = a1[1:] + setDescription2.append(' by ') + setDescription2.append(HT.Italic('%s, and colleagues' % a1)) + setDescription = HT.Span(PubMedLink, setDescription2) + + elif self.db.type == 'Temp': + setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ + ('%s','%s','')" % (self.db.name,self.name), Class = "fs14") + setDescription = HT.Span(setDescription) + + elif self.db.type == 'Geno': # Genome DB only available for single search + if formName: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ + (formName, self.db.name, self.name), Class = "fs14") + else: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ + (self.db.name,self.name), Class = "fs14") + + setDescription = HT.Span(setDescription) + + else: + if self.cellid: + if formName: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ + "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ + "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \ + Class = "fs14") + else: + if formName: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name,self.name), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), \ + Class = "fs14") + if self.symbol and self.chr and self.mb: + setDescription.append(' [') + setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb")) + setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb)) + if self.description: + setDescription.append(': %s' % self.description) + if self.probe_target_description: + setDescription.append('; %s' % self.probe_target_description) + setDescription = HT.Span(setDescription) + + if self.db.type != 'Temp' and dispFromDatabase: + setDescription.append( ' --- FROM : ') + setDescription.append(self.db.genHTML(Class='cori')) + return setDescription diff --git a/wqflask/basicStatistics/BasicStatisticsFunctions.py b/wqflask/basicStatistics/BasicStatisticsFunctions.py index 5cbbb145..285addae 100755 --- a/wqflask/basicStatistics/BasicStatisticsFunctions.py +++ b/wqflask/basicStatistics/BasicStatisticsFunctions.py @@ -13,162 +13,162 @@ from dbFunction import webqtlDatabaseFunction def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None): - valsOnly = [] - dataXZ = vals[:] - for i in range(len(dataXZ)): - valsOnly.append(dataXZ[i][1]) - - traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future - - tbl = HT.TableLite(cellpadding=20, cellspacing=0) - dataXZ = vals[:] - dataXZ.sort(webqtlUtil.cmpOrder) - tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180), - HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60))) - tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"), - HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - #tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - # HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222"))) - tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - if (trait_type != None and trait_type == 'ProbeSet'): - #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") - #IRQuest.append(HT.BR()) - #IRQuest.append(" (fold difference)") - tbl.append(HT.TR(HT.TD("Range (log2)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - tbl.append(HT.TR(HT.TD(HT.Span(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold")), align="left", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) - - #XZ, 04/01/2009: don't try to get H2 value for probe. - if cellid: - pass - else: - if heritability: - tbl.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - else: - pass - # Lei Yan - # 2008/12/19 - - return tbl + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) + + traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(valsOnly) #ZS: Should convert this from reaper to R in the future + + tbl = HT.TableLite(cellpadding=20, cellspacing=0) + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180), + HT.TD("Value", align="right", Class="fs14 fwb ffl b1 cw cbrb", width = 60))) + tbl.append(HT.TR(HT.TD("N of Samples",align="left", Class="fs13 b1 cbw c222"), + HT.TD(N,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Mean",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmean,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Median",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmedian,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + #tbl.append(HT.TR(HT.TD("Variance",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + # HT.TD("%2.3f" % traitvar,nowrap="yes",align="left", Class="fs13 b1 cbw c222"))) + tbl.append(HT.TR(HT.TD("Standard Error (SE)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitsem,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Standard Deviation (SD)", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitstdev,nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Minimum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[0][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD("Maximum", align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[-1][1],nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + if (trait_type != None and trait_type == 'ProbeSet'): + #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") + #IRQuest.append(HT.BR()) + #IRQuest.append(" (fold difference)") + tbl.append(HT.TR(HT.TD("Range (log2)",align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + tbl.append(HT.TR(HT.TD(HT.Span(HT.Href(url="/glossary.html#Interquartile", target="_blank", text="Interquartile Range", Class="non_bold")), align="left", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes", Class="fs13 b1 cbw c222"), align="right")) + + #XZ, 04/01/2009: don't try to get H2 value for probe. + if cellid: + pass + else: + if heritability: + tbl.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + else: + pass + # Lei Yan + # 2008/12/19 + + return tbl def plotNormalProbability(vals=None, RISet='', title=None, showstrains=0, specialStrains=[None], size=(750,500)): - dataXZ = vals[:] - dataXZ.sort(webqtlUtil.cmpOrder) - dataLabel = [] - dataX = map(lambda X: X[1], dataXZ) + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + dataLabel = [] + dataX = map(lambda X: X[1], dataXZ) - showLabel = showstrains - if len(dataXZ) > 50: - showLabel = 0 - for item in dataXZ: - strainName = webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=item[0]) - dataLabel.append(strainName) + showLabel = showstrains + if len(dataXZ) > 50: + showLabel = 0 + for item in dataXZ: + strainName = webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=item[0]) + dataLabel.append(strainName) - dataY=Plot.U(len(dataX)) - dataZ=map(Plot.inverseCumul,dataY) - c = pid.PILCanvas(size=(750,500)) - Plot.plotXY(c, dataZ, dataX, dataLabel = dataLabel, XLabel='Expected Z score', connectdot=0, YLabel='Trait value', title=title, specialCases=specialStrains, showLabel = showLabel) + dataY=Plot.U(len(dataX)) + dataZ=map(Plot.inverseCumul,dataY) + c = pid.PILCanvas(size=(750,500)) + Plot.plotXY(c, dataZ, dataX, dataLabel = dataLabel, XLabel='Expected Z score', connectdot=0, YLabel='Trait value', title=title, specialCases=specialStrains, showLabel = showLabel) - filename= webqtlUtil.genRandStr("nP_") - c.save(webqtlConfig.IMGDIR+filename, format='gif') + filename= webqtlUtil.genRandStr("nP_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') - img=HT.Image('/image/'+filename+'.gif',border=0) + img=HT.Image('/image/'+filename+'.gif',border=0) - return img + return img def plotBoxPlot(vals): - valsOnly = [] - dataXZ = vals[:] - for i in range(len(dataXZ)): - valsOnly.append(dataXZ[i][1]) + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) - plotHeight = 320 - plotWidth = 220 - xLeftOffset = 60 - xRightOffset = 40 - yTopOffset = 40 - yBottomOffset = 60 + plotHeight = 320 + plotWidth = 220 + xLeftOffset = 60 + xRightOffset = 40 + yTopOffset = 40 + yBottomOffset = 60 - canvasHeight = plotHeight + yTopOffset + yBottomOffset - canvasWidth = plotWidth + xLeftOffset + xRightOffset - canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) - XXX = [('', valsOnly[:])] + canvasHeight = plotHeight + yTopOffset + yBottomOffset + canvasWidth = plotWidth + xLeftOffset + xRightOffset + canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) + XXX = [('', valsOnly[:])] - Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") - filename= webqtlUtil.genRandStr("Box_") - canvas.save(webqtlConfig.IMGDIR+filename, format='gif') - img=HT.Image('/image/'+filename+'.gif',border=0) + Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") + filename= webqtlUtil.genRandStr("Box_") + canvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) - plotLink = HT.Span("More about ", HT.Href(text="Box Plots", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs13")) + plotLink = HT.Span("More about ", HT.Href(text="Box Plots", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs13")) - return img, plotLink + return img, plotLink def plotBarGraph(identification='', RISet='', vals=None, type="name"): - this_identification = "unnamed trait" - if identification: - this_identification = identification - - if type=="rank": - dataXZ = vals[:] - dataXZ.sort(webqtlUtil.cmpOrder) - title='%s' % this_identification - else: - dataXZ = vals[:] - title='%s' % this_identification - - tvals = [] - tnames = [] - tvars = [] - for i in range(len(dataXZ)): - tvals.append(dataXZ[i][1]) - tnames.append(webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=dataXZ[i][0])) - tvars.append(dataXZ[i][2]) - nnStrain = len(tnames) - - sLabel = 1 - - ###determine bar width and space width - if nnStrain < 20: - sw = 4 - elif nnStrain < 40: - sw = 3 - else: - sw = 2 - - ### 700 is the default plot width minus Xoffsets for 40 strains - defaultWidth = 650 - if nnStrain > 40: - defaultWidth += (nnStrain-40)*10 - defaultOffset = 100 - bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) - if bw < 10: - bw = 10 - - plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset - plotHeight = 500 - #print [plotWidth, plotHeight, bw, sw, nnStrain] - c = pid.PILCanvas(size=(plotWidth,plotHeight)) - Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title=title, sLabel = sLabel, barSpace = sw) - - filename= webqtlUtil.genRandStr("Bar_") - c.save(webqtlConfig.IMGDIR+filename, format='gif') - img=HT.Image('/image/'+filename+'.gif',border=0) - - return img + this_identification = "unnamed trait" + if identification: + this_identification = identification + + if type=="rank": + dataXZ = vals[:] + dataXZ.sort(webqtlUtil.cmpOrder) + title='%s' % this_identification + else: + dataXZ = vals[:] + title='%s' % this_identification + + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(RISet=RISet, input_strainName=dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + nnStrain = len(tnames) + + sLabel = 1 + + ###determine bar width and space width + if nnStrain < 20: + sw = 4 + elif nnStrain < 40: + sw = 3 + else: + sw = 2 + + ### 700 is the default plot width minus Xoffsets for 40 strains + defaultWidth = 650 + if nnStrain > 40: + defaultWidth += (nnStrain-40)*10 + defaultOffset = 100 + bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) + if bw < 10: + bw = 10 + + plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset + plotHeight = 500 + #print [plotWidth, plotHeight, bw, sw, nnStrain] + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title=title, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) + + return img diff --git a/wqflask/basicStatistics/BasicStatisticsPage_alpha.py b/wqflask/basicStatistics/BasicStatisticsPage_alpha.py index 4ba9d54a..365143db 100755 --- a/wqflask/basicStatistics/BasicStatisticsPage_alpha.py +++ b/wqflask/basicStatistics/BasicStatisticsPage_alpha.py @@ -43,306 +43,302 @@ from dbFunction import webqtlDatabaseFunction class BasicStatisticsPage_alpha(templatePage): - plotMinInformative = 4 - - def __init__(self, fd): - - templatePage.__init__(self, fd) - - if not fd.genotype: - fd.readGenotype() - strainlist2 = fd.strainlist - - if fd.allstrainlist: - strainlist2 = fd.allstrainlist - - fd.readData(strainlist2) - - specialStrains = [] - setStrains = [] - for item in strainlist2: - if item not in fd.strainlist and item.find('F1') < 0: - specialStrains.append(item) - else: - setStrains.append(item) - specialStrains.sort() - #So called MDP Panel - if specialStrains: - specialStrains = fd.f1list+fd.parlist+specialStrains - - self.plotType = fd.formdata.getvalue('ptype', '0') - plotStrains = strainlist2 - if specialStrains: - if self.plotType == '1': - plotStrains = setStrains - if self.plotType == '2': - plotStrains = specialStrains - - self.dict['title'] = 'Basic Statistics' - if not self.openMysql(): - return - - self.showstrains = 1 - self.identification = "unnamed trait" - - self.fullname = fd.formdata.getvalue('fullname', '') - if self.fullname: - self.Trait = webqtlTrait(fullname=self.fullname, cursor=self.cursor) - self.Trait.retrieveInfo() - else: - self.Trait = None - - if fd.identification: - self.identification = fd.identification - self.dict['title'] = self.identification + ' / '+self.dict['title'] - TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - - ##should not display Variance, but cannot convert Variance to SE - #print plotStrains, fd.allTraitData.keys() - if len(fd.allTraitData) > 0: - vals=[] - InformData = [] - for _strain in plotStrains: - if fd.allTraitData.has_key(_strain): - _val, _var = fd.allTraitData[_strain].val, fd.allTraitData[_strain].var - if _val != None: - vals.append([_strain, _val, _var]) - InformData.append(_val) - - if len(vals) >= self.plotMinInformative: - supertable2 = HT.TableLite(border=0, cellspacing=0, cellpadding=5,width="800") - - staIntro1 = HT.Paragraph("The table and plots below list the basic statistical analysis result of trait",HT.Strong(" %s" % self.identification)) - - ##### - #anova - ##### - traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(InformData) - TDStatis = HT.TD(width="360", valign="top") - tbl2 = HT.TableLite(cellpadding=5, cellspacing=0, Class="collap") - dataXZ = vals[:] - dataXZ.sort(self.cmpValue) - tbl2.append(HT.TR(HT.TD("Statistic",align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 200), - HT.TD("Value", align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 140))) - tbl2.append(HT.TR(HT.TD("N of Cases",align="center", Class="fs13 b1 cbw c222"), - HT.TD(N,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("Mean",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitmean,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("Median",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitmedian,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - #tbl2.append(HT.TR(HT.TD("Variance",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - # HT.TD("%2.3f" % traitvar,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("SEM",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitsem,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("SD",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % traitstdev,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("Minimum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%s" % dataXZ[0][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD("Maximum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%s" % dataXZ[-1][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - if self.Trait and self.Trait.db.type == 'ProbeSet': - #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") - #IRQuest.append(HT.BR()) - #IRQuest.append(" (fold difference)") - tbl2.append(HT.TR(HT.TD("Range (log2)",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - tbl2.append(HT.TR(HT.TD(HT.Span("Quartile Range",HT.BR()," (fold difference)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), - HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - - # (Lei Yan) - # 2008/12/19 - self.Trait.retrieveData() - #XZ, 04/01/2009: don't try to get H2 value for probe. - if self.Trait.cellid: - pass - else: - self.cursor.execute("SELECT DataId, h2 from ProbeSetXRef WHERE DataId = %d" % self.Trait.mysqlid) - dataid, heritability = self.cursor.fetchone() - if heritability: - tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - else: - tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("NaN", nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) - - # Lei Yan - # 2008/12/19 - - TDStatis.append(tbl2) - - plotHeight = 220 - plotWidth = 120 - xLeftOffset = 60 - xRightOffset = 25 - yTopOffset = 20 - yBottomOffset = 53 - - canvasHeight = plotHeight + yTopOffset + yBottomOffset - canvasWidth = plotWidth + xLeftOffset + xRightOffset - canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) - XXX = [('', InformData[:])] - - Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") - filename= webqtlUtil.genRandStr("Box_") - canvas.save(webqtlConfig.IMGDIR+filename, format='gif') - img=HT.Image('/image/'+filename+'.gif',border=0) - - #supertable2.append(HT.TR(HT.TD(staIntro1, colspan=3 ))) - tb = HT.TableLite(border=0, cellspacing=0, cellpadding=0) - tb.append(HT.TR(HT.TD(img, align="left", style="border: 1px solid #999999; padding:0px;"))) - supertable2.append(HT.TR(TDStatis, HT.TD(tb))) - - dataXZ = vals[:] - tvals = [] - tnames = [] - tvars = [] - for i in range(len(dataXZ)): - tvals.append(dataXZ[i][1]) - tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) - tvars.append(dataXZ[i][2]) - nnStrain = len(tnames) - - sLabel = 1 - - ###determine bar width and space width - if nnStrain < 20: - sw = 4 - elif nnStrain < 40: - sw = 3 - else: - sw = 2 - - ### 700 is the default plot width minus Xoffsets for 40 strains - defaultWidth = 650 - if nnStrain > 40: - defaultWidth += (nnStrain-40)*10 - defaultOffset = 100 - bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) - if bw < 10: - bw = 10 - - plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset - plotHeight = 500 - #print [plotWidth, plotHeight, bw, sw, nnStrain] - c = pid.PILCanvas(size=(plotWidth,plotHeight)) - Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (sorted by name)' % self.identification, sLabel = sLabel, barSpace = sw) - - filename= webqtlUtil.genRandStr("Bar_") - c.save(webqtlConfig.IMGDIR+filename, format='gif') - img0=HT.Image('/image/'+filename+'.gif',border=0) - - dataXZ = vals[:] - dataXZ.sort(self.cmpValue) - tvals = [] - tnames = [] - tvars = [] - for i in range(len(dataXZ)): - tvals.append(dataXZ[i][1]) - tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) - tvars.append(dataXZ[i][2]) - - c = pid.PILCanvas(size=(plotWidth,plotHeight)) - Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (ranked)' % self.identification, sLabel = sLabel, barSpace = sw) - - filename= webqtlUtil.genRandStr("Bar_") - c.save(webqtlConfig.IMGDIR+filename, format='gif') - img1=HT.Image('/image/'+filename+'.gif',border=0) - - # Lei Yan - # 05/18/2009 - # report - - title = HT.Paragraph('REPORT on the variation of Shh (or PCA Composite Trait XXXX) (sonic hedgehog) in the (insert Data set name) of (insert Species informal name, e.g., Mouse, Rat, Human, Barley, Arabidopsis)', Class="title") - header = HT.Paragraph('''This report was generated by GeneNetwork on May 11, 2009, at 11.20 AM using the Basic Statistics module (v 1.0) and data from the Hippocampus Consortium M430v2 (Jun06) PDNN data set. For more details and updates on this data set please link to URL:get Basic Statistics''') - hr = HT.HR() - p1 = HT.Paragraph('''Trait values for Shh were taken from the (insert Database name, Hippocampus Consortium M430v2 (Jun06) PDNN). GeneNetwork contains data for NN (e.g., 99) cases. In general, data are averages for each case. A summary of mean, median, and the range of these data are provided in Table 1 and in the box plot (Figure 1). Data for individual cases are provided in Figure 2A and 2B, often with error bars (SEM). ''') - p2 = HT.Paragraph('''Trait values for Shh range 5.1-fold: from a low of 8.2 (please round value) in 129S1/SvImJ to a high of 10.6 (please round value) in BXD9. The interquartile range (the difference between values closest to the 25% and 75% levels) is a more modest 1.8-fold. The mean value is XX. ''') - t1 = HT.Paragraph('''Table 1. Summary of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''') - f1 = HT.Paragraph('''Figure 1. ''') - f1.append(HT.Href(text="Box plot", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs14")) - f1.append(HT.Text(''' of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''')) - f2A = HT.Paragraph('''Figure 2A: Bar chart of Shh data ordered by case from the Hippocampus Consortium M430v2 (june06) PDNN data set''') - f2B = HT.Paragraph('''Figure 2B: Bar chart of Shh values ordered by from the Hippocampus Consortium M430v2 (june06) PDNN data set''') - TD_LR.append(HT.Blockquote(title, HT.P(), header, hr, p1, HT.P(), p2, HT.P(), supertable2, t1, f1, HT.P(), img0, f2A, HT.P(), img1, f2B)) - self.dict['body'] = str(TD_LR) - else: - heading = "Basic Statistics" - detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] - self.error(heading=heading,detail=detail) - return - else: - heading = "Basic Statistics" - detail = ['Empty data set, please check your data.'] - self.error(heading=heading,detail=detail) - return - - def traitInfo(self, fd, specialStrains = None): - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) - heading2 = HT.Paragraph(HT.Strong('Population: '), "%s %s" % (species.title(), fd.RISet) , HT.BR()) - if self.Trait: - trait_url = HT.Href(text=self.Trait.name, url = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + \ - "?FormID=showDatabase&incparentsf1=1&database=%s&ProbeSetID=%s" % (self.Trait.db.name, self.Trait.name), \ - target='_blank', Class="fs13 fwn") - heading2.append(HT.Strong("Database: "), - HT.Href(text=self.Trait.db.fullname, url = webqtlConfig.INFOPAGEHREF % self.Trait.db.name , - target='_blank',Class="fs13 fwn"),HT.BR()) - if self.Trait.db.type == 'ProbeSet': - heading2.append(HT.Strong('Trait ID: '), trait_url, HT.BR(), - HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.symbol,id="green"),HT.BR()) - if self.Trait.chr and self.Trait.mb: - heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) - elif self.Trait.db.type == 'Geno': - heading2.append(HT.Strong('Locus : '), trait_url, HT.BR()) - #heading2.append(HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.Symbol,id="green"),HT.BR()) - if self.Trait.chr and self.Trait.mb: - heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) - elif self.Trait.db.type == 'Publish': - heading2.append(HT.Strong('Record ID: '), trait_url, HT.BR()) - heading2.append(HT.Strong('Phenotype: '), self.Trait.phenotype, HT.BR()) - heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) - elif self.Trait.db.type == 'Temp': - heading2.append(HT.Strong('Description: '), self.Trait.description, HT.BR()) - #heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) - else: - pass - else: - heading2.append(HT.Strong("Trait Name: "), fd.identification) - - if specialStrains: - mdpform = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='MDP_Form',submit=HT.Input(type='hidden')) - mdphddn = {'FormID':'dataEditing', 'submitID':'basicStatistics','RISet':fd.RISet, "allstrainlist":string.join(fd.allstrainlist, " "), "ptype":self.plotType, 'identification':fd.identification, "incparentsf1":1} - if self.fullname: mdphddn['fullname'] = self.fullname - webqtlUtil.exportData(mdphddn, fd.allTraitData) - for key in mdphddn.keys(): - mdpform.append(HT.Input(name=key, value=mdphddn[key], type='hidden')) - btn0 = HT.Input(type='button' ,name='',value='All Cases',onClick="this.form.ptype.value=0;submit();", Class="button") - btn1 = HT.Input(type='button' ,name='',value='%s Only' % fd.RISet,onClick="this.form.ptype.value=1;submit();", Class="button") - btn2 = HT.Input(type='button' ,name='',value='MDP Only', onClick="this.form.ptype.value=2;submit();", Class="button") - mdpform.append(btn0) - mdpform.append(btn1) - mdpform.append(btn2) - heading2.append(HT.P(), mdpform) - - return HT.Span(heading2) - - def calSD(self,var): - try: - return sqrt(abs(var)) - except: - return None - - - def cmpValue(self,A,B): - try: - if A[1] < B[1]: - return -1 - elif A[1] == B[1]: - return 0 - else: - return 1 - except: - return 0 - - - - + plotMinInformative = 4 + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + if not fd.genotype: + fd.readGenotype() + strainlist2 = fd.strainlist + + if fd.allstrainlist: + strainlist2 = fd.allstrainlist + + fd.readData(strainlist2) + + specialStrains = [] + setStrains = [] + for item in strainlist2: + if item not in fd.strainlist and item.find('F1') < 0: + specialStrains.append(item) + else: + setStrains.append(item) + specialStrains.sort() + #So called MDP Panel + if specialStrains: + specialStrains = fd.f1list+fd.parlist+specialStrains + + self.plotType = fd.formdata.getvalue('ptype', '0') + plotStrains = strainlist2 + if specialStrains: + if self.plotType == '1': + plotStrains = setStrains + if self.plotType == '2': + plotStrains = specialStrains + + self.dict['title'] = 'Basic Statistics' + if not self.openMysql(): + return + + self.showstrains = 1 + self.identification = "unnamed trait" + + self.fullname = fd.formdata.getvalue('fullname', '') + if self.fullname: + self.Trait = webqtlTrait(fullname=self.fullname, cursor=self.cursor) + self.Trait.retrieveInfo() + else: + self.Trait = None + + if fd.identification: + self.identification = fd.identification + self.dict['title'] = self.identification + ' / '+self.dict['title'] + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + ##should not display Variance, but cannot convert Variance to SE + #print plotStrains, fd.allTraitData.keys() + if len(fd.allTraitData) > 0: + vals=[] + InformData = [] + for _strain in plotStrains: + if fd.allTraitData.has_key(_strain): + _val, _var = fd.allTraitData[_strain].val, fd.allTraitData[_strain].var + if _val != None: + vals.append([_strain, _val, _var]) + InformData.append(_val) + + if len(vals) >= self.plotMinInformative: + supertable2 = HT.TableLite(border=0, cellspacing=0, cellpadding=5,width="800") + + staIntro1 = HT.Paragraph("The table and plots below list the basic statistical analysis result of trait",HT.Strong(" %s" % self.identification)) + + ##### + #anova + ##### + traitmean, traitmedian, traitvar, traitstdev, traitsem, N = reaper.anova(InformData) + TDStatis = HT.TD(width="360", valign="top") + tbl2 = HT.TableLite(cellpadding=5, cellspacing=0, Class="collap") + dataXZ = vals[:] + dataXZ.sort(self.cmpValue) + tbl2.append(HT.TR(HT.TD("Statistic",align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 200), + HT.TD("Value", align="center", Class="fs14 fwb ffl b1 cw cbrb", width = 140))) + tbl2.append(HT.TR(HT.TD("N of Cases",align="center", Class="fs13 b1 cbw c222"), + HT.TD(N,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Mean",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmean,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Median",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitmedian,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + #tbl2.append(HT.TR(HT.TD("Variance",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + # HT.TD("%2.3f" % traitvar,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("SEM",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitsem,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("SD",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % traitstdev,nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Minimum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[0][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD("Maximum",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%s" % dataXZ[-1][1],nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + if self.Trait and self.Trait.db.type == 'ProbeSet': + #IRQuest = HT.Href(text="Interquartile Range", url=webqtlConfig.glossaryfile +"#Interquartile",target="_blank", Class="fs14") + #IRQuest.append(HT.BR()) + #IRQuest.append(" (fold difference)") + tbl2.append(HT.TR(HT.TD("Range (log2)",align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.3f" % (dataXZ[-1][1]-dataXZ[0][1]),nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD(HT.Span("Range (fold)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[-1][1]-dataXZ[0][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + tbl2.append(HT.TR(HT.TD(HT.Span("Quartile Range",HT.BR()," (fold difference)"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"), + HT.TD("%2.2f" % pow(2.0,(dataXZ[int((N-1)*3.0/4.0)][1]-dataXZ[int((N-1)/4.0)][1])), nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + + # (Lei Yan) + # 2008/12/19 + self.Trait.retrieveData() + #XZ, 04/01/2009: don't try to get H2 value for probe. + if self.Trait.cellid: + pass + else: + self.cursor.execute("SELECT DataId, h2 from ProbeSetXRef WHERE DataId = %d" % self.Trait.mysqlid) + dataid, heritability = self.cursor.fetchone() + if heritability: + tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("%s" % heritability, nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + else: + tbl2.append(HT.TR(HT.TD(HT.Span("Heritability"),align="center", Class="fs13 b1 cbw c222",nowrap="yes"),HT.TD("NaN", nowrap="yes",align="center", Class="fs13 b1 cbw c222"))) + + # Lei Yan + # 2008/12/19 + + TDStatis.append(tbl2) + + plotHeight = 220 + plotWidth = 120 + xLeftOffset = 60 + xRightOffset = 25 + yTopOffset = 20 + yBottomOffset = 53 + + canvasHeight = plotHeight + yTopOffset + yBottomOffset + canvasWidth = plotWidth + xLeftOffset + xRightOffset + canvas = pid.PILCanvas(size=(canvasWidth,canvasHeight)) + XXX = [('', InformData[:])] + + Plot.plotBoxPlot(canvas, XXX, offset=(xLeftOffset, xRightOffset, yTopOffset, yBottomOffset), XLabel= "Trait") + filename= webqtlUtil.genRandStr("Box_") + canvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0) + + #supertable2.append(HT.TR(HT.TD(staIntro1, colspan=3 ))) + tb = HT.TableLite(border=0, cellspacing=0, cellpadding=0) + tb.append(HT.TR(HT.TD(img, align="left", style="border: 1px solid #999999; padding:0px;"))) + supertable2.append(HT.TR(TDStatis, HT.TD(tb))) + + dataXZ = vals[:] + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + nnStrain = len(tnames) + + sLabel = 1 + + ###determine bar width and space width + if nnStrain < 20: + sw = 4 + elif nnStrain < 40: + sw = 3 + else: + sw = 2 + + ### 700 is the default plot width minus Xoffsets for 40 strains + defaultWidth = 650 + if nnStrain > 40: + defaultWidth += (nnStrain-40)*10 + defaultOffset = 100 + bw = int(0.5+(defaultWidth - (nnStrain-1.0)*sw)/nnStrain) + if bw < 10: + bw = 10 + + plotWidth = (nnStrain-1)*sw + nnStrain*bw + defaultOffset + plotHeight = 500 + #print [plotWidth, plotHeight, bw, sw, nnStrain] + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (sorted by name)' % self.identification, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img0=HT.Image('/image/'+filename+'.gif',border=0) + + dataXZ = vals[:] + dataXZ.sort(self.cmpValue) + tvals = [] + tnames = [] + tvars = [] + for i in range(len(dataXZ)): + tvals.append(dataXZ[i][1]) + tnames.append(webqtlUtil.genShortStrainName(fd, dataXZ[i][0])) + tvars.append(dataXZ[i][2]) + + c = pid.PILCanvas(size=(plotWidth,plotHeight)) + Plot.plotBarText(c, tvals, tnames, variance=tvars, YLabel='Value', title='%s by Case (ranked)' % self.identification, sLabel = sLabel, barSpace = sw) + + filename= webqtlUtil.genRandStr("Bar_") + c.save(webqtlConfig.IMGDIR+filename, format='gif') + img1=HT.Image('/image/'+filename+'.gif',border=0) + + # Lei Yan + # 05/18/2009 + # report + + title = HT.Paragraph('REPORT on the variation of Shh (or PCA Composite Trait XXXX) (sonic hedgehog) in the (insert Data set name) of (insert Species informal name, e.g., Mouse, Rat, Human, Barley, Arabidopsis)', Class="title") + header = HT.Paragraph('''This report was generated by GeneNetwork on May 11, 2009, at 11.20 AM using the Basic Statistics module (v 1.0) and data from the Hippocampus Consortium M430v2 (Jun06) PDNN data set. For more details and updates on this data set please link to URL:get Basic Statistics''') + hr = HT.HR() + p1 = HT.Paragraph('''Trait values for Shh were taken from the (insert Database name, Hippocampus Consortium M430v2 (Jun06) PDNN). GeneNetwork contains data for NN (e.g., 99) cases. In general, data are averages for each case. A summary of mean, median, and the range of these data are provided in Table 1 and in the box plot (Figure 1). Data for individual cases are provided in Figure 2A and 2B, often with error bars (SEM). ''') + p2 = HT.Paragraph('''Trait values for Shh range 5.1-fold: from a low of 8.2 (please round value) in 129S1/SvImJ to a high of 10.6 (please round value) in BXD9. The interquartile range (the difference between values closest to the 25% and 75% levels) is a more modest 1.8-fold. The mean value is XX. ''') + t1 = HT.Paragraph('''Table 1. Summary of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + f1 = HT.Paragraph('''Figure 1. ''') + f1.append(HT.Href(text="Box plot", url="http://davidmlane.com/hyperstat/A37797.html", target="_blank", Class="fs14")) + f1.append(HT.Text(''' of Shh data from the Hippocampus Consortium M430v2 (june06) PDNN data set''')) + f2A = HT.Paragraph('''Figure 2A: Bar chart of Shh data ordered by case from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + f2B = HT.Paragraph('''Figure 2B: Bar chart of Shh values ordered by from the Hippocampus Consortium M430v2 (june06) PDNN data set''') + TD_LR.append(HT.Blockquote(title, HT.P(), header, hr, p1, HT.P(), p2, HT.P(), supertable2, t1, f1, HT.P(), img0, f2A, HT.P(), img1, f2B)) + self.dict['body'] = str(TD_LR) + else: + heading = "Basic Statistics" + detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = "Basic Statistics" + detail = ['Empty data set, please check your data.'] + self.error(heading=heading,detail=detail) + return + + def traitInfo(self, fd, specialStrains = None): + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + heading2 = HT.Paragraph(HT.Strong('Population: '), "%s %s" % (species.title(), fd.RISet) , HT.BR()) + if self.Trait: + trait_url = HT.Href(text=self.Trait.name, url = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + \ + "?FormID=showDatabase&incparentsf1=1&database=%s&ProbeSetID=%s" % (self.Trait.db.name, self.Trait.name), \ + target='_blank', Class="fs13 fwn") + heading2.append(HT.Strong("Database: "), + HT.Href(text=self.Trait.db.fullname, url = webqtlConfig.INFOPAGEHREF % self.Trait.db.name , + target='_blank',Class="fs13 fwn"),HT.BR()) + if self.Trait.db.type == 'ProbeSet': + heading2.append(HT.Strong('Trait ID: '), trait_url, HT.BR(), + HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.symbol,id="green"),HT.BR()) + if self.Trait.chr and self.Trait.mb: + heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) + elif self.Trait.db.type == 'Geno': + heading2.append(HT.Strong('Locus : '), trait_url, HT.BR()) + #heading2.append(HT.Strong("Gene Symbol: "), HT.Italic('%s' % self.Trait.Symbol,id="green"),HT.BR()) + if self.Trait.chr and self.Trait.mb: + heading2.append(HT.Strong("Location: "), 'Chr %s @ %s Mb' % (self.Trait.chr, self.Trait.mb)) + elif self.Trait.db.type == 'Publish': + heading2.append(HT.Strong('Record ID: '), trait_url, HT.BR()) + heading2.append(HT.Strong('Phenotype: '), self.Trait.phenotype, HT.BR()) + heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) + elif self.Trait.db.type == 'Temp': + heading2.append(HT.Strong('Description: '), self.Trait.description, HT.BR()) + #heading2.append(HT.Strong('Author: '), self.Trait.authors, HT.BR()) + else: + pass + else: + heading2.append(HT.Strong("Trait Name: "), fd.identification) + + if specialStrains: + mdpform = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), name='MDP_Form',submit=HT.Input(type='hidden')) + mdphddn = {'FormID':'dataEditing', 'submitID':'basicStatistics','RISet':fd.RISet, "allstrainlist":string.join(fd.allstrainlist, " "), "ptype":self.plotType, 'identification':fd.identification, "incparentsf1":1} + if self.fullname: mdphddn['fullname'] = self.fullname + webqtlUtil.exportData(mdphddn, fd.allTraitData) + for key in mdphddn.keys(): + mdpform.append(HT.Input(name=key, value=mdphddn[key], type='hidden')) + btn0 = HT.Input(type='button' ,name='',value='All Cases',onClick="this.form.ptype.value=0;submit();", Class="button") + btn1 = HT.Input(type='button' ,name='',value='%s Only' % fd.RISet,onClick="this.form.ptype.value=1;submit();", Class="button") + btn2 = HT.Input(type='button' ,name='',value='MDP Only', onClick="this.form.ptype.value=2;submit();", Class="button") + mdpform.append(btn0) + mdpform.append(btn1) + mdpform.append(btn2) + heading2.append(HT.P(), mdpform) + + return HT.Span(heading2) + + def calSD(self,var): + try: + return sqrt(abs(var)) + except: + return None + + + def cmpValue(self,A,B): + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 diff --git a/wqflask/basicStatistics/updatedBasicStatisticsPage.py b/wqflask/basicStatistics/updatedBasicStatisticsPage.py index ab7ed07d..3f30619d 100755 --- a/wqflask/basicStatistics/updatedBasicStatisticsPage.py +++ b/wqflask/basicStatistics/updatedBasicStatisticsPage.py @@ -6,145 +6,145 @@ import BasicStatisticsFunctions #Window generated from the Trait Data and Analysis page (DataEditingPage.py) with updated stats figures; takes the page's values that can bed edited by the user class updatedBasicStatisticsPage(templatePage): - - plotMinInformative = 4 - - def __init__(self, fd): - - templatePage.__init__(self, fd) - - if not fd.genotype: - fd.readGenotype() - this_strainlist = fd.strainlist - - if fd.allstrainlist: - this_strainlist = fd.allstrainlist - - fd.readData(this_strainlist) - - specialStrains = [] #This appears to be the "other/non-RISet strainlist" without parents/f1 strains; not sure what to name it - setStrains = [] - for item in this_strainlist: - if item not in fd.strainlist and item.find('F1') < 0: - specialStrains.append(item) - else: - continue - - specialStrains.sort() - if specialStrains: - specialStrains = fd.f1list+fd.parlist+specialStrains - - self.dict['title'] = 'Basic Statistics' - TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") - - stats_row = HT.TR() - stats_cell = HT.TD() - stats_script = HT.Script(language="Javascript") - - #Get strain names, values, and variances - strain_names = fd.formdata.getvalue('strainNames').split(',') - strain_vals = fd.formdata.getvalue('strainVals').split(',') - strain_vars = fd.formdata.getvalue('strainVars').split(',') - - vals = [] - if (len(strain_names) > 0): - if (len(strain_names) > 3): - #Need to create "vals" object - for i in range(len(strain_names)): - try: - this_strain_val = float(strain_vals[i]) - except: - continue - try: - this_strain_var = float(strain_vars[i]) - except: - this_strain_var = None - - thisValFull = [strain_names[i], this_strain_val, this_strain_var] - vals.append(thisValFull) - - stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-2", Class="stats_tab"), - HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), - HT.Href(text="Box Plot", url="#statstabs-5", Class="stats_tab")] - stats_tabs = HT.List(stats_tab_list) - - stats_container = HT.Div(id="stats_tabs", Class="ui-tabs") - stats_container.append(stats_tabs) - - stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" #Javascript enabling tabs - - table_div = HT.Div(id="statstabs-1", style="height:320px;width:740px;overflow:scroll;") - table_container = HT.Paragraph() - - statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - this_trait_type = fd.formdata.getvalue('trait_type', None) - this_cellid = fd.formdata.getvalue('cellid', None) - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait_type, cellid=this_cellid) - statsTable.append(HT.TR(HT.TD(statsTableCell))) - - table_container.append(statsTable) - table_div.append(table_container) - stats_container.append(table_div) - - normalplot_div = HT.Div(id="statstabs-2", style="height:540px;width:740px;overflow:scroll;") - normalplot_container = HT.Paragraph() - normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - plotTitle = fd.formdata.getvalue("normalPlotTitle","") - normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) - normalplot.append(HT.TR(HT.TD(normalplot_img))) - normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ - normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), - "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", - target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) - normalplot_container.append(normalplot) - normalplot_div.append(normalplot_container) - stats_container.append(normalplot_div) - - barName_div = HT.Div(id="statstabs-3", style="height:540px;width:740px;overflow:scroll;") - barName_container = HT.Paragraph() - barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") - barName.append(HT.TR(HT.TD(barName_img))) - barName_container.append(barName) - barName_div.append(barName_container) - stats_container.append(barName_div) - - barRank_div = HT.Div(id="statstabs-4", style="height:540px;width:740px;overflow:scroll;") - barRank_container = HT.Paragraph() - barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") - barRank.append(HT.TR(HT.TD(barRank_img))) - barRank_container.append(barRank) - barRank_div.append(barRank_container) - stats_container.append(barRank_div) - - boxplot_div = HT.Div(id="statstabs-5", style="height:540px;width:740px;overflow:scroll;") - boxplot_container = HT.Paragraph() - boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) - boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) - boxplot_container.append(boxplot) - boxplot_div.append(boxplot_container) - stats_container.append(boxplot_div) - - stats_cell.append(stats_container) - stats_script.append(stats_script_text) - - submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - stats_row.append(stats_cell) - - submitTable.append(stats_row) - submitTable.append(stats_script) - - TD_LR.append(submitTable) - self.dict['body'] = str(TD_LR) - else: - heading = "Basic Statistics" - detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] - self.error(heading=heading,detail=detail) - return - else: - heading = "Basic Statistics" - detail = ['Empty data set, please check your data.'] - self.error(heading=heading,detail=detail) - return \ No newline at end of file + + plotMinInformative = 4 + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + if not fd.genotype: + fd.readGenotype() + this_strainlist = fd.strainlist + + if fd.allstrainlist: + this_strainlist = fd.allstrainlist + + fd.readData(this_strainlist) + + specialStrains = [] #This appears to be the "other/non-RISet strainlist" without parents/f1 strains; not sure what to name it + setStrains = [] + for item in this_strainlist: + if item not in fd.strainlist and item.find('F1') < 0: + specialStrains.append(item) + else: + continue + + specialStrains.sort() + if specialStrains: + specialStrains = fd.f1list+fd.parlist+specialStrains + + self.dict['title'] = 'Basic Statistics' + TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") + + stats_row = HT.TR() + stats_cell = HT.TD() + stats_script = HT.Script(language="Javascript") + + #Get strain names, values, and variances + strain_names = fd.formdata.getvalue('strainNames').split(',') + strain_vals = fd.formdata.getvalue('strainVals').split(',') + strain_vars = fd.formdata.getvalue('strainVars').split(',') + + vals = [] + if (len(strain_names) > 0): + if (len(strain_names) > 3): + #Need to create "vals" object + for i in range(len(strain_names)): + try: + this_strain_val = float(strain_vals[i]) + except: + continue + try: + this_strain_var = float(strain_vars[i]) + except: + this_strain_var = None + + thisValFull = [strain_names[i], this_strain_val, this_strain_var] + vals.append(thisValFull) + + stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-2", Class="stats_tab"), + HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), + HT.Href(text="Box Plot", url="#statstabs-5", Class="stats_tab")] + stats_tabs = HT.List(stats_tab_list) + + stats_container = HT.Div(id="stats_tabs", Class="ui-tabs") + stats_container.append(stats_tabs) + + stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" #Javascript enabling tabs + + table_div = HT.Div(id="statstabs-1", style="height:320px;width:740px;overflow:scroll;") + table_container = HT.Paragraph() + + statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + this_trait_type = fd.formdata.getvalue('trait_type', None) + this_cellid = fd.formdata.getvalue('cellid', None) + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait_type, cellid=this_cellid) + statsTable.append(HT.TR(HT.TD(statsTableCell))) + + table_container.append(statsTable) + table_div.append(table_container) + stats_container.append(table_div) + + normalplot_div = HT.Div(id="statstabs-2", style="height:540px;width:740px;overflow:scroll;") + normalplot_container = HT.Paragraph() + normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + plotTitle = fd.formdata.getvalue("normalPlotTitle","") + normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + normalplot.append(HT.TR(HT.TD(normalplot_img))) + normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + normalplot_container.append(normalplot) + normalplot_div.append(normalplot_container) + stats_container.append(normalplot_div) + + barName_div = HT.Div(id="statstabs-3", style="height:540px;width:740px;overflow:scroll;") + barName_container = HT.Paragraph() + barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + barName.append(HT.TR(HT.TD(barName_img))) + barName_container.append(barName) + barName_div.append(barName_container) + stats_container.append(barName_div) + + barRank_div = HT.Div(id="statstabs-4", style="height:540px;width:740px;overflow:scroll;") + barRank_container = HT.Paragraph() + barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + barRank.append(HT.TR(HT.TD(barRank_img))) + barRank_container.append(barRank) + barRank_div.append(barRank_container) + stats_container.append(barRank_div) + + boxplot_div = HT.Div(id="statstabs-5", style="height:540px;width:740px;overflow:scroll;") + boxplot_container = HT.Paragraph() + boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + boxplot_container.append(boxplot) + boxplot_div.append(boxplot_container) + stats_container.append(boxplot_div) + + stats_cell.append(stats_container) + stats_script.append(stats_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + stats_row.append(stats_cell) + + submitTable.append(stats_row) + submitTable.append(stats_script) + + TD_LR.append(submitTable) + self.dict['body'] = str(TD_LR) + else: + heading = "Basic Statistics" + detail = ['Fewer than %d case data were entered for %s data set. No statitical analysis has been attempted.' % (self.plotMinInformative, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = "Basic Statistics" + detail = ['Empty data set, please check your data.'] + self.error(heading=heading,detail=detail) + return diff --git a/wqflask/dbFunction/webqtlDatabaseFunction.py b/wqflask/dbFunction/webqtlDatabaseFunction.py index 772e0526..7e33da3f 100755 --- a/wqflask/dbFunction/webqtlDatabaseFunction.py +++ b/wqflask/dbFunction/webqtlDatabaseFunction.py @@ -26,7 +26,7 @@ #webqtlDatabaseFunction.py # -#This file consists of various database related functions; the names are generally self-explanatory. +#This file consists of various database related functions; the names are generally self-explanatory. import MySQLdb import string @@ -49,63 +49,63 @@ def getCursor(): ########################################################################### #input: cursor, groupName (string) #output: mappingMethodId (int) info, value will be Null or else -#function: retrieve mappingMethodId info from InbredSet table -########################################################################### +#function: retrieve mappingMethodId info from InbredSet table +########################################################################### def getMappingMethod(cursor=None, groupName=None): - cursor.execute("select MappingMethodId from InbredSet where Name= '%s'" % groupName) - mappingMethodId = cursor.fetchone()[0] - return mappingMethodId + cursor.execute("select MappingMethodId from InbredSet where Name= '%s'" % groupName) + mappingMethodId = cursor.fetchone()[0] + return mappingMethodId ########################################################################### #input: cursor, inbredSetId (int), strainId (int) -#output: isMappingId (bull) info, value will be 0,1,2 or else, 0 or Null means -# "can not do mapping", >0 means "can do mapping", >1 means "there exsists +#output: isMappingId (bull) info, value will be 0,1,2 or else, 0 or Null means +# "can not do mapping", >0 means "can do mapping", >1 means "there exsists # redundant data, user needs to choose one to do mapping function" -#function: retrieve isMappingId info from StrainXRef table -########################################################################### - -def isMapping(cursor=None, inbredSetId=None, strainId=None): - cursor.execute("select IsMapping from StrainXRef where InbredSetId='%d' and StrainId = '%d'" %(inbredSetId, strainId)) - isMappingId = cursor.fetchone()[0] - return isMappingId +#function: retrieve isMappingId info from StrainXRef table +########################################################################### + +def isMapping(cursor=None, inbredSetId=None, strainId=None): + cursor.execute("select IsMapping from StrainXRef where InbredSetId='%d' and StrainId = '%d'" %(inbredSetId, strainId)) + isMappingId = cursor.fetchone()[0] + return isMappingId ########################################################################### #input: cursor, groupName (string) #output: all species data info (array), value will be Null or else -#function: retrieve all species info from Species table -########################################################################### +#function: retrieve all species info from Species table +########################################################################### def getAllSpecies(cursor=None): - cursor.execute("select Id, Name, MenuName, FullName, TaxonomyId,OrderId from Species Order by OrderId") - allSpecies = cursor.fetchall() - return allSpecies + cursor.execute("select Id, Name, MenuName, FullName, TaxonomyId,OrderId from Species Order by OrderId") + allSpecies = cursor.fetchall() + return allSpecies ########################################################################### #input: cursor, RISet (string) #output: specie's name (string), value will be None or else -#function: retrieve specie's name info based on RISet -########################################################################### +#function: retrieve specie's name info based on RISet +########################################################################### def retrieveSpecies(cursor=None, RISet=None): - try: - cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % RISet) - return cursor.fetchone()[0] - except: - return None + try: + cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % RISet) + return cursor.fetchone()[0] + except: + return None ########################################################################### #input: cursor, RISet (string) #output: specie's Id (string), value will be None or else -#function: retrieve specie's Id info based on RISet -########################################################################### - +#function: retrieve specie's Id info based on RISet +########################################################################### + def retrieveSpeciesId(cursor=None, RISet=None): - try: - cursor.execute("select SpeciesId from InbredSet where Name = '%s'" % RISet) - return cursor.fetchone()[0] - except: - return None + try: + cursor.execute("select SpeciesId from InbredSet where Name = '%s'" % RISet) + return cursor.fetchone()[0] + except: + return None ########################################################################### # input: cursor @@ -118,24 +118,24 @@ def retrieveSpeciesId(cursor=None, RISet=None): ########################################################################### def getTissueDataSet(cursor=None): - tissProbeSetFreezeIdList=[] - nameList =[] - fullNameList = [] - - query = "select Id,Name,FullName from TissueProbeSetFreeze; " - try: - cursor.execute(query) - result = cursor.fetchall() - - for row in result: - tissProbeSetFreezeIdList.append(row[0]) - nameList.append(row[1]) - fullNameList.append(row[2]) - except: - return None - - return tissProbeSetFreezeIdList,nameList,fullNameList - + tissProbeSetFreezeIdList=[] + nameList =[] + fullNameList = [] + + query = "select Id,Name,FullName from TissueProbeSetFreeze; " + try: + cursor.execute(query) + result = cursor.fetchall() + + for row in result: + tissProbeSetFreezeIdList.append(row[0]) + nameList.append(row[1]) + fullNameList.append(row[2]) + except: + return None + + return tissProbeSetFreezeIdList,nameList,fullNameList + ########################################################################### # input: cursor,GeneSymbol (string), and TissueProbeSetFreezeId (string) # output: geneId (string), dataId (string) @@ -143,42 +143,42 @@ def getTissueDataSet(cursor=None): ########################################################################### def getGeneIdDataIdForTissueBySymbol(cursor=None, GeneSymbol=None, TissueProbeSetFreezeId= 0): - query ="select GeneId, DataId from TissueProbeSetXRef where Symbol = '%s' and TissueProbeSetFreezeId=%s order by Mean desc" %(GeneSymbol,TissueProbeSetFreezeId) - try: - cursor.execute(query) - result = cursor.fetchone() - geneId = result[0] - dataId = result[1] - except: - geneId = 0 - dataId = 0 - - return geneId,dataId + query ="select GeneId, DataId from TissueProbeSetXRef where Symbol = '%s' and TissueProbeSetFreezeId=%s order by Mean desc" %(GeneSymbol,TissueProbeSetFreezeId) + try: + cursor.execute(query) + result = cursor.fetchone() + geneId = result[0] + dataId = result[1] + except: + geneId = 0 + dataId = 0 + + return geneId,dataId ########################################################################### # input: cursor, TissueProbeSetFreezeId (int) # output: chipId (int) -# function: retrieve chipId from TissueProbeFreeze table +# function: retrieve chipId from TissueProbeFreeze table ########################################################################### def getChipIdByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): - query = "select TissueProbeFreezeId from TissueProbeSetFreeze where Id =%s" % TissueProbeSetFreezeId - try: - cursor.execute(query) - result = cursor.fetchone() - TissueProbeFreezeId = result[0] - except: - TissueProbeFreezeId =0 - - query1 = "select ChipId from TissueProbeFreeze where Id =%s" % TissueProbeFreezeId - try: - cursor.execute(query1) - result1 = cursor.fetchone() - chipId = result1[0] - except: - chipId =0 - - return chipId + query = "select TissueProbeFreezeId from TissueProbeSetFreeze where Id =%s" % TissueProbeSetFreezeId + try: + cursor.execute(query) + result = cursor.fetchone() + TissueProbeFreezeId = result[0] + except: + TissueProbeFreezeId =0 + + query1 = "select ChipId from TissueProbeFreeze where Id =%s" % TissueProbeFreezeId + try: + cursor.execute(query1) + result1 = cursor.fetchone() + chipId = result1[0] + except: + chipId =0 + + return chipId ########################################################################### # input: cursor, TissueProbeSetFreezeId (int) @@ -186,80 +186,79 @@ def getChipIdByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): # function: retrieve how many tissue used in the specific dataset based on TissueProbeSetFreezeId ########################################################################### def getTissueCountByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): - query1 ="select DataId from TissueProbeSetXRef where TissueProbeSetFreezeId =%s limit 1" % TissueProbeSetFreezeId - try: - cursor.execute(query1) - result1 = cursor.fetchone() - DataId = result1[0] - - query2 =" select count(*) from TissueProbeSetData where Id=%s" % DataId - try: - cursor.execute(query2) - result2 = cursor.fetchone() - TissueCount = result2[0] - except: - TissueCount =0 - except: - TissueCount =0 - - return TissueCount - + query1 ="select DataId from TissueProbeSetXRef where TissueProbeSetFreezeId =%s limit 1" % TissueProbeSetFreezeId + try: + cursor.execute(query1) + result1 = cursor.fetchone() + DataId = result1[0] + + query2 =" select count(*) from TissueProbeSetData where Id=%s" % DataId + try: + cursor.execute(query2) + result2 = cursor.fetchone() + TissueCount = result2[0] + except: + TissueCount =0 + except: + TissueCount =0 + + return TissueCount + ########################################################################### # input: cursor, TissueProbeSetFreezeId (int) # output: DatasetName(string),DatasetFullName(string) # function: retrieve DatasetName, DatasetFullName based on TissueProbeSetFreezeId ########################################################################### def getDatasetNamesByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): - query ="select Name, FullName from TissueProbeSetFreeze where Id=%s" % TissueProbeSetFreezeId - try: - cursor.execute(query) - result = cursor.fetchone() - DatasetName = result[0] - DatasetFullName =result[1] - except: - DatasetName =None - DatasetFullName =None - - return DatasetName, DatasetFullName - + query ="select Name, FullName from TissueProbeSetFreeze where Id=%s" % TissueProbeSetFreezeId + try: + cursor.execute(query) + result = cursor.fetchone() + DatasetName = result[0] + DatasetFullName =result[1] + except: + DatasetName =None + DatasetFullName =None + + return DatasetName, DatasetFullName + ########################################################################### # input: cursor, geneIdLst (list) # output: geneIdSymbolPair(dict),key is geneId, value is geneSymbol # function: retrieve GeneId, GeneSymbol based on geneId List -########################################################################### +########################################################################### def getGeneIdSymbolPairByGeneId(cursor=None, geneIdLst =None): - geneIdSymbolPair={} - for geneId in geneIdLst: - geneIdSymbolPair[geneId]=None - - query ="select GeneId,GeneSymbol from GeneList where GeneId in (%s)" % string.join(geneIdLst, ", ") - try: - cursor.execute(query) - results = cursor.fetchall() - for item in results: - geneId =item[0] - geneSymbol =item[1] - geneIdSymbolPair[geneId]=geneSymbol - except: - geneIdSymbolPair=None - - return geneIdSymbolPair - - + geneIdSymbolPair={} + for geneId in geneIdLst: + geneIdSymbolPair[geneId]=None + + query ="select GeneId,GeneSymbol from GeneList where GeneId in (%s)" % string.join(geneIdLst, ", ") + try: + cursor.execute(query) + results = cursor.fetchall() + for item in results: + geneId =item[0] + geneSymbol =item[1] + geneIdSymbolPair[geneId]=geneSymbol + except: + geneIdSymbolPair=None + + return geneIdSymbolPair + + def updateTissueProbesetXRefByProbesetId(cursor=None, probesetId=None): - query ="select Symbol,GeneId,Chr,Mb,description, Probe_Target_Description from ProbeSet where Id =%s"%probesetId - try: - cursor.execute(query) - result =cursor.fetchone() - - updateQuery =''' - Update TissueProbeSetXRef - Set Symbol='%s',GeneId='%s', Chr='%s', Mb='%s', description ='%s',Probe_Target_Description='%s' - where ProbesetId=%s - '''%(result[0],result[1],result[2],result[3],result[4],result[5],probesetId) - - cursor.execute(updateQuery) - - except: - return None - \ No newline at end of file + query ="select Symbol,GeneId,Chr,Mb,description, Probe_Target_Description from ProbeSet where Id =%s"%probesetId + try: + cursor.execute(query) + result =cursor.fetchone() + + updateQuery =''' + Update TissueProbeSetXRef + Set Symbol='%s',GeneId='%s', Chr='%s', Mb='%s', description ='%s',Probe_Target_Description='%s' + where ProbesetId=%s + '''%(result[0],result[1],result[2],result[3],result[4],result[5],probesetId) + + cursor.execute(updateQuery) + + except: + return None diff --git a/wqflask/utility/AJAX_table.py b/wqflask/utility/AJAX_table.py index 963a530e..083d1c0d 100755 --- a/wqflask/utility/AJAX_table.py +++ b/wqflask/utility/AJAX_table.py @@ -39,115 +39,115 @@ import webqtlUtil class AJAX_table: - def __init__(self, fd): - file = fd.formdata.getfirst("file", "") - sort = fd.formdata.getfirst("sort", "") - order = fd.formdata.getfirst("order", "up") - cmd = fd.formdata.getfirst("cmd", "") - tableID = fd.formdata.getfirst("tableID", "") - addIndex = fd.formdata.getfirst("addIndex", "1") - hiddenColumnsString = fd.formdata.getfirst("hiddenColumns", "") - hiddenColumns = hiddenColumnsString.split(',') - - try: - fp = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'rb') - tblobj = cPickle.load(fp) - fp.close() - - if cmd == 'addCorr': - dbId = int(fd.formdata.getfirst("db")) - dbFullName = fd.formdata.getfirst("dbname") - trait = fd.formdata.getfirst("trait") - form = fd.formdata.getfirst("form") - ids = fd.formdata.getfirst("ids") - vals = fd.formdata.getfirst("vals") - ids = eval(ids) - nnCorr = len(ids) - vals = eval(vals) - - workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+file)) - worksheet = workbook.add_worksheet() - - con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) - cursor = con.cursor() - - cursor.execute("Select name, ShortName from ProbeSetFreeze where Id = %s", dbId) - dbName, dbShortName = cursor.fetchone() - - tblobj['header'][0].append( - THCell(HT.TD(dbShortName, Class="fs11 ffl b1 cw cbrb"), - text="%s" % dbShortName, idx=tblobj['header'][0][-1].idx + 1), - ) - - headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") - for i, item in enumerate(tblobj['header'][0]): - if (i > 0): - worksheet.write([8, i-1], item.text, headingStyle) - worksheet.set_column([i-1, i-1], 2*len(item.text)) - - for i, row in enumerate(tblobj['body']): - ProbeSetId = row[1].text - #XZ, 03/02/2009: Xiaodong changed Data to ProbeSetData - cursor.execute(""" - Select ProbeSetData.StrainId, ProbeSetData.Value - From ProbeSetData, ProbeSetXRef, ProbeSet - where ProbeSetXRef.ProbeSetFreezeId = %d AND - ProbeSetXRef.DataId = ProbeSetData.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSet.Name = '%s' - """ % (dbId, ProbeSetId)) - results = cursor.fetchall() - vdict = {} - for item in results: - vdict[item[0]] = item[1] - newvals = [] - for id in ids: - if vdict.has_key(id): - newvals.append(vdict[id]) - else: - newvals.append(None) - corr,nOverlap= webqtlUtil.calCorrelation(newvals,vals,nnCorr) - repr = '%0.4f' % corr - row.append( - TDCell(HT.TD(HT.Href(text=repr, url="javascript:showCorrPlotThird('%s', '%s', '%s')" % (form, dbName, ProbeSetId), Class="fs11 fwn ffl"), " / ", nOverlap, Class="fs11 fwn ffl b1 c222", align="middle"),repr,abs(corr)) - ) - - last_row=0 - for j, item in enumerate(tblobj['body'][i]): - if (j > 0): - worksheet.write([9+i, j-1], item.text) - last_row = 9+i - last_row += 1 - - titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray") - ##Write title Info - # Modified by Hongqiang Li - worksheet.write([0, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) - worksheet.write([1, 0], "Trait : %s" % trait, titleStyle) - worksheet.write([2, 0], "Database : %s" % dbFullName, titleStyle) - worksheet.write([3, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle) - worksheet.write([4, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle) - worksheet.write([5, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle) - #Write footer info - worksheet.write([1 + last_row, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle) - worksheet.write([2 + last_row, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle) - - cursor.close() - workbook.close() - - objfile = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'wb') - cPickle.dump(tblobj, objfile) - objfile.close() - else: - pass - - self.value = str(webqtlUtil.genTableObj(tblobj=tblobj, file=file, sortby=(sort, order), tableID = tableID, addIndex = addIndex, hiddenColumns = hiddenColumns)) - - except: - self.value = "The table is no longer available on this server" - - def __str__(self): - return self.value - - def write(self): - return str(self) + def __init__(self, fd): + file = fd.formdata.getfirst("file", "") + sort = fd.formdata.getfirst("sort", "") + order = fd.formdata.getfirst("order", "up") + cmd = fd.formdata.getfirst("cmd", "") + tableID = fd.formdata.getfirst("tableID", "") + addIndex = fd.formdata.getfirst("addIndex", "1") + hiddenColumnsString = fd.formdata.getfirst("hiddenColumns", "") + hiddenColumns = hiddenColumnsString.split(',') + + try: + fp = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'rb') + tblobj = cPickle.load(fp) + fp.close() + + if cmd == 'addCorr': + dbId = int(fd.formdata.getfirst("db")) + dbFullName = fd.formdata.getfirst("dbname") + trait = fd.formdata.getfirst("trait") + form = fd.formdata.getfirst("form") + ids = fd.formdata.getfirst("ids") + vals = fd.formdata.getfirst("vals") + ids = eval(ids) + nnCorr = len(ids) + vals = eval(vals) + + workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+file)) + worksheet = workbook.add_worksheet() + + con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) + cursor = con.cursor() + + cursor.execute("Select name, ShortName from ProbeSetFreeze where Id = %s", dbId) + dbName, dbShortName = cursor.fetchone() + + tblobj['header'][0].append( + THCell(HT.TD(dbShortName, Class="fs11 ffl b1 cw cbrb"), + text="%s" % dbShortName, idx=tblobj['header'][0][-1].idx + 1), + ) + + headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") + for i, item in enumerate(tblobj['header'][0]): + if (i > 0): + worksheet.write([8, i-1], item.text, headingStyle) + worksheet.set_column([i-1, i-1], 2*len(item.text)) + + for i, row in enumerate(tblobj['body']): + ProbeSetId = row[1].text + #XZ, 03/02/2009: Xiaodong changed Data to ProbeSetData + cursor.execute(""" + Select ProbeSetData.StrainId, ProbeSetData.Value + From ProbeSetData, ProbeSetXRef, ProbeSet + where ProbeSetXRef.ProbeSetFreezeId = %d AND + ProbeSetXRef.DataId = ProbeSetData.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSet.Name = '%s' + """ % (dbId, ProbeSetId)) + results = cursor.fetchall() + vdict = {} + for item in results: + vdict[item[0]] = item[1] + newvals = [] + for id in ids: + if vdict.has_key(id): + newvals.append(vdict[id]) + else: + newvals.append(None) + corr,nOverlap= webqtlUtil.calCorrelation(newvals,vals,nnCorr) + repr = '%0.4f' % corr + row.append( + TDCell(HT.TD(HT.Href(text=repr, url="javascript:showCorrPlotThird('%s', '%s', '%s')" % (form, dbName, ProbeSetId), Class="fs11 fwn ffl"), " / ", nOverlap, Class="fs11 fwn ffl b1 c222", align="middle"),repr,abs(corr)) + ) + + last_row=0 + for j, item in enumerate(tblobj['body'][i]): + if (j > 0): + worksheet.write([9+i, j-1], item.text) + last_row = 9+i + last_row += 1 + + titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray") + ##Write title Info + # Modified by Hongqiang Li + worksheet.write([0, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) + worksheet.write([1, 0], "Trait : %s" % trait, titleStyle) + worksheet.write([2, 0], "Database : %s" % dbFullName, titleStyle) + worksheet.write([3, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle) + worksheet.write([4, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle) + worksheet.write([5, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle) + #Write footer info + worksheet.write([1 + last_row, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle) + worksheet.write([2 + last_row, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle) + + cursor.close() + workbook.close() + + objfile = open(os.path.join(webqtlConfig.TMPDIR, file + '.obj'), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + else: + pass + + self.value = str(webqtlUtil.genTableObj(tblobj=tblobj, file=file, sortby=(sort, order), tableID = tableID, addIndex = addIndex, hiddenColumns = hiddenColumns)) + + except: + self.value = "The table is no longer available on this server" + + def __str__(self): + return self.value + + def write(self): + return str(self) diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index e00b8e9e..04fe85bf 100755 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -39,1245 +39,1245 @@ from base import webqtlConfig def cformat(d, rank=0): - 'custom string format' - strD = "%2.6f" % d - - if rank == 0: - while strD[-1] in ('0','.'): - if strD[-1] == '0' and strD[-2] == '.' and len(strD) <= 4: - break - elif strD[-1] == '.': - strD = strD[:-1] - break - else: - strD = strD[:-1] - - else: - strD = strD.split(".")[0] - - if strD == '-0.0': - strD = '0.0' - return strD + 'custom string format' + strD = "%2.6f" % d + + if rank == 0: + while strD[-1] in ('0','.'): + if strD[-1] == '0' and strD[-2] == '.' and len(strD) <= 4: + break + elif strD[-1] == '.': + strD = strD[:-1] + break + else: + strD = strD[:-1] + + else: + strD = strD.split(".")[0] + + if strD == '-0.0': + strD = '0.0' + return strD def frange(start, end=None, inc=1.0): - "A faster range-like function that does accept float increments..." - if end == None: - end = start + 0.0 - start = 0.0 - else: - start += 0.0 # force it to be a float - count = int((end - start) / inc) - if start + count * inc != end: - # Need to adjust the count. AFAICT, it always comes up one short. - count += 1 - L = [start] * count - for i in xrange(1, count): - L[i] = start + i * inc - return L + "A faster range-like function that does accept float increments..." + if end == None: + end = start + 0.0 + start = 0.0 + else: + start += 0.0 # force it to be a float + count = int((end - start) / inc) + if start + count * inc != end: + # Need to adjust the count. AFAICT, it always comes up one short. + count += 1 + L = [start] * count + for i in xrange(1, count): + L[i] = start + i * inc + return L def gammln(xx): - cof=[76.18009173,-86.50532033,24.01409822,-1.231739516,0.120858003e-2,-0.536382e-5] - x=xx-1.0 - tmp=x+5.5 - tmp -=(x+0.5)*log(tmp) - ser=1.0 - for item in cof: - x+=1.0 - ser+=item/x + cof=[76.18009173,-86.50532033,24.01409822,-1.231739516,0.120858003e-2,-0.536382e-5] + x=xx-1.0 + tmp=x+5.5 + tmp -=(x+0.5)*log(tmp) + ser=1.0 + for item in cof: + x+=1.0 + ser+=item/x - return -tmp+log(2.50662827465*ser) + return -tmp+log(2.50662827465*ser) def gser(a,x): - gln=gammln(a) - ITMAX=100 - EPS=3.0e-7 - - if x<=0.0: - gamser=0.0 - return [gamser,gln] - else: - ap=a - sum=1.0/a - dele=sum - for i in range(1,ITMAX+1): - ap+=1.0 - dele*=x/ap - sum+=dele - if abs(dele)=0.0: - return ans - else: - return 2.0-ans + z=abs(x) + t=1.0/(1.0+0.5*z) + ans=t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277))))))))) + if x>=0.0: + return ans + else: + return 2.0-ans def calMeanVar(data): - n=len(data) - if n<2: - return None - else: - sum=reduce(lambda x,y:x+y,data,0.0) - mean=sum/n - z=data[:] - for i in range(n): - z[i]=z[i]-mean - variance=reduce(lambda x,y:x+y*y,z,0.0) - variance /= n-1 - variance =sqrt(variance) - for i in range(n): - z[i]=z[i]/variance - return z + n=len(data) + if n<2: + return None + else: + sum=reduce(lambda x,y:x+y,data,0.0) + mean=sum/n + z=data[:] + for i in range(n): + z[i]=z[i]-mean + variance=reduce(lambda x,y:x+y*y,z,0.0) + variance /= n-1 + variance =sqrt(variance) + for i in range(n): + z[i]=z[i]/variance + return z def inverseCumul(p): - #Coefficients in rational approximations. - a = [-3.969683028665376e+01,2.209460984245205e+02,-2.759285104469687e+02,1.383577518672690e+02,-3.066479806614716e+01,2.506628277459239e+00] + #Coefficients in rational approximations. + a = [-3.969683028665376e+01,2.209460984245205e+02,-2.759285104469687e+02,1.383577518672690e+02,-3.066479806614716e+01,2.506628277459239e+00] - b = [-5.447609879822406e+01,1.615858368580409e+02,-1.556989798598866e+02,6.680131188771972e+01,-1.328068155288572e+01] + b = [-5.447609879822406e+01,1.615858368580409e+02,-1.556989798598866e+02,6.680131188771972e+01,-1.328068155288572e+01] - c = [-7.784894002430293e-03,-3.223964580411365e-01,-2.400758277161838e+00,-2.549732539343734e+00,4.374664141464968e+00,2.938163982698783e+00] + c = [-7.784894002430293e-03,-3.223964580411365e-01,-2.400758277161838e+00,-2.549732539343734e+00,4.374664141464968e+00,2.938163982698783e+00] - d = [7.784695709041462e-03,3.224671290700398e-01,2.445134137142996e+00,3.754408661907416e+00] + d = [7.784695709041462e-03,3.224671290700398e-01,2.445134137142996e+00,3.754408661907416e+00] - #Define break-points. + #Define break-points. - p_low = 0.02425 - p_high = 1 - p_low + p_low = 0.02425 + p_high = 1 - p_low - #Rational approximation for lower region. + #Rational approximation for lower region. - if p > 0 and p < p_low: - q = sqrt(-2*log(p)) - x = (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) + if p > 0 and p < p_low: + q = sqrt(-2*log(p)) + x = (((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) / ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) - #Rational approximation for central region. + #Rational approximation for central region. - elif p>= p_low and p <= p_high: - q = p - 0.5 - r = q*q - x = (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /(((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1) + elif p>= p_low and p <= p_high: + q = p - 0.5 + r = q*q + x = (((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /(((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1) - #Rational approximation for upper region. + #Rational approximation for upper region. - elif p>p_high and p < 1: - q = sqrt(-2*log(1-p)) - x = -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) + elif p>p_high and p < 1: + q = sqrt(-2*log(1-p)) + x = -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1) - else: - return None + else: + return None - if p>0 and p < 1: - e = 0.5 * erfcc(-x/sqrt(2)) - p - u = e * sqrt(2*pi) * exp(x*x/2) - x = x - u/(1 + x*u/2) - return x - else: - return None + if p>0 and p < 1: + e = 0.5 * erfcc(-x/sqrt(2)) - p + u = e * sqrt(2*pi) * exp(x*x/2) + x = x - u/(1 + x*u/2) + return x + else: + return None def gmean(lst): - N = len(lst) - if N == 0: - return 0 - else: - return (reduce(lambda x,y: x+y, lst, 0.0))/N + N = len(lst) + if N == 0: + return 0 + else: + return (reduce(lambda x,y: x+y, lst, 0.0))/N def gmedian(lst2): - lst = lst2[:] - N = len(lst) - if N == 0: - return 0 - else: - lst.sort() - if N % 2 == 0: - return (lst[N/2]+lst[(N-2)/2])/2.0 - else: - return lst[(N-1)/2] + lst = lst2[:] + N = len(lst) + if N == 0: + return 0 + else: + lst.sort() + if N % 2 == 0: + return (lst[N/2]+lst[(N-2)/2])/2.0 + else: + return lst[(N-1)/2] def gpercentile(lst2, np): - lst = lst2[:] - N = len(lst) - if N == 0 or np > 100 or np < 0: - return None - else: - lst.sort() - pNadd1 = (np/100.0)*N - k = int(pNadd1) - d = pNadd1 - k - if k == 0: - return lst[0] - elif k >= N-1: - return lst[N-1] - else: - return lst[k-1] + d*(lst[k] - lst[k-1]) + lst = lst2[:] + N = len(lst) + if N == 0 or np > 100 or np < 0: + return None + else: + lst.sort() + pNadd1 = (np/100.0)*N + k = int(pNadd1) + d = pNadd1 - k + if k == 0: + return lst[0] + elif k >= N-1: + return lst[N-1] + else: + return lst[k-1] + d*(lst[k] - lst[k-1]) def findOutliers(vals): - valsOnly = [] - dataXZ = vals[:] - for i in range(len(dataXZ)): - valsOnly.append(dataXZ[i][1]) - - data = [('', valsOnly[:])] - - for item in data: - itemvalue = item[1] - nValue = len(itemvalue) - catValue = [] - - for item2 in itemvalue: - try: - tstrain, tvalue = item2 - except: - tvalue = item2 - if nValue <= 4: - continue - else: - catValue.append(tvalue) - - if catValue != []: - lowHinge = gpercentile(catValue, 25) - upHinge = gpercentile(catValue, 75) - Hstep = 1.5*(upHinge - lowHinge) - - outlier = [] - extreme = [] - - upperBound = upHinge + Hstep - lowerBound = lowHinge - Hstep - - for item in catValue: - if item >= upHinge + 2*Hstep: - extreme.append(item) - elif item >= upHinge + Hstep: - outlier.append(item) - else: - pass - - for item in catValue: - if item <= lowHinge - 2*Hstep: - extreme.append(item) - elif item <= lowHinge - Hstep: - outlier.append(item) - else: - pass - else: - upperBound = 1000 - lowerBound = -1000 - - return upperBound, lowerBound + valsOnly = [] + dataXZ = vals[:] + for i in range(len(dataXZ)): + valsOnly.append(dataXZ[i][1]) + + data = [('', valsOnly[:])] + + for item in data: + itemvalue = item[1] + nValue = len(itemvalue) + catValue = [] + + for item2 in itemvalue: + try: + tstrain, tvalue = item2 + except: + tvalue = item2 + if nValue <= 4: + continue + else: + catValue.append(tvalue) + + if catValue != []: + lowHinge = gpercentile(catValue, 25) + upHinge = gpercentile(catValue, 75) + Hstep = 1.5*(upHinge - lowHinge) + + outlier = [] + extreme = [] + + upperBound = upHinge + Hstep + lowerBound = lowHinge - Hstep + + for item in catValue: + if item >= upHinge + 2*Hstep: + extreme.append(item) + elif item >= upHinge + Hstep: + outlier.append(item) + else: + pass + + for item in catValue: + if item <= lowHinge - 2*Hstep: + extreme.append(item) + elif item <= lowHinge - Hstep: + outlier.append(item) + else: + pass + else: + upperBound = 1000 + lowerBound = -1000 + + return upperBound, lowerBound def plotBoxPlot(canvas, data, offset= (40, 40, 40, 40), XLabel="Category", YLabel="Value"): - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - iValues = [] - for item in data: - for item2 in item[1]: - try: - iValues.append(item2[1]) - except: - iValues.append(item2) - - #draw frame - max_Y = max(iValues) - min_Y = min(iValues) - scaleY = detScale(min_Y, max_Y) - Yll = scaleY[0] - Yur = scaleY[1] - nStep = scaleY[2] - stepY = (Yur - Yll)/nStep - stepYPixel = plotHeight/(nStep) - canvas.drawRect(plotWidth+xLeftOffset, plotHeight + yTopOffset, xLeftOffset, yTopOffset) - - ##draw Y Scale - YYY = Yll - YCoord = plotHeight + yTopOffset - scaleFont=pid.Font(ttf="cour",size=11,bold=1) - for i in range(nStep+1): - strY = cformat(d=YYY, rank=0) - YCoord = max(YCoord, yTopOffset) - canvas.drawLine(xLeftOffset,YCoord,xLeftOffset-5,YCoord) - canvas.drawString(strY, xLeftOffset -30,YCoord +5,font=scaleFont) - YYY += stepY - YCoord -= stepYPixel - - ##draw X Scale - stepX = plotWidth/len(data) - XCoord = xLeftOffset + 0.5*stepX - YCoord = plotHeight + yTopOffset - scaleFont = pid.Font(ttf="tahoma",size=12,bold=0) - labelFont = pid.Font(ttf="tahoma",size=13,bold=0) - for item in data: - itemname, itemvalue = item - canvas.drawLine(XCoord, YCoord,XCoord, YCoord+5, color=pid.black) - canvas.drawString(itemname, XCoord - canvas.stringWidth(itemname,font=labelFont)/2.0,\ - YCoord +20,font=labelFont) - - nValue = len(itemvalue) - catValue = [] - for item2 in itemvalue: - try: - tstrain, tvalue = item2 - except: - tvalue = item2 - if nValue <= 4: - canvas.drawCross(XCoord, plotHeight + yTopOffset - (tvalue-Yll)*plotHeight/(Yur - Yll), color=pid.red,size=5) - else: - catValue.append(tvalue) - if catValue != []: - catMean = gmean(catValue) - catMedian = gmedian(catValue) - lowHinge = gpercentile(catValue, 25) - upHinge = gpercentile(catValue, 75) - Hstep = 1.5*(upHinge - lowHinge) - - outlier = [] - extrem = [] - - upperAdj = None - for item in catValue: - if item >= upHinge + 2*Hstep: - extrem.append(item) - elif item >= upHinge + Hstep: - outlier.append(item) - elif item > upHinge and item < upHinge + Hstep: - if upperAdj == None or item > upperAdj: - upperAdj = item - else: - pass - lowerAdj = None - for item in catValue: - if item <= lowHinge - 2*Hstep: - extrem.append(item) - elif item <= lowHinge - Hstep: - outlier.append(item) - if item < lowHinge and item > lowHinge - Hstep: - if lowerAdj == None or item < lowerAdj: - lowerAdj = item - else: - pass - canvas.drawRect(XCoord-20, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ - XCoord+20, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll)) - canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll), \ - XCoord+20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll)) - if upperAdj != None: - canvas.drawLine(XCoord, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll), \ - XCoord, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) - canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll), \ - XCoord+20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) - if lowerAdj != None: - canvas.drawLine(XCoord, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ - XCoord, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) - canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll), \ - XCoord+20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) - - outlierFont = pid.Font(ttf="cour",size=12,bold=0) - if outlier != []: - for item in outlier: - yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) - #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) - canvas.drawString('o', XCoord-3, yc+5, font=outlierFont, color=pid.orange) - if extrem != []: - for item in extrem: - yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) - #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) - canvas.drawString('*', XCoord-3, yc+6, font=outlierFont, color=pid.red) - - canvas.drawCross(XCoord, plotHeight + yTopOffset - (catMean-Yll)*plotHeight/(Yur - Yll), \ - color=pid.blue,size=3) - #print (catMean, catMedian, cat25per, cat75per) - pass - - XCoord += stepX - - labelFont=pid.Font(ttf="verdana",size=18,bold=0) - canvas.drawString(XLabel, xLeftOffset + (plotWidth -canvas.stringWidth(XLabel,font=labelFont))/2.0, \ - YCoord +40, font=labelFont) - canvas.drawString(YLabel,xLeftOffset-40, YCoord-(plotHeight -canvas.stringWidth(YLabel,font=labelFont))/2.0,\ - font=labelFont, angle =90) + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + iValues = [] + for item in data: + for item2 in item[1]: + try: + iValues.append(item2[1]) + except: + iValues.append(item2) + + #draw frame + max_Y = max(iValues) + min_Y = min(iValues) + scaleY = detScale(min_Y, max_Y) + Yll = scaleY[0] + Yur = scaleY[1] + nStep = scaleY[2] + stepY = (Yur - Yll)/nStep + stepYPixel = plotHeight/(nStep) + canvas.drawRect(plotWidth+xLeftOffset, plotHeight + yTopOffset, xLeftOffset, yTopOffset) + + ##draw Y Scale + YYY = Yll + YCoord = plotHeight + yTopOffset + scaleFont=pid.Font(ttf="cour",size=11,bold=1) + for i in range(nStep+1): + strY = cformat(d=YYY, rank=0) + YCoord = max(YCoord, yTopOffset) + canvas.drawLine(xLeftOffset,YCoord,xLeftOffset-5,YCoord) + canvas.drawString(strY, xLeftOffset -30,YCoord +5,font=scaleFont) + YYY += stepY + YCoord -= stepYPixel + + ##draw X Scale + stepX = plotWidth/len(data) + XCoord = xLeftOffset + 0.5*stepX + YCoord = plotHeight + yTopOffset + scaleFont = pid.Font(ttf="tahoma",size=12,bold=0) + labelFont = pid.Font(ttf="tahoma",size=13,bold=0) + for item in data: + itemname, itemvalue = item + canvas.drawLine(XCoord, YCoord,XCoord, YCoord+5, color=pid.black) + canvas.drawString(itemname, XCoord - canvas.stringWidth(itemname,font=labelFont)/2.0,\ + YCoord +20,font=labelFont) + + nValue = len(itemvalue) + catValue = [] + for item2 in itemvalue: + try: + tstrain, tvalue = item2 + except: + tvalue = item2 + if nValue <= 4: + canvas.drawCross(XCoord, plotHeight + yTopOffset - (tvalue-Yll)*plotHeight/(Yur - Yll), color=pid.red,size=5) + else: + catValue.append(tvalue) + if catValue != []: + catMean = gmean(catValue) + catMedian = gmedian(catValue) + lowHinge = gpercentile(catValue, 25) + upHinge = gpercentile(catValue, 75) + Hstep = 1.5*(upHinge - lowHinge) + + outlier = [] + extrem = [] + + upperAdj = None + for item in catValue: + if item >= upHinge + 2*Hstep: + extrem.append(item) + elif item >= upHinge + Hstep: + outlier.append(item) + elif item > upHinge and item < upHinge + Hstep: + if upperAdj == None or item > upperAdj: + upperAdj = item + else: + pass + lowerAdj = None + for item in catValue: + if item <= lowHinge - 2*Hstep: + extrem.append(item) + elif item <= lowHinge - Hstep: + outlier.append(item) + if item < lowHinge and item > lowHinge - Hstep: + if lowerAdj == None or item < lowerAdj: + lowerAdj = item + else: + pass + canvas.drawRect(XCoord-20, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (catMedian-Yll)*plotHeight/(Yur - Yll)) + if upperAdj != None: + canvas.drawLine(XCoord, plotHeight + yTopOffset - (upHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (upperAdj-Yll)*plotHeight/(Yur - Yll)) + if lowerAdj != None: + canvas.drawLine(XCoord, plotHeight + yTopOffset - (lowHinge-Yll)*plotHeight/(Yur - Yll), \ + XCoord, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) + canvas.drawLine(XCoord-20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll), \ + XCoord+20, plotHeight + yTopOffset - (lowerAdj-Yll)*plotHeight/(Yur - Yll)) + + outlierFont = pid.Font(ttf="cour",size=12,bold=0) + if outlier != []: + for item in outlier: + yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) + #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) + canvas.drawString('o', XCoord-3, yc+5, font=outlierFont, color=pid.orange) + if extrem != []: + for item in extrem: + yc = plotHeight + yTopOffset - (item-Yll)*plotHeight/(Yur - Yll) + #canvas.drawEllipse(XCoord-3, yc-3, XCoord+3, yc+3) + canvas.drawString('*', XCoord-3, yc+6, font=outlierFont, color=pid.red) + + canvas.drawCross(XCoord, plotHeight + yTopOffset - (catMean-Yll)*plotHeight/(Yur - Yll), \ + color=pid.blue,size=3) + #print (catMean, catMedian, cat25per, cat75per) + pass + + XCoord += stepX + + labelFont=pid.Font(ttf="verdana",size=18,bold=0) + canvas.drawString(XLabel, xLeftOffset + (plotWidth -canvas.stringWidth(XLabel,font=labelFont))/2.0, \ + YCoord +40, font=labelFont) + canvas.drawString(YLabel,xLeftOffset-40, YCoord-(plotHeight -canvas.stringWidth(YLabel,font=labelFont))/2.0,\ + font=labelFont, angle =90) def plotSecurity(canvas, text="12345"): - if not text: - return - - plotWidth = canvas.size[0] - plotHeight = canvas.size[1] - if plotHeight<=0 or plotWidth<=0: - return - - bgColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) - canvas.drawRect(0,0,plotWidth,plotHeight, edgeColor=bgColor, fillColor=bgColor) - - for i in range(30): - randomColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) - scaleFont=pid.Font(ttf="cour",size=random.choice(range(20, 50))) - canvas.drawString(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), - int(random.random()*plotWidth), int(random.random()*plotHeight), font=scaleFont, - color=randomColor, angle=random.choice(range(-45, 50))) - - step = (plotWidth-20)/len(text) - startX = 20 - for item in text: - randomColor = pid.Color(0.6*random.random(),0.6*random.random(), 0.6*random.random()) - scaleFont=pid.Font(ttf="verdana",size=random.choice(range(50, 60)),bold=1) - canvas.drawString(item, startX, plotHeight/2-10, font=scaleFont, - color=randomColor, angle=random.choice(range(-45, 50))) - startX += step + if not text: + return + + plotWidth = canvas.size[0] + plotHeight = canvas.size[1] + if plotHeight<=0 or plotWidth<=0: + return + + bgColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) + canvas.drawRect(0,0,plotWidth,plotHeight, edgeColor=bgColor, fillColor=bgColor) + + for i in range(30): + randomColor = pid.Color(0.6+0.4*random.random(), 0.6+0.4*random.random(), 0.6+0.4*random.random()) + scaleFont=pid.Font(ttf="cour",size=random.choice(range(20, 50))) + canvas.drawString(random.choice('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), + int(random.random()*plotWidth), int(random.random()*plotHeight), font=scaleFont, + color=randomColor, angle=random.choice(range(-45, 50))) + + step = (plotWidth-20)/len(text) + startX = 20 + for item in text: + randomColor = pid.Color(0.6*random.random(),0.6*random.random(), 0.6*random.random()) + scaleFont=pid.Font(ttf="verdana",size=random.choice(range(50, 60)),bold=1) + canvas.drawString(item, startX, plotHeight/2-10, font=scaleFont, + color=randomColor, angle=random.choice(range(-45, 50))) + startX += step # parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py) # or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - - if len(data) < 2: - return - - max_D = max(data) - min_D = min(data) - #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong - if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: - max_D=webqtlConfig.MAXLRS #maximum LRS value - - xLow, xTop, stepX = detScale(min_D, max_D) - - #reduce data - step = ceil((xTop-xLow)/50.0) - j = xLow - dataXY = [] - Count = [] - while j <= xTop: - dataXY.append(j) - Count.append(0) - j += step - - for i, item in enumerate(data): - if item == float('inf') or item>webqtlConfig.MAXLRS: - item = webqtlConfig.MAXLRS #maximum LRS value - j = int((item-xLow)/step) - Count[j] += 1 - - yLow, yTop, stepY=detScale(0,max(Count)) - - #draw data - xScale = plotWidth/(xTop-xLow) - yScale = plotHeight/(yTop-yLow) - barWidth = xScale*step - - for i, count in enumerate(Count): - if count: - xc = (dataXY[i]-xLow)*xScale+xLeftOffset - yc =-(count-yLow)*yScale+yTopOffset+plotHeight - canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) - - #draw drawing region - canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) - - #draw scale - scaleFont=pid.Font(ttf="cour",size=11,bold=1) - x=xLow - for i in range(stepX+1): - xc=xLeftOffset+(x-xLow)*xScale - canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) - strX = cformat(d=x, rank=0) - canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) - x+= (xTop - xLow)/stepX - - y=yLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-yLow)*yScale - canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) - strY = "%d" %y - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) - y+= (yTop - yLow)/stepY - - #draw label - labelFont=pid.Font(ttf="tahoma",size=17,bold=0) - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, - yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, - font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=16,bold=0) - if title: - canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, - 20,font=labelFont,color=labelColor) + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + + if len(data) < 2: + return + + max_D = max(data) + min_D = min(data) + #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong + if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: + max_D=webqtlConfig.MAXLRS #maximum LRS value + + xLow, xTop, stepX = detScale(min_D, max_D) + + #reduce data + step = ceil((xTop-xLow)/50.0) + j = xLow + dataXY = [] + Count = [] + while j <= xTop: + dataXY.append(j) + Count.append(0) + j += step + + for i, item in enumerate(data): + if item == float('inf') or item>webqtlConfig.MAXLRS: + item = webqtlConfig.MAXLRS #maximum LRS value + j = int((item-xLow)/step) + Count[j] += 1 + + yLow, yTop, stepY=detScale(0,max(Count)) + + #draw data + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + barWidth = xScale*step + + for i, count in enumerate(Count): + if count: + xc = (dataXY[i]-xLow)*xScale+xLeftOffset + yc =-(count-yLow)*yScale+yTopOffset+plotHeight + canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) + + #draw drawing region + canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) + + #draw scale + scaleFont=pid.Font(ttf="cour",size=11,bold=1) + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) + strX = cformat(d=x, rank=0) + canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) + strY = "%d" %y + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) + y+= (yTop - yLow)/stepY + + #draw label + labelFont=pid.Font(ttf="tahoma",size=17,bold=0) + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, + yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, + font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=16,bold=0) + if title: + canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, + 20,font=labelFont,color=labelColor) def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, sLabel = None, offset= (80, 20, 40, 100), barSpace = 2, zoom = 1): - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - - NNN = len(data) - if NNN < 2 or NNN != len(label): - return - if variance and len(variance)!=NNN: - variance = [] - - Y2 = data[:] - if variance: - for i in range(NNN): - if variance[i]: - Y2 += [data[i]-variance[i]] - - #Y axis - YLow, YTop, stepY = detScale(min(Y2), max(Y2)) - YScale = plotHeight/(YTop - YLow) - - if YLow < 0 and YTop > 0: - drawZero = 1 - else: - drawZero = 0 - - #X axis - X = range(NNN) - Xll= 0 - Xur= NNN-1 - - - if drawZero: - YZero = yTopOffset+plotHeight-YScale*(0-YLow) - canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) - else: - YZero = yTopOffset+plotHeight - #draw data - spaceWidth = barSpace - if spaceWidth < 1: - spaceWidth = 1 - barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) - - xc= xLeftOffset - scaleFont=pid.Font(ttf="verdana",size=11,bold=0) - for i in range(NNN): - yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale - canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) - if variance and variance[i]: - varlen = variance[i]*YScale - if yc-varlen < yTopOffset: - topYd = yTopOffset - else: - topYd = yc-varlen - canvas.drawLine(xc+barWidth/2-2,yc-varlen,xc+barWidth/2+2,yc-varlen,color=pid.red) - canvas.drawLine(xc+barWidth/2,yc+varlen,xc+barWidth/2,topYd,color=pid.red) - canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) - strX = label[i] - canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) - xc += barWidth + spaceWidth - - #draw drawing region - canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) - - #draw Y scale - scaleFont=pid.Font(ttf="cour",size=16,bold=1) - y=YLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-YLow)*YScale - canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) - strY = cformat(d=y, rank=0) - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) - y+= (YTop - YLow)/stepY - - #draw label - labelFont=pid.Font(ttf="verdana",size=17,bold=0) - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=18,bold=0) - if title: - canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) - - return + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + + NNN = len(data) + if NNN < 2 or NNN != len(label): + return + if variance and len(variance)!=NNN: + variance = [] + + Y2 = data[:] + if variance: + for i in range(NNN): + if variance[i]: + Y2 += [data[i]-variance[i]] + + #Y axis + YLow, YTop, stepY = detScale(min(Y2), max(Y2)) + YScale = plotHeight/(YTop - YLow) + + if YLow < 0 and YTop > 0: + drawZero = 1 + else: + drawZero = 0 + + #X axis + X = range(NNN) + Xll= 0 + Xur= NNN-1 + + + if drawZero: + YZero = yTopOffset+plotHeight-YScale*(0-YLow) + canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) + else: + YZero = yTopOffset+plotHeight + #draw data + spaceWidth = barSpace + if spaceWidth < 1: + spaceWidth = 1 + barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) + + xc= xLeftOffset + scaleFont=pid.Font(ttf="verdana",size=11,bold=0) + for i in range(NNN): + yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale + canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) + if variance and variance[i]: + varlen = variance[i]*YScale + if yc-varlen < yTopOffset: + topYd = yTopOffset + else: + topYd = yc-varlen + canvas.drawLine(xc+barWidth/2-2,yc-varlen,xc+barWidth/2+2,yc-varlen,color=pid.red) + canvas.drawLine(xc+barWidth/2,yc+varlen,xc+barWidth/2,topYd,color=pid.red) + canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) + strX = label[i] + canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) + xc += barWidth + spaceWidth + + #draw drawing region + canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) + + #draw Y scale + scaleFont=pid.Font(ttf="cour",size=16,bold=1) + y=YLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-YLow)*YScale + canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) + strY = cformat(d=y, rank=0) + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) + y+= (YTop - YLow)/stepY + + #draw label + labelFont=pid.Font(ttf="verdana",size=17,bold=0) + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=18,bold=0) + if title: + canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) + + return def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, axesColor=pid.black, labelColor=pid.black, lineSize="thin", lineColor=pid.grey, idFont="arial", idColor=pid.blue, idSize="14", symbolColor=pid.black, symbolType="circle", filled="yes", symbolSize="tiny", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1, bufferSpace = 15): - 'displayR : correlation scatter plot, loadings : loading plot' - - dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) - - #get ID font size - idFontSize = int(idSize) - - #If filled is yes, set fill color - if filled == "yes": - fillColor = symbolColor - else: - fillColor = None - - if symbolSize == "large": - sizeModifier = 7 - fontModifier = 12 - elif symbolSize == "medium": - sizeModifier = 5 - fontModifier = 8 - elif symbolSize == "small": - sizeModifier = 3 - fontModifier = 3 - else: - sizeModifier = 1 - fontModifier = -1 - - if rank == 0: # Pearson correlation - bufferSpace = 0 - dataXPrimary = dataX - dataYPrimary = dataY - dataXAlt = dataXRanked #Values used just for printing the other corr type to the graph image - dataYAlt = dataYRanked #Values used just for printing the other corr type to the graph image - else: # Spearman correlation: Switching Ranked and Unranked X and Y values - dataXPrimary = dataXRanked - dataYPrimary = dataYRanked - dataXAlt = dataX #Values used just for printing the other corr type to the graph image - dataYAlt = dataY #Values used just for printing the other corr type to the graph image - - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): - return - - max_X=max(dataXPrimary) - min_X=min(dataXPrimary) - max_Y=max(dataYPrimary) - min_Y=min(dataYPrimary) - - #for some reason I forgot why I need to do this - if loadingPlot: - min_X = min(-0.1,min_X) - max_X = max(0.1,max_X) - min_Y = min(-0.1,min_Y) - max_Y = max(0.1,max_Y) - - xLow, xTop, stepX=detScale(min_X,max_X) - yLow, yTop, stepY=detScale(min_Y,max_Y) - xScale = plotWidth/(xTop-xLow) - yScale = plotHeight/(yTop-yLow) - - #draw drawing region - canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) - canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) - - #calculate data points - data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) - xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) - - labelFont=pid.Font(ttf=idFont,size=idFontSize,bold=0) - - if loadingPlot: - xZero = -xLow*xScale+xLeftOffset - yZero = yTopOffset+plotHeight+yLow*yScale - for point in xCoord: - canvas.drawLine(xZero,yZero,point[0],point[1],color=pid.red) - else: - if connectdot: - canvas.drawPolygon(xCoord,edgeColor=plotColor,closed=0) - else: - pass - - symbolFont = pid.Font(ttf="fnt_bs", size=12+fontModifier,bold=0) - - for i, item in enumerate(xCoord): - if dataLabel and dataLabel[i] in specialCases: - canvas.drawRect(item[0]-3, item[1]-3, item[0]+3, item[1]+3, edgeColor=pid.green) - #canvas.drawCross(item[0],item[1],color=pid.blue,size=5) - else: - if symbolType == "vertRect": - canvas.drawRect(x1=item[0]-sizeModifier+2,y1=item[1]-sizeModifier-2, x2=item[0]+sizeModifier-1,y2=item[1]+sizeModifier+2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "circle" and filled != "yes"): - canvas.drawString(":", item[0]-canvas.stringWidth(":",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) - elif (symbolType == "circle" and filled == "yes"): - canvas.drawString("5", item[0]-canvas.stringWidth("5",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) - elif symbolType == "horiRect": - canvas.drawRect(x1=item[0]-sizeModifier-1,y1=item[1]-sizeModifier+3, x2=item[0]+sizeModifier+3,y2=item[1]+sizeModifier-2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "square"): - canvas.drawRect(x1=item[0]-sizeModifier+1,y1=item[1]-sizeModifier-4, x2=item[0]+sizeModifier+2,y2=item[1]+sizeModifier-3, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "diamond" and filled != "yes"): - canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) - elif (symbolType == "diamond" and filled == "yes"): - canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) - elif symbolType == "4-star": - canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) - elif symbolType == "3-star": - canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) - else: - canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) - - if showLabel and dataLabel: - if (symbolType == "vertRect" or symbolType == "diamond"): - labelGap = 15 - elif (symbolType == "4-star" or symbolType == "3-star"): - labelGap = 12 - else: - labelGap = 11 - canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], - font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) - - #draw scale - scaleFont=pid.Font(ttf="cour",size=16,bold=1) - - - x=xLow - for i in range(stepX+1): - xc=xLeftOffset+(x-xLow)*xScale - if ((x == 0) & (rank == 1)): - pass - else: - canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) - strX = cformat(d=x, rank=rank) - if ((strX == "0") & (rank == 1)): - pass - else: - canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) - x+= (xTop - xLow)/stepX - - y=yLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-yLow)*yScale - if ((y == 0) & (rank == 1)): - pass - else: - canvas.drawLine(xLeftOffset - bufferSpace,yc,xLeftOffset-5 - bufferSpace,yc, color=axesColor) - strY = cformat(d=y, rank=rank) - if ((strY == "0") & (rank == 1)): - pass - else: - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) - y+= (yTop - yLow)/stepY - - #draw label - - labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) - titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) - - if (rank == 1 and not title): - canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, - 25,font=titleFont,color=labelColor) - elif (rank == 0 and not title): - canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, - 25,font=titleFont,color=labelColor) - - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, - yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, - font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=20,bold=0) - if title: - canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, - 20,font=labelFont,color=labelColor) - - if fitcurve: - import sys - sys.argv = [ "mod_python" ] - #from numarray import linear_algebra as la - #from numarray import ones, array, dot, swapaxes - fitYY = array(dataYPrimary) - fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) - AA = dot(fitXX,swapaxes(fitXX,0,1)) - BB = dot(fitXX,fitYY) - bb = la.linear_least_squares(AA,BB)[0] - - xc1 = xLeftOffset - yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale - if yc1 > yTopOffset+plotHeight: - yc1 = yTopOffset+plotHeight - xc1 = (yLow-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - elif yc1 < yTopOffset: - yc1 = yTopOffset - xc1 = (yTop-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - else: - pass - - xc2 = xLeftOffset + plotWidth - yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale - if yc2 > yTopOffset+plotHeight: - yc2 = yTopOffset+plotHeight - xc2 = (yLow-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - elif yc2 < yTopOffset: - yc2 = yTopOffset - xc2 = (yTop-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - else: - pass - - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace,xc2,yc2,color=lineColor) - if lineSize == "medium": - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) - if lineSize == "thick": - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) - - - if displayR: - labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) - NNN = len(dataX) - corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] - - if NNN < 3: - corrPValue = 1.0 - else: - if abs(corr) >= 1.0: - corrPValue = 0.0 - else: - ZValue = 0.5*log((1.0+corr)/(1.0-corr)) - ZValue = ZValue*sqrt(NNN-3) - corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - - NStr = "N = %d" % NNN - strLenN = canvas.stringWidth(NStr,font=labelFont) - - if rank == 1: - if corrPValue < 0.0000000000000001: - corrStr = "Rho = %1.3f P < 1.00 E-16" % (corr) - else: - corrStr = "Rho = %1.3f P = %3.2E" % (corr, corrPValue) - else: - if corrPValue < 0.0000000000000001: - corrStr = "r = %1.3f P < 1.00 E-16" % (corr) - else: - corrStr = "r = %1.3f P = %3.2E" % (corr, corrPValue) - strLen = canvas.stringWidth(corrStr,font=labelFont) - - canvas.drawString(NStr,xLeftOffset,yTopOffset-10,font=labelFont,color=labelColor) - canvas.drawString(corrStr,xLeftOffset+plotWidth-strLen,yTopOffset-10,font=labelFont,color=labelColor) - - return xCoord + 'displayR : correlation scatter plot, loadings : loading plot' + + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) + + #get ID font size + idFontSize = int(idSize) + + #If filled is yes, set fill color + if filled == "yes": + fillColor = symbolColor + else: + fillColor = None + + if symbolSize == "large": + sizeModifier = 7 + fontModifier = 12 + elif symbolSize == "medium": + sizeModifier = 5 + fontModifier = 8 + elif symbolSize == "small": + sizeModifier = 3 + fontModifier = 3 + else: + sizeModifier = 1 + fontModifier = -1 + + if rank == 0: # Pearson correlation + bufferSpace = 0 + dataXPrimary = dataX + dataYPrimary = dataY + dataXAlt = dataXRanked #Values used just for printing the other corr type to the graph image + dataYAlt = dataYRanked #Values used just for printing the other corr type to the graph image + else: # Spearman correlation: Switching Ranked and Unranked X and Y values + dataXPrimary = dataXRanked + dataYPrimary = dataYRanked + dataXAlt = dataX #Values used just for printing the other corr type to the graph image + dataYAlt = dataY #Values used just for printing the other corr type to the graph image + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): + return + + max_X=max(dataXPrimary) + min_X=min(dataXPrimary) + max_Y=max(dataYPrimary) + min_Y=min(dataYPrimary) + + #for some reason I forgot why I need to do this + if loadingPlot: + min_X = min(-0.1,min_X) + max_X = max(0.1,max_X) + min_Y = min(-0.1,min_Y) + max_Y = max(0.1,max_Y) + + xLow, xTop, stepX=detScale(min_X,max_X) + yLow, yTop, stepY=detScale(min_Y,max_Y) + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + + #draw drawing region + canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) + canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) + + #calculate data points + data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) + xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) + + labelFont=pid.Font(ttf=idFont,size=idFontSize,bold=0) + + if loadingPlot: + xZero = -xLow*xScale+xLeftOffset + yZero = yTopOffset+plotHeight+yLow*yScale + for point in xCoord: + canvas.drawLine(xZero,yZero,point[0],point[1],color=pid.red) + else: + if connectdot: + canvas.drawPolygon(xCoord,edgeColor=plotColor,closed=0) + else: + pass + + symbolFont = pid.Font(ttf="fnt_bs", size=12+fontModifier,bold=0) + + for i, item in enumerate(xCoord): + if dataLabel and dataLabel[i] in specialCases: + canvas.drawRect(item[0]-3, item[1]-3, item[0]+3, item[1]+3, edgeColor=pid.green) + #canvas.drawCross(item[0],item[1],color=pid.blue,size=5) + else: + if symbolType == "vertRect": + canvas.drawRect(x1=item[0]-sizeModifier+2,y1=item[1]-sizeModifier-2, x2=item[0]+sizeModifier-1,y2=item[1]+sizeModifier+2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "circle" and filled != "yes"): + canvas.drawString(":", item[0]-canvas.stringWidth(":",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) + elif (symbolType == "circle" and filled == "yes"): + canvas.drawString("5", item[0]-canvas.stringWidth("5",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) + elif symbolType == "horiRect": + canvas.drawRect(x1=item[0]-sizeModifier-1,y1=item[1]-sizeModifier+3, x2=item[0]+sizeModifier+3,y2=item[1]+sizeModifier-2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "square"): + canvas.drawRect(x1=item[0]-sizeModifier+1,y1=item[1]-sizeModifier-4, x2=item[0]+sizeModifier+2,y2=item[1]+sizeModifier-3, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) + elif (symbolType == "diamond" and filled != "yes"): + canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) + elif (symbolType == "diamond" and filled == "yes"): + canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) + elif symbolType == "4-star": + canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + elif symbolType == "3-star": + canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) + else: + canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) + + if showLabel and dataLabel: + if (symbolType == "vertRect" or symbolType == "diamond"): + labelGap = 15 + elif (symbolType == "4-star" or symbolType == "3-star"): + labelGap = 12 + else: + labelGap = 11 + canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], + font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) + + #draw scale + scaleFont=pid.Font(ttf="cour",size=16,bold=1) + + + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + if ((x == 0) & (rank == 1)): + pass + else: + canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) + strX = cformat(d=x, rank=rank) + if ((strX == "0") & (rank == 1)): + pass + else: + canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + if ((y == 0) & (rank == 1)): + pass + else: + canvas.drawLine(xLeftOffset - bufferSpace,yc,xLeftOffset-5 - bufferSpace,yc, color=axesColor) + strY = cformat(d=y, rank=rank) + if ((strY == "0") & (rank == 1)): + pass + else: + canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) + y+= (yTop - yLow)/stepY + + #draw label + + labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) + titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) + + if (rank == 1 and not title): + canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, + 25,font=titleFont,color=labelColor) + elif (rank == 0 and not title): + canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, + 25,font=titleFont,color=labelColor) + + if XLabel: + canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, + yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) + + if YLabel: + canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, + font=labelFont,color=labelColor,angle=90) + + labelFont=pid.Font(ttf="verdana",size=20,bold=0) + if title: + canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, + 20,font=labelFont,color=labelColor) + + if fitcurve: + import sys + sys.argv = [ "mod_python" ] + #from numarray import linear_algebra as la + #from numarray import ones, array, dot, swapaxes + fitYY = array(dataYPrimary) + fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) + AA = dot(fitXX,swapaxes(fitXX,0,1)) + BB = dot(fitXX,fitYY) + bb = la.linear_least_squares(AA,BB)[0] + + xc1 = xLeftOffset + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + if yc1 > yTopOffset+plotHeight: + yc1 = yTopOffset+plotHeight + xc1 = (yLow-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + elif yc1 < yTopOffset: + yc1 = yTopOffset + xc1 = (yTop-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + else: + pass + + xc2 = xLeftOffset + plotWidth + yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale + if yc2 > yTopOffset+plotHeight: + yc2 = yTopOffset+plotHeight + xc2 = (yLow-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + elif yc2 < yTopOffset: + yc2 = yTopOffset + xc2 = (yTop-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + else: + pass + + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace,xc2,yc2,color=lineColor) + if lineSize == "medium": + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) + if lineSize == "thick": + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) + canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) + + + if displayR: + labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) + NNN = len(dataX) + corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] + + if NNN < 3: + corrPValue = 1.0 + else: + if abs(corr) >= 1.0: + corrPValue = 0.0 + else: + ZValue = 0.5*log((1.0+corr)/(1.0-corr)) + ZValue = ZValue*sqrt(NNN-3) + corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) + + NStr = "N = %d" % NNN + strLenN = canvas.stringWidth(NStr,font=labelFont) + + if rank == 1: + if corrPValue < 0.0000000000000001: + corrStr = "Rho = %1.3f P < 1.00 E-16" % (corr) + else: + corrStr = "Rho = %1.3f P = %3.2E" % (corr, corrPValue) + else: + if corrPValue < 0.0000000000000001: + corrStr = "r = %1.3f P < 1.00 E-16" % (corr) + else: + corrStr = "r = %1.3f P = %3.2E" % (corr, corrPValue) + strLen = canvas.stringWidth(corrStr,font=labelFont) + + canvas.drawString(NStr,xLeftOffset,yTopOffset-10,font=labelFont,color=labelColor) + canvas.drawString(corrStr,xLeftOffset+plotWidth-strLen,yTopOffset-10,font=labelFont,color=labelColor) + + return xCoord def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black", axesColor="black", labelColor="black", symbolColor="red", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1): - 'displayR : correlation scatter plot, loadings : loading plot' - - dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) - - # Switching Ranked and Unranked X and Y values if a Spearman Rank Correlation - if rank == 0: - dataXPrimary = dataX - dataYPrimary = dataY - dataXAlt = dataXRanked - dataYAlt = dataYRanked - - else: - dataXPrimary = dataXRanked - dataYPrimary = dataYRanked - dataXAlt = dataX - dataYAlt = dataY - - - - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = drawSpace.attributes['width'] - xLeftOffset - xRightOffset - plotHeight = drawSpace.attributes['height'] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): - return - - max_X=max(dataXPrimary) - min_X=min(dataXPrimary) - max_Y=max(dataYPrimary) - min_Y=min(dataYPrimary) - - #for some reason I forgot why I need to do this - if loadingPlot: - min_X = min(-0.1,min_X) - max_X = max(0.1,max_X) - min_Y = min(-0.1,min_Y) - max_Y = max(0.1,max_Y) - - xLow, xTop, stepX=detScale(min_X,max_X) - yLow, yTop, stepY=detScale(min_Y,max_Y) - xScale = plotWidth/(xTop-xLow) - yScale = plotHeight/(yTop-yLow) - - #draw drawing region - r = svg.rect(xLeftOffset, yTopOffset, plotWidth, plotHeight, 'none', axesColor, 1) - drawSpace.addElement(r) - - #calculate data points - data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) - xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) - labelFontF = "verdana" - labelFontS = 11 - - if loadingPlot: - xZero = -xLow*xScale+xLeftOffset - yZero = yTopOffset+plotHeight+yLow*yScale - for point in xCoord: - drawSpace.addElement(svg.line(xZero,yZero,point[0],point[1], "red", 1)) - else: - if connectdot: - pass - #drawSpace.drawPolygon(xCoord,edgeColor=plotColor,closed=0) - else: - pass - - for i, item in enumerate(xCoord): - if dataLabel and dataLabel[i] in specialCases: - drawSpace.addElement(svg.rect(item[0]-3, item[1]-3, 6, 6, "none", "green", 0.5)) - #drawSpace.drawCross(item[0],item[1],color=pid.blue,size=5) - else: - drawSpace.addElement(svg.line(item[0],item[1]+5,item[0],item[1]-5,symbolColor,1)) - drawSpace.addElement(svg.line(item[0]+5,item[1],item[0]-5,item[1],symbolColor,1)) - if showLabel and dataLabel: - pass - drawSpace.addElement(svg.text(item[0], item[1]+14, dataLabel[i], labelFontS, - labelFontF, text_anchor="middle", style="stroke:blue;stroke-width:0.5;")) - #canvas.drawString(, item[0]- canvas.stringWidth(dataLabel[i], - # font=labelFont)/2, item[1]+14, font=labelFont, color=pid.blue) - - #draw scale - #scaleFont=pid.Font(ttf="cour",size=14,bold=1) - x=xLow - for i in range(stepX+1): - xc=xLeftOffset+(x-xLow)*xScale - drawSpace.addElement(svg.line(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, axesColor, 1)) - strX = cformat(d=x, rank=rank) - drawSpace.addElement(svg.text(xc,yTopOffset+plotHeight+20,strX,13, "courier", text_anchor="middle")) - x+= (xTop - xLow)/stepX - - y=yLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-yLow)*yScale - drawSpace.addElement(svg.line(xLeftOffset,yc,xLeftOffset-5,yc, axesColor, 1)) - strY = cformat(d=y, rank=rank) - drawSpace.addElement(svg.text(xLeftOffset-10,yc+5,strY,13, "courier", text_anchor="end")) - y+= (yTop - yLow)/stepY - - #draw label - labelFontF = "verdana" - labelFontS = 17 - if XLabel: - drawSpace.addElement(svg.text(xLeftOffset+plotWidth/2.0, - yTopOffset+plotHeight+yBottomOffset-10,XLabel, - labelFontS, labelFontF, text_anchor="middle")) - - if YLabel: - drawSpace.addElement(svg.text(xLeftOffset-50, - yTopOffset+plotHeight/2,YLabel, - labelFontS, labelFontF, text_anchor="middle", style="writing-mode:tb-rl", transform="rotate(270 %d %d)" % (xLeftOffset-50, yTopOffset+plotHeight/2))) - #drawSpace.drawString(YLabel, xLeftOffset-50, yTopOffset+plotHeight- (plotHeight-drawSpace.stringWidth(YLabel,font=labelFont))/2.0, - # font=labelFont,color=labelColor,angle=90) - - - if fitcurve: - sys.argv = [ "mod_python" ] - #from numarray import linear_algebra as la - #from numarray import ones, array, dot, swapaxes - fitYY = array(dataYPrimary) - fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) - AA = dot(fitXX,swapaxes(fitXX,0,1)) - BB = dot(fitXX,fitYY) - bb = la.linear_least_squares(AA,BB)[0] - - xc1 = xLeftOffset - yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale - if yc1 > yTopOffset+plotHeight: - yc1 = yTopOffset+plotHeight - xc1 = (yLow-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - elif yc1 < yTopOffset: - yc1 = yTopOffset - xc1 = (yTop-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - else: - pass - - xc2 = xLeftOffset + plotWidth - yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale - if yc2 > yTopOffset+plotHeight: - yc2 = yTopOffset+plotHeight - xc2 = (yLow-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - elif yc2 < yTopOffset: - yc2 = yTopOffset - xc2 = (yTop-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - else: - pass - - drawSpace.addElement(svg.line(xc1,yc1,xc2,yc2,"green", 1)) - - if displayR: - labelFontF = "trebuc" - labelFontS = 14 - NNN = len(dataX) - - corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] - - if NNN < 3: - corrPValue = 1.0 - else: - if abs(corr) >= 1.0: - corrPValue = 0.0 - else: - ZValue = 0.5*log((1.0+corr)/(1.0-corr)) - ZValue = ZValue*sqrt(NNN-3) - corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - - NStr = "N of Cases=%d" % NNN - - if rank == 1: - corrStr = "Spearman's r=%1.3f P=%3.2E" % (corr, corrPValue) - else: - corrStr = "Pearson's r=%1.3f P=%3.2E" % (corr, corrPValue) - - drawSpace.addElement(svg.text(xLeftOffset,yTopOffset-10,NStr, - labelFontS, labelFontF, text_anchor="start")) - drawSpace.addElement(svg.text(xLeftOffset+plotWidth,yTopOffset-25,corrStr, - labelFontS, labelFontF, text_anchor="end")) - """ - """ - return + 'displayR : correlation scatter plot, loadings : loading plot' + + dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) + + # Switching Ranked and Unranked X and Y values if a Spearman Rank Correlation + if rank == 0: + dataXPrimary = dataX + dataYPrimary = dataY + dataXAlt = dataXRanked + dataYAlt = dataYRanked + + else: + dataXPrimary = dataXRanked + dataYPrimary = dataYRanked + dataXAlt = dataX + dataYAlt = dataY + + + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = drawSpace.attributes['width'] - xLeftOffset - xRightOffset + plotHeight = drawSpace.attributes['height'] - yTopOffset - yBottomOffset + if plotHeight<=0 or plotWidth<=0: + return + if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): + return + + max_X=max(dataXPrimary) + min_X=min(dataXPrimary) + max_Y=max(dataYPrimary) + min_Y=min(dataYPrimary) + + #for some reason I forgot why I need to do this + if loadingPlot: + min_X = min(-0.1,min_X) + max_X = max(0.1,max_X) + min_Y = min(-0.1,min_Y) + max_Y = max(0.1,max_Y) + + xLow, xTop, stepX=detScale(min_X,max_X) + yLow, yTop, stepY=detScale(min_Y,max_Y) + xScale = plotWidth/(xTop-xLow) + yScale = plotHeight/(yTop-yLow) + + #draw drawing region + r = svg.rect(xLeftOffset, yTopOffset, plotWidth, plotHeight, 'none', axesColor, 1) + drawSpace.addElement(r) + + #calculate data points + data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) + xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) + labelFontF = "verdana" + labelFontS = 11 + + if loadingPlot: + xZero = -xLow*xScale+xLeftOffset + yZero = yTopOffset+plotHeight+yLow*yScale + for point in xCoord: + drawSpace.addElement(svg.line(xZero,yZero,point[0],point[1], "red", 1)) + else: + if connectdot: + pass + #drawSpace.drawPolygon(xCoord,edgeColor=plotColor,closed=0) + else: + pass + + for i, item in enumerate(xCoord): + if dataLabel and dataLabel[i] in specialCases: + drawSpace.addElement(svg.rect(item[0]-3, item[1]-3, 6, 6, "none", "green", 0.5)) + #drawSpace.drawCross(item[0],item[1],color=pid.blue,size=5) + else: + drawSpace.addElement(svg.line(item[0],item[1]+5,item[0],item[1]-5,symbolColor,1)) + drawSpace.addElement(svg.line(item[0]+5,item[1],item[0]-5,item[1],symbolColor,1)) + if showLabel and dataLabel: + pass + drawSpace.addElement(svg.text(item[0], item[1]+14, dataLabel[i], labelFontS, + labelFontF, text_anchor="middle", style="stroke:blue;stroke-width:0.5;")) + #canvas.drawString(, item[0]- canvas.stringWidth(dataLabel[i], + # font=labelFont)/2, item[1]+14, font=labelFont, color=pid.blue) + + #draw scale + #scaleFont=pid.Font(ttf="cour",size=14,bold=1) + x=xLow + for i in range(stepX+1): + xc=xLeftOffset+(x-xLow)*xScale + drawSpace.addElement(svg.line(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, axesColor, 1)) + strX = cformat(d=x, rank=rank) + drawSpace.addElement(svg.text(xc,yTopOffset+plotHeight+20,strX,13, "courier", text_anchor="middle")) + x+= (xTop - xLow)/stepX + + y=yLow + for i in range(stepY+1): + yc=yTopOffset+plotHeight-(y-yLow)*yScale + drawSpace.addElement(svg.line(xLeftOffset,yc,xLeftOffset-5,yc, axesColor, 1)) + strY = cformat(d=y, rank=rank) + drawSpace.addElement(svg.text(xLeftOffset-10,yc+5,strY,13, "courier", text_anchor="end")) + y+= (yTop - yLow)/stepY + + #draw label + labelFontF = "verdana" + labelFontS = 17 + if XLabel: + drawSpace.addElement(svg.text(xLeftOffset+plotWidth/2.0, + yTopOffset+plotHeight+yBottomOffset-10,XLabel, + labelFontS, labelFontF, text_anchor="middle")) + + if YLabel: + drawSpace.addElement(svg.text(xLeftOffset-50, + yTopOffset+plotHeight/2,YLabel, + labelFontS, labelFontF, text_anchor="middle", style="writing-mode:tb-rl", transform="rotate(270 %d %d)" % (xLeftOffset-50, yTopOffset+plotHeight/2))) + #drawSpace.drawString(YLabel, xLeftOffset-50, yTopOffset+plotHeight- (plotHeight-drawSpace.stringWidth(YLabel,font=labelFont))/2.0, + # font=labelFont,color=labelColor,angle=90) + + + if fitcurve: + sys.argv = [ "mod_python" ] + #from numarray import linear_algebra as la + #from numarray import ones, array, dot, swapaxes + fitYY = array(dataYPrimary) + fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) + AA = dot(fitXX,swapaxes(fitXX,0,1)) + BB = dot(fitXX,fitYY) + bb = la.linear_least_squares(AA,BB)[0] + + xc1 = xLeftOffset + yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale + if yc1 > yTopOffset+plotHeight: + yc1 = yTopOffset+plotHeight + xc1 = (yLow-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + elif yc1 < yTopOffset: + yc1 = yTopOffset + xc1 = (yTop-bb[0])/bb[1] + xc1=(xc1-xLow)*xScale+xLeftOffset + else: + pass + + xc2 = xLeftOffset + plotWidth + yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale + if yc2 > yTopOffset+plotHeight: + yc2 = yTopOffset+plotHeight + xc2 = (yLow-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + elif yc2 < yTopOffset: + yc2 = yTopOffset + xc2 = (yTop-bb[0])/bb[1] + xc2=(xc2-xLow)*xScale+xLeftOffset + else: + pass + + drawSpace.addElement(svg.line(xc1,yc1,xc2,yc2,"green", 1)) + + if displayR: + labelFontF = "trebuc" + labelFontS = 14 + NNN = len(dataX) + + corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] + + if NNN < 3: + corrPValue = 1.0 + else: + if abs(corr) >= 1.0: + corrPValue = 0.0 + else: + ZValue = 0.5*log((1.0+corr)/(1.0-corr)) + ZValue = ZValue*sqrt(NNN-3) + corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) + + NStr = "N of Cases=%d" % NNN + + if rank == 1: + corrStr = "Spearman's r=%1.3f P=%3.2E" % (corr, corrPValue) + else: + corrStr = "Pearson's r=%1.3f P=%3.2E" % (corr, corrPValue) + + drawSpace.addElement(svg.text(xLeftOffset,yTopOffset-10,NStr, + labelFontS, labelFontF, text_anchor="start")) + drawSpace.addElement(svg.text(xLeftOffset+plotWidth,yTopOffset-25,corrStr, + labelFontS, labelFontF, text_anchor="end")) + """ + """ + return # This function determines the scale of the plot def detScaleOld(min,max): - if min>=max: - return None - elif min == -1.0 and max == 1.0: - return [-1.2,1.2,12] - else: - a=max-min - b=floor(log10(a)) - c=pow(10.0,b) - if a < c*5.0: - c/=2.0 - #print a,b,c - low=c*floor(min/c) - high=c*ceil(max/c) - return [low,high,round((high-low)/c)] + if min>=max: + return None + elif min == -1.0 and max == 1.0: + return [-1.2,1.2,12] + else: + a=max-min + b=floor(log10(a)) + c=pow(10.0,b) + if a < c*5.0: + c/=2.0 + #print a,b,c + low=c*floor(min/c) + high=c*ceil(max/c) + return [low,high,round((high-low)/c)] def detScale(min=0,max=0,bufferSpace=3): - if min>=max: - return None - elif min == -1.0 and max == 1.0: - return [-1.2,1.2,12] - else: - a=max-min - if max != 0: - max += 0.1*a - if min != 0: - if min > 0 and min < 0.1*a: - min = 0.0 - else: - min -= 0.1*a - a=max-min - b=floor(log10(a)) - c=pow(10.0,b) - low=c*floor(min/c) - high=c*ceil(max/c) - n = round((high-low)/c) - div = 2.0 - while n < 5 or n > 15: - if n < 5: - c /= div - else: - c *= div - if div == 2.0: - div =5.0 - else: - div =2.0 - low=c*floor(min/c) - high=c*ceil(max/c) - n = round((high-low)/c) - - return [low,high,n] + if min>=max: + return None + elif min == -1.0 and max == 1.0: + return [-1.2,1.2,12] + else: + a=max-min + if max != 0: + max += 0.1*a + if min != 0: + if min > 0 and min < 0.1*a: + min = 0.0 + else: + min -= 0.1*a + a=max-min + b=floor(log10(a)) + c=pow(10.0,b) + low=c*floor(min/c) + high=c*ceil(max/c) + n = round((high-low)/c) + div = 2.0 + while n < 5 or n > 15: + if n < 5: + c /= div + else: + c *= div + if div == 2.0: + div =5.0 + else: + div =2.0 + low=c*floor(min/c) + high=c*ceil(max/c) + n = round((high-low)/c) + + return [low,high,n] def colorSpectrumOld(n): - if n == 1: - return [pid.Color(1,0,0)] - elif n == 2: - return [pid.Color(1,0,0),pid.Color(0,0,1)] - elif n == 3: - return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] - else: - step = 2.0/(n-1) - red = 1.0 - green = 0.0 - blue = 0.0 - colors = [pid.Color(red,green,blue)] - i = 1 - greenpeak = 0 - while i < n: - if red >= step: - red -= step - green += step - if green >= 1.0: - greenpeak = 1 - blue += green -1.0 - green = 1.0 - else: - red = 0.0 - if greenpeak: - green -= step - blue += step - else: - green += step - if green >= 1.0: - greenpeak = 1 - blue += green -1.0 - green = 2.0 -green - elif green < 0.0: - green = 0.0 - else: - pass - colors.append(pid.Color(red,green,blue)) - i += 1 - return colors + if n == 1: + return [pid.Color(1,0,0)] + elif n == 2: + return [pid.Color(1,0,0),pid.Color(0,0,1)] + elif n == 3: + return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] + else: + step = 2.0/(n-1) + red = 1.0 + green = 0.0 + blue = 0.0 + colors = [pid.Color(red,green,blue)] + i = 1 + greenpeak = 0 + while i < n: + if red >= step: + red -= step + green += step + if green >= 1.0: + greenpeak = 1 + blue += green -1.0 + green = 1.0 + else: + red = 0.0 + if greenpeak: + green -= step + blue += step + else: + green += step + if green >= 1.0: + greenpeak = 1 + blue += green -1.0 + green = 2.0 -green + elif green < 0.0: + green = 0.0 + else: + pass + colors.append(pid.Color(red,green,blue)) + i += 1 + return colors def bluefunc(x): - return 1.0 / (1.0 + exp(-10*(x-0.6))) + return 1.0 / (1.0 + exp(-10*(x-0.6))) def redfunc(x): - return 1.0 / (1.0 + exp(10*(x-0.5))) + return 1.0 / (1.0 + exp(10*(x-0.5))) def greenfunc(x): - return 1 - pow(redfunc(x+0.2),2) - bluefunc(x-0.3) + return 1 - pow(redfunc(x+0.2),2) - bluefunc(x-0.3) def colorSpectrum(n=100): - multiple = 10 - if n == 1: - return [pid.Color(1,0,0)] - elif n == 2: - return [pid.Color(1,0,0),pid.Color(0,0,1)] - elif n == 3: - return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] - N = n*multiple - out = [None]*N; - for i in range(N): - x = float(i)/N - out[i] = pid.Color(redfunc(x), greenfunc(x), bluefunc(x)); - out2 = [out[0]] - step = N/float(n-1) - j = 0 - for i in range(n-2): - j += step - out2.append(out[int(j)]) - out2.append(out[-1]) - return out2 + multiple = 10 + if n == 1: + return [pid.Color(1,0,0)] + elif n == 2: + return [pid.Color(1,0,0),pid.Color(0,0,1)] + elif n == 3: + return [pid.Color(1,0,0),pid.Color(0,1,0),pid.Color(0,0,1)] + N = n*multiple + out = [None]*N; + for i in range(N): + x = float(i)/N + out[i] = pid.Color(redfunc(x), greenfunc(x), bluefunc(x)); + out2 = [out[0]] + step = N/float(n-1) + j = 0 + for i in range(n-2): + j += step + out2.append(out[int(j)]) + out2.append(out[-1]) + return out2 def colorSpectrumSVG(n=100): - multiple = 10 - if n == 1: - return ["rgb(255,0,0)"] - elif n == 2: - return ["rgb(255,0,0)","rgb(0,0,255)"] - elif n == 3: - return ["rgb(255,0,0)","rgb(0,255,0)","rgb(0,0,255)"] - N = n*multiple - out = [None]*N; - for i in range(N): - x = float(i)/N - out[i] = "rgb(%d, %d, %d)" % (redfunc(x)*255, greenfunc(x)*255, bluefunc(x)*255); - out2 = [out[0]] - step = N/float(n-1) - j = 0 - for i in range(n-2): - j += step - out2.append(out[int(j)]) - out2.append(out[-1]) - return out2 + multiple = 10 + if n == 1: + return ["rgb(255,0,0)"] + elif n == 2: + return ["rgb(255,0,0)","rgb(0,0,255)"] + elif n == 3: + return ["rgb(255,0,0)","rgb(0,255,0)","rgb(0,0,255)"] + N = n*multiple + out = [None]*N; + for i in range(N): + x = float(i)/N + out[i] = "rgb(%d, %d, %d)" % (redfunc(x)*255, greenfunc(x)*255, bluefunc(x)*255); + out2 = [out[0]] + step = N/float(n-1) + j = 0 + for i in range(n-2): + j += step + out2.append(out[int(j)]) + out2.append(out[-1]) + return out2 def BWSpectrum(n=100): - multiple = 10 - if n == 1: - return [pid.Color(0,0,0)] - elif n == 2: - return [pid.Color(0,0,0),pid.Color(1,1,1)] - elif n == 3: - return [pid.Color(0,0,0),pid.Color(0.5,0.5,0.5),pid.Color(1,1,1)] - - step = 1.0/n - x = 0.0 - out = [] - for i in range(n): - out.append(pid.Color(x,x,x)); - x += step - return out + multiple = 10 + if n == 1: + return [pid.Color(0,0,0)] + elif n == 2: + return [pid.Color(0,0,0),pid.Color(1,1,1)] + elif n == 3: + return [pid.Color(0,0,0),pid.Color(0.5,0.5,0.5),pid.Color(1,1,1)] + + step = 1.0/n + x = 0.0 + out = [] + for i in range(n): + out.append(pid.Color(x,x,x)); + x += step + return out diff --git a/wqflask/utility/TDCell.py b/wqflask/utility/TDCell.py index 76b9c5db..8de8e050 100755 --- a/wqflask/utility/TDCell.py +++ b/wqflask/utility/TDCell.py @@ -30,13 +30,12 @@ # ########################################################## - + class TDCell: - def __init__(self, html="", text="", val=0.0): - self.html = html #html, for web page - self.text = text #text value, for output to a text file - self.val = val #sort by value - - def __str__(self): - return self.text + def __init__(self, html="", text="", val=0.0): + self.html = html #html, for web page + self.text = text #text value, for output to a text file + self.val = val #sort by value + def __str__(self): + return self.text diff --git a/wqflask/utility/THCell.py b/wqflask/utility/THCell.py index a96b9e49..dde221b5 100755 --- a/wqflask/utility/THCell.py +++ b/wqflask/utility/THCell.py @@ -32,13 +32,11 @@ class THCell: - def __init__(self, html="", text="", sort=1, idx=-1): - self.html = html #html, for web page - self.text = text #Column text value - self.sort = sort #0: not sortable, 1: yes - self.idx = idx #sort by value - - def __str__(self): - return self.text - + def __init__(self, html="", text="", sort=1, idx=-1): + self.html = html #html, for web page + self.text = text #Column text value + self.sort = sort #0: not sortable, 1: yes + self.idx = idx #sort by value + def __str__(self): + return self.text diff --git a/wqflask/utility/svg.py b/wqflask/utility/svg.py index e49a6c3c..512bc9e6 100755 --- a/wqflask/utility/svg.py +++ b/wqflask/utility/svg.py @@ -74,7 +74,7 @@ by using easy to use classes and methods usualy you start by creating a drawing d.setSVG(s) #and finaly you xmlify the drawing d.toXml() - + this results in the svg source of the drawing, which consists of a circle on a white background. Its as easy as that;) @@ -112,7 +112,7 @@ if sys.version_info[1]<2: True=1 False=0 file=open - + sys.setrecursionlimit=50 #The recursion limit is set conservative so mistakes like s=svg() s.addElement(s) #won't eat up too much processor time. @@ -167,7 +167,7 @@ def _xypointlist(a): def _viewboxlist(a): """formats a tuple""" s='' - for e in a: + for e in a: s+=str(e)+' ' return s @@ -178,7 +178,7 @@ def _pointlist(a): class pathdata: """class used to create a pathdata object which can be used for a path. although most methods are pretty straightforward it might be useful to look at the SVG specification.""" - #I didn't test the methods below. + #I didn't test the methods below. def __init__(self,x=None,y=None): self.path=[] if x is not None and y is not None: @@ -242,10 +242,10 @@ class pathdata: self.path.append('a'+str(rx)+','+str(ry)+' '+str(xrot)+' '+str(laf)+' '+str(sf)+' '+str(x)+' '+str(y)) def __repr__(self): return ' '.join(self.path) - - + + class SVGelement: """SVGelement(type,attributes,elements,text,namespace,**args) Creates a arbitrary svg element and is intended to be subclassed not used on its own. @@ -296,7 +296,7 @@ class SVGelement: if self.cdata: f.write('\n'+'\t'*(level+1)+'\n') if self.text: if type(self.text)==type(''): #If the text is only text @@ -305,13 +305,13 @@ class SVGelement: f.write(str(self.text)) if self.elements: f.write('\t'*level+'\n') - elif self.text: + elif self.text: f.write('\n') elif self.cdata: f.write('\t'*level+'\n') else: f.write('/>\n') - + class tspan(SVGelement): """ts=tspan(text='',**args) @@ -330,12 +330,12 @@ class tspan(SVGelement): def __repr__(self): s="None: self.attributes['stroke-width']=stroke_width - + class ellipse(SVGelement): """e=ellipse(rx,ry,x,y,fill,stroke,stroke_width,**args) @@ -440,8 +440,8 @@ class ellipse(SVGelement): self.attributes['stroke']=stroke if stroke_width<>None: self.attributes['stroke-width']=stroke_width - - + + class circle(SVGelement): """c=circle(x,y,radius,fill,stroke,stroke_width,**args) @@ -464,7 +464,7 @@ class circle(SVGelement): class point(circle): """p=point(x,y,color) - + A point is defined as a circle with a size 1 radius. It may be more efficient to use a very small rectangle if you use many points because a circle is difficult to render. """ @@ -473,7 +473,7 @@ class point(circle): class line(SVGelement): """l=line(x1,y1,x2,y2,stroke,stroke_width,**args) - + A line is defined by a begin x,y pair and an end x,y pair """ def __init__(self,x1=None,y1=None,x2=None,y2=None,stroke=None,stroke_width=None,**args): @@ -490,10 +490,10 @@ class line(SVGelement): self.attributes['stroke-width']=stroke_width if stroke<>None: self.attributes['stroke']=stroke - + class polyline(SVGelement): """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) - + a polyline is defined by a list of xy pairs """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): @@ -507,7 +507,7 @@ class polyline(SVGelement): class polygon(SVGelement): """pl=polyline([[x1,y1],[x2,y2],...],fill,stroke,stroke_width,**args) - + a polygon is defined by a list of xy pairs """ def __init__(self,points,fill=None,stroke=None,stroke_width=None,**args): @@ -534,11 +534,11 @@ class path(SVGelement): self.attributes['stroke-width']=stroke_width if id<>None: self.attributes['id']=id - - + + class text(SVGelement): """t=text(x,y,text,font_size,font_family,**args) - + a text element can bge used for displaying text on the screen """ def __init__(self,x=None,y=None,text=None,font_size=None,font_family=None,text_anchor=None,**args): @@ -560,7 +560,7 @@ class text(SVGelement): class textpath(SVGelement): """tp=textpath(text,link,**args) - a textpath places a text on a path which is referenced by a link. + a textpath places a text on a path which is referenced by a link. """ def __init__(self,link,text=None,**args): SVGelement.__init__(self,'textPath',{'xlink:href':link},**args) @@ -589,7 +589,7 @@ class pattern(SVGelement): class title(SVGelement): """t=title(text,**args) - + a title is a text element. The text is displayed in the title bar add at least one to the root svg element """ @@ -600,7 +600,7 @@ class title(SVGelement): class description(SVGelement): """d=description(text,**args) - + a description can be added to any element and is used for a tooltip Add this element before adding other elements. """ @@ -648,7 +648,7 @@ class radialgradient(SVGelement): self.attributes['fy']=fy if id<>None: self.attributes['id']=id - + class stop(SVGelement): """st=stop(offset,stop_color,**args) @@ -658,7 +658,7 @@ class stop(SVGelement): SVGelement.__init__(self,'stop',{'offset':offset},**args) if stop_color<>None: self.attributes['stop-color']=stop_color - + class style(SVGelement): """st=style(type,cdata=None,**args) @@ -666,8 +666,8 @@ class style(SVGelement): """ def __init__(self,type,cdata=None,**args): SVGelement.__init__(self,'style',{'type':type},cdata=cdata, **args) - - + + class image(SVGelement): """im=image(url,width,height,x,y,**args) @@ -686,7 +686,7 @@ class image(SVGelement): self.attributes['x']=x if y<>None: self.attributes['y']=y - + class cursor(SVGelement): """c=cursor(url,**args) @@ -695,10 +695,10 @@ class cursor(SVGelement): def __init__(self,url,**args): SVGelement.__init__(self,'cursor',{'xlink:href':url},**args) - + class marker(SVGelement): """m=marker(id,viewbox,refX,refY,markerWidth,markerHeight,**args) - + defines a marker which can be used as an endpoint for a line or other pathtypes add an element to it which should be used as a marker. """ @@ -716,10 +716,10 @@ class marker(SVGelement): self.attributes['markerWidth']=markerWidth if markerHeight<>None: self.attributes['markerHeight']=markerHeight - + class group(SVGelement): """g=group(id,**args) - + a group is defined by an id and is used to contain elements g.addElement(SVGelement) """ @@ -736,14 +736,14 @@ class symbol(SVGelement): display it by referencing its id. sy.addElement(SVGelement) """ - + def __init__(self,id=None,viewBox=None,**args): SVGelement.__init__(self,'symbol',**args) if id<>None: self.attributes['id']=id if viewBox<>None: self.attributes['viewBox']=_viewboxlist(viewBox) - + class defs(SVGelement): """d=defs(**args) @@ -762,10 +762,10 @@ class switch(SVGelement): def __init__(self,**args): SVGelement.__init__(self,'switch',**args) - + class use(SVGelement): """u=use(link,x,y,width,height,**args) - + references a symbol by linking to its id and its position, height and width """ def __init__(self,link,x=None,y=None,width=None,height=None,**args): @@ -779,8 +779,8 @@ class use(SVGelement): self.attributes['width']=width if height<>None: self.attributes['height']=height - - + + class link(SVGelement): """a=link(url,**args) @@ -789,7 +789,7 @@ class link(SVGelement): """ def __init__(self,link='',**args): SVGelement.__init__(self,'a',{'xlink:href':link},**args) - + class view(SVGelement): """v=view(id,**args) @@ -807,11 +807,11 @@ class script(SVGelement): """ def __init__(self,type,cdata=None,**args): SVGelement.__init__(self,'script',{'type':type},cdata=cdata,**args) - + class animate(SVGelement): """an=animate(attribute,from,to,during,**args) - animates an attribute. + animates an attribute. """ def __init__(self,attribute,fr=None,to=None,dur=None,**args): SVGelement.__init__(self,'animate',{'attributeName':attribute},**args) @@ -821,7 +821,7 @@ class animate(SVGelement): self.attributes['to']=to if dur<>None: self.attributes['dur']=dur - + class animateMotion(SVGelement): """an=animateMotion(pathdata,dur,**args) @@ -836,7 +836,7 @@ class animateMotion(SVGelement): class animateTransform(SVGelement): """antr=animateTransform(type,from,to,dur,**args) - + transform an element from and to a value. """ def __init__(self,type=None,fr=None,to=None,dur=None,**args): @@ -864,10 +864,10 @@ class animateColor(SVGelement): if to<>None: self.attributes['to']=to if dur<>None: - self.attributes['dur']=dur + self.attributes['dur']=dur class set(SVGelement): """st=set(attribute,to,during,**args) - + sets an attribute to a value for a """ def __init__(self,attribute,to=None,dur=None,**args): @@ -878,10 +878,10 @@ class set(SVGelement): self.attributes['dur']=dur - + class svg(SVGelement): """s=svg(viewbox,width,height,**args) - + a svg or element is the root of a drawing add all elements to a svg element. You can have different svg elements in one svg file s.addElement(SVGelement) @@ -903,7 +903,7 @@ class svg(SVGelement): if height<>None: self.attributes['height']=height self.namespace="http://www.w3.org/2000/svg" - + class drawing: """d=drawing() @@ -921,17 +921,17 @@ class drawing: def setSVG(self,svg): self.svg=svg #Voeg een element toe aan de grafiek toe. - if use_dom_implementation==0: + if use_dom_implementation==0: def toXml(self, filename='',compress=False): import cStringIO xml=cStringIO.StringIO() xml.write("\n") xml.write("\n" % (item, self.entity[item])) - xml.write("]") + xml.write(" [\n") + for item in self.entity.keys(): + xml.write("\n" % (item, self.entity[item])) + xml.write("]") xml.write(">\n") self.svg.toXml(0,xml) if not filename: @@ -964,7 +964,7 @@ class drawing: compresses if filename ends with svgz or if compress is true """ doctype = implementation.createDocumentType('svg',"-//W3C//DTD SVG 1.0//EN""",'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd ') - + global root #root is defined global so it can be used by the appender. Its also possible to use it as an arugument but #that is a bit messy. @@ -1034,12 +1034,12 @@ class drawing: print "SVG well formed" if __name__=='__main__': - + d=drawing() s=svg((0,0,100,100)) r=rect(-100,-100,300,300,'cyan') s.addElement(r) - + t=title('SVGdraw Demo') s.addElement(t) g=group('animations') @@ -1064,6 +1064,5 @@ if __name__=='__main__': c=circle(i,j,1,'red','black',.5) s.addElement(c) d.setSVG(s) - - print d.toXml() + print d.toXml() diff --git a/wqflask/utility/webqtlUtil.py b/wqflask/utility/webqtlUtil.py index 6af7f846..6409e781 100755 --- a/wqflask/utility/webqtlUtil.py +++ b/wqflask/utility/webqtlUtil.py @@ -90,741 +90,741 @@ PROGRESSBAR = HT.Image('/images/waitAnima2.gif', alt='checkblue',align="middle", ######################################### def decodeEscape(str): - a = str - pattern = re.compile('(%[0-9A-Fa-f][0-9A-Fa-f])') - match = pattern.findall(a) - matched = [] - for item in match: - if item not in matched: - a = a.replace(item, '%c' % eval("0x"+item[-2:])) - matched.append(item) - return a - + a = str + pattern = re.compile('(%[0-9A-Fa-f][0-9A-Fa-f])') + match = pattern.findall(a) + matched = [] + for item in match: + if item not in matched: + a = a.replace(item, '%c' % eval("0x"+item[-2:])) + matched.append(item) + return a + def exportData(hddn, tdata, NP = None): - for key in tdata.keys(): - _val, _var, _N = tdata[key].val, tdata[key].var, tdata[key].N - if _val != None: - hddn[key] = _val - if _var != None: - hddn['V'+key] = _var - if NP and _N != None: - hddn['N'+key] = _N - + for key in tdata.keys(): + _val, _var, _N = tdata[key].val, tdata[key].var, tdata[key].N + if _val != None: + hddn[key] = _val + if _var != None: + hddn['V'+key] = _var + if NP and _N != None: + hddn['N'+key] = _N + def genShortStrainName(RISet='', input_strainName=''): - #aliasStrainDict = {'C57BL/6J':'B6','DBA/2J':'D2'} - strainName = input_strainName - if RISet != 'AXBXA': - if RISet == 'BXD300': - this_RISet = 'BXD' - elif RISet == 'BDF2-2005': - this_RISet = 'CASE05_' - else: - this_RISet = RISet - strainName = string.replace(strainName,this_RISet,'') - strainName = string.replace(strainName,'CASE','') - try: - strainName = "%02d" % int(strainName) - except: - pass - else: - strainName = string.replace(strainName,'AXB','A') - strainName = string.replace(strainName,'BXA','B') - try: - strainName = strainName[0] + "%02d" % int(strainName[1:]) - except: - pass - return strainName + #aliasStrainDict = {'C57BL/6J':'B6','DBA/2J':'D2'} + strainName = input_strainName + if RISet != 'AXBXA': + if RISet == 'BXD300': + this_RISet = 'BXD' + elif RISet == 'BDF2-2005': + this_RISet = 'CASE05_' + else: + this_RISet = RISet + strainName = string.replace(strainName,this_RISet,'') + strainName = string.replace(strainName,'CASE','') + try: + strainName = "%02d" % int(strainName) + except: + pass + else: + strainName = string.replace(strainName,'AXB','A') + strainName = string.replace(strainName,'BXA','B') + try: + strainName = strainName[0] + "%02d" % int(strainName[1:]) + except: + pass + return strainName def toInt(in_str): - "Converts an arbitrary string to an unsigned integer" - start = -1 - end = -1 - for i, char in enumerate(in_str): - if char >= '0' and char <= '9': - if start < 0: - start = i - end = i+1 - else: - if start >= 0: - break - if start < end: - return int(in_str[start:end]) - else: - return -1 + "Converts an arbitrary string to an unsigned integer" + start = -1 + end = -1 + for i, char in enumerate(in_str): + if char >= '0' and char <= '9': + if start < 0: + start = i + end = i+1 + else: + if start >= 0: + break + if start < end: + return int(in_str[start:end]) + else: + return -1 def transpose(m): - 'transpose a matrix' - n = len(m) - return [[m[j][i] for i in range(len(m[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m[0]))] + 'transpose a matrix' + n = len(m) + return [[m[j][i] for i in range(len(m[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m[0]))] def asymTranspose(m): - 'transpose a matrix' - t = max(map(len, m)) - n = len(m) - m2 = [["-"]]*n - for i in range(n): - m2[i] = m[i] + [""]*(t- len(m[i])) - return [[m2[j][i] for i in range(len(m2[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m2[0]))] + 'transpose a matrix' + t = max(map(len, m)) + n = len(m) + m2 = [["-"]]*n + for i in range(n): + m2[i] = m[i] + [""]*(t- len(m[i])) + return [[m2[j][i] for i in range(len(m2[0])) for j in range(n)][k*n:k*n+n] for k in range(len(m2[0]))] def genRandStr(prefix = "", length=8, chars=string.letters+string.digits): - from random import choice - _str = prefix[:] - for i in range(length): - _str += choice(chars) - return _str + from random import choice + _str = prefix[:] + for i in range(length): + _str += choice(chars) + return _str def generate_session(): - import sha - return sha.new(str(time.time())).hexdigest() + import sha + return sha.new(str(time.time())).hexdigest() def cvt2Dict(x): - tmp = {} - for key in x.keys(): - tmp[key] = x[key] - return tmp + tmp = {} + for key in x.keys(): + tmp[key] = x[key] + return tmp def dump_session(session_obj, filename): - "It seems mod python can only cPickle most basic data type" - import cPickle - session_file = open(filename, 'wb') - #try: - # pass - #except: - # pass - cPickle.dump(session_obj, session_file) - session_file.close() - + "It seems mod python can only cPickle most basic data type" + import cPickle + session_file = open(filename, 'wb') + #try: + # pass + #except: + # pass + cPickle.dump(session_obj, session_file) + session_file.close() + def StringAsFloat(str): - 'Converts string to float but catches any exception and returns None' - try: - return float(str) - except: - return None - + 'Converts string to float but catches any exception and returns None' + try: + return float(str) + except: + return None + def IntAsFloat(str): - 'Converts string to Int but catches any exception and returns None' - try: - return int(str) - except: - return None - + 'Converts string to Int but catches any exception and returns None' + try: + return int(str) + except: + return None + def FloatAsFloat(flt): - 'Converts float to string but catches any exception and returns None' - try: - return float("%2.3f" % flt) - except: - return None + 'Converts float to string but catches any exception and returns None' + try: + return float("%2.3f" % flt) + except: + return None def RemoveZero(flt): - 'Converts string to float but catches any exception and returns None' - try: - if abs(flt) < 1e-6: - return None - else: - return flt - except: - return None + 'Converts string to float but catches any exception and returns None' + try: + if abs(flt) < 1e-6: + return None + else: + return flt + except: + return None def SciFloat(d): - 'Converts string to float but catches any exception and returns None' + 'Converts string to float but catches any exception and returns None' - try: - if abs(d) <= 1.0e-4: - return "%1.2e" % d - else: - return "%1.5f" % d - except: - return None + try: + if abs(d) <= 1.0e-4: + return "%1.2e" % d + else: + return "%1.5f" % d + except: + return None ###To be removed def FloatList2String(lst): - 'Converts float list to string but catches any exception and returns None' - tt='' - try: - for item in lst: - if item == None: - tt += 'X ' - else: - tt += '%f ' % item - return tt - except: - return "" + 'Converts float list to string but catches any exception and returns None' + tt='' + try: + for item in lst: + if item == None: + tt += 'X ' + else: + tt += '%f ' % item + return tt + except: + return "" def ListNotNull(lst): - 'Determine if the elements in a list are all null' - for item in lst: - if item is not None: - return 1 - return None - + 'Determine if the elements in a list are all null' + for item in lst: + if item is not None: + return 1 + return None + ###To be removed def FileDataProcess(str): - 'Remove the description text from the input file if theres any' - i=0 - while i'\x20': - break - else: - i+=1 - str=str[i:] - str=string.join(string.split(str,'\000'),'') - i=string.find(str,"*****") - if i>-1: - return str[i+5:] - else: - return str + 'Remove the description text from the input file if theres any' + i=0 + while i'\x20': + break + else: + i+=1 + str=str[i:] + str=string.join(string.split(str,'\000'),'') + i=string.find(str,"*****") + if i>-1: + return str[i+5:] + else: + return str def rank(a,lst,offset=0): - """Calculate the integer rank of a number in an array, can be used to calculate p-value""" - n = len(lst) - if n == 2: - if a lst[1]: - return offset + 2 - else: - return offset +1 - elif n == 1: - if a lst[1]: + return offset + 2 + else: + return offset +1 + elif n == 1: + if a B.LRS: - return 1 - elif A.LRS == B.LRS: - return 0 - else: - return -1 - except: - return 0 - - + try: + if A.LRS > B.LRS: + return 1 + elif A.LRS == B.LRS: + return 0 + else: + return -1 + except: + return 0 + + def cmpScanResult2(A,B): - try: - if A.LRS < B.LRS: - return 1 - elif A.LRS == B.LRS: - return 0 - else: - return -1 - except: - return 0 + try: + if A.LRS < B.LRS: + return 1 + elif A.LRS == B.LRS: + return 0 + else: + return -1 + except: + return 0 def cmpOrder(A,B): - try: - if A[1] < B[1]: - return -1 - elif A[1] == B[1]: - return 0 - else: - return 1 - except: - return 0 + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 def cmpOrder2(A,B): - try: - if A[-1] < B[-1]: - return -1 - elif A[-1] == B[-1]: - return 0 - else: - return 1 - except: - return 0 + try: + if A[-1] < B[-1]: + return -1 + elif A[-1] == B[-1]: + return 0 + else: + return 1 + except: + return 0 def calRank(xVals, yVals, N): ### Zach Sloan, February 4 2010 - """ - Returns a ranked set of X and Y values. These are used when generating - a Spearman scatterplot. Bear in mind that this sets values equal to each - other as the same rank. - """ - XX = [] - YY = [] - X = [0]*len(xVals) - Y = [0]*len(yVals) - j = 0 - - for i in range(len(xVals)): - - if xVals[i] != None and yVals[i] != None: - XX.append((j, xVals[i])) - YY.append((j, yVals[i])) - j = j + 1 - - NN = len(XX) - - XX.sort(cmpOrder2) - YY.sort(cmpOrder2) - - j = 1 - rank = 0.0 - - while j < NN: - - if XX[j][1] != XX[j-1][1]: - X[XX[j-1][0]] = j - j = j+1 - - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (XX[jt][1] != XX[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - X[XX[ji][0]] = rank - if (jt == NN-1): - if (XX[jt][1] == XX[j-1][1]): - X[XX[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if X[XX[NN-1][0]] == 0: - X[XX[NN-1][0]] = NN - - j = 1 - rank = 0.0 - - while j < NN: - - if YY[j][1] != YY[j-1][1]: - Y[YY[j-1][0]] = j - j = j+1 - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (YY[jt][1] != YY[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - Y[YY[ji][0]] = rank - if (jt == NN-1): - if (YY[jt][1] == YY[j-1][1]): - Y[YY[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if Y[YY[NN-1][0]] == 0: - Y[YY[NN-1][0]] = NN - - return (X,Y) + """ + Returns a ranked set of X and Y values. These are used when generating + a Spearman scatterplot. Bear in mind that this sets values equal to each + other as the same rank. + """ + XX = [] + YY = [] + X = [0]*len(xVals) + Y = [0]*len(yVals) + j = 0 + + for i in range(len(xVals)): + + if xVals[i] != None and yVals[i] != None: + XX.append((j, xVals[i])) + YY.append((j, yVals[i])) + j = j + 1 + + NN = len(XX) + + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + + j = 1 + rank = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + return (X,Y) def calCorrelationRank(xVals,yVals,N): - """ - Calculated Spearman Ranked Correlation. The algorithm works - by setting all tied ranks to the average of those ranks (for - example, if ranks 5-10 all have the same value, each will be set - to rank 7.5). - """ - - XX = [] - YY = [] - j = 0 - - for i in range(len(xVals)): - if xVals[i]!= None and yVals[i]!= None: - XX.append((j,xVals[i])) - YY.append((j,yVals[i])) - j = j+1 - - NN = len(XX) - if NN <6: - return (0.0,NN) - XX.sort(cmpOrder2) - YY.sort(cmpOrder2) - X = [0]*NN - Y = [0]*NN - - j = 1 - rank = 0.0 - t = 0.0 - sx = 0.0 - - while j < NN: - - if XX[j][1] != XX[j-1][1]: - X[XX[j-1][0]] = j - j = j+1 - - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (XX[jt][1] != XX[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - X[XX[ji][0]] = rank - t = jt-j - sx = sx + (t*t*t-t) - if (jt == NN-1): - if (XX[jt][1] == XX[j-1][1]): - X[XX[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if X[XX[NN-1][0]] == 0: - X[XX[NN-1][0]] = NN - - j = 1 - rank = 0.0 - t = 0.0 - sy = 0.0 - - while j < NN: - - if YY[j][1] != YY[j-1][1]: - Y[YY[j-1][0]] = j - j = j+1 - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (YY[jt][1] != YY[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - Y[YY[ji][0]] = rank - t = jt - j - sy = sy + (t*t*t-t) - if (jt == NN-1): - if (YY[jt][1] == YY[j-1][1]): - Y[YY[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if Y[YY[NN-1][0]] == 0: - Y[YY[NN-1][0]] = NN - - D = 0.0 - - for i in range(NN): - D += (X[i]-Y[i])*(X[i]-Y[i]) - - fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) - - return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) - - + """ + Calculated Spearman Ranked Correlation. The algorithm works + by setting all tied ranks to the average of those ranks (for + example, if ranks 5-10 all have the same value, each will be set + to rank 7.5). + """ + + XX = [] + YY = [] + j = 0 + + for i in range(len(xVals)): + if xVals[i]!= None and yVals[i]!= None: + XX.append((j,xVals[i])) + YY.append((j,yVals[i])) + j = j+1 + + NN = len(XX) + if NN <6: + return (0.0,NN) + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + X = [0]*NN + Y = [0]*NN + + j = 1 + rank = 0.0 + t = 0.0 + sx = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + t = jt-j + sx = sx + (t*t*t-t) + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + t = 0.0 + sy = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + t = jt - j + sy = sy + (t*t*t-t) + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + D = 0.0 + + for i in range(NN): + D += (X[i]-Y[i])*(X[i]-Y[i]) + + fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) + + return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) + + def calCorrelationRankText(dbdata,userdata,N): ### dcrowell = David Crowell, July 2008 - """Calculates correlation ranks with data formatted from the text file. - dbdata, userdata are lists of strings. N is an int. Returns a float. - Used by correlationPage""" - XX = [] - YY = [] - j = 0 - for i in range(N): - if (dbdata[i]!= None and userdata[i]!=None) and (dbdata[i]!= 'None' and userdata[i]!='None'): - XX.append((j,float(dbdata[i]))) - YY.append((j,float(userdata[i]))) - j += 1 - NN = len(XX) - if NN <6: - return (0.0,NN) - XX.sort(cmpOrder2) - YY.sort(cmpOrder2) - X = [0]*NN - Y = [0]*NN - - j = 1 - rank = 0.0 - t = 0.0 - sx = 0.0 - - while j < NN: - - if XX[j][1] != XX[j-1][1]: - X[XX[j-1][0]] = j - j = j+1 - - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (XX[jt][1] != XX[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - X[XX[ji][0]] = rank - t = jt-j - sx = sx + (t*t*t-t) - if (jt == NN-1): - if (XX[jt][1] == XX[j-1][1]): - X[XX[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if X[XX[NN-1][0]] == 0: - X[XX[NN-1][0]] = NN - - j = 1 - rank = 0.0 - t = 0.0 - sy = 0.0 - - while j < NN: - - if YY[j][1] != YY[j-1][1]: - Y[YY[j-1][0]] = j - j = j+1 - else: - jt = j+1 - ji = j - for jt in range(j+1, NN): - if (YY[jt][1] != YY[j-1][1]): - break - rank = 0.5*(j+jt) - for ji in range(j-1, jt): - Y[YY[ji][0]] = rank - t = jt - j - sy = sy + (t*t*t-t) - if (jt == NN-1): - if (YY[jt][1] == YY[j-1][1]): - Y[YY[NN-1][0]] = rank - j = jt+1 - - if j == NN: - if Y[YY[NN-1][0]] == 0: - Y[YY[NN-1][0]] = NN - - D = 0.0 - - for i in range(NN): - D += (X[i]-Y[i])*(X[i]-Y[i]) - - fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) - - return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) + """Calculates correlation ranks with data formatted from the text file. + dbdata, userdata are lists of strings. N is an int. Returns a float. + Used by correlationPage""" + XX = [] + YY = [] + j = 0 + for i in range(N): + if (dbdata[i]!= None and userdata[i]!=None) and (dbdata[i]!= 'None' and userdata[i]!='None'): + XX.append((j,float(dbdata[i]))) + YY.append((j,float(userdata[i]))) + j += 1 + NN = len(XX) + if NN <6: + return (0.0,NN) + XX.sort(cmpOrder2) + YY.sort(cmpOrder2) + X = [0]*NN + Y = [0]*NN + + j = 1 + rank = 0.0 + t = 0.0 + sx = 0.0 + + while j < NN: + + if XX[j][1] != XX[j-1][1]: + X[XX[j-1][0]] = j + j = j+1 + + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (XX[jt][1] != XX[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + X[XX[ji][0]] = rank + t = jt-j + sx = sx + (t*t*t-t) + if (jt == NN-1): + if (XX[jt][1] == XX[j-1][1]): + X[XX[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if X[XX[NN-1][0]] == 0: + X[XX[NN-1][0]] = NN + + j = 1 + rank = 0.0 + t = 0.0 + sy = 0.0 + + while j < NN: + + if YY[j][1] != YY[j-1][1]: + Y[YY[j-1][0]] = j + j = j+1 + else: + jt = j+1 + ji = j + for jt in range(j+1, NN): + if (YY[jt][1] != YY[j-1][1]): + break + rank = 0.5*(j+jt) + for ji in range(j-1, jt): + Y[YY[ji][0]] = rank + t = jt - j + sy = sy + (t*t*t-t) + if (jt == NN-1): + if (YY[jt][1] == YY[j-1][1]): + Y[YY[NN-1][0]] = rank + j = jt+1 + + if j == NN: + if Y[YY[NN-1][0]] == 0: + Y[YY[NN-1][0]] = NN + + D = 0.0 + + for i in range(NN): + D += (X[i]-Y[i])*(X[i]-Y[i]) + + fac = (1.0 -sx/(NN*NN*NN-NN))*(1.0-sy/(NN*NN*NN-NN)) + + return ((1-(6.0/(NN*NN*NN-NN))*(D+(sx+sy)/12.0))/math.sqrt(fac),NN) def calCorrelation(dbdata,userdata,N): - X = [] - Y = [] - for i in range(N): - if dbdata[i]!= None and userdata[i]!= None: - X.append(dbdata[i]) - Y.append(userdata[i]) - NN = len(X) - if NN <6: - return (0.0,NN) - sx = reduce(lambda x,y:x+y,X,0.0) - sy = reduce(lambda x,y:x+y,Y,0.0) - meanx = sx/NN - meany = sy/NN - xyd = 0.0 - sxd = 0.0 - syd = 0.0 - for i in range(NN): - xyd += (X[i] - meanx)*(Y[i]-meany) - sxd += (X[i] - meanx)*(X[i] - meanx) - syd += (Y[i] - meany)*(Y[i] - meany) - try: - corr = xyd/(sqrt(sxd)*sqrt(syd)) - except: - corr = 0 - return (corr,NN) + X = [] + Y = [] + for i in range(N): + if dbdata[i]!= None and userdata[i]!= None: + X.append(dbdata[i]) + Y.append(userdata[i]) + NN = len(X) + if NN <6: + return (0.0,NN) + sx = reduce(lambda x,y:x+y,X,0.0) + sy = reduce(lambda x,y:x+y,Y,0.0) + meanx = sx/NN + meany = sy/NN + xyd = 0.0 + sxd = 0.0 + syd = 0.0 + for i in range(NN): + xyd += (X[i] - meanx)*(Y[i]-meany) + sxd += (X[i] - meanx)*(X[i] - meanx) + syd += (Y[i] - meany)*(Y[i] - meany) + try: + corr = xyd/(sqrt(sxd)*sqrt(syd)) + except: + corr = 0 + return (corr,NN) def calCorrelationText(dbdata,userdata,N): ### dcrowell July 2008 - """Calculates correlation coefficients with values formatted from text files. dbdata, userdata are lists of strings. N is an int. Returns a float - Used by correlationPage""" - X = [] - Y = [] - for i in range(N): - #if (dbdata[i]!= None and userdata[i]!= None) and (dbdata[i]!= 'None' and userdata[i]!= 'None'): - # X.append(float(dbdata[i])) - # Y.append(float(userdata[i])) - if dbdata[i] == None or dbdata[i] == 'None' or userdata[i] == None or userdata[i] == 'None': - continue - else: - X.append(float(dbdata[i])) - Y.append(float(userdata[i])) - NN = len(X) - if NN <6: - return (0.0,NN) - sx = sum(X) - sy = sum(Y) - meanx = sx/float(NN) - meany = sy/float(NN) - xyd = 0.0 - sxd = 0.0 - syd = 0.0 - for i in range(NN): - x1 = X[i]-meanx - y1 = Y[i]-meany - xyd += x1*y1 - sxd += x1**2 - syd += y1**2 - try: - corr = xyd/(sqrt(sxd)*sqrt(syd)) - except: - corr = 0 - return (corr,NN) + """Calculates correlation coefficients with values formatted from text files. dbdata, userdata are lists of strings. N is an int. Returns a float + Used by correlationPage""" + X = [] + Y = [] + for i in range(N): + #if (dbdata[i]!= None and userdata[i]!= None) and (dbdata[i]!= 'None' and userdata[i]!= 'None'): + # X.append(float(dbdata[i])) + # Y.append(float(userdata[i])) + if dbdata[i] == None or dbdata[i] == 'None' or userdata[i] == None or userdata[i] == 'None': + continue + else: + X.append(float(dbdata[i])) + Y.append(float(userdata[i])) + NN = len(X) + if NN <6: + return (0.0,NN) + sx = sum(X) + sy = sum(Y) + meanx = sx/float(NN) + meany = sy/float(NN) + xyd = 0.0 + sxd = 0.0 + syd = 0.0 + for i in range(NN): + x1 = X[i]-meanx + y1 = Y[i]-meany + xyd += x1*y1 + sxd += x1**2 + syd += y1**2 + try: + corr = xyd/(sqrt(sxd)*sqrt(syd)) + except: + corr = 0 + return (corr,NN) def readLineCSV(line): ### dcrowell July 2008 - """Parses a CSV string of text and returns a list containing each element as a string. - Used by correlationPage""" - returnList = line.split('","') - returnList[-1]=returnList[-1][:-2] - returnList[0]=returnList[0][1:] - return returnList + """Parses a CSV string of text and returns a list containing each element as a string. + Used by correlationPage""" + returnList = line.split('","') + returnList[-1]=returnList[-1][:-2] + returnList[0]=returnList[0][1:] + return returnList def cmpCorr(A,B): - try: - if abs(A[1]) < abs(B[1]): - return 1 - elif abs(A[1]) == abs(B[1]): - return 0 - else: - return -1 - except: - return 0 + try: + if abs(A[1]) < abs(B[1]): + return 1 + elif abs(A[1]) == abs(B[1]): + return 0 + else: + return -1 + except: + return 0 def cmpLitCorr(A,B): - try: - if abs(A[3]) < abs(B[3]): return 1 - elif abs(A[3]) == abs(B[3]): - if abs(A[1]) < abs(B[1]): return 1 - elif abs(A[1]) == abs(B[1]): return 0 - else: return -1 - else: return -1 - except: - return 0 + try: + if abs(A[3]) < abs(B[3]): return 1 + elif abs(A[3]) == abs(B[3]): + if abs(A[1]) < abs(B[1]): return 1 + elif abs(A[1]) == abs(B[1]): return 0 + else: return -1 + else: return -1 + except: + return 0 def cmpPValue(A,B): - try: - if A.corrPValue < B.corrPValue: - return -1 - elif A.corrPValue == B.corrPValue: - if abs(A.corr) > abs(B.corr): - return -1 - elif abs(A.corr) < abs(B.corr): - return 1 - else: - return 0 - else: - return 1 - except: - return 0 + try: + if A.corrPValue < B.corrPValue: + return -1 + elif A.corrPValue == B.corrPValue: + if abs(A.corr) > abs(B.corr): + return -1 + elif abs(A.corr) < abs(B.corr): + return 1 + else: + return 0 + else: + return 1 + except: + return 0 def cmpEigenValue(A,B): - try: - if A[0] > B[0]: - return -1 - elif A[0] == B[0]: - return 0 - else: - return 1 - except: - return 0 + try: + if A[0] > B[0]: + return -1 + elif A[0] == B[0]: + return 0 + else: + return 1 + except: + return 0 def cmpLRSFull(A,B): - try: - if A[0] < B[0]: - return -1 - elif A[0] == B[0]: - return 0 - else: - return 1 - except: - return 0 + try: + if A[0] < B[0]: + return -1 + elif A[0] == B[0]: + return 0 + else: + return 1 + except: + return 0 def cmpLRSInteract(A,B): - try: - if A[1] < B[1]: - return -1 - elif A[1] == B[1]: - return 0 - else: - return 1 - except: - return 0 - - + try: + if A[1] < B[1]: + return -1 + elif A[1] == B[1]: + return 0 + else: + return 1 + except: + return 0 + + def cmpPos(A,B): - try: - try: - AChr = int(A.chr) - except: - AChr = 20 - try: - BChr = int(B.chr) - except: - BChr = 20 - if AChr > BChr: - return 1 - elif AChr == BChr: - if A.mb > B.mb: - return 1 - if A.mb == B.mb: - return 0 - else: - return -1 - else: - return -1 - except: - return 0 - + try: + try: + AChr = int(A.chr) + except: + AChr = 20 + try: + BChr = int(B.chr) + except: + BChr = 20 + if AChr > BChr: + return 1 + elif AChr == BChr: + if A.mb > B.mb: + return 1 + if A.mb == B.mb: + return 0 + else: + return -1 + else: + return -1 + except: + return 0 + def cmpGenoPos(A,B): - try: - A1 = A.chr - B1 = B.chr - try: - A1 = int(A1) - except: - A1 = 25 - try: - B1 = int(B1) - except: - B1 = 25 - if A1 > B1: - return 1 - elif A1 == B1: - if A.mb > B.mb: - return 1 - if A.mb == B.mb: - return 0 - else: - return -1 - else: - return -1 - except: - return 0 + try: + A1 = A.chr + B1 = B.chr + try: + A1 = int(A1) + except: + A1 = 25 + try: + B1 = int(B1) + except: + B1 = 25 + if A1 > B1: + return 1 + elif A1 == B1: + if A.mb > B.mb: + return 1 + if A.mb == B.mb: + return 0 + else: + return -1 + else: + return -1 + except: + return 0 #XZhou: Must use "BINARY" to enable case sensitive comparison. def authUser(name,password,db, encrypt=None): - try: - if encrypt: - query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY \'%s\'' % (name,password) - else: - query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY SHA(\'%s\')' % (name,password) - db.execute(query) - records = db.fetchone() - if not records: - raise ValueError - return records#(privilege,id,name,password,grpName) - except: - return (None, None, None, None, None) + try: + if encrypt: + query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY \'%s\'' % (name,password) + else: + query = 'SELECT privilege, id,name,password, grpName FROM User WHERE name= BINARY \'%s\' and password= BINARY SHA(\'%s\')' % (name,password) + db.execute(query) + records = db.fetchone() + if not records: + raise ValueError + return records#(privilege,id,name,password,grpName) + except: + return (None, None, None, None, None) def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users): @@ -840,9 +840,9 @@ def hasAccessToConfidentialPhenotypeTrait(privilege, userName, authorized_users) class VisualizeException(Exception): def __init__(self, message): - self.message = message + self.message = message def __str__(self): - return self.message + return self.message # safeConvert : (string -> A) -> A -> A # to convert a string to type A, using the supplied default value @@ -852,12 +852,12 @@ def safeConvert(f, value, default): return f(value) except: return default - + # safeFloat : string -> float -> float # to convert a string to a float safely def safeFloat(value, default): return safeConvert(float, value, default) - + # safeInt: string -> int -> int # to convert a string to an int safely def safeInt(value, default): @@ -878,7 +878,7 @@ def yesNoToInt(value): if value == "yes": return 1 elif value == "no": - return 0 + return 0 else: return None @@ -890,79 +890,79 @@ def intToYesNo(value): elif value == 0: return "no" else: - return None - + return None + def formatField(name): - name = name.replace("_", " ") - name = name.title() - #name = name.replace("Mb Mm6", "Mb"); - return name.replace("Id", "ID") + name = name.replace("_", " ") + name = name.title() + #name = name.replace("Mb Mm6", "Mb"); + return name.replace("Id", "ID") #XZ, 03/27/2009: This function is very specific. #It is used by AJAX_table.py, correlationPage.py and dataPage.py def genTableObj(tblobj=None, file="", sortby = ("", ""), tableID = "sortable", addIndex = "1", hiddenColumns=[]): - header = tblobj['header'] - body = tblobj['body'] - field, order = sortby - - #ZAS 9/12/2011 - The hiddenColumns array needs to be converted into a string so they can be placed into the javascript of each up/down button - hiddenColumnsString = ",".join(hiddenColumns) - - tbl = HT.TableLite(Class="collap b2", cellspacing=1, cellpadding=5) - - hiddenColumnIdx = [] #indices of columns to hide - idx = -1 - last_idx = 0 #ZS: This is the index of the last item in the regular table header (without any extra parameters). It is used to determine the index of each extra parameter. - for row in header: - hr = HT.TR() - for i, item in enumerate(row): - if (item.text == '') or (item.text not in hiddenColumns): - if item.sort and item.text: - down = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=down&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGDESC) - up = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=up&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGASC) - if item.text == field: - idx = item.idx - last_idx = idx - if order == 'up': - up = IMGASCON - elif order == 'down': - down = IMGDESCON - item.html.append(HT.Div(up, down, style="float: bottom;")) - hr.append(item.html) - else: - hiddenColumnIdx.append(i) - tbl.append(hr) - - for i, row in enumerate(body): - for j, item in enumerate(row): - if order == 'down': - if (item.val == '' or item.val == 'x' or item.val == 'None'): - item.val = 0 - if order == 'up': - if (item.val == '' or item.val == 'x' or item.val == 'None'): - item.val = 'zzzzz' - - if idx >= 0: - if order == 'down': - body.sort(lambda A, B: cmp(B[idx].val, A[idx].val), key=natsort_key) - elif order == 'up': - body.sort(lambda A, B: cmp(A[idx].val, B[idx].val), key=natsort_key) - else: - pass - - for i, row in enumerate(body): - hr = HT.TR(Id = row[0].text) - for j, item in enumerate(row): - if (j not in hiddenColumnIdx): - if j == 0: - if addIndex == "1": - item.html.contents = [i+1] + item.html.contents - hr.append(item.html) - tbl.append(hr) - - return tbl + header = tblobj['header'] + body = tblobj['body'] + field, order = sortby + + #ZAS 9/12/2011 - The hiddenColumns array needs to be converted into a string so they can be placed into the javascript of each up/down button + hiddenColumnsString = ",".join(hiddenColumns) + + tbl = HT.TableLite(Class="collap b2", cellspacing=1, cellpadding=5) + + hiddenColumnIdx = [] #indices of columns to hide + idx = -1 + last_idx = 0 #ZS: This is the index of the last item in the regular table header (without any extra parameters). It is used to determine the index of each extra parameter. + for row in header: + hr = HT.TR() + for i, item in enumerate(row): + if (item.text == '') or (item.text not in hiddenColumns): + if item.sort and item.text: + down = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=down&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGDESC) + up = HT.Href("javascript:xmlhttpPost('%smain.py?FormID=AJAX_table', '%s', 'sort=%s&order=up&file=%s&tableID=%s&addIndex=%s&hiddenColumns=%s')" % (webqtlConfig.CGIDIR, tableID, item.text, file, tableID, addIndex, hiddenColumnsString),IMGASC) + if item.text == field: + idx = item.idx + last_idx = idx + if order == 'up': + up = IMGASCON + elif order == 'down': + down = IMGDESCON + item.html.append(HT.Div(up, down, style="float: bottom;")) + hr.append(item.html) + else: + hiddenColumnIdx.append(i) + tbl.append(hr) + + for i, row in enumerate(body): + for j, item in enumerate(row): + if order == 'down': + if (item.val == '' or item.val == 'x' or item.val == 'None'): + item.val = 0 + if order == 'up': + if (item.val == '' or item.val == 'x' or item.val == 'None'): + item.val = 'zzzzz' + + if idx >= 0: + if order == 'down': + body.sort(lambda A, B: cmp(B[idx].val, A[idx].val), key=natsort_key) + elif order == 'up': + body.sort(lambda A, B: cmp(A[idx].val, B[idx].val), key=natsort_key) + else: + pass + + for i, row in enumerate(body): + hr = HT.TR(Id = row[0].text) + for j, item in enumerate(row): + if (j not in hiddenColumnIdx): + if j == 0: + if addIndex == "1": + item.html.contents = [i+1] + item.html.contents + hr.append(item.html) + tbl.append(hr) + + return tbl def natsort_key(string): r = [] @@ -974,4 +974,3 @@ def natsort_key(string): except: r.append(c) return r - diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index b50428fc..6d709012 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -18,1908 +18,1908 @@ from basicStatistics import BasicStatisticsFunctions ######################################### class DataEditingPage(templatePage): - def __init__(self, fd, thisTrait=None): - - templatePage.__init__(self, fd) - - self.dict['title'] = 'Data Editing' - TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") - - if not self.openMysql(): - return - if not fd.genotype: - fd.readData(incf1=1) - - ############################# - # determine data editing page format - ############################# - varianceDataPage = 0 - if fd.formID == 'varianceChoice': - varianceDataPage = 1 - - if varianceDataPage: - fmID='dataEditing' - nCols = 6 - else: - if fd.enablevariance: - fmID='pre_dataEditing' - nCols = 4 - else: - fmID='dataEditing' - nCols = 4 - - ############################# - ## titles, etc. - ############################# - - #titleTop = HT.Div() - # - #title1 = HT.Paragraph("  Details and Links", style="border-radius: 5px;", Id="title1", Class="sectionheader") - #title1Body = HT.Paragraph(Id="sectionbody1") - # - #if fd.enablevariance and not varianceDataPage: - # title2 = HT.Paragraph("  Submit Variance", style="border-radius: 5px;", Id="title2", Class="sectionheader") - #else: - # title2 = HT.Paragraph("  Basic Statistics", style="border-radius: 5px;", Id="title2", Class="sectionheader") - #title2Body = HT.Paragraph(Id="sectionbody2") - # - #title3 = HT.Paragraph("  Calculate Correlations", style="border-radius: 5px;", Id="title3", Class="sectionheader") - #title3Body = HT.Paragraph(Id="sectionbody3") - # - #title4 = HT.Paragraph("  Mapping Tools", style="border-radius: 5px;", Id="title4", Class="sectionheader") - #title4Body = HT.Paragraph(Id="sectionbody4") - # - #title5 = HT.Paragraph("  Review and Edit Data", style="border-radius: 5px;", Id="title5", Class="sectionheader") - #title5Body = HT.Paragraph(Id="sectionbody5") - - ############################# - ## Hidden field - ############################# - - # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery - hddn = { - 'FormID':fmID, - 'RISet':fd.RISet, - 'submitID':'', - 'scale':'physic', - 'additiveCheck':'ON', - 'showSNP':'ON', - 'showGenes':'ON', - 'method':None, - 'parentsf14regression':'OFF', - 'stats_method':'1', - 'chromosomes':'-1', - 'topten':'', - 'viewLegend':'ON', - 'intervalAnalystCheck':'ON', - 'valsHidden':'OFF', - 'database':'', - 'criteria':None, - 'MDPChoice':None, - 'bootCheck':None, - 'permCheck':None, - 'applyVarianceSE':None, - 'strainNames':'_', - 'strainVals':'_', - 'strainVars':'_', - 'otherStrainNames':'_', - 'otherStrainVals':'_', - 'otherStrainVars':'_', - 'extra_attributes':'_', - 'other_extra_attributes':'_' - } - - if fd.enablevariance: - hddn['enablevariance']='ON' - if fd.incparentsf1: - hddn['incparentsf1']='ON' - - if thisTrait: - hddn['fullname'] = str(thisTrait) - try: - hddn['normalPlotTitle'] = thisTrait.symbol - hddn['normalPlotTitle'] += ": " - hddn['normalPlotTitle'] += thisTrait.name - except: - hddn['normalPlotTitle'] = str(thisTrait.name) - hddn['fromDataEditingPage'] = 1 - if thisTrait.db and thisTrait.db.type and thisTrait.db.type == 'ProbeSet': - hddn['trait_type'] = thisTrait.db.type - if thisTrait.cellid: - hddn['cellid'] = thisTrait.cellid - else: - self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % thisTrait.mysqlid) - heritability = self.cursor.fetchone() - hddn['heritability'] = heritability - - hddn['attribute_names'] = "" - - hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, groupName=fd.RISet) - - ############################# - ## Display Trait Information - ############################# - - #headSpan = self.dispHeader(fd,thisTrait) #Draw header - # - #titleTop.append(headSpan) - - if fd.identification: - hddn['identification'] = fd.identification - - else: - hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named - - self.dispTraitInformation(fd, "", hddn, thisTrait) #Display trait information + function buttons - - ############################# - ## Generate form and buttons - ############################# - - mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), - name='dataInput', submit=HT.Input(type='hidden')) - - next=HT.Input(type='submit', name='submit',value='Next',Class="button") - reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") - correlationMenus = [] - - if thisTrait == None: - thisTrait = webqtlTrait(data=fd.allTraitData, db=None) - - # Variance submit page only - if fd.enablevariance and not varianceDataPage: - title2Body.append("Click the next button to go to the variance submission form.", - HT.Center(next,reset)) - else: - self.dispBasicStatistics(fd, title2Body, thisTrait) - self.dispCorrelationTools(fd, title3Body, thisTrait) - self.dispMappingTools(fd, title4Body, thisTrait) - - ############################# - ## Trait Value Table - ############################# - - self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) - - if fd.allstrainlist: - hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') - for key in hddn.keys(): - mainForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) - - if fd.enablevariance and not varianceDataPage: - #pre dataediting page, need to submit variance - mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) - else: - mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) - TD_LR.append(HT.Paragraph(mainForm)) - self.dict['body'] = str(TD_LR) - - ########################################## - ## Function to display header - ########################################## - def dispHeader(self, fd, thisTrait): - headSpan = HT.Div(style="font-size:14px;") - - #If trait, use trait name; otherwise, use identification value - if thisTrait: - if thisTrait.cellid: - headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Probe ID ', thisTrait.cellid) - else: - headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Record ID ', thisTrait.name) - else: - if fd.identification: - headSpan.append(HT.Strong('Trait ID ', style='font-size:16px;'),fd.identification) - else: - headSpan.append(HT.Strong('Un-named Trait', style='font-size:16px;')) - - return headSpan - - ########################################## - ## Function to display trait infos - ########################################## - def dispTraitInformation(self, fd, title1Body, hddn, thisTrait): - - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) - - #tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") - - #reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") - - #XZ, August 02, 2011: The display of icons is decided by the trait type (if trait exists), along with user log-in status. Note that the new submitted trait might not be trait object. - addSelectionButton = "" - verifyButton = "" - rnaseqButton = "" - geneWikiButton = "" - probeButton = "" - similarButton = "" - snpBrowserButton = "" - updateButton = "" - - addSelectionText = "" - verifyText = "" - rnaseqText = "" - geneWikiText = "" - probeText = "" - similarText = "" - snpBrowserText = "" - updateText = "" - - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: - - if thisTrait==None or thisTrait.db.type=='Temp': - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - elif thisTrait.db.type != 'Temp': - if thisTrait.db.type == 'Publish' and thisTrait.confidential: #XZ: confidential phenotype trait - if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - else: - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - else: - pass - - self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.RISet) - if thisTrait: - addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, 'dataInput')) - addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") - #addSelectionButton.append(addSelectionButton_img) - addSelectionText = "Add" - elif self.cursor.fetchall(): - addSelectionButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('%s')[0], 'addRecord');" % ('dataInput')) - addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="", alt="Add To Collection", title="Add To Collection", style="border:none;") - #addSelectionButton.append(addSelectionButton_img) - addSelectionText = "Add" - else: - pass - - - # Microarray database information to display - if thisTrait and thisTrait.db and thisTrait.db.type == 'ProbeSet': #before, this line was only reached if thisTrait != 0, but now we need to check - try: - hddn['GeneId'] = int(string.strip(thisTrait.geneid)) - except: - pass - - #Info2Disp = HT.Paragraph() - - #XZ: Gene Symbol - if thisTrait.symbol: - #XZ: Show SNP Browser only for mouse - if _Species == 'mouse': - self.cursor.execute("select geneSymbol from GeneList where geneSymbol = %s", thisTrait.symbol) - geneName = self.cursor.fetchone() - if geneName: - snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + "&geneName=%s" % geneName[0] - else: - if thisTrait.chr and thisTrait.mb: - snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + \ - "&chr=%s&start=%2.6f&end=%2.6f" % (thisTrait.chr, thisTrait.mb-0.002, thisTrait.mb+0.002) - else: - snpurl = "" - - if snpurl: - snpBrowserButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % snpurl) - snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="snpbrowser", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") - snpBrowserButton.append(snpBrowserButton_img) - snpBrowserText = "SNPs" - - #XZ: Show GeneWiki for all species - geneWikiButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % thisTrait.symbol)) - geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="genewiki", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") - geneWikiButton.append(geneWikiButton_img) - geneWikiText = 'GeneWiki' - - #XZ: display similar traits in other selected datasets - if thisTrait and thisTrait.db and thisTrait.db.type=="ProbeSet" and thisTrait.symbol: - if _Species in ("mouse", "rat", "human"): - similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) - similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) - similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") - similarButton.append(similarButton_img) - similarText = "Find" - else: - pass - tbl.append(HT.TR( - HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span('%s' % thisTrait.symbol, valign="top", Class="fs13 fsI"), valign="top", width=740) - )) - else: - tbl.append(HT.TR( - HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span('Not available', Class="fs13 fsI"), valign="top") - )) - - #XZ: Gene Alias - if thisTrait.alias: - alias = string.replace(thisTrait.alias, ";", " ") - alias = string.join(string.split(alias), ", ") - tbl.append(HT.TR( - HT.TD('Aliases: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(alias, Class="fs13 fsI"), valign="top") - )) - - #XZ: Description - if thisTrait.description: - tSpan = HT.Span(thisTrait.description, Class="fs13") - if thisTrait.probe_target_description: - tSpan.append('; ', thisTrait.probe_target_description) - else: - tSpan = HT.Span('Not available', Class="fs13") - tbl.append(HT.TR( - HT.TD('Description: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - #XZ: Location - - #XZ: deal with Chr and Mb - if thisTrait.chr and thisTrait.mb: - tSpan = HT.Span('Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb),Class="fs13") - elif (thisTrait.chr): - tSpan = HT.Span('Chr %s @ Unknown position' % (thisTrait.chr), Class="fs13") - else: - tSpan = HT.Span('Not available', Class="fs13") - - #XZ: deal with direction - if thisTrait.strand_probe == '+': - tSpan.append(' on the plus strand ') - elif thisTrait.strand_probe == '-': - tSpan.append(' on the minus strand ') - else: - pass - - tbl.append(HT.TR( - HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - ##display Verify Location button - try: - blatsequence = thisTrait.blatseq - if not blatsequence: - #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. - self.cursor.execute("""SELECT Probe.Sequence, Probe.Name - FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) - seqs = self.cursor.fetchall() - if not seqs: - raise ValueError - else: - blatsequence = '' - for seqt in seqs: - if int(seqt[1][-1]) % 2 == 1: - blatsequence += string.strip(seqt[0]) - - #--------Hongqiang add this part in order to not only blat ProbeSet, but also blat Probe - blatsequence = '%3E'+thisTrait.name+'%0A'+blatsequence+'%0A' - #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. - self.cursor.execute("""SELECT Probe.Sequence, Probe.Name - FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) - - seqs = self.cursor.fetchall() - for seqt in seqs: - if int(seqt[1][-1]) %2 == 1: - blatsequence += '%3EProbe_'+string.strip(seqt[1])+'%0A'+string.strip(seqt[0])+'%0A' - #-------- - #XZ, 07/16/2009: targetsequence is not used, so I comment out this block - #targetsequence = thisTrait.targetseq - #if targetsequence==None: - # targetsequence = "" - - #XZ: Pay attention to the parameter of version (rn, mm, hg). They need to be changed if necessary. - if _Species == "rat": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', blatsequence) - UTHSC_BLAT_URL = "" - elif _Species == "mouse": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', blatsequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', blatsequence) - elif _Species == "human": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) - UTHSC_BLAT_URL = "" - else: - UCSC_BLAT_URL = "" - UTHSC_BLAT_URL = "" - - if UCSC_BLAT_URL: - verifyButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL) - verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", - title=" Check probe locations at UCSC ", style="border:none;") - verifyButton.append(verifyButtonImg) - verifyText = 'Verify' - if UTHSC_BLAT_URL: - rnaseqButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL) - rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", - title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") - rnaseqButton.append(rnaseqButtonImg) - rnaseqText = 'RNA-seq' - tSpan.append(HT.BR()) - except: - pass - - #Display probe information (if any) - if thisTrait.db.name.find('Liver') >= 0 and thisTrait.db.name.find('F2') < 0: - pass - else: - #query database for number of probes associated with trait; if count > 0, set probe tool button and text - self.cursor.execute("""SELECT count(*) - FROM Probe, ProbeSet - WHERE ProbeSet.Name = '%s' AND Probe.ProbeSetId = ProbeSet.Id""" % (thisTrait.name)) - - probeResult = self.cursor.fetchone() - if probeResult[0] > 0: - probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&RISet=%s&incparentsf1=ON" \ - % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.db, thisTrait.name, thisTrait.cellid, fd.RISet) - probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) - probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") - probeButton.append(probeButton_img) - probeText = "Probes" - - tSpan = HT.Span(Class="fs13") - - #XZ: deal with blat score and blat specificity. - if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: - if thisTrait.probe_set_specificity: - tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) - if thisTrait.probe_set_blat_score: - tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) - - onClick="openNewWin('/blatInfo.html')" - - tbl.append(HT.TR( - HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - tSpan = HT.Span(Class="fs13") - tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) - - tbl.append(HT.TR( - HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - if thisTrait.cellid: - self.cursor.execute(""" - select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze - where - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Id = %d""" % thisTrait.db.id) - probeDBName = self.cursor.fetchone()[0] - tbl.append(HT.TR( - HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") - )) - else: - tbl.append(HT.TR( - HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, - target='_blank', Class="fs13 fwn non_bold"), valign="top") - )) - - #XZ: ID links - if thisTrait.genbankid or thisTrait.geneid or thisTrait.unigeneid or thisTrait.omim or thisTrait.homologeneid: - idStyle = "background:#dddddd;padding:2" - tSpan = HT.Span(Class="fs13") - if thisTrait.geneid: - gurl = HT.Href(text= 'Gene', target='_blank',\ - url=webqtlConfig.NCBI_LOCUSID % thisTrait.geneid, Class="fs14 fwn", title="Info from NCBI Entrez Gene") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) - if thisTrait.omim: - gurl = HT.Href(text= 'OMIM', target='_blank', \ - url= webqtlConfig.OMIM_ID % thisTrait.omim,Class="fs14 fwn", title="Summary from On Mendelian Inheritance in Man") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) - if thisTrait.unigeneid: - try: - gurl = HT.Href(text= 'UniGene',target='_blank',\ - url= webqtlConfig.UNIGEN_ID % tuple(string.split(thisTrait.unigeneid,'.')[:2]),Class="fs14 fwn", title="UniGene ID") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) - except: - pass - if thisTrait.genbankid: - thisTrait.genbankid = '|'.join(thisTrait.genbankid.split('|')[0:10]) - if thisTrait.genbankid[-1]=='|': - thisTrait.genbankid=thisTrait.genbankid[0:-1] - gurl = HT.Href(text= 'GenBank', target='_blank', \ - url= webqtlConfig.GENBANK_ID % thisTrait.genbankid,Class="fs14 fwn", title="Find the original GenBank sequence used to design the probes") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) - if thisTrait.homologeneid: - hurl = HT.Href(text= 'HomoloGene', target='_blank',\ - url=webqtlConfig.HOMOLOGENE_ID % thisTrait.homologeneid, Class="fs14 fwn", title="Find similar genes in other species") - tSpan.append(HT.Span(hurl, style=idStyle), " "*2) - - tbl.append( - HT.TR(HT.TD(colspan=3,height=6)), - HT.TR( - HT.TD('Resource Links: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - #XZ: Resource Links: - if thisTrait.symbol: - linkStyle = "background:#dddddd;padding:2" - tSpan = HT.Span(style="font-family:verdana,serif;font-size:13px") - - #XZ,12/26/2008: Gene symbol may contain single quotation mark. - #For example, Affymetrix, mouse430v2, 1440338_at, the symbol is 2'-Pde (geneid 211948) - #I debug this by using double quotation marks. - if _Species == "rat": - - #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more - #symatlas_species = "Rattus norvegicus" - - #self.cursor.execute("SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = '%s'" % thisTrait.symbol) - self.cursor.execute('SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = "%s"' % thisTrait.symbol) - try: - kgId, chr, txst, txen = self.cursor.fetchall()[0] - if chr and txst and txen and kgId: - txst = int(txst*1000000) - txen = int(txen*1000000) - tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ - title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('rn3',kgId,chr,txst,txen),Class="fs14 fwn"), style=linkStyle) - , " "*2) - except: - pass - if _Species == "mouse": - - #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more - #symatlas_species = "Mus musculus" - - #self.cursor.execute("SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = '%s'" % thisTrait.symbol) - self.cursor.execute('SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = "%s"' % thisTrait.symbol) - try: - chr, txst, txen = self.cursor.fetchall()[0] - if chr and txst and txen and thisTrait.refseq_transcriptid : - txst = int(txst*1000000) - txen = int(txen*1000000) - tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ - title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('mm9',thisTrait.refseq_transcriptid,chr,txst,txen), - Class="fs14 fwn"), style=linkStyle) - , " "*2) - except: - pass - - #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more - #tSpan.append(HT.Span(HT.Href(text= 'SymAtlas',target="mainFrame",\ - # url="http://symatlas.gnf.org/SymAtlas/bioentry?querytext=%s&query=14&species=%s&type=Expression" \ - # % (thisTrait.symbol,symatlas_species),Class="fs14 fwn", \ - # title="Expression across many tissues and cell types"), style=linkStyle), " "*2) - if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): - tSpan.append(HT.Span(HT.Href(text= 'BioGPS',target="mainFrame",\ - url="http://biogps.gnf.org/?org=%s#goto=genereport&id=%s" \ - % (_Species, thisTrait.geneid),Class="fs14 fwn", \ - title="Expression across many tissues and cell types"), style=linkStyle), " "*2) - tSpan.append(HT.Span(HT.Href(text= 'STRING',target="mainFrame",\ - url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ - % thisTrait.symbol,Class="fs14 fwn", \ - title="Protein interactions: known and inferred"), style=linkStyle), " "*2) - if thisTrait.symbol: - #ZS: The "species scientific" converts the plain English species names we're using to their scientific names, which are needed for PANTHER's input - #We should probably use the scientific name along with the English name (if not instead of) elsewhere as well, given potential non-English speaking users - if _Species == "mouse": - species_scientific = "Mus%20musculus" - elif _Species == "rat": - species_scientific = "Rattus%20norvegicus" - elif _Species == "human": - species_scientific = "Homo%20sapiens" - elif _Species == "drosophila": - species_scientific = "Drosophila%20melanogaster" - else: - species_scientific = "all" - - species_scientific - tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ - url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ - % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ - title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) - else: - pass - #tSpan.append(HT.Span(HT.Href(text= 'BIND',target="mainFrame",\ - # url="http://bind.ca/?textquery=%s" \ - # % thisTrait.symbol,Class="fs14 fwn", \ - # title="Protein interactions"), style=linkStyle), " "*2) - if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): - tSpan.append(HT.Span(HT.Href(text= 'Gemma',target="mainFrame",\ - url="http://www.chibi.ubc.ca/Gemma/gene/showGene.html?ncbiid=%s" \ - % thisTrait.geneid, Class="fs14 fwn", \ - title="Meta-analysis of gene expression data"), style=linkStyle), " "*2) - tSpan.append(HT.Span(HT.Href(text= 'SynDB',target="mainFrame",\ - url="http://lily.uthsc.edu:8080/20091027_GNInterfaces/20091027_redirectSynDB.jsp?query=%s" \ - % thisTrait.symbol, Class="fs14 fwn", \ - title="Brain synapse database"), style=linkStyle), " "*2) - if _Species == "mouse": - tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ - url="http://mouse.brain-map.org/brain/%s.html" \ - % thisTrait.symbol, Class="fs14 fwn", \ - title="Allen Brain Atlas"), style=linkStyle), " "*2) - - if thisTrait.geneid: - #if _Species == "mouse": - # tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ - # url="http://www.brain-map.org/search.do?queryText=egeneid=%s" \ - # % thisTrait.geneid, Class="fs14 fwn", \ - # title="Allen Brain Atlas"), style=linkStyle), " "*2) - if _Species == "human": - tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ - url="http://humancortex.alleninstitute.org/has/human/imageseries/search/1.html?searchSym=t&searchAlt=t&searchName=t&gene_term=&entrez_term=%s" \ - % thisTrait.geneid, Class="fs14 fwn", \ - title="Allen Brain Atlas"), style=linkStyle), " "*2) - tbl.append( - HT.TR(HT.TD(colspan=3,height=6)), - HT.TR( - HT.TD(' '), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top"))) - - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="620", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(similarButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(geneWikiButton, align="center"),HT.TD(snpBrowserButton, align="center"),HT.TD(rnaseqButton, align="center"),HT.TD(probeButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(similarText, align="center"),HT.TD(verifyText, align="center"),HT.TD(geneWikiText, align="center"),HT.TD(snpBrowserText, align="center"),HT.TD(rnaseqText, align="center"),HT.TD(probeText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - - - #for zhou mi's cliques, need to be removed - #if self.database[:6] == 'BXDMic' and self.ProbeSetID in cliqueID: - # Info2Disp.append(HT.Strong('Clique Search: '),HT.Href(text='Search',\ - # url ="http://compbio1.utmem.edu/clique_go/results.php?pid=%s&pval_1=0&pval_2=0.001" \ - # % self.ProbeSetID,target='_blank',Class="normalsize"),HT.BR()) - - #linkTable.append(HT.TR(linkTD)) - #Info2Disp.append(linkTable) - title1Body.append(tbl, HT.BR(), menuTable) - - elif thisTrait and thisTrait.db and thisTrait.db.type =='Publish': #Check if trait is phenotype - - if thisTrait.confidential: - tbl.append(HT.TR( - HT.TD('Pre-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.pre_publication_description, Class="fs13"), valign="top", width=740) - )) - if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): - tbl.append(HT.TR( - HT.TD('Post-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Pre-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.pre_publication_abbreviation, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Post-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_abbreviation, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Lab code: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.lab_code, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Owner: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.owner, Class="fs13"), valign="top", width=740) - )) - else: - tbl.append(HT.TR( - HT.TD('Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Authors: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.authors, Class="fs13"), - valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Title: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.title, Class="fs13"), - valign="top", width=740) - )) - if thisTrait.journal: - journal = thisTrait.journal - if thisTrait.year: - journal = thisTrait.journal + " (%s)" % thisTrait.year - - tbl.append(HT.TR( - HT.TD('Journal: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(journal, Class="fs13"), - valign="top", width=740) - )) - PubMedLink = "" - if thisTrait.pubmed_id: - PubMedLink = webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id - if PubMedLink: - tbl.append(HT.TR( - HT.TD('Link: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(HT.Href(url=PubMedLink, text="PubMed",target='_blank',Class="fs14 fwn"), - style = "background:#cddcff;padding:2"), valign="top", width=740) - )) - - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - - title1Body.append(tbl, HT.BR(), menuTable) - - elif thisTrait and thisTrait.db and thisTrait.db.type == 'Geno': #Check if trait is genotype - - GenoInfo = HT.Paragraph() - if thisTrait.chr and thisTrait.mb: - location = ' Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb) - else: - location = "not available" - - if thisTrait.sequence and len(thisTrait.sequence) > 100: - if _Species == "rat": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', thisTrait.sequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('rat', 'rn3', thisTrait.sequence) - elif _Species == "mouse": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) - elif _Species == "human": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('human', 'hg19', thisTrait.sequence) - else: - UCSC_BLAT_URL = "" - UTHSC_BLAT_URL = "" - if UCSC_BLAT_URL: - #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) - verifyButton = HT.Href(url="#") - verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") - verifyButton.append(verifyButtonImg) - verifyText = "Verify" - rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) - rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") - rnaseqButton.append(rnaseqButtonImg) - rnaseqText = "RNA-seq" - - tbl.append(HT.TR( - HT.TD('Location: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(location, Class="fs13"), valign="top", width=740) - ), - HT.TR( - HT.TD('SNP Search: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Href("http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=snp&cmd=search&term=%s" % thisTrait.name, 'NCBI',Class="fs13"), - valign="top", width=740) - )) - - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - - title1Body.append(tbl, HT.BR(), menuTable) - - elif (thisTrait == None or thisTrait.db.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) - - TempInfo = HT.Paragraph() - if thisTrait != None: - if thisTrait.description: - tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),' %s ' % thisTrait.description,HT.BR()), colspan=3, height=15)) - else: - tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),'not available',HT.BR(),HT.BR()), colspan=3, height=15)) - - if (updateText == "Edit"): - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") - else: - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="80", id="target1") - - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="right"),HT.TD(updateButton, align="right"), colspan=3, height=50, style="vertical-align:bottom;") ) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - - title1Body.append(tbl, HT.BR(), menuTable) - - else: - pass - - - ########################################## - ## Function to display analysis tools - ########################################## - def dispBasicStatistics(self, fd, title2Body, thisTrait): - - #XZ, June 22, 2011: The definition and usage of primary_strains, other_strains, specialStrains, all_strains are not clear and hard to understand. But since they are only used in this function for draw graph purpose, they will not hurt the business logic outside. As of June 21, 2011, this function seems work fine, so no hurry to clean up. These parameters and code in this function should be cleaned along with fd.f1list, fd.parlist, fd.strainlist later. - stats_row = HT.TR() - stats_cell = HT.TD() - - if fd.genotype.type == "riset": - strainlist = fd.f1list + fd.strainlist - else: - strainlist = fd.f1list + fd.parlist + fd.strainlist - - other_strains = [] #XZ: strain that is not of primary group - specialStrains = [] #XZ: This might be replaced by other_strains / ZS: It is just other strains without parent/f1 strains. - all_strains = [] - primary_strains = [] #XZ: strain of primary group, e.g., BXD, LXS - - MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') - - for strain in thisTrait.data.keys(): - strainName = strain.replace("_2nd_", "") - if strain not in strainlist: - if (thisTrait.data[strainName].val != None): - if strain.find('F1') < 0: - specialStrains.append(strain) - if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): - other_strains.append(strain) #XZ: at current stage, other_strains doesn't include parent strains and F1 strains of primary group - else: - if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): - primary_strains.append(strain) #XZ: at current stage, the primary_strains is the same as fd.strainlist / ZS: I tried defining primary_strains as fd.strainlist instead, but in some cases it ended up including the parent strains (1436869_at BXD) - - if len(other_strains) > 3: - other_strains.sort(key=webqtlUtil.natsort_key) - primary_strains.sort(key=webqtlUtil.natsort_key) - primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains #XZ: note that fd.f1list and fd.parlist are added. - all_strains = primary_strains + other_strains - other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #XZ: note that fd.f1list and fd.parlist are added. - MDP_menu.append(('All Cases','0')) - MDP_menu.append(('%s Only' % fd.RISet,'1')) - MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) - stats_row.append("Include: ", MDP_menu, HT.BR(), HT.BR()) - else: - if (len(other_strains) > 0) and (len(primary_strains) + len(other_strains) > 3): - MDP_menu.append(('All Cases','0')) - MDP_menu.append(('%s Only' % fd.RISet,'1')) - MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) - stats_row.append("Include: ", MDP_menu, " "*3) - all_strains = primary_strains - all_strains.sort(key=webqtlUtil.natsort_key) - all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains - primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains - else: - all_strains = strainlist - - other_strains.sort(key=webqtlUtil.natsort_key) - all_strains = all_strains + other_strains - pass - - update_button = HT.Input(type='button',value=' Update Figures ', Class="button update") #This is used to reload the page and update the Basic Statistics figures with user-edited data - stats_row.append(update_button, HT.BR(), HT.BR()) - - if (len(other_strains)) > 0 and (len(primary_strains) + len(other_strains) > 4): - #One set of vals for all, selected strain only, and non-selected only - vals1 = [] - vals2 = [] - vals3 = [] - - #Using all strains/cases for values - for i, strainNameOrig in enumerate(all_strains): - strainName = strainNameOrig.replace("_2nd_", "") - - try: - thisval = thisTrait.data[strainName].val - thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] - except: - continue - - vals1.append(thisValFull) - - #Using just the RISet strain - for i, strainNameOrig in enumerate(primary_strains): - strainName = strainNameOrig.replace("_2nd_", "") - - try: - thisval = thisTrait.data[strainName].val - thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] - except: - continue - - vals2.append(thisValFull) - - #Using all non-RISet strains only - for i, strainNameOrig in enumerate(other_strains): - strainName = strainNameOrig.replace("_2nd_", "") - - try: - thisval = thisTrait.data[strainName].val - thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] - except: - continue - - vals3.append(thisValFull) - - vals_set = [vals1,vals2,vals3] - - else: - vals = [] - - #Using all strains/cases for values - for i, strainNameOrig in enumerate(all_strains): - strainName = strainNameOrig.replace("_2nd_", "") - - try: - thisval = thisTrait.data[strainName].val - thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] - except: - continue - - vals.append(thisValFull) - - vals_set = [vals] - - stats_script = HT.Script(language="Javascript") #script needed for tabs - - for i, vals in enumerate(vals_set): - if i == 0 and len(vals) < 4: - stats_container = HT.Div(id="stats_tabs", style="padding:10px;", Class="ui-tabs") #Needed for tabs; notice the "stats_script_text" below referring to this element - stats_container.append(HT.Div(HT.Italic("Fewer than 4 case data were entered. No statistical analysis has been attempted."))) - stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" - stats_cell.append(stats_container) - break - elif (i == 1 and len(primary_strains) < 4): - stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") - stats_container.append(HT.Div(HT.Italic("Fewer than 4 " + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) - elif (i == 2 and len(other_strains) < 4): - stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") - stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) - stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" - else: - stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") - stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" - if len(vals) > 4: - stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"), - HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), - HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")] - stats_tabs = HT.List(stats_tab_list) - stats_container.append(stats_tabs) - - table_div = HT.Div(id="statstabs-1") - table_container = HT.Paragraph() - - statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - - if thisTrait.db: - if thisTrait.cellid: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type, cellid=thisTrait.cellid) - else: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type) - else: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals) - - statsTable.append(HT.TR(HT.TD(statsTableCell))) - - table_container.append(statsTable) - table_div.append(table_container) - stats_container.append(table_div) - - normalplot_div = HT.Div(id="statstabs-5") - normalplot_container = HT.Paragraph() - normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - - try: - plotTitle = thisTrait.symbol - plotTitle += ": " - plotTitle += thisTrait.name - except: - plotTitle = str(thisTrait.name) - - normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) - normalplot.append(HT.TR(HT.TD(normalplot_img))) - normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ - normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), - "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", - target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) - normalplot_container.append(normalplot) - normalplot_div.append(normalplot_container) - stats_container.append(normalplot_div) - - boxplot_div = HT.Div(id="statstabs-2") - boxplot_container = HT.Paragraph() - boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) - boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) - boxplot_container.append(boxplot) - boxplot_div.append(boxplot_container) - stats_container.append(boxplot_div) - - - barName_div = HT.Div(id="statstabs-3") - barName_container = HT.Paragraph() - barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") - barName.append(HT.TR(HT.TD(barName_img))) - barName_container.append(barName) - barName_div.append(barName_container) - stats_container.append(barName_div) - - barRank_div = HT.Div(id="statstabs-4") - barRank_container = HT.Paragraph() - barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") - barRank.append(HT.TR(HT.TD(barRank_img))) - barRank_container.append(barRank) - barRank_div.append(barRank_container) - stats_container.append(barRank_div) - - stats_cell.append(stats_container) - - stats_script.append(stats_script_text) - - submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") - stats_row.append(stats_cell) - - submitTable.append(stats_row) - submitTable.append(stats_script) - - title2Body.append(submitTable) - - - def dispCorrelationTools(self, fd, title3Body, thisTrait): - - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) - - RISetgp = fd.RISet - if RISetgp[:3] == 'BXD': - RISetgp = 'BXD' - - if RISetgp: - sample_correlation = HT.Input(type='button',name='sample_corr', value=' Compute ', Class="button sample_corr") - lit_correlation = HT.Input(type='button',name='lit_corr', value=' Compute ', Class="button lit_corr") - tissue_correlation = HT.Input(type='button',name='tiss_corr', value=' Compute ', Class="button tiss_corr") - methodText = HT.Span("Calculate:", Class="ffl fwb fs12") - - databaseText = HT.Span("Database:", Class="ffl fwb fs12") - databaseMenu1 = HT.Select(name='database1') - databaseMenu2 = HT.Select(name='database2') - databaseMenu3 = HT.Select(name='database3') - - nmenu = 0 - self.cursor.execute('SELECT PublishFreeze.FullName,PublishFreeze.Name FROM \ - PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id \ - and InbredSet.Name = "%s" and PublishFreeze.public > %d' % \ - (RISetgp,webqtlConfig.PUBLICTHRESH)) - for item in self.cursor.fetchall(): - databaseMenu1.append(item) - databaseMenu2.append(item) - databaseMenu3.append(item) - nmenu += 1 - self.cursor.execute('SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze,\ - InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = \ - "%s" and GenoFreeze.public > %d' % (RISetgp,webqtlConfig.PUBLICTHRESH)) - for item in self.cursor.fetchall(): - databaseMenu1.append(item) - databaseMenu2.append(item) - databaseMenu3.append(item) - nmenu += 1 - #03/09/2009: Xiaodong changed the SQL query to order by Name as requested by Rob. - self.cursor.execute('SELECT Id, Name FROM Tissue order by Name') - for item in self.cursor.fetchall(): - TId, TName = item - databaseMenuSub = HT.Optgroup(label = '%s ------' % TName) - self.cursor.execute('SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, \ - InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %d and \ - ProbeSetFreeze.public > %d and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like "%s%%" \ - order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ' % (TId,webqtlConfig.PUBLICTHRESH, RISetgp)) - for item2 in self.cursor.fetchall(): - databaseMenuSub.append(item2) - nmenu += 1 - databaseMenu1.append(databaseMenuSub) - databaseMenu2.append(databaseMenuSub) - databaseMenu3.append(databaseMenuSub) - if nmenu: - if thisTrait and thisTrait.db != None: - databaseMenu1.selected.append(thisTrait.db.fullname) - databaseMenu2.selected.append(thisTrait.db.fullname) - databaseMenu3.selected.append(thisTrait.db.fullname) - - criteriaText = HT.Span("Return:", Class="ffl fwb fs12") - - criteriaMenu1 = HT.Select(name='criteria1', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") - criteriaMenu1.append(('top 100','100')) - criteriaMenu1.append(('top 200','200')) - criteriaMenu1.append(('top 500','500')) - criteriaMenu1.append(('top 1000','1000')) - criteriaMenu1.append(('top 2000','2000')) - criteriaMenu1.append(('top 5000','5000')) - criteriaMenu1.append(('top 10000','10000')) - criteriaMenu1.append(('top 15000','15000')) - criteriaMenu1.append(('top 20000','20000')) - - criteriaMenu2 = HT.Select(name='criteria2', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") - criteriaMenu2.append(('top 100','100')) - criteriaMenu2.append(('top 200','200')) - criteriaMenu2.append(('top 500','500')) - criteriaMenu2.append(('top 1000','1000')) - criteriaMenu2.append(('top 2000','2000')) - criteriaMenu2.append(('top 5000','5000')) - criteriaMenu2.append(('top 10000','10000')) - criteriaMenu2.append(('top 15000','15000')) - criteriaMenu2.append(('top 20000','20000')) - - criteriaMenu3 = HT.Select(name='criteria3', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") - criteriaMenu3.append(('top 100','100')) - criteriaMenu3.append(('top 200','200')) - criteriaMenu3.append(('top 500','500')) - criteriaMenu3.append(('top 1000','1000')) - criteriaMenu3.append(('top 2000','2000')) - criteriaMenu3.append(('top 5000','5000')) - criteriaMenu3.append(('top 10000','10000')) - criteriaMenu3.append(('top 15000','15000')) - criteriaMenu3.append(('top 20000','20000')) - - - self.MDPRow1 = HT.TR(Class='mdp1') - self.MDPRow2 = HT.TR(Class='mdp2') - self.MDPRow3 = HT.TR(Class='mdp3') - - correlationMenus1 = HT.TableLite( - HT.TR(HT.TD(databaseText), HT.TD(databaseMenu1, colspan="3")), - HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu1)), - self.MDPRow1, cellspacing=0, width="619px", cellpadding=2) - correlationMenus1.append(HT.Input(name='orderBy', value='2', type='hidden')) # to replace the orderBy menu - correlationMenus2 = HT.TableLite( - HT.TR(HT.TD(databaseText), HT.TD(databaseMenu2, colspan="3")), - HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu2)), - self.MDPRow2, cellspacing=0, width="619px", cellpadding=2) - correlationMenus2.append(HT.Input(name='orderBy', value='2', type='hidden')) - correlationMenus3 = HT.TableLite( - HT.TR(HT.TD(databaseText), HT.TD(databaseMenu3, colspan="3")), - HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu3)), - self.MDPRow3, cellspacing=0, width="619px", cellpadding=2) - correlationMenus3.append(HT.Input(name='orderBy', value='2', type='hidden')) - - else: - correlationMenus = "" - - - corr_row = HT.TR() - corr_container = HT.Div(id="corr_tabs", Class="ui-tabs") - - if (thisTrait.db != None and thisTrait.db.type =='ProbeSet'): - corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1"), HT.Href(text='Literature r', url="#corrtabs-2"), HT.Href(text='Tissue r', url="#corrtabs-3")] - else: - corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1")] - - corr_tabs = HT.List(corr_tab_list) - corr_container.append(corr_tabs) - - if correlationMenus1 or correlationMenus2 or correlationMenus3: - sample_div = HT.Div(id="corrtabs-1") - sample_container = HT.Span() - - sample_type = HT.Input(type="radio", name="sample_method", value="1", checked="checked") - sample_type2 = HT.Input(type="radio", name="sample_method", value="2") - - sampleTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - sampleTD = HT.TD(correlationMenus1, HT.BR(), - "Pearson", sample_type, " "*3, "Spearman Rank", sample_type2, HT.BR(), HT.BR(), - sample_correlation, HT.BR(), HT.BR()) - - sampleTD.append(HT.Span("The ",HT.Href(url="/correlationAnnotation.html#sample_r", target="_blank", text="Sample Correlation")," is computed between trait data and", - " any ",HT.BR()," other traits in the sample database selected above. Use ", - HT.Href(url="/glossary.html#Correlations", target="_blank", text="Spearman Rank"), - HT.BR(),"when the sample size is small (<20) or when there are influential \ - outliers.", HT.BR(),Class="fs12")) - - sampleTable.append(sampleTD) - - sample_container.append(sampleTable) - sample_div.append(sample_container) - corr_container.append(sample_div) - - literature_div = HT.Div(id="corrtabs-2") - literature_container = HT.Span() - - literatureTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - literatureTD = HT.TD(correlationMenus2,HT.BR(),lit_correlation, HT.BR(), HT.BR()) - literatureTD.append(HT.Span("The ", HT.Href(url="/correlationAnnotation.html", target="_blank",text="Literature Correlation"), " (Lit r) between this gene and all other genes is computed",HT.BR(), - "using the ", HT.Href(url="https://grits.eecs.utk.edu/sgo/sgo.html", target="_blank", text="Semantic Gene Organizer"), - " and human, rat, and mouse data from PubMed. ", HT.BR(),"Values are ranked by Lit r, \ - but Sample r and Tissue r are also displayed.", HT.BR(), HT.BR(), - HT.Href(url="/glossary.html#Literature", target="_blank", text="More on using Lit r"), Class="fs12")) - literatureTable.append(literatureTD) - - literature_container.append(literatureTable) - literature_div.append(literature_container) - - if thisTrait.db != None: - if (thisTrait.db.type =='ProbeSet'): - corr_container.append(literature_div) - - tissue_div = HT.Div(id="corrtabs-3") - tissue_container = HT.Span() - - tissue_type = HT.Input(type="radio", name="tissue_method", value="4", checked="checked") - tissue_type2 = HT.Input(type="radio", name="tissue_method", value="5") - - tissueTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - tissueTD = HT.TD(correlationMenus3,HT.BR(), - "Pearson", tissue_type, " "*3, "Spearman Rank", tissue_type2, HT.BR(), HT.BR(), - tissue_correlation, HT.BR(), HT.BR()) - tissueTD.append(HT.Span("The ", HT.Href(url="/webqtl/main.py?FormID=tissueCorrelation", target="_blank", text="Tissue Correlation"), - " (Tissue r) estimates the similarity of expression of two genes",HT.BR()," or \ - transcripts across different cells, tissues, or organs (",HT.Href(url="/correlationAnnotation.html#tissue_r", target="_blank", text="glossary"),"). \ - Tissue correlations",HT.BR()," are generated by analyzing expression in multiple samples usually taken from \ - single cases.",HT.BR(),HT.Bold("Pearson")," and ",HT.Bold("Spearman Rank")," correlations have been computed for all pairs \ - of genes",HT.BR()," using data from mouse samples.", - HT.BR(), Class="fs12")) - tissueTable.append(tissueTD) - - tissue_container.append(tissueTable) - tissue_div.append(tissue_container) - if thisTrait.db != None: - if (thisTrait.db.type =='ProbeSet'): - corr_container.append(tissue_div) - - corr_row.append(HT.TD(corr_container)) - - corr_script = HT.Script(language="Javascript") - corr_script_text = """$(function() { $("#corr_tabs").tabs(); });""" - corr_script.append(corr_script_text) - - submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target4") - submitTable.append(corr_row) - submitTable.append(corr_script) - - title3Body.append(submitTable) - - - def dispMappingTools(self, fd, title4Body, thisTrait): - - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) - - RISetgp = fd.RISet - if RISetgp[:3] == 'BXD': - RISetgp = 'BXD' - - #check boxes - one for regular interval mapping, the other for composite - permCheck1= HT.Input(type='checkbox', Class='checkbox', name='permCheck1',checked="on") - bootCheck1= HT.Input(type='checkbox', Class='checkbox', name='bootCheck1',checked=0) - permCheck2= HT.Input(type='checkbox', Class='checkbox', name='permCheck2',checked="on") - bootCheck2= HT.Input(type='checkbox', Class='checkbox', name='bootCheck2',checked=0) - optionbox1 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression1',checked=0) - optionbox2 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression2',checked=0) - optionbox3 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression3',checked=0) - applyVariance1 = HT.Input(name='applyVarianceSE1',type='checkbox', Class='checkbox') - applyVariance2 = HT.Input(name='applyVarianceSE2',type='checkbox', Class='checkbox') - - IntervalMappingButton=HT.Input(type='button' ,name='interval',value=' Compute ', Class="button") - CompositeMappingButton=HT.Input(type='button' ,name='composite',value=' Compute ', Class="button") - MarkerRegressionButton=HT.Input(type='button',name='marker', value=' Compute ', Class="button") - - chrText = HT.Span("Chromosome:", Class="ffl fwb fs12") - - # updated by NL 5-28-2010 - # Interval Mapping - chrMenu = HT.Select(name='chromosomes1') - chrMenu.append(tuple(["All",-1])) - for i in range(len(fd.genotype)): - if len(fd.genotype[i]) > 1: - chrMenu.append(tuple([fd.genotype[i].name,i])) - - #Menu for Composite Interval Mapping - chrMenu2 = HT.Select(name='chromosomes2') - chrMenu2.append(tuple(["All",-1])) - for i in range(len(fd.genotype)): - if len(fd.genotype[i]) > 1: - chrMenu2.append(tuple([fd.genotype[i].name,i])) - - if fd.genotype.Mbmap: - scaleText = HT.Span("Mapping Scale:", Class="ffl fwb fs12") - scaleMenu1 = HT.Select(name='scale1', onChange="checkUncheck(window.document.dataInput.scale1.value, window.document.dataInput.permCheck1, window.document.dataInput.bootCheck1)") - scaleMenu1.append(("Megabase",'physic')) - scaleMenu1.append(("Centimorgan",'morgan')) - scaleMenu2 = HT.Select(name='scale2', onChange="checkUncheck(window.document.dataInput.scale2.value, window.document.dataInput.permCheck2, window.document.dataInput.bootCheck2)") - scaleMenu2.append(("Megabase",'physic')) - scaleMenu2.append(("Centimorgan",'morgan')) - - controlText = HT.Span("Control Locus:", Class="ffl fwb fs12") - controlMenu = HT.Input(type="text", name="controlLocus", Class="controlLocus") - - if fd.genotype.Mbmap: - intMappingMenu = HT.TableLite( - HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), - HT.TR(HT.TD(scaleText), HT.TD(scaleMenu1)), - cellspacing=0, width="263px", cellpadding=2) - compMappingMenu = HT.TableLite( - HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), - HT.TR(HT.TD(scaleText), HT.TD(scaleMenu2)), - HT.TR(HT.TD(controlText), HT.TD(controlMenu)), - cellspacing=0, width="325px", cellpadding=2) - else: - intMappingMenu = HT.TableLite( - HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), - cellspacing=0, width="263px", cellpadding=2) - compMappingMenu = HT.TableLite( - HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), - HT.TR(HT.TD(controlText), HT.TD(controlMenu)), - cellspacing=0, width="325px", cellpadding=2) - - directPlotButton = "" - directPlotButton = HT.Input(type='button',name='', value=' Compute ',\ - onClick="dataEditingFunc(this.form,'directPlot');",Class="button") - directPlotSortText = HT.Span(HT.Bold("Sort by: "), Class="ffl fwb fs12") - directPlotSortMenu = HT.Select(name='graphSort') - directPlotSortMenu.append(('LRS Full',0)) - directPlotSortMenu.append(('LRS Interact',1)) - directPlotPermuText = HT.Span("Permutation Test (n=500)", Class="ffl fs12") - directPlotPermu = HT.Input(type='checkbox', Class='checkbox',name='directPermuCheckbox', checked="on") - pairScanReturnText = HT.Span(HT.Bold("Return: "), Class="ffl fwb fs12") - pairScanReturnMenu = HT.Select(name='pairScanReturn') - pairScanReturnMenu.append(('top 50','50')) - pairScanReturnMenu.append(('top 100','100')) - pairScanReturnMenu.append(('top 200','200')) - pairScanReturnMenu.append(('top 500','500')) - - pairScanMenus = HT.TableLite( - HT.TR(HT.TD(directPlotSortText), HT.TD(directPlotSortMenu)), - HT.TR(HT.TD(pairScanReturnText), HT.TD(pairScanReturnMenu)), - cellspacing=0, width="232px", cellpadding=2) - - markerSuggestiveText = HT.Span(HT.Bold("Display LRS greater than:"), Class="ffl fwb fs12") - markerSuggestive = HT.Input(name='suggestive', size=5, maxlength=8) - displayAllText = HT.Span(" Display all LRS ", Class="ffl fs12") - displayAll = HT.Input(name='displayAllLRS', type="checkbox", Class='checkbox') - useParentsText = HT.Span(" Use Parents ", Class="ffl fs12") - useParents = optionbox2 - applyVarianceText = HT.Span(" Use Weighted ", Class="ffl fs12") - - markerMenu = HT.TableLite( - HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive)), - HT.TR(HT.TD(displayAll,displayAllText)), - HT.TR(HT.TD(useParents,useParentsText)), - HT.TR(HT.TD(applyVariance2,applyVarianceText)), - cellspacing=0, width="263px", cellpadding=2) - - - mapping_row = HT.TR() - mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") - - mapping_tab_list = [HT.Href(text="Interval", url="#mappingtabs-1"), HT.Href(text="Marker Regression", url="#mappingtabs-2"), HT.Href(text="Composite", url="#mappingtabs-3"), HT.Href(text="Pair-Scan", url="#mappingtabs-4")] - mapping_tabs = HT.List(mapping_tab_list) - mapping_container.append(mapping_tabs) - - interval_div = HT.Div(id="mappingtabs-1") - interval_container = HT.Span() - - intervalTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - intTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") - intTD.append(intMappingMenu,HT.BR()) - - intTD.append(permCheck1,'Permutation Test (n=2000)',HT.BR(), - bootCheck1,'Bootstrap Test (n=2000)', HT.BR(), optionbox1, 'Use Parents', HT.BR(), - applyVariance1,'Use Weighted', HT.BR(), HT.BR(),IntervalMappingButton, HT.BR(), HT.BR()) - intervalTable.append(HT.TR(intTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#intmap', target='_blank', text='Interval Mapping'), - ' computes linkage maps for the entire genome or single',HT.BR(),' chromosomes.', - ' The ',HT.Href(url='/glossary.html#permutation', target='_blank', text='Permutation Test'),' estimates suggestive and significant ',HT.BR(),' linkage scores. \ - The ',HT.Href(url='/glossary.html#bootstrap', target='_blank', text='Bootstrap Test'), ' estimates the precision of the QTL location.' - ,Class="fs12"), HT.BR(), valign="top"))) - - interval_container.append(intervalTable) - interval_div.append(interval_container) - mapping_container.append(interval_div) - - # Marker Regression - - marker_div = HT.Div(id="mappingtabs-2") - marker_container = HT.Span() - - markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") - markerTD.append(markerMenu,HT.BR()) - - markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) - - markerTable.append(HT.TR(markerTD),HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#',target='_blank',text='Marker regression'), - ' computes and displays LRS values for individual markers.',HT.BR(), - 'This function also lists additive effects (phenotype units per allele) and', HT.BR(), - 'dominance deviations for some datasets.', HT.BR(),Class="fs12"), HT.BR(), valign="top"))) - - marker_container.append(markerTable) - marker_div.append(marker_container) - mapping_container.append(marker_div) - - # Composite interval mapping - composite_div = HT.Div(id="mappingtabs-3") - composite_container = HT.Span() - - compositeTable = HT.TableLite(cellspacing=0, cellpadding=3, width="100%") - compTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") - compTD.append(compMappingMenu,HT.BR()) - - compTD.append(permCheck2, 'Permutation Test (n=2000)',HT.BR(), - bootCheck2,'Bootstrap Test (n=2000)', HT.BR(), - optionbox3, 'Use Parents', HT.BR(), HT.BR(), CompositeMappingButton, HT.BR(), HT.BR()) - compositeTable.append(HT.TR(compTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Composite',target='_blank',text='Composite Interval Mapping'), - " allows you to control for a single marker as",HT.BR()," a cofactor. ", - "To find a control marker, run the ",HT.Bold("Marker Regression")," function."), - HT.BR(), valign="top"))) - - composite_container.append(compositeTable) - composite_div.append(composite_container) - mapping_container.append(composite_div) - - # Pair Scan - - pairscan_div = HT.Div(id="mappingtabs-4") - pairscan_container = HT.Span() - - pairScanTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - pairScanTD = HT.TD(NOWRAP='ON', Class="fs12 fwn") - pairScanTD.append(pairScanMenus,HT.BR()) - pairScanTD.append(directPlotPermu, directPlotPermuText, HT.BR(), HT.BR(), - directPlotButton,HT.BR(),HT.BR()) - pairScanTable.append(HT.TR(pairScanTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Pair_Scan', target="_blank", text='Pair-Scan'), - ' searches for pairs of chromosomal regions that are',HT.BR(), - 'involved in two-locus epistatic interactions.'), HT.BR(), valign="top"))) - - pairscan_container.append(pairScanTable) - pairscan_div.append(pairscan_container) - mapping_container.append(pairscan_div) - - mapping_row.append(HT.TD(mapping_container)) - - # Treat Interval Mapping and Marker Regression and Pair Scan as a group for displaying - #disable Interval Mapping and Marker Regression and Pair Scan for human and the dataset doesn't have genotype file - mappingMethodId = webqtlDatabaseFunction.getMappingMethod(cursor=self.cursor, groupName=RISetgp) - - mapping_script = HT.Script(language="Javascript") - mapping_script_text = """$(function() { $("#mapping_tabs").tabs(); });""" - mapping_script.append(mapping_script_text) - - submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") - - if mappingMethodId != None: - if int(mappingMethodId) == 1: - submitTable.append(mapping_row) - submitTable.append(mapping_script) - elif int(mappingMethodId) == 4: - # NL; 09-26-2011 testing for Human Genome Association function - mapping_row=HT.TR() - mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") - - mapping_tab_list = [HT.Href(text="Genome Association", url="#mappingtabs-1")] - mapping_tabs = HT.List(mapping_tab_list) - mapping_container.append(mapping_tabs) - - # Genome Association - markerSuggestiveText = HT.Span(HT.Bold("P Value:"), Class="ffl fwb fs12") - - markerSuggestive = HT.Input(name='pValue', value='0.001', size=10, maxlength=20,onClick="this.value='';",onBlur="if(this.value==''){this.value='0.001'};") - markerMenu = HT.TableLite(HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive),HT.TD(HT.Italic('   (e.g. 0.001 or 1e-3 or 1E-3 or 3)'))),cellspacing=0, width="400px", cellpadding=2) - MarkerRegressionButton=HT.Input(type='button',name='computePlink', value='  Compute Using PLINK  ', onClick= "validatePvalue(this.form);", Class="button") - - marker_div = HT.Div(id="mappingtabs-1") - marker_container = HT.Span() - markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") - markerTD.append(markerMenu,HT.BR()) - markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) - markerTable.append(HT.TR(markerTD)) - - marker_container.append(markerTable) - marker_div.append(marker_container) - - mapping_container.append(marker_div) - mapping_row.append(HT.TD(mapping_container)) - submitTable.append(mapping_row) - submitTable.append(mapping_script) - else: - submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("mappingMethodId %s has not been implemented for this dataset yet." % mappingMethodId), id="mapping_tabs", Class="ui-tabs")))) - submitTable.append(mapping_script) - - else: - submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("Mapping options are disabled for data not matched with genotypes."), id="mapping_tabs", Class="ui-tabs")))) - submitTable.append(mapping_script) - - title4Body.append(submitTable) - - - def natural_sort(strain_list): - - sorted = [] - for strain in strain_list: - try: - strain = int(strain) - try: sorted[-1] = sorted[-1] * 10 + strain - except: sorted.append(strain) - except: - sorted.append(strain) - return sorted - - ########################################## - ## Function to display trait tables - ########################################## - def dispTraitValues(self, fd , title5Body, varianceDataPage, nCols, mainForm, thisTrait): - traitTableOptions = HT.Div(style="border: 3px solid #EEEEEE; -moz-border-radius: 10px; -webkit-border-radius: 10px; width: 625px; padding: 5px 5px 10px 8px; font-size: 12px; background: #DDDDDD;") - resetButton = HT.Input(type='button',name='resetButton',value=' Reset ',Class="button") - blockSamplesField = HT.Input(type="text",style="background-color:white;border: 1px solid black;font-size: 14px;", name="removeField") - blockSamplesButton = HT.Input(type='button',value=' Block ', name='blockSamples', Class="button") - showHideNoValue = HT.Input(type='button', name='showHideNoValue', value=' Hide No Value ',Class='button') - blockMenuSpan = HT.Span(Id="blockMenuSpan") - blockMenu = HT.Select(name='block_method') - - if fd.genotype.type == "riset": - allstrainlist_neworder = fd.f1list + fd.strainlist - else: - allstrainlist_neworder = fd.f1list + fd.parlist + fd.strainlist - - attribute_ids = [] - attribute_names = [] - try: - #ZS: Id values for this trait's extra attributes; used to create "Exclude" dropdown and query for attribute values and create - self.cursor.execute("""SELECT CaseAttribute.Id, CaseAttribute.Name - FROM CaseAttribute, CaseAttributeXRef - WHERE CaseAttributeXRef.ProbeSetFreezeId = '%s' AND - CaseAttribute.Id = CaseAttributeXRef.CaseAttributeId - group by CaseAttributeXRef.CaseAttributeId""" % (str(thisTrait.db.id))) - - exclude_menu = HT.Select(name="exclude_menu") - dropdown_menus = [] #ZS: list of dropdown menus with the distinct values of each attribute (contained in DIVs so the style parameter can be edited and they can be hidden) - - for attribute in self.cursor.fetchall(): - attribute_ids.append(attribute[0]) - attribute_names.append(attribute[1]) - for this_attr_name in attribute_names: - exclude_menu.append((this_attr_name.capitalize(), this_attr_name)) - self.cursor.execute("""SELECT DISTINCT CaseAttributeXRef.Value - FROM CaseAttribute, CaseAttributeXRef - WHERE CaseAttribute.Name = '%s' AND - CaseAttributeXRef.CaseAttributeId = CaseAttribute.Id""" % (this_attr_name)) - try: - distinct_values = self.cursor.fetchall() - attr_value_menu_div = HT.Div(style="display:none;", Class="attribute_values") #container used to show/hide dropdown menus - attr_value_menu = HT.Select(name=this_attr_name) - attr_value_menu.append(("None", "show_all")) - for value in distinct_values: - attr_value_menu.append((str(value[0]), value[0])) - attr_value_menu_div.append(attr_value_menu) - dropdown_menus.append(attr_value_menu_div) - except: - pass - except: - pass - - other_strains = [] - for strain in thisTrait.data.keys(): - if strain not in allstrainlist_neworder: - other_strains.append(strain) - - if other_strains: - blockMenu.append(('%s Only' % fd.RISet,'1')) - blockMenu.append(('Non-%s Only' % fd.RISet,'0')) - blockMenuSpan.append(blockMenu) - else: - pass - - showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') - showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") - if other_strains: - showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) - else: - showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) - - exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') - if len(attribute_names) > 0: - excludeButton = HT.Input(type='button', name='excludeGroup', value=' Block ', Class='button') - showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) - for menu in dropdown_menus: - showHideMenuOptions.append(menu) - showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) - showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) - - traitTableOptions.append(showHideMenuOptions,HT.BR(),HT.BR()) - traitTableOptions.append(HT.Span("  Outliers highlighted in ", HT.Bold(" yellow ", style="background-color:yellow;"), " can be hidden using the ", - HT.Strong(" Hide Outliers "), " button,",HT.BR(),"  and samples with no value (x) can be hidden by clicking ", - HT.Strong(" Hide No Value "), "."), HT.BR()) - - - dispintro = HT.Paragraph("Edit or delete values in the Trait Data boxes, and use the ", HT.Strong("Reset"), " option as needed.",Class="fs12", style="margin-left:20px;") - - table = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target5") #Everything needs to be inside this table object in order for the toggle to work - container = HT.Div() #This will contain everything and be put into a cell of the table defined above - - container.append(dispintro, traitTableOptions, HT.BR()) - - primary_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable1", Class="tablesorter") - primary_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for primary table object - - other_strainsExist = False - for strain in thisTrait.data.keys(): - if strain not in allstrainlist_neworder: - other_strainsExist = True - break - - primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') - - primary_table.append(primary_header) - for i in range(len(primary_body)): - primary_table.append(primary_body[i]) - - other_strains = [] - for strain in thisTrait.data.keys(): - if strain not in allstrainlist_neworder: - allstrainlist_neworder.append(strain) - other_strains.append(strain) - - if other_strains: - other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits - other_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for other table object; same function is used as the one used for the primary table, since the header is the same - other_strains.sort() #Sort other strains - other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #Append F1 and parent strains to the beginning of the sorted list of other strains - - MDPText = HT.Span("Samples:", Class="ffl fwb fs12") - MDPMenu1 = HT.Select(name='MDPChoice1') - MDPMenu2 = HT.Select(name='MDPChoice2') - MDPMenu3 = HT.Select(name='MDPChoice3') - MDPMenu1.append(('%s Only' % fd.RISet,'1')) - MDPMenu2.append(('%s Only' % fd.RISet,'1')) - MDPMenu3.append(('%s Only' % fd.RISet,'1')) - MDPMenu1.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu2.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu3.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu1.append(('All Cases','0')) - MDPMenu2.append(('All Cases','0')) - MDPMenu3.append(('All Cases','0')) - self.MDPRow1.append(HT.TD(MDPText),HT.TD(MDPMenu1)) - self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) - self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) - - other_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') - - other_table.append(other_header) - for i in range(len(other_body)): - other_table.append(other_body[i]) - else: - pass - - if other_strains or (fd.f1list and thisTrait.data.has_key(fd.f1list[0])) \ - or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): - fd.allstrainlist = allstrainlist_neworder - - if nCols == 6 and fd.varianceDispName != 'Variance': - mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) - - primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values - container.append(primary_div) - - if other_strains: - other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values - container.append(HT.Div(' ', height=30)) - container.append(other_div) - - table.append(HT.TR(HT.TD(container))) - title5Body.append(table) - - def addTrait2Table(self, fd, varianceDataPage, strainlist, mainForm, thisTrait, other_strainsExist=None, attribute_ids=[], attribute_names=[], strains='primary'): - #XZ, Aug 23, 2010: I commented the code related to the display of animal case - #strainInfo = thisTrait.has_key('strainInfo') and thisTrait.strainInfo - - table_body = [] - vals = [] - - for i, strainNameOrig in enumerate(strainlist): - strainName = strainNameOrig.replace("_2nd_", "") - - try: - thisval = thisTrait.data[strainName].val - thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] - except: - continue - - vals.append(thisValFull) - - upperBound, lowerBound = Plot.findOutliers(vals) # ZS: Values greater than upperBound or less than lowerBound are considered outliers. - - for i, strainNameOrig in enumerate(strainlist): - - trId = strainNameOrig - selectCheck = HT.Input(type="checkbox", name="selectCheck", value=trId, Class="checkbox", onClick="highlight(this)") - - strainName = strainNameOrig.replace("_2nd_", "") - strainNameAdd = '' - if fd.RISet == 'AXBXA' and strainName in ('AXB18/19/20','AXB13/14','BXA8/17'): - strainNameAdd = HT.Href(url='/mouseCross.html#AXB/BXA', text=HT.Sup('#'), Class='fs12', target="_blank") - - try: - thisval, thisvar, thisNP = thisTrait.data[strainName].val, thisTrait.data[strainName].var, thisTrait.data[strainName].N - if thisNP: - mainForm.append(HT.Input(name='N'+strainName, value=thisNP, type='hidden')) - else: - pass - except: - thisval = thisvar = 'x' - - try: - traitVal = thisval - dispVal = "%2.3f" % thisval - except: - traitVal = '' - dispVal = 'x' - - strainNameDisp = HT.Span(strainName, Class='fs14 fwn ffl') - - if varianceDataPage: - try: - traitVar = thisvar - dispVar = "%2.3f" % thisvar - except: - traitVar = '' - dispVar = 'x' - - if thisval == 'x': - traitVar = '' #ZS: Used to be 0, but it doesn't seem like a good idea for values of 0 to *always* be at the bottom when you sort; it makes more sense to put "nothing" - - className = 'fs13 b1 c222 ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = 'novalue ' - else: - if (thisval >= upperBound) or (thisval <= lowerBound): - className = 'fs13 b1 c222 outlier ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = 'outlier' - else: - className = 'fs13 b1 c222 ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = ' ' - - if varianceDataPage: - varClassName = valueClassName + str(traitVar) - valueClassName += str(traitVal) - - if strainNameOrig == strainName: - if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): - ######################################################################################################################################################## - # ZS: Append value and variance to the value and variance input fields' list of classes; this is so the javascript can update the value when the user - # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. - ######################################################################################################################################################### - - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, - onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) - if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) - else: - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) - if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) - else: - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, - onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) - if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) - - if (strains == 'primary'): - table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) - else: - table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) - - if varianceDataPage: - table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) - table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) - table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) - table_row.append(HT.TD("±", width=20, align='center', Class=className)) - table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) - else: - table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) - table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) - table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) - - if thisTrait and thisTrait.db and thisTrait.db.type =='ProbeSet': - if len(attribute_ids) > 0: - - #ZS: Get StrainId value for the next query - self.cursor.execute("""SELECT Strain.Id - FROM Strain, StrainXRef, InbredSet - WHERE Strain.Name = '%s' and - StrainXRef.StrainId = Strain.Id and - InbredSet.Id = StrainXRef.InbredSetId and - InbredSet.Name = '%s'""" % (strainName, fd.RISet)) - - strain_id = self.cursor.fetchone()[0] - - attr_counter = 1 # This is needed so the javascript can know which attribute type to associate this value with for the exported excel sheet (each attribute type being a column). - for attribute_id in attribute_ids: - - #ZS: Add extra case attribute values (if any) - self.cursor.execute("""SELECT Value - FROM CaseAttributeXRef - WHERE ProbeSetFreezeId = '%s' AND - StrainId = '%s' AND - CaseAttributeId = '%s' - group by CaseAttributeXRef.CaseAttributeId""" % (thisTrait.db.id, strain_id, str(attribute_id))) - - attributeValue = self.cursor.fetchone()[0] #Trait-specific attributes, if any - - #ZS: If it's an int, turn it into one for sorting (for example, 101 would be lower than 80 if they're strings instead of ints) - try: - attributeValue = int(attributeValue) - except: - pass - - span_Id = strains+"_attribute"+str(attr_counter)+"_sample"+str(i+1) - attr_container = HT.Span(attributeValue, Id=span_Id) - attr_className = str(attributeValue) + " " + className - table_row.append(HT.TD(attr_container, align='right', Class=attr_className)) - attr_counter += 1 - - table_body.append(table_row) - return table_body - - def getTableHeader(self, fd, thisTrait, nCols, attribute_names): - - table_header = HT.TR() - - col_class = "fs13 fwb ff1 b1 cw cbrb" - - if nCols == 6: - try: - if fd.varianceDispName: - pass - except: - fd.varianceDispName = 'Variance' - - table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), - HT.TH('Sample', align='right', width=100, Class=col_class), - HT.TH('Value', align='right', width=70, Class=col_class), - HT.TH(' ', width=20, Class=col_class), - HT.TH(fd.varianceDispName, align='right', width=80, Class=col_class)) - - elif nCols == 4: - table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), - HT.TH('Sample', align='right', width=100, Class=col_class), - HT.TH('Value', align='right', width=70, Class=col_class)) - - else: - pass - - if len(attribute_names) > 0: - i=0 - for attribute in attribute_names: - char_count = len(attribute) - cell_width = char_count * 14 - table_header.append(HT.TH(attribute, align='right', width=cell_width, Class="attribute_name " + col_class)) - i+=1 - - return table_header - - - def getSortByValue(self): - - sortby = ("", "") - - return sortby + def __init__(self, fd, thisTrait=None): + + templatePage.__init__(self, fd) + + self.dict['title'] = 'Data Editing' + TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") + + if not self.openMysql(): + return + if not fd.genotype: + fd.readData(incf1=1) + + ############################# + # determine data editing page format + ############################# + varianceDataPage = 0 + if fd.formID == 'varianceChoice': + varianceDataPage = 1 + + if varianceDataPage: + fmID='dataEditing' + nCols = 6 + else: + if fd.enablevariance: + fmID='pre_dataEditing' + nCols = 4 + else: + fmID='dataEditing' + nCols = 4 + + ############################# + ## titles, etc. + ############################# + + #titleTop = HT.Div() + # + #title1 = HT.Paragraph("  Details and Links", style="border-radius: 5px;", Id="title1", Class="sectionheader") + #title1Body = HT.Paragraph(Id="sectionbody1") + # + #if fd.enablevariance and not varianceDataPage: + # title2 = HT.Paragraph("  Submit Variance", style="border-radius: 5px;", Id="title2", Class="sectionheader") + #else: + # title2 = HT.Paragraph("  Basic Statistics", style="border-radius: 5px;", Id="title2", Class="sectionheader") + #title2Body = HT.Paragraph(Id="sectionbody2") + # + #title3 = HT.Paragraph("  Calculate Correlations", style="border-radius: 5px;", Id="title3", Class="sectionheader") + #title3Body = HT.Paragraph(Id="sectionbody3") + # + #title4 = HT.Paragraph("  Mapping Tools", style="border-radius: 5px;", Id="title4", Class="sectionheader") + #title4Body = HT.Paragraph(Id="sectionbody4") + # + #title5 = HT.Paragraph("  Review and Edit Data", style="border-radius: 5px;", Id="title5", Class="sectionheader") + #title5Body = HT.Paragraph(Id="sectionbody5") + + ############################# + ## Hidden field + ############################# + + # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery + hddn = { + 'FormID':fmID, + 'RISet':fd.RISet, + 'submitID':'', + 'scale':'physic', + 'additiveCheck':'ON', + 'showSNP':'ON', + 'showGenes':'ON', + 'method':None, + 'parentsf14regression':'OFF', + 'stats_method':'1', + 'chromosomes':'-1', + 'topten':'', + 'viewLegend':'ON', + 'intervalAnalystCheck':'ON', + 'valsHidden':'OFF', + 'database':'', + 'criteria':None, + 'MDPChoice':None, + 'bootCheck':None, + 'permCheck':None, + 'applyVarianceSE':None, + 'strainNames':'_', + 'strainVals':'_', + 'strainVars':'_', + 'otherStrainNames':'_', + 'otherStrainVals':'_', + 'otherStrainVars':'_', + 'extra_attributes':'_', + 'other_extra_attributes':'_' + } + + if fd.enablevariance: + hddn['enablevariance']='ON' + if fd.incparentsf1: + hddn['incparentsf1']='ON' + + if thisTrait: + hddn['fullname'] = str(thisTrait) + try: + hddn['normalPlotTitle'] = thisTrait.symbol + hddn['normalPlotTitle'] += ": " + hddn['normalPlotTitle'] += thisTrait.name + except: + hddn['normalPlotTitle'] = str(thisTrait.name) + hddn['fromDataEditingPage'] = 1 + if thisTrait.db and thisTrait.db.type and thisTrait.db.type == 'ProbeSet': + hddn['trait_type'] = thisTrait.db.type + if thisTrait.cellid: + hddn['cellid'] = thisTrait.cellid + else: + self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % thisTrait.mysqlid) + heritability = self.cursor.fetchone() + hddn['heritability'] = heritability + + hddn['attribute_names'] = "" + + hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, groupName=fd.RISet) + + ############################# + ## Display Trait Information + ############################# + + #headSpan = self.dispHeader(fd,thisTrait) #Draw header + # + #titleTop.append(headSpan) + + if fd.identification: + hddn['identification'] = fd.identification + + else: + hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named + + self.dispTraitInformation(fd, "", hddn, thisTrait) #Display trait information + function buttons + + ############################# + ## Generate form and buttons + ############################# + + mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), + name='dataInput', submit=HT.Input(type='hidden')) + + next=HT.Input(type='submit', name='submit',value='Next',Class="button") + reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + correlationMenus = [] + + if thisTrait == None: + thisTrait = webqtlTrait(data=fd.allTraitData, db=None) + + # Variance submit page only + if fd.enablevariance and not varianceDataPage: + title2Body.append("Click the next button to go to the variance submission form.", + HT.Center(next,reset)) + else: + self.dispBasicStatistics(fd, title2Body, thisTrait) + self.dispCorrelationTools(fd, title3Body, thisTrait) + self.dispMappingTools(fd, title4Body, thisTrait) + + ############################# + ## Trait Value Table + ############################# + + self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) + + if fd.allstrainlist: + hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') + for key in hddn.keys(): + mainForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + if fd.enablevariance and not varianceDataPage: + #pre dataediting page, need to submit variance + mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + else: + mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + TD_LR.append(HT.Paragraph(mainForm)) + self.dict['body'] = str(TD_LR) + + ########################################## + ## Function to display header + ########################################## + def dispHeader(self, fd, thisTrait): + headSpan = HT.Div(style="font-size:14px;") + + #If trait, use trait name; otherwise, use identification value + if thisTrait: + if thisTrait.cellid: + headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Probe ID ', thisTrait.cellid) + else: + headSpan.append(HT.Strong('Trait Data and Analysis ', style='font-size:16px;'),' for Record ID ', thisTrait.name) + else: + if fd.identification: + headSpan.append(HT.Strong('Trait ID ', style='font-size:16px;'),fd.identification) + else: + headSpan.append(HT.Strong('Un-named Trait', style='font-size:16px;')) + + return headSpan + + ########################################## + ## Function to display trait infos + ########################################## + def dispTraitInformation(self, fd, title1Body, hddn, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + #tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") + + #reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + + #XZ, August 02, 2011: The display of icons is decided by the trait type (if trait exists), along with user log-in status. Note that the new submitted trait might not be trait object. + addSelectionButton = "" + verifyButton = "" + rnaseqButton = "" + geneWikiButton = "" + probeButton = "" + similarButton = "" + snpBrowserButton = "" + updateButton = "" + + addSelectionText = "" + verifyText = "" + rnaseqText = "" + geneWikiText = "" + probeText = "" + similarText = "" + snpBrowserText = "" + updateText = "" + + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: + + if thisTrait==None or thisTrait.db.type=='Temp': + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + elif thisTrait.db.type != 'Temp': + if thisTrait.db.type == 'Publish' and thisTrait.confidential: #XZ: confidential phenotype trait + if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + else: + updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + updateButton.append(updateButton_img) + updateText = "Edit" + else: + pass + + self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.RISet) + if thisTrait: + addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, 'dataInput')) + addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") + #addSelectionButton.append(addSelectionButton_img) + addSelectionText = "Add" + elif self.cursor.fetchall(): + addSelectionButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('%s')[0], 'addRecord');" % ('dataInput')) + addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="", alt="Add To Collection", title="Add To Collection", style="border:none;") + #addSelectionButton.append(addSelectionButton_img) + addSelectionText = "Add" + else: + pass + + + # Microarray database information to display + if thisTrait and thisTrait.db and thisTrait.db.type == 'ProbeSet': #before, this line was only reached if thisTrait != 0, but now we need to check + try: + hddn['GeneId'] = int(string.strip(thisTrait.geneid)) + except: + pass + + #Info2Disp = HT.Paragraph() + + #XZ: Gene Symbol + if thisTrait.symbol: + #XZ: Show SNP Browser only for mouse + if _Species == 'mouse': + self.cursor.execute("select geneSymbol from GeneList where geneSymbol = %s", thisTrait.symbol) + geneName = self.cursor.fetchone() + if geneName: + snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + "&geneName=%s" % geneName[0] + else: + if thisTrait.chr and thisTrait.mb: + snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + \ + "&chr=%s&start=%2.6f&end=%2.6f" % (thisTrait.chr, thisTrait.mb-0.002, thisTrait.mb+0.002) + else: + snpurl = "" + + if snpurl: + snpBrowserButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % snpurl) + snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="snpbrowser", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") + snpBrowserButton.append(snpBrowserButton_img) + snpBrowserText = "SNPs" + + #XZ: Show GeneWiki for all species + geneWikiButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % thisTrait.symbol)) + geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="genewiki", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") + geneWikiButton.append(geneWikiButton_img) + geneWikiText = 'GeneWiki' + + #XZ: display similar traits in other selected datasets + if thisTrait and thisTrait.db and thisTrait.db.type=="ProbeSet" and thisTrait.symbol: + if _Species in ("mouse", "rat", "human"): + similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) + similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) + similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") + similarButton.append(similarButton_img) + similarText = "Find" + else: + pass + tbl.append(HT.TR( + HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('%s' % thisTrait.symbol, valign="top", Class="fs13 fsI"), valign="top", width=740) + )) + else: + tbl.append(HT.TR( + HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('Not available', Class="fs13 fsI"), valign="top") + )) + + #XZ: Gene Alias + if thisTrait.alias: + alias = string.replace(thisTrait.alias, ";", " ") + alias = string.join(string.split(alias), ", ") + tbl.append(HT.TR( + HT.TD('Aliases: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(alias, Class="fs13 fsI"), valign="top") + )) + + #XZ: Description + if thisTrait.description: + tSpan = HT.Span(thisTrait.description, Class="fs13") + if thisTrait.probe_target_description: + tSpan.append('; ', thisTrait.probe_target_description) + else: + tSpan = HT.Span('Not available', Class="fs13") + tbl.append(HT.TR( + HT.TD('Description: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + #XZ: Location + + #XZ: deal with Chr and Mb + if thisTrait.chr and thisTrait.mb: + tSpan = HT.Span('Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb),Class="fs13") + elif (thisTrait.chr): + tSpan = HT.Span('Chr %s @ Unknown position' % (thisTrait.chr), Class="fs13") + else: + tSpan = HT.Span('Not available', Class="fs13") + + #XZ: deal with direction + if thisTrait.strand_probe == '+': + tSpan.append(' on the plus strand ') + elif thisTrait.strand_probe == '-': + tSpan.append(' on the minus strand ') + else: + pass + + tbl.append(HT.TR( + HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + ##display Verify Location button + try: + blatsequence = thisTrait.blatseq + if not blatsequence: + #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. + self.cursor.execute("""SELECT Probe.Sequence, Probe.Name + FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) + seqs = self.cursor.fetchall() + if not seqs: + raise ValueError + else: + blatsequence = '' + for seqt in seqs: + if int(seqt[1][-1]) % 2 == 1: + blatsequence += string.strip(seqt[0]) + + #--------Hongqiang add this part in order to not only blat ProbeSet, but also blat Probe + blatsequence = '%3E'+thisTrait.name+'%0A'+blatsequence+'%0A' + #XZ, 06/03/2009: ProbeSet name is not unique among platforms. We should use ProbeSet Id instead. + self.cursor.execute("""SELECT Probe.Sequence, Probe.Name + FROM Probe, ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' AND + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (thisTrait.db.name, thisTrait.name) ) + + seqs = self.cursor.fetchall() + for seqt in seqs: + if int(seqt[1][-1]) %2 == 1: + blatsequence += '%3EProbe_'+string.strip(seqt[1])+'%0A'+string.strip(seqt[0])+'%0A' + #-------- + #XZ, 07/16/2009: targetsequence is not used, so I comment out this block + #targetsequence = thisTrait.targetseq + #if targetsequence==None: + # targetsequence = "" + + #XZ: Pay attention to the parameter of version (rn, mm, hg). They need to be changed if necessary. + if _Species == "rat": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', blatsequence) + UTHSC_BLAT_URL = "" + elif _Species == "mouse": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', blatsequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', blatsequence) + elif _Species == "human": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) + UTHSC_BLAT_URL = "" + else: + UCSC_BLAT_URL = "" + UTHSC_BLAT_URL = "" + + if UCSC_BLAT_URL: + verifyButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UCSC_BLAT_URL) + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", + title=" Check probe locations at UCSC ", style="border:none;") + verifyButton.append(verifyButtonImg) + verifyText = 'Verify' + if UTHSC_BLAT_URL: + rnaseqButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % UTHSC_BLAT_URL) + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", + title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButton.append(rnaseqButtonImg) + rnaseqText = 'RNA-seq' + tSpan.append(HT.BR()) + except: + pass + + #Display probe information (if any) + if thisTrait.db.name.find('Liver') >= 0 and thisTrait.db.name.find('F2') < 0: + pass + else: + #query database for number of probes associated with trait; if count > 0, set probe tool button and text + self.cursor.execute("""SELECT count(*) + FROM Probe, ProbeSet + WHERE ProbeSet.Name = '%s' AND Probe.ProbeSetId = ProbeSet.Id""" % (thisTrait.name)) + + probeResult = self.cursor.fetchone() + if probeResult[0] > 0: + probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&RISet=%s&incparentsf1=ON" \ + % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.db, thisTrait.name, thisTrait.cellid, fd.RISet) + probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) + probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") + probeButton.append(probeButton_img) + probeText = "Probes" + + tSpan = HT.Span(Class="fs13") + + #XZ: deal with blat score and blat specificity. + if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: + if thisTrait.probe_set_specificity: + tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) + if thisTrait.probe_set_blat_score: + tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) + + onClick="openNewWin('/blatInfo.html')" + + tbl.append(HT.TR( + HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + tSpan = HT.Span(Class="fs13") + tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) + + tbl.append(HT.TR( + HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + if thisTrait.cellid: + self.cursor.execute(""" + select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze + where + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Id = %d""" % thisTrait.db.id) + probeDBName = self.cursor.fetchone()[0] + tbl.append(HT.TR( + HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") + )) + else: + tbl.append(HT.TR( + HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, + target='_blank', Class="fs13 fwn non_bold"), valign="top") + )) + + #XZ: ID links + if thisTrait.genbankid or thisTrait.geneid or thisTrait.unigeneid or thisTrait.omim or thisTrait.homologeneid: + idStyle = "background:#dddddd;padding:2" + tSpan = HT.Span(Class="fs13") + if thisTrait.geneid: + gurl = HT.Href(text= 'Gene', target='_blank',\ + url=webqtlConfig.NCBI_LOCUSID % thisTrait.geneid, Class="fs14 fwn", title="Info from NCBI Entrez Gene") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.omim: + gurl = HT.Href(text= 'OMIM', target='_blank', \ + url= webqtlConfig.OMIM_ID % thisTrait.omim,Class="fs14 fwn", title="Summary from On Mendelian Inheritance in Man") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.unigeneid: + try: + gurl = HT.Href(text= 'UniGene',target='_blank',\ + url= webqtlConfig.UNIGEN_ID % tuple(string.split(thisTrait.unigeneid,'.')[:2]),Class="fs14 fwn", title="UniGene ID") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + except: + pass + if thisTrait.genbankid: + thisTrait.genbankid = '|'.join(thisTrait.genbankid.split('|')[0:10]) + if thisTrait.genbankid[-1]=='|': + thisTrait.genbankid=thisTrait.genbankid[0:-1] + gurl = HT.Href(text= 'GenBank', target='_blank', \ + url= webqtlConfig.GENBANK_ID % thisTrait.genbankid,Class="fs14 fwn", title="Find the original GenBank sequence used to design the probes") + tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + if thisTrait.homologeneid: + hurl = HT.Href(text= 'HomoloGene', target='_blank',\ + url=webqtlConfig.HOMOLOGENE_ID % thisTrait.homologeneid, Class="fs14 fwn", title="Find similar genes in other species") + tSpan.append(HT.Span(hurl, style=idStyle), " "*2) + + tbl.append( + HT.TR(HT.TD(colspan=3,height=6)), + HT.TR( + HT.TD('Resource Links: ', Class="fwb fs13", valign="top", nowrap="on"), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top") + )) + + #XZ: Resource Links: + if thisTrait.symbol: + linkStyle = "background:#dddddd;padding:2" + tSpan = HT.Span(style="font-family:verdana,serif;font-size:13px") + + #XZ,12/26/2008: Gene symbol may contain single quotation mark. + #For example, Affymetrix, mouse430v2, 1440338_at, the symbol is 2'-Pde (geneid 211948) + #I debug this by using double quotation marks. + if _Species == "rat": + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #symatlas_species = "Rattus norvegicus" + + #self.cursor.execute("SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = '%s'" % thisTrait.symbol) + self.cursor.execute('SELECT kgID, chromosome,txStart,txEnd FROM GeneList_rn33 WHERE geneSymbol = "%s"' % thisTrait.symbol) + try: + kgId, chr, txst, txen = self.cursor.fetchall()[0] + if chr and txst and txen and kgId: + txst = int(txst*1000000) + txen = int(txen*1000000) + tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('rn3',kgId,chr,txst,txen),Class="fs14 fwn"), style=linkStyle) + , " "*2) + except: + pass + if _Species == "mouse": + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #symatlas_species = "Mus musculus" + + #self.cursor.execute("SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = '%s'" % thisTrait.symbol) + self.cursor.execute('SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = "%s"' % thisTrait.symbol) + try: + chr, txst, txen = self.cursor.fetchall()[0] + if chr and txst and txen and thisTrait.refseq_transcriptid : + txst = int(txst*1000000) + txen = int(txen*1000000) + tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('mm9',thisTrait.refseq_transcriptid,chr,txst,txen), + Class="fs14 fwn"), style=linkStyle) + , " "*2) + except: + pass + + #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more + #tSpan.append(HT.Span(HT.Href(text= 'SymAtlas',target="mainFrame",\ + # url="http://symatlas.gnf.org/SymAtlas/bioentry?querytext=%s&query=14&species=%s&type=Expression" \ + # % (thisTrait.symbol,symatlas_species),Class="fs14 fwn", \ + # title="Expression across many tissues and cell types"), style=linkStyle), " "*2) + if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): + tSpan.append(HT.Span(HT.Href(text= 'BioGPS',target="mainFrame",\ + url="http://biogps.gnf.org/?org=%s#goto=genereport&id=%s" \ + % (_Species, thisTrait.geneid),Class="fs14 fwn", \ + title="Expression across many tissues and cell types"), style=linkStyle), " "*2) + tSpan.append(HT.Span(HT.Href(text= 'STRING',target="mainFrame",\ + url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ + % thisTrait.symbol,Class="fs14 fwn", \ + title="Protein interactions: known and inferred"), style=linkStyle), " "*2) + if thisTrait.symbol: + #ZS: The "species scientific" converts the plain English species names we're using to their scientific names, which are needed for PANTHER's input + #We should probably use the scientific name along with the English name (if not instead of) elsewhere as well, given potential non-English speaking users + if _Species == "mouse": + species_scientific = "Mus%20musculus" + elif _Species == "rat": + species_scientific = "Rattus%20norvegicus" + elif _Species == "human": + species_scientific = "Homo%20sapiens" + elif _Species == "drosophila": + species_scientific = "Drosophila%20melanogaster" + else: + species_scientific = "all" + + species_scientific + tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ + url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ + % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ + title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) + else: + pass + #tSpan.append(HT.Span(HT.Href(text= 'BIND',target="mainFrame",\ + # url="http://bind.ca/?textquery=%s" \ + # % thisTrait.symbol,Class="fs14 fwn", \ + # title="Protein interactions"), style=linkStyle), " "*2) + if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): + tSpan.append(HT.Span(HT.Href(text= 'Gemma',target="mainFrame",\ + url="http://www.chibi.ubc.ca/Gemma/gene/showGene.html?ncbiid=%s" \ + % thisTrait.geneid, Class="fs14 fwn", \ + title="Meta-analysis of gene expression data"), style=linkStyle), " "*2) + tSpan.append(HT.Span(HT.Href(text= 'SynDB',target="mainFrame",\ + url="http://lily.uthsc.edu:8080/20091027_GNInterfaces/20091027_redirectSynDB.jsp?query=%s" \ + % thisTrait.symbol, Class="fs14 fwn", \ + title="Brain synapse database"), style=linkStyle), " "*2) + if _Species == "mouse": + tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + url="http://mouse.brain-map.org/brain/%s.html" \ + % thisTrait.symbol, Class="fs14 fwn", \ + title="Allen Brain Atlas"), style=linkStyle), " "*2) + + if thisTrait.geneid: + #if _Species == "mouse": + # tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + # url="http://www.brain-map.org/search.do?queryText=egeneid=%s" \ + # % thisTrait.geneid, Class="fs14 fwn", \ + # title="Allen Brain Atlas"), style=linkStyle), " "*2) + if _Species == "human": + tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + url="http://humancortex.alleninstitute.org/has/human/imageseries/search/1.html?searchSym=t&searchAlt=t&searchName=t&gene_term=&entrez_term=%s" \ + % thisTrait.geneid, Class="fs14 fwn", \ + title="Allen Brain Atlas"), style=linkStyle), " "*2) + tbl.append( + HT.TR(HT.TD(colspan=3,height=6)), + HT.TR( + HT.TD(' '), + HT.TD(width=10, valign="top"), + HT.TD(tSpan, valign="top"))) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="620", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(similarButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(geneWikiButton, align="center"),HT.TD(snpBrowserButton, align="center"),HT.TD(rnaseqButton, align="center"),HT.TD(probeButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(similarText, align="center"),HT.TD(verifyText, align="center"),HT.TD(geneWikiText, align="center"),HT.TD(snpBrowserText, align="center"),HT.TD(rnaseqText, align="center"),HT.TD(probeText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + + #for zhou mi's cliques, need to be removed + #if self.database[:6] == 'BXDMic' and self.ProbeSetID in cliqueID: + # Info2Disp.append(HT.Strong('Clique Search: '),HT.Href(text='Search',\ + # url ="http://compbio1.utmem.edu/clique_go/results.php?pid=%s&pval_1=0&pval_2=0.001" \ + # % self.ProbeSetID,target='_blank',Class="normalsize"),HT.BR()) + + #linkTable.append(HT.TR(linkTD)) + #Info2Disp.append(linkTable) + title1Body.append(tbl, HT.BR(), menuTable) + + elif thisTrait and thisTrait.db and thisTrait.db.type =='Publish': #Check if trait is phenotype + + if thisTrait.confidential: + tbl.append(HT.TR( + HT.TD('Pre-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.pre_publication_description, Class="fs13"), valign="top", width=740) + )) + if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): + tbl.append(HT.TR( + HT.TD('Post-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Pre-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.pre_publication_abbreviation, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Post-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_abbreviation, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Lab code: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.lab_code, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Owner: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.owner, Class="fs13"), valign="top", width=740) + )) + else: + tbl.append(HT.TR( + HT.TD('Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Authors: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.authors, Class="fs13"), + valign="top", width=740) + )) + tbl.append(HT.TR( + HT.TD('Title: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(thisTrait.title, Class="fs13"), + valign="top", width=740) + )) + if thisTrait.journal: + journal = thisTrait.journal + if thisTrait.year: + journal = thisTrait.journal + " (%s)" % thisTrait.year + + tbl.append(HT.TR( + HT.TD('Journal: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(journal, Class="fs13"), + valign="top", width=740) + )) + PubMedLink = "" + if thisTrait.pubmed_id: + PubMedLink = webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id + if PubMedLink: + tbl.append(HT.TR( + HT.TD('Link: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(HT.Href(url=PubMedLink, text="PubMed",target='_blank',Class="fs14 fwn"), + style = "background:#cddcff;padding:2"), valign="top", width=740) + )) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + elif thisTrait and thisTrait.db and thisTrait.db.type == 'Geno': #Check if trait is genotype + + GenoInfo = HT.Paragraph() + if thisTrait.chr and thisTrait.mb: + location = ' Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb) + else: + location = "not available" + + if thisTrait.sequence and len(thisTrait.sequence) > 100: + if _Species == "rat": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', thisTrait.sequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('rat', 'rn3', thisTrait.sequence) + elif _Species == "mouse": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', thisTrait.sequence) + elif _Species == "human": + UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) + UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('human', 'hg19', thisTrait.sequence) + else: + UCSC_BLAT_URL = "" + UTHSC_BLAT_URL = "" + if UCSC_BLAT_URL: + #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) + verifyButton = HT.Href(url="#") + verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") + verifyButton.append(verifyButtonImg) + verifyText = "Verify" + rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) + rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + rnaseqButton.append(rnaseqButtonImg) + rnaseqText = "RNA-seq" + + tbl.append(HT.TR( + HT.TD('Location: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Span(location, Class="fs13"), valign="top", width=740) + ), + HT.TR( + HT.TD('SNP Search: ', Class="fs13 fwb", + valign="top", nowrap="on", width=90), + HT.TD(width=10, valign="top"), + HT.TD(HT.Href("http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=snp&cmd=search&term=%s" % thisTrait.name, 'NCBI',Class="fs13"), + valign="top", width=740) + )) + + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + elif (thisTrait == None or thisTrait.db.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) + + TempInfo = HT.Paragraph() + if thisTrait != None: + if thisTrait.description: + tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),' %s ' % thisTrait.description,HT.BR()), colspan=3, height=15)) + else: + tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),'not available',HT.BR(),HT.BR()), colspan=3, height=15)) + + if (updateText == "Edit"): + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") + else: + menuTable = HT.TableLite(cellpadding=2, Class="collap", width="80", id="target1") + + menuTable.append(HT.TR(HT.TD(addSelectionButton, align="right"),HT.TD(updateButton, align="right"), colspan=3, height=50, style="vertical-align:bottom;") ) + menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + + title1Body.append(tbl, HT.BR(), menuTable) + + else: + pass + + + ########################################## + ## Function to display analysis tools + ########################################## + def dispBasicStatistics(self, fd, title2Body, thisTrait): + + #XZ, June 22, 2011: The definition and usage of primary_strains, other_strains, specialStrains, all_strains are not clear and hard to understand. But since they are only used in this function for draw graph purpose, they will not hurt the business logic outside. As of June 21, 2011, this function seems work fine, so no hurry to clean up. These parameters and code in this function should be cleaned along with fd.f1list, fd.parlist, fd.strainlist later. + stats_row = HT.TR() + stats_cell = HT.TD() + + if fd.genotype.type == "riset": + strainlist = fd.f1list + fd.strainlist + else: + strainlist = fd.f1list + fd.parlist + fd.strainlist + + other_strains = [] #XZ: strain that is not of primary group + specialStrains = [] #XZ: This might be replaced by other_strains / ZS: It is just other strains without parent/f1 strains. + all_strains = [] + primary_strains = [] #XZ: strain of primary group, e.g., BXD, LXS + + MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') + + for strain in thisTrait.data.keys(): + strainName = strain.replace("_2nd_", "") + if strain not in strainlist: + if (thisTrait.data[strainName].val != None): + if strain.find('F1') < 0: + specialStrains.append(strain) + if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): + other_strains.append(strain) #XZ: at current stage, other_strains doesn't include parent strains and F1 strains of primary group + else: + if (thisTrait.data[strainName].val != None) and (strain not in (fd.f1list + fd.parlist)): + primary_strains.append(strain) #XZ: at current stage, the primary_strains is the same as fd.strainlist / ZS: I tried defining primary_strains as fd.strainlist instead, but in some cases it ended up including the parent strains (1436869_at BXD) + + if len(other_strains) > 3: + other_strains.sort(key=webqtlUtil.natsort_key) + primary_strains.sort(key=webqtlUtil.natsort_key) + primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains #XZ: note that fd.f1list and fd.parlist are added. + all_strains = primary_strains + other_strains + other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #XZ: note that fd.f1list and fd.parlist are added. + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet,'1')) + MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + stats_row.append("Include: ", MDP_menu, HT.BR(), HT.BR()) + else: + if (len(other_strains) > 0) and (len(primary_strains) + len(other_strains) > 3): + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet,'1')) + MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + stats_row.append("Include: ", MDP_menu, " "*3) + all_strains = primary_strains + all_strains.sort(key=webqtlUtil.natsort_key) + all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains + primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains + else: + all_strains = strainlist + + other_strains.sort(key=webqtlUtil.natsort_key) + all_strains = all_strains + other_strains + pass + + update_button = HT.Input(type='button',value=' Update Figures ', Class="button update") #This is used to reload the page and update the Basic Statistics figures with user-edited data + stats_row.append(update_button, HT.BR(), HT.BR()) + + if (len(other_strains)) > 0 and (len(primary_strains) + len(other_strains) > 4): + #One set of vals for all, selected strain only, and non-selected only + vals1 = [] + vals2 = [] + vals3 = [] + + #Using all strains/cases for values + for i, strainNameOrig in enumerate(all_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals1.append(thisValFull) + + #Using just the RISet strain + for i, strainNameOrig in enumerate(primary_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals2.append(thisValFull) + + #Using all non-RISet strains only + for i, strainNameOrig in enumerate(other_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals3.append(thisValFull) + + vals_set = [vals1,vals2,vals3] + + else: + vals = [] + + #Using all strains/cases for values + for i, strainNameOrig in enumerate(all_strains): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals.append(thisValFull) + + vals_set = [vals] + + stats_script = HT.Script(language="Javascript") #script needed for tabs + + for i, vals in enumerate(vals_set): + if i == 0 and len(vals) < 4: + stats_container = HT.Div(id="stats_tabs", style="padding:10px;", Class="ui-tabs") #Needed for tabs; notice the "stats_script_text" below referring to this element + stats_container.append(HT.Div(HT.Italic("Fewer than 4 case data were entered. No statistical analysis has been attempted."))) + stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" + stats_cell.append(stats_container) + break + elif (i == 1 and len(primary_strains) < 4): + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_container.append(HT.Div(HT.Italic("Fewer than 4 " + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + elif (i == 2 and len(other_strains) < 4): + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" + else: + stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" + if len(vals) > 4: + stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"), + HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), + HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")] + stats_tabs = HT.List(stats_tab_list) + stats_container.append(stats_tabs) + + table_div = HT.Div(id="statstabs-1") + table_container = HT.Paragraph() + + statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + + if thisTrait.db: + if thisTrait.cellid: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type, cellid=thisTrait.cellid) + else: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type) + else: + statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals) + + statsTable.append(HT.TR(HT.TD(statsTableCell))) + + table_container.append(statsTable) + table_div.append(table_container) + stats_container.append(table_div) + + normalplot_div = HT.Div(id="statstabs-5") + normalplot_container = HT.Paragraph() + normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + + try: + plotTitle = thisTrait.symbol + plotTitle += ": " + plotTitle += thisTrait.name + except: + plotTitle = str(thisTrait.name) + + normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + normalplot.append(HT.TR(HT.TD(normalplot_img))) + normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + normalplot_container.append(normalplot) + normalplot_div.append(normalplot_container) + stats_container.append(normalplot_div) + + boxplot_div = HT.Div(id="statstabs-2") + boxplot_container = HT.Paragraph() + boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + boxplot_container.append(boxplot) + boxplot_div.append(boxplot_container) + stats_container.append(boxplot_div) + + + barName_div = HT.Div(id="statstabs-3") + barName_container = HT.Paragraph() + barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + barName.append(HT.TR(HT.TD(barName_img))) + barName_container.append(barName) + barName_div.append(barName_container) + stats_container.append(barName_div) + + barRank_div = HT.Div(id="statstabs-4") + barRank_container = HT.Paragraph() + barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + barRank.append(HT.TR(HT.TD(barRank_img))) + barRank_container.append(barRank) + barRank_div.append(barRank_container) + stats_container.append(barRank_div) + + stats_cell.append(stats_container) + + stats_script.append(stats_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") + stats_row.append(stats_cell) + + submitTable.append(stats_row) + submitTable.append(stats_script) + + title2Body.append(submitTable) + + + def dispCorrelationTools(self, fd, title3Body, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + RISetgp = fd.RISet + if RISetgp[:3] == 'BXD': + RISetgp = 'BXD' + + if RISetgp: + sample_correlation = HT.Input(type='button',name='sample_corr', value=' Compute ', Class="button sample_corr") + lit_correlation = HT.Input(type='button',name='lit_corr', value=' Compute ', Class="button lit_corr") + tissue_correlation = HT.Input(type='button',name='tiss_corr', value=' Compute ', Class="button tiss_corr") + methodText = HT.Span("Calculate:", Class="ffl fwb fs12") + + databaseText = HT.Span("Database:", Class="ffl fwb fs12") + databaseMenu1 = HT.Select(name='database1') + databaseMenu2 = HT.Select(name='database2') + databaseMenu3 = HT.Select(name='database3') + + nmenu = 0 + self.cursor.execute('SELECT PublishFreeze.FullName,PublishFreeze.Name FROM \ + PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id \ + and InbredSet.Name = "%s" and PublishFreeze.public > %d' % \ + (RISetgp,webqtlConfig.PUBLICTHRESH)) + for item in self.cursor.fetchall(): + databaseMenu1.append(item) + databaseMenu2.append(item) + databaseMenu3.append(item) + nmenu += 1 + self.cursor.execute('SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze,\ + InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = \ + "%s" and GenoFreeze.public > %d' % (RISetgp,webqtlConfig.PUBLICTHRESH)) + for item in self.cursor.fetchall(): + databaseMenu1.append(item) + databaseMenu2.append(item) + databaseMenu3.append(item) + nmenu += 1 + #03/09/2009: Xiaodong changed the SQL query to order by Name as requested by Rob. + self.cursor.execute('SELECT Id, Name FROM Tissue order by Name') + for item in self.cursor.fetchall(): + TId, TName = item + databaseMenuSub = HT.Optgroup(label = '%s ------' % TName) + self.cursor.execute('SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, \ + InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %d and \ + ProbeSetFreeze.public > %d and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like "%s%%" \ + order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ' % (TId,webqtlConfig.PUBLICTHRESH, RISetgp)) + for item2 in self.cursor.fetchall(): + databaseMenuSub.append(item2) + nmenu += 1 + databaseMenu1.append(databaseMenuSub) + databaseMenu2.append(databaseMenuSub) + databaseMenu3.append(databaseMenuSub) + if nmenu: + if thisTrait and thisTrait.db != None: + databaseMenu1.selected.append(thisTrait.db.fullname) + databaseMenu2.selected.append(thisTrait.db.fullname) + databaseMenu3.selected.append(thisTrait.db.fullname) + + criteriaText = HT.Span("Return:", Class="ffl fwb fs12") + + criteriaMenu1 = HT.Select(name='criteria1', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu1.append(('top 100','100')) + criteriaMenu1.append(('top 200','200')) + criteriaMenu1.append(('top 500','500')) + criteriaMenu1.append(('top 1000','1000')) + criteriaMenu1.append(('top 2000','2000')) + criteriaMenu1.append(('top 5000','5000')) + criteriaMenu1.append(('top 10000','10000')) + criteriaMenu1.append(('top 15000','15000')) + criteriaMenu1.append(('top 20000','20000')) + + criteriaMenu2 = HT.Select(name='criteria2', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu2.append(('top 100','100')) + criteriaMenu2.append(('top 200','200')) + criteriaMenu2.append(('top 500','500')) + criteriaMenu2.append(('top 1000','1000')) + criteriaMenu2.append(('top 2000','2000')) + criteriaMenu2.append(('top 5000','5000')) + criteriaMenu2.append(('top 10000','10000')) + criteriaMenu2.append(('top 15000','15000')) + criteriaMenu2.append(('top 20000','20000')) + + criteriaMenu3 = HT.Select(name='criteria3', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") + criteriaMenu3.append(('top 100','100')) + criteriaMenu3.append(('top 200','200')) + criteriaMenu3.append(('top 500','500')) + criteriaMenu3.append(('top 1000','1000')) + criteriaMenu3.append(('top 2000','2000')) + criteriaMenu3.append(('top 5000','5000')) + criteriaMenu3.append(('top 10000','10000')) + criteriaMenu3.append(('top 15000','15000')) + criteriaMenu3.append(('top 20000','20000')) + + + self.MDPRow1 = HT.TR(Class='mdp1') + self.MDPRow2 = HT.TR(Class='mdp2') + self.MDPRow3 = HT.TR(Class='mdp3') + + correlationMenus1 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu1, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu1)), + self.MDPRow1, cellspacing=0, width="619px", cellpadding=2) + correlationMenus1.append(HT.Input(name='orderBy', value='2', type='hidden')) # to replace the orderBy menu + correlationMenus2 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu2, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu2)), + self.MDPRow2, cellspacing=0, width="619px", cellpadding=2) + correlationMenus2.append(HT.Input(name='orderBy', value='2', type='hidden')) + correlationMenus3 = HT.TableLite( + HT.TR(HT.TD(databaseText), HT.TD(databaseMenu3, colspan="3")), + HT.TR(HT.TD(criteriaText), HT.TD(criteriaMenu3)), + self.MDPRow3, cellspacing=0, width="619px", cellpadding=2) + correlationMenus3.append(HT.Input(name='orderBy', value='2', type='hidden')) + + else: + correlationMenus = "" + + + corr_row = HT.TR() + corr_container = HT.Div(id="corr_tabs", Class="ui-tabs") + + if (thisTrait.db != None and thisTrait.db.type =='ProbeSet'): + corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1"), HT.Href(text='Literature r', url="#corrtabs-2"), HT.Href(text='Tissue r', url="#corrtabs-3")] + else: + corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1")] + + corr_tabs = HT.List(corr_tab_list) + corr_container.append(corr_tabs) + + if correlationMenus1 or correlationMenus2 or correlationMenus3: + sample_div = HT.Div(id="corrtabs-1") + sample_container = HT.Span() + + sample_type = HT.Input(type="radio", name="sample_method", value="1", checked="checked") + sample_type2 = HT.Input(type="radio", name="sample_method", value="2") + + sampleTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + sampleTD = HT.TD(correlationMenus1, HT.BR(), + "Pearson", sample_type, " "*3, "Spearman Rank", sample_type2, HT.BR(), HT.BR(), + sample_correlation, HT.BR(), HT.BR()) + + sampleTD.append(HT.Span("The ",HT.Href(url="/correlationAnnotation.html#sample_r", target="_blank", text="Sample Correlation")," is computed between trait data and", + " any ",HT.BR()," other traits in the sample database selected above. Use ", + HT.Href(url="/glossary.html#Correlations", target="_blank", text="Spearman Rank"), + HT.BR(),"when the sample size is small (<20) or when there are influential \ + outliers.", HT.BR(),Class="fs12")) + + sampleTable.append(sampleTD) + + sample_container.append(sampleTable) + sample_div.append(sample_container) + corr_container.append(sample_div) + + literature_div = HT.Div(id="corrtabs-2") + literature_container = HT.Span() + + literatureTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + literatureTD = HT.TD(correlationMenus2,HT.BR(),lit_correlation, HT.BR(), HT.BR()) + literatureTD.append(HT.Span("The ", HT.Href(url="/correlationAnnotation.html", target="_blank",text="Literature Correlation"), " (Lit r) between this gene and all other genes is computed",HT.BR(), + "using the ", HT.Href(url="https://grits.eecs.utk.edu/sgo/sgo.html", target="_blank", text="Semantic Gene Organizer"), + " and human, rat, and mouse data from PubMed. ", HT.BR(),"Values are ranked by Lit r, \ + but Sample r and Tissue r are also displayed.", HT.BR(), HT.BR(), + HT.Href(url="/glossary.html#Literature", target="_blank", text="More on using Lit r"), Class="fs12")) + literatureTable.append(literatureTD) + + literature_container.append(literatureTable) + literature_div.append(literature_container) + + if thisTrait.db != None: + if (thisTrait.db.type =='ProbeSet'): + corr_container.append(literature_div) + + tissue_div = HT.Div(id="corrtabs-3") + tissue_container = HT.Span() + + tissue_type = HT.Input(type="radio", name="tissue_method", value="4", checked="checked") + tissue_type2 = HT.Input(type="radio", name="tissue_method", value="5") + + tissueTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + tissueTD = HT.TD(correlationMenus3,HT.BR(), + "Pearson", tissue_type, " "*3, "Spearman Rank", tissue_type2, HT.BR(), HT.BR(), + tissue_correlation, HT.BR(), HT.BR()) + tissueTD.append(HT.Span("The ", HT.Href(url="/webqtl/main.py?FormID=tissueCorrelation", target="_blank", text="Tissue Correlation"), + " (Tissue r) estimates the similarity of expression of two genes",HT.BR()," or \ + transcripts across different cells, tissues, or organs (",HT.Href(url="/correlationAnnotation.html#tissue_r", target="_blank", text="glossary"),"). \ + Tissue correlations",HT.BR()," are generated by analyzing expression in multiple samples usually taken from \ + single cases.",HT.BR(),HT.Bold("Pearson")," and ",HT.Bold("Spearman Rank")," correlations have been computed for all pairs \ + of genes",HT.BR()," using data from mouse samples.", + HT.BR(), Class="fs12")) + tissueTable.append(tissueTD) + + tissue_container.append(tissueTable) + tissue_div.append(tissue_container) + if thisTrait.db != None: + if (thisTrait.db.type =='ProbeSet'): + corr_container.append(tissue_div) + + corr_row.append(HT.TD(corr_container)) + + corr_script = HT.Script(language="Javascript") + corr_script_text = """$(function() { $("#corr_tabs").tabs(); });""" + corr_script.append(corr_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target4") + submitTable.append(corr_row) + submitTable.append(corr_script) + + title3Body.append(submitTable) + + + def dispMappingTools(self, fd, title4Body, thisTrait): + + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + + RISetgp = fd.RISet + if RISetgp[:3] == 'BXD': + RISetgp = 'BXD' + + #check boxes - one for regular interval mapping, the other for composite + permCheck1= HT.Input(type='checkbox', Class='checkbox', name='permCheck1',checked="on") + bootCheck1= HT.Input(type='checkbox', Class='checkbox', name='bootCheck1',checked=0) + permCheck2= HT.Input(type='checkbox', Class='checkbox', name='permCheck2',checked="on") + bootCheck2= HT.Input(type='checkbox', Class='checkbox', name='bootCheck2',checked=0) + optionbox1 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression1',checked=0) + optionbox2 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression2',checked=0) + optionbox3 = HT.Input(type='checkbox', Class='checkbox', name='parentsf14regression3',checked=0) + applyVariance1 = HT.Input(name='applyVarianceSE1',type='checkbox', Class='checkbox') + applyVariance2 = HT.Input(name='applyVarianceSE2',type='checkbox', Class='checkbox') + + IntervalMappingButton=HT.Input(type='button' ,name='interval',value=' Compute ', Class="button") + CompositeMappingButton=HT.Input(type='button' ,name='composite',value=' Compute ', Class="button") + MarkerRegressionButton=HT.Input(type='button',name='marker', value=' Compute ', Class="button") + + chrText = HT.Span("Chromosome:", Class="ffl fwb fs12") + + # updated by NL 5-28-2010 + # Interval Mapping + chrMenu = HT.Select(name='chromosomes1') + chrMenu.append(tuple(["All",-1])) + for i in range(len(fd.genotype)): + if len(fd.genotype[i]) > 1: + chrMenu.append(tuple([fd.genotype[i].name,i])) + + #Menu for Composite Interval Mapping + chrMenu2 = HT.Select(name='chromosomes2') + chrMenu2.append(tuple(["All",-1])) + for i in range(len(fd.genotype)): + if len(fd.genotype[i]) > 1: + chrMenu2.append(tuple([fd.genotype[i].name,i])) + + if fd.genotype.Mbmap: + scaleText = HT.Span("Mapping Scale:", Class="ffl fwb fs12") + scaleMenu1 = HT.Select(name='scale1', onChange="checkUncheck(window.document.dataInput.scale1.value, window.document.dataInput.permCheck1, window.document.dataInput.bootCheck1)") + scaleMenu1.append(("Megabase",'physic')) + scaleMenu1.append(("Centimorgan",'morgan')) + scaleMenu2 = HT.Select(name='scale2', onChange="checkUncheck(window.document.dataInput.scale2.value, window.document.dataInput.permCheck2, window.document.dataInput.bootCheck2)") + scaleMenu2.append(("Megabase",'physic')) + scaleMenu2.append(("Centimorgan",'morgan')) + + controlText = HT.Span("Control Locus:", Class="ffl fwb fs12") + controlMenu = HT.Input(type="text", name="controlLocus", Class="controlLocus") + + if fd.genotype.Mbmap: + intMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), + HT.TR(HT.TD(scaleText), HT.TD(scaleMenu1)), + cellspacing=0, width="263px", cellpadding=2) + compMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), + HT.TR(HT.TD(scaleText), HT.TD(scaleMenu2)), + HT.TR(HT.TD(controlText), HT.TD(controlMenu)), + cellspacing=0, width="325px", cellpadding=2) + else: + intMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu, colspan="3")), + cellspacing=0, width="263px", cellpadding=2) + compMappingMenu = HT.TableLite( + HT.TR(HT.TD(chrText), HT.TD(chrMenu2, colspan="3")), + HT.TR(HT.TD(controlText), HT.TD(controlMenu)), + cellspacing=0, width="325px", cellpadding=2) + + directPlotButton = "" + directPlotButton = HT.Input(type='button',name='', value=' Compute ',\ + onClick="dataEditingFunc(this.form,'directPlot');",Class="button") + directPlotSortText = HT.Span(HT.Bold("Sort by: "), Class="ffl fwb fs12") + directPlotSortMenu = HT.Select(name='graphSort') + directPlotSortMenu.append(('LRS Full',0)) + directPlotSortMenu.append(('LRS Interact',1)) + directPlotPermuText = HT.Span("Permutation Test (n=500)", Class="ffl fs12") + directPlotPermu = HT.Input(type='checkbox', Class='checkbox',name='directPermuCheckbox', checked="on") + pairScanReturnText = HT.Span(HT.Bold("Return: "), Class="ffl fwb fs12") + pairScanReturnMenu = HT.Select(name='pairScanReturn') + pairScanReturnMenu.append(('top 50','50')) + pairScanReturnMenu.append(('top 100','100')) + pairScanReturnMenu.append(('top 200','200')) + pairScanReturnMenu.append(('top 500','500')) + + pairScanMenus = HT.TableLite( + HT.TR(HT.TD(directPlotSortText), HT.TD(directPlotSortMenu)), + HT.TR(HT.TD(pairScanReturnText), HT.TD(pairScanReturnMenu)), + cellspacing=0, width="232px", cellpadding=2) + + markerSuggestiveText = HT.Span(HT.Bold("Display LRS greater than:"), Class="ffl fwb fs12") + markerSuggestive = HT.Input(name='suggestive', size=5, maxlength=8) + displayAllText = HT.Span(" Display all LRS ", Class="ffl fs12") + displayAll = HT.Input(name='displayAllLRS', type="checkbox", Class='checkbox') + useParentsText = HT.Span(" Use Parents ", Class="ffl fs12") + useParents = optionbox2 + applyVarianceText = HT.Span(" Use Weighted ", Class="ffl fs12") + + markerMenu = HT.TableLite( + HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive)), + HT.TR(HT.TD(displayAll,displayAllText)), + HT.TR(HT.TD(useParents,useParentsText)), + HT.TR(HT.TD(applyVariance2,applyVarianceText)), + cellspacing=0, width="263px", cellpadding=2) + + + mapping_row = HT.TR() + mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") + + mapping_tab_list = [HT.Href(text="Interval", url="#mappingtabs-1"), HT.Href(text="Marker Regression", url="#mappingtabs-2"), HT.Href(text="Composite", url="#mappingtabs-3"), HT.Href(text="Pair-Scan", url="#mappingtabs-4")] + mapping_tabs = HT.List(mapping_tab_list) + mapping_container.append(mapping_tabs) + + interval_div = HT.Div(id="mappingtabs-1") + interval_container = HT.Span() + + intervalTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + intTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + intTD.append(intMappingMenu,HT.BR()) + + intTD.append(permCheck1,'Permutation Test (n=2000)',HT.BR(), + bootCheck1,'Bootstrap Test (n=2000)', HT.BR(), optionbox1, 'Use Parents', HT.BR(), + applyVariance1,'Use Weighted', HT.BR(), HT.BR(),IntervalMappingButton, HT.BR(), HT.BR()) + intervalTable.append(HT.TR(intTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#intmap', target='_blank', text='Interval Mapping'), + ' computes linkage maps for the entire genome or single',HT.BR(),' chromosomes.', + ' The ',HT.Href(url='/glossary.html#permutation', target='_blank', text='Permutation Test'),' estimates suggestive and significant ',HT.BR(),' linkage scores. \ + The ',HT.Href(url='/glossary.html#bootstrap', target='_blank', text='Bootstrap Test'), ' estimates the precision of the QTL location.' + ,Class="fs12"), HT.BR(), valign="top"))) + + interval_container.append(intervalTable) + interval_div.append(interval_container) + mapping_container.append(interval_div) + + # Marker Regression + + marker_div = HT.Div(id="mappingtabs-2") + marker_container = HT.Span() + + markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + markerTD.append(markerMenu,HT.BR()) + + markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) + + markerTable.append(HT.TR(markerTD),HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#',target='_blank',text='Marker regression'), + ' computes and displays LRS values for individual markers.',HT.BR(), + 'This function also lists additive effects (phenotype units per allele) and', HT.BR(), + 'dominance deviations for some datasets.', HT.BR(),Class="fs12"), HT.BR(), valign="top"))) + + marker_container.append(markerTable) + marker_div.append(marker_container) + mapping_container.append(marker_div) + + # Composite interval mapping + composite_div = HT.Div(id="mappingtabs-3") + composite_container = HT.Span() + + compositeTable = HT.TableLite(cellspacing=0, cellpadding=3, width="100%") + compTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + compTD.append(compMappingMenu,HT.BR()) + + compTD.append(permCheck2, 'Permutation Test (n=2000)',HT.BR(), + bootCheck2,'Bootstrap Test (n=2000)', HT.BR(), + optionbox3, 'Use Parents', HT.BR(), HT.BR(), CompositeMappingButton, HT.BR(), HT.BR()) + compositeTable.append(HT.TR(compTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Composite',target='_blank',text='Composite Interval Mapping'), + " allows you to control for a single marker as",HT.BR()," a cofactor. ", + "To find a control marker, run the ",HT.Bold("Marker Regression")," function."), + HT.BR(), valign="top"))) + + composite_container.append(compositeTable) + composite_div.append(composite_container) + mapping_container.append(composite_div) + + # Pair Scan + + pairscan_div = HT.Div(id="mappingtabs-4") + pairscan_container = HT.Span() + + pairScanTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + pairScanTD = HT.TD(NOWRAP='ON', Class="fs12 fwn") + pairScanTD.append(pairScanMenus,HT.BR()) + pairScanTD.append(directPlotPermu, directPlotPermuText, HT.BR(), HT.BR(), + directPlotButton,HT.BR(),HT.BR()) + pairScanTable.append(HT.TR(pairScanTD), HT.TR(HT.TD(HT.Span(HT.Href(url='/glossary.html#Pair_Scan', target="_blank", text='Pair-Scan'), + ' searches for pairs of chromosomal regions that are',HT.BR(), + 'involved in two-locus epistatic interactions.'), HT.BR(), valign="top"))) + + pairscan_container.append(pairScanTable) + pairscan_div.append(pairscan_container) + mapping_container.append(pairscan_div) + + mapping_row.append(HT.TD(mapping_container)) + + # Treat Interval Mapping and Marker Regression and Pair Scan as a group for displaying + #disable Interval Mapping and Marker Regression and Pair Scan for human and the dataset doesn't have genotype file + mappingMethodId = webqtlDatabaseFunction.getMappingMethod(cursor=self.cursor, groupName=RISetgp) + + mapping_script = HT.Script(language="Javascript") + mapping_script_text = """$(function() { $("#mapping_tabs").tabs(); });""" + mapping_script.append(mapping_script_text) + + submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") + + if mappingMethodId != None: + if int(mappingMethodId) == 1: + submitTable.append(mapping_row) + submitTable.append(mapping_script) + elif int(mappingMethodId) == 4: + # NL; 09-26-2011 testing for Human Genome Association function + mapping_row=HT.TR() + mapping_container = HT.Div(id="mapping_tabs", Class="ui-tabs") + + mapping_tab_list = [HT.Href(text="Genome Association", url="#mappingtabs-1")] + mapping_tabs = HT.List(mapping_tab_list) + mapping_container.append(mapping_tabs) + + # Genome Association + markerSuggestiveText = HT.Span(HT.Bold("P Value:"), Class="ffl fwb fs12") + + markerSuggestive = HT.Input(name='pValue', value='0.001', size=10, maxlength=20,onClick="this.value='';",onBlur="if(this.value==''){this.value='0.001'};") + markerMenu = HT.TableLite(HT.TR(HT.TD(markerSuggestiveText), HT.TD(markerSuggestive),HT.TD(HT.Italic('   (e.g. 0.001 or 1e-3 or 1E-3 or 3)'))),cellspacing=0, width="400px", cellpadding=2) + MarkerRegressionButton=HT.Input(type='button',name='computePlink', value='  Compute Using PLINK  ', onClick= "validatePvalue(this.form);", Class="button") + + marker_div = HT.Div(id="mappingtabs-1") + marker_container = HT.Span() + markerTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + markerTD = HT.TD(valign="top",NOWRAP='ON', Class="fs12 fwn") + markerTD.append(markerMenu,HT.BR()) + markerTD.append(MarkerRegressionButton,HT.BR(),HT.BR()) + markerTable.append(HT.TR(markerTD)) + + marker_container.append(markerTable) + marker_div.append(marker_container) + + mapping_container.append(marker_div) + mapping_row.append(HT.TD(mapping_container)) + submitTable.append(mapping_row) + submitTable.append(mapping_script) + else: + submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("mappingMethodId %s has not been implemented for this dataset yet." % mappingMethodId), id="mapping_tabs", Class="ui-tabs")))) + submitTable.append(mapping_script) + + else: + submitTable.append(HT.TR(HT.TD(HT.Div(HT.Italic("Mapping options are disabled for data not matched with genotypes."), id="mapping_tabs", Class="ui-tabs")))) + submitTable.append(mapping_script) + + title4Body.append(submitTable) + + + def natural_sort(strain_list): + + sorted = [] + for strain in strain_list: + try: + strain = int(strain) + try: sorted[-1] = sorted[-1] * 10 + strain + except: sorted.append(strain) + except: + sorted.append(strain) + return sorted + + ########################################## + ## Function to display trait tables + ########################################## + def dispTraitValues(self, fd , title5Body, varianceDataPage, nCols, mainForm, thisTrait): + traitTableOptions = HT.Div(style="border: 3px solid #EEEEEE; -moz-border-radius: 10px; -webkit-border-radius: 10px; width: 625px; padding: 5px 5px 10px 8px; font-size: 12px; background: #DDDDDD;") + resetButton = HT.Input(type='button',name='resetButton',value=' Reset ',Class="button") + blockSamplesField = HT.Input(type="text",style="background-color:white;border: 1px solid black;font-size: 14px;", name="removeField") + blockSamplesButton = HT.Input(type='button',value=' Block ', name='blockSamples', Class="button") + showHideNoValue = HT.Input(type='button', name='showHideNoValue', value=' Hide No Value ',Class='button') + blockMenuSpan = HT.Span(Id="blockMenuSpan") + blockMenu = HT.Select(name='block_method') + + if fd.genotype.type == "riset": + allstrainlist_neworder = fd.f1list + fd.strainlist + else: + allstrainlist_neworder = fd.f1list + fd.parlist + fd.strainlist + + attribute_ids = [] + attribute_names = [] + try: + #ZS: Id values for this trait's extra attributes; used to create "Exclude" dropdown and query for attribute values and create + self.cursor.execute("""SELECT CaseAttribute.Id, CaseAttribute.Name + FROM CaseAttribute, CaseAttributeXRef + WHERE CaseAttributeXRef.ProbeSetFreezeId = '%s' AND + CaseAttribute.Id = CaseAttributeXRef.CaseAttributeId + group by CaseAttributeXRef.CaseAttributeId""" % (str(thisTrait.db.id))) + + exclude_menu = HT.Select(name="exclude_menu") + dropdown_menus = [] #ZS: list of dropdown menus with the distinct values of each attribute (contained in DIVs so the style parameter can be edited and they can be hidden) + + for attribute in self.cursor.fetchall(): + attribute_ids.append(attribute[0]) + attribute_names.append(attribute[1]) + for this_attr_name in attribute_names: + exclude_menu.append((this_attr_name.capitalize(), this_attr_name)) + self.cursor.execute("""SELECT DISTINCT CaseAttributeXRef.Value + FROM CaseAttribute, CaseAttributeXRef + WHERE CaseAttribute.Name = '%s' AND + CaseAttributeXRef.CaseAttributeId = CaseAttribute.Id""" % (this_attr_name)) + try: + distinct_values = self.cursor.fetchall() + attr_value_menu_div = HT.Div(style="display:none;", Class="attribute_values") #container used to show/hide dropdown menus + attr_value_menu = HT.Select(name=this_attr_name) + attr_value_menu.append(("None", "show_all")) + for value in distinct_values: + attr_value_menu.append((str(value[0]), value[0])) + attr_value_menu_div.append(attr_value_menu) + dropdown_menus.append(attr_value_menu_div) + except: + pass + except: + pass + + other_strains = [] + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + other_strains.append(strain) + + if other_strains: + blockMenu.append(('%s Only' % fd.RISet,'1')) + blockMenu.append(('Non-%s Only' % fd.RISet,'0')) + blockMenuSpan.append(blockMenu) + else: + pass + + showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') + showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") + if other_strains: + showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) + else: + showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) + + exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') + if len(attribute_names) > 0: + excludeButton = HT.Input(type='button', name='excludeGroup', value=' Block ', Class='button') + showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) + for menu in dropdown_menus: + showHideMenuOptions.append(menu) + showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) + showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) + + traitTableOptions.append(showHideMenuOptions,HT.BR(),HT.BR()) + traitTableOptions.append(HT.Span("  Outliers highlighted in ", HT.Bold(" yellow ", style="background-color:yellow;"), " can be hidden using the ", + HT.Strong(" Hide Outliers "), " button,",HT.BR(),"  and samples with no value (x) can be hidden by clicking ", + HT.Strong(" Hide No Value "), "."), HT.BR()) + + + dispintro = HT.Paragraph("Edit or delete values in the Trait Data boxes, and use the ", HT.Strong("Reset"), " option as needed.",Class="fs12", style="margin-left:20px;") + + table = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target5") #Everything needs to be inside this table object in order for the toggle to work + container = HT.Div() #This will contain everything and be put into a cell of the table defined above + + container.append(dispintro, traitTableOptions, HT.BR()) + + primary_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable1", Class="tablesorter") + primary_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for primary table object + + other_strainsExist = False + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + other_strainsExist = True + break + + primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') + + primary_table.append(primary_header) + for i in range(len(primary_body)): + primary_table.append(primary_body[i]) + + other_strains = [] + for strain in thisTrait.data.keys(): + if strain not in allstrainlist_neworder: + allstrainlist_neworder.append(strain) + other_strains.append(strain) + + if other_strains: + other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits + other_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for other table object; same function is used as the one used for the primary table, since the header is the same + other_strains.sort() #Sort other strains + other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #Append F1 and parent strains to the beginning of the sorted list of other strains + + MDPText = HT.Span("Samples:", Class="ffl fwb fs12") + MDPMenu1 = HT.Select(name='MDPChoice1') + MDPMenu2 = HT.Select(name='MDPChoice2') + MDPMenu3 = HT.Select(name='MDPChoice3') + MDPMenu1.append(('%s Only' % fd.RISet,'1')) + MDPMenu2.append(('%s Only' % fd.RISet,'1')) + MDPMenu3.append(('%s Only' % fd.RISet,'1')) + MDPMenu1.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu2.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu3.append(('Non-%s Only' % fd.RISet,'2')) + MDPMenu1.append(('All Cases','0')) + MDPMenu2.append(('All Cases','0')) + MDPMenu3.append(('All Cases','0')) + self.MDPRow1.append(HT.TD(MDPText),HT.TD(MDPMenu1)) + self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) + self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) + + other_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') + + other_table.append(other_header) + for i in range(len(other_body)): + other_table.append(other_body[i]) + else: + pass + + if other_strains or (fd.f1list and thisTrait.data.has_key(fd.f1list[0])) \ + or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): + fd.allstrainlist = allstrainlist_neworder + + if nCols == 6 and fd.varianceDispName != 'Variance': + mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) + + primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values + container.append(primary_div) + + if other_strains: + other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values + container.append(HT.Div(' ', height=30)) + container.append(other_div) + + table.append(HT.TR(HT.TD(container))) + title5Body.append(table) + + def addTrait2Table(self, fd, varianceDataPage, strainlist, mainForm, thisTrait, other_strainsExist=None, attribute_ids=[], attribute_names=[], strains='primary'): + #XZ, Aug 23, 2010: I commented the code related to the display of animal case + #strainInfo = thisTrait.has_key('strainInfo') and thisTrait.strainInfo + + table_body = [] + vals = [] + + for i, strainNameOrig in enumerate(strainlist): + strainName = strainNameOrig.replace("_2nd_", "") + + try: + thisval = thisTrait.data[strainName].val + thisvar = thisTrait.data[strainName].var + thisValFull = [strainName,thisval,thisvar] + except: + continue + + vals.append(thisValFull) + + upperBound, lowerBound = Plot.findOutliers(vals) # ZS: Values greater than upperBound or less than lowerBound are considered outliers. + + for i, strainNameOrig in enumerate(strainlist): + + trId = strainNameOrig + selectCheck = HT.Input(type="checkbox", name="selectCheck", value=trId, Class="checkbox", onClick="highlight(this)") + + strainName = strainNameOrig.replace("_2nd_", "") + strainNameAdd = '' + if fd.RISet == 'AXBXA' and strainName in ('AXB18/19/20','AXB13/14','BXA8/17'): + strainNameAdd = HT.Href(url='/mouseCross.html#AXB/BXA', text=HT.Sup('#'), Class='fs12', target="_blank") + + try: + thisval, thisvar, thisNP = thisTrait.data[strainName].val, thisTrait.data[strainName].var, thisTrait.data[strainName].N + if thisNP: + mainForm.append(HT.Input(name='N'+strainName, value=thisNP, type='hidden')) + else: + pass + except: + thisval = thisvar = 'x' + + try: + traitVal = thisval + dispVal = "%2.3f" % thisval + except: + traitVal = '' + dispVal = 'x' + + strainNameDisp = HT.Span(strainName, Class='fs14 fwn ffl') + + if varianceDataPage: + try: + traitVar = thisvar + dispVar = "%2.3f" % thisvar + except: + traitVar = '' + dispVar = 'x' + + if thisval == 'x': + traitVar = '' #ZS: Used to be 0, but it doesn't seem like a good idea for values of 0 to *always* be at the bottom when you sort; it makes more sense to put "nothing" + + className = 'fs13 b1 c222 ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = 'novalue ' + else: + if (thisval >= upperBound) or (thisval <= lowerBound): + className = 'fs13 b1 c222 outlier ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = 'outlier' + else: + className = 'fs13 b1 c222 ' + valueClassName = 'fs13 b1 c222 valueField ' + rowClassName = ' ' + + if varianceDataPage: + varClassName = valueClassName + str(traitVar) + valueClassName += str(traitVal) + + if strainNameOrig == strainName: + if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): + ######################################################################################################################################################## + # ZS: Append value and variance to the value and variance input fields' list of classes; this is so the javascript can update the value when the user + # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. + ######################################################################################################################################################### + + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, + onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + else: + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) + else: + valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, + onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + if varianceDataPage: + seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + + if (strains == 'primary'): + table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) + else: + table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) + + if varianceDataPage: + table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + table_row.append(HT.TD("±", width=20, align='center', Class=className)) + table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) + else: + table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + + if thisTrait and thisTrait.db and thisTrait.db.type =='ProbeSet': + if len(attribute_ids) > 0: + + #ZS: Get StrainId value for the next query + self.cursor.execute("""SELECT Strain.Id + FROM Strain, StrainXRef, InbredSet + WHERE Strain.Name = '%s' and + StrainXRef.StrainId = Strain.Id and + InbredSet.Id = StrainXRef.InbredSetId and + InbredSet.Name = '%s'""" % (strainName, fd.RISet)) + + strain_id = self.cursor.fetchone()[0] + + attr_counter = 1 # This is needed so the javascript can know which attribute type to associate this value with for the exported excel sheet (each attribute type being a column). + for attribute_id in attribute_ids: + + #ZS: Add extra case attribute values (if any) + self.cursor.execute("""SELECT Value + FROM CaseAttributeXRef + WHERE ProbeSetFreezeId = '%s' AND + StrainId = '%s' AND + CaseAttributeId = '%s' + group by CaseAttributeXRef.CaseAttributeId""" % (thisTrait.db.id, strain_id, str(attribute_id))) + + attributeValue = self.cursor.fetchone()[0] #Trait-specific attributes, if any + + #ZS: If it's an int, turn it into one for sorting (for example, 101 would be lower than 80 if they're strings instead of ints) + try: + attributeValue = int(attributeValue) + except: + pass + + span_Id = strains+"_attribute"+str(attr_counter)+"_sample"+str(i+1) + attr_container = HT.Span(attributeValue, Id=span_Id) + attr_className = str(attributeValue) + " " + className + table_row.append(HT.TD(attr_container, align='right', Class=attr_className)) + attr_counter += 1 + + table_body.append(table_row) + return table_body + + def getTableHeader(self, fd, thisTrait, nCols, attribute_names): + + table_header = HT.TR() + + col_class = "fs13 fwb ff1 b1 cw cbrb" + + if nCols == 6: + try: + if fd.varianceDispName: + pass + except: + fd.varianceDispName = 'Variance' + + table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), + HT.TH('Sample', align='right', width=100, Class=col_class), + HT.TH('Value', align='right', width=70, Class=col_class), + HT.TH(' ', width=20, Class=col_class), + HT.TH(fd.varianceDispName, align='right', width=80, Class=col_class)) + + elif nCols == 4: + table_header.append(HT.TH('Index', align='right', width=60, Class=col_class), + HT.TH('Sample', align='right', width=100, Class=col_class), + HT.TH('Value', align='right', width=70, Class=col_class)) + + else: + pass + + if len(attribute_names) > 0: + i=0 + for attribute in attribute_names: + char_count = len(attribute) + cell_width = char_count * 14 + table_header.append(HT.TH(attribute, align='right', width=cell_width, Class="attribute_name " + col_class)) + i+=1 + + return table_header + + + def getSortByValue(self): + + sortby = ("", "") + + return sortby diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index a63071c3..57c68a1c 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -40,148 +40,148 @@ from DataEditingPage import DataEditingPage class ShowTraitPage(DataEditingPage): - def __init__(self, fd, traitInfos = None): - - #templatePage.__init__(self, fd) - - if not self.openMysql(): - return - - #TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - print("j2") - # When is traitInfos used? - if traitInfos: - print("j2.2") - database, ProbeSetID, CellID = traitInfos - else: - print("j2.3") - print("fd is:", fd) - database = fd['database'][0] - ProbeSetID = fd['ProbeSetID'][0] - print("j2.4") - CellID = fd.get('CellID') - print("j2.6") - - # We're no longer wrapping this in an exception. If we fail, let's fail hard - # Log it and fix it - #try: - print("j3") - thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) - #except: - # heading = "Trait Data and Analysis Form" - # detail = ["The trait isn't available currently."] - # self.error(heading=heading,detail=detail,error="Error") - # return - print("j4") - if thisTrait.db.type == "ProbeSet": - - self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers - FROM ProbeSetFreeze WHERE Name = "%s"''' % database) - - indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] - - if confidential == 1: - access_to_confidential_dataset = 0 - - #for the dataset that confidentiality is 1 - #1. 'admin' and 'root' can see all of the dataset - #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) - if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: - access_to_confidential_dataset = 1 - else: - AuthorisedUsersList=AuthorisedUsers.split(',') - if AuthorisedUsersList.__contains__(self.userName): - access_to_confidential_dataset = 1 - - if not access_to_confidential_dataset: - #Error, Confidential Database - heading = "Show Database" - detail = ["The %s database you selected is not open to the public \ - at this time, please go back and select other database." % indFullName] - self.error(heading=heading,detail=detail,error="Confidential Database") - return - print("environ:", request.environ) - - # Becuase of proxying remote_addr is probably localhost, so we first try for - # HTTP_X_FORWARDED_FOR - user_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.remote_addr # in old app was fd.remote_ip - print("user_ip is:", user_ip) - query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ - UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" - self.cursor.execute(query,user_ip) - daycount = self.cursor.fetchall() - if daycount: - daycount = daycount[0][0] - if daycount > webqtlConfig.DAILYMAXIMUM: - heading = "Retrieve Data" - detail = ['For security reasons, the maximum access to a database is \ - %d times per day per ip address. You have reached the limit, please \ - try it again tomorrow.' % webqtlConfig.DAILYMAXIMUM] - self.error(heading=heading,detail=detail) - return - else: - pass - else: - pass - - if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: - heading = "Retrieve Data" - detail = ['The Record you requested doesn\'t exist!'] - self.error(heading=heading,detail=detail) - return - - #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore - # check if animal information are available - """ - self.cursor.execute(''' - SELECT - SampleXRef.ProbeFreezeId - FROM - SampleXRef, ProbeSetFreeze - WHERE - SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % thisTrait.db.name) - - sampleId = self.cursor.fetchall() - if sampleId: - thisTrait.strainInfo = 1 - else: - thisTrait.strainInfo = None - """ - - ##identification, etc. - fd.identification = '%s : %s' % (thisTrait.db.shortname,ProbeSetID) - thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database, ProbeSetID, fd['RISet']) - - if CellID: - fd.identification = '%s/%s'%(fd.identification, CellID) - thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) - - #retrieve trait information - try: - thisTrait.retrieveInfo() - thisTrait.retrieveData() - self.updMysql() - self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)", user_ip) - self.openMysql() - except Exception as why: - print("Got an exception:", why) - heading = "Retrieve Data" - detail = ["The information you requested is not avaiable at this time."] - self.error(heading=heading, detail=detail) - return - - ##read genotype file - fd.RISet = thisTrait.riset - fd.readGenotype() - - if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): - fd.displayVariance = 1 - fd.varianceDispName = 'SE' - fd.formID = 'varianceChoice' - - #self.dict['body']= thisTrait - DataEditingPage.__init__(self, fd, thisTrait) - #self.dict['title'] = '%s: Display Trait' % fd.identification + def __init__(self, fd, traitInfos = None): + + #templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + #TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + print("j2") + # When is traitInfos used? + if traitInfos: + print("j2.2") + database, ProbeSetID, CellID = traitInfos + else: + print("j2.3") + print("fd is:", fd) + database = fd['database'][0] + ProbeSetID = fd['ProbeSetID'][0] + print("j2.4") + CellID = fd.get('CellID') + print("j2.6") + + # We're no longer wrapping this in an exception. If we fail, let's fail hard + # Log it and fix it + #try: + print("j3") + thisTrait = webqtlTrait(db=database, name=ProbeSetID, cellid= CellID, cursor=self.cursor) + #except: + # heading = "Trait Data and Analysis Form" + # detail = ["The trait isn't available currently."] + # self.error(heading=heading,detail=detail,error="Error") + # return + print("j4") + if thisTrait.db.type == "ProbeSet": + + self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers + FROM ProbeSetFreeze WHERE Name = "%s"''' % database) + + indId, indName, indFullName, confidential, AuthorisedUsers = self.cursor.fetchall()[0] + + if confidential == 1: + access_to_confidential_dataset = 0 + + #for the dataset that confidentiality is 1 + #1. 'admin' and 'root' can see all of the dataset + #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: + access_to_confidential_dataset = 1 + else: + AuthorisedUsersList=AuthorisedUsers.split(',') + if AuthorisedUsersList.__contains__(self.userName): + access_to_confidential_dataset = 1 + + if not access_to_confidential_dataset: + #Error, Confidential Database + heading = "Show Database" + detail = ["The %s database you selected is not open to the public \ + at this time, please go back and select other database." % indFullName] + self.error(heading=heading,detail=detail,error="Confidential Database") + return + print("environ:", request.environ) + + # Becuase of proxying remote_addr is probably localhost, so we first try for + # HTTP_X_FORWARDED_FOR + user_ip = request.environ.get('HTTP_X_FORWARDED_FOR') or request.remote_addr # in old app was fd.remote_ip + print("user_ip is:", user_ip) + query = "SELECT count(id) FROM AccessLog WHERE ip_address = %s and \ + UNIX_TIMESTAMP()-UNIX_TIMESTAMP(accesstime)<86400" + self.cursor.execute(query,user_ip) + daycount = self.cursor.fetchall() + if daycount: + daycount = daycount[0][0] + if daycount > webqtlConfig.DAILYMAXIMUM: + heading = "Retrieve Data" + detail = ['For security reasons, the maximum access to a database is \ + %d times per day per ip address. You have reached the limit, please \ + try it again tomorrow.' % webqtlConfig.DAILYMAXIMUM] + self.error(heading=heading,detail=detail) + return + else: + pass + else: + pass + + if thisTrait.db.type != 'ProbeSet' and thisTrait.cellid: + heading = "Retrieve Data" + detail = ['The Record you requested doesn\'t exist!'] + self.error(heading=heading,detail=detail) + return + + #XZ: Aug 23, 2010: I commented out this block because this feature is not used anymore + # check if animal information are available + """ + self.cursor.execute(''' + SELECT + SampleXRef.ProbeFreezeId + FROM + SampleXRef, ProbeSetFreeze + WHERE + SampleXRef.ProbeFreezeId = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % thisTrait.db.name) + + sampleId = self.cursor.fetchall() + if sampleId: + thisTrait.strainInfo = 1 + else: + thisTrait.strainInfo = None + """ + + ##identification, etc. + fd.identification = '%s : %s' % (thisTrait.db.shortname,ProbeSetID) + thisTrait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ + &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database, ProbeSetID, fd['RISet']) + + if CellID: + fd.identification = '%s/%s'%(fd.identification, CellID) + thisTrait.returnURL = '%s&CellID=%s' % (thisTrait.returnURL, CellID) + + #retrieve trait information + try: + thisTrait.retrieveInfo() + thisTrait.retrieveData() + self.updMysql() + self.cursor.execute("insert into AccessLog(accesstime,ip_address) values(Now(),%s)", user_ip) + self.openMysql() + except Exception as why: + print("Got an exception:", why) + heading = "Retrieve Data" + detail = ["The information you requested is not avaiable at this time."] + self.error(heading=heading, detail=detail) + return + + ##read genotype file + fd.RISet = thisTrait.riset + fd.readGenotype() + + if webqtlUtil.ListNotNull(map(lambda x:x.var, thisTrait.data.values())): + fd.displayVariance = 1 + fd.varianceDispName = 'SE' + fd.formID = 'varianceChoice' + + #self.dict['body']= thisTrait + DataEditingPage.__init__(self, fd, thisTrait) + #self.dict['title'] = '%s: Display Trait' % fd.identification -- cgit v1.2.3 From f2ed5f043df623f68cf6936a8dbe9cbbeb89981d Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Tue, 5 Jun 2012 02:29:16 -0400 Subject: Actually getting some results out of the trait and data analysis page --- wqflask/runserver.py | 4 +- wqflask/wqflask/show_trait/DataEditingPage.py | 461 +++++++++++---------- .../wqflask/templates/trait_data_and_analysis.html | 7 +- wqflask/wqflask/views.py | 2 +- 4 files changed, 242 insertions(+), 232 deletions(-) diff --git a/wqflask/runserver.py b/wqflask/runserver.py index 7bd82619..a61e4029 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -18,4 +18,6 @@ _log = logging.getLogger("search") _ch = logging.StreamHandler() _log.addHandler(_ch) -app.run(host='0.0.0.0') +app.run(host='0.0.0.0', + use_debugger=False, + use_reloader=True) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 6d709012..439797c5 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -22,8 +22,8 @@ class DataEditingPage(templatePage): templatePage.__init__(self, fd) - self.dict['title'] = 'Data Editing' - TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") + #self.dict['title'] = 'Data Editing' + #TD_LR = HT.TD(valign="top",width="100%",bgcolor="#fafafa") if not self.openMysql(): return @@ -156,43 +156,49 @@ class DataEditingPage(templatePage): ## Generate form and buttons ############################# - mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), - name='dataInput', submit=HT.Input(type='hidden')) + #mainForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), + # name='dataInput', submit=HT.Input(type='hidden')) - next=HT.Input(type='submit', name='submit',value='Next',Class="button") - reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") - correlationMenus = [] + #next=HT.Input(type='submit', name='submit',value='Next',Class="button") + #reset=HT.Input(type='Reset',name='',value=' Reset ',Class="button") + #correlationMenus = [] if thisTrait == None: thisTrait = webqtlTrait(data=fd.allTraitData, db=None) # Variance submit page only if fd.enablevariance and not varianceDataPage: - title2Body.append("Click the next button to go to the variance submission form.", - HT.Center(next,reset)) + pass + #title2Body.append("Click the next button to go to the variance submission form.", + # HT.Center(next,reset)) else: - self.dispBasicStatistics(fd, title2Body, thisTrait) - self.dispCorrelationTools(fd, title3Body, thisTrait) - self.dispMappingTools(fd, title4Body, thisTrait) + pass + # We'll get this part working later + #self.dispBasicStatistics(fd, title2Body, thisTrait) + #self.dispCorrelationTools(fd, title3Body, thisTrait) + #self.dispMappingTools(fd, title4Body, thisTrait) ############################# ## Trait Value Table ############################# + # + #self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) + # + #if fd.allstrainlist: + # hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') + #for key in hddn.keys(): + # mainForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + # + #if fd.enablevariance and not varianceDataPage: + # #pre dataediting page, need to submit variance + # mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + #else: + # mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) + #TD_LR.append(HT.Paragraph(mainForm)) + #self.dict['body'] = str(TD_LR) - self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) - - if fd.allstrainlist: - hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') - for key in hddn.keys(): - mainForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) - - if fd.enablevariance and not varianceDataPage: - #pre dataediting page, need to submit variance - mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) - else: - mainForm.append(titleTop, title1,title1Body,title2,title2Body,title3,title3Body,title4,title4Body,title5,title5Body) - TD_LR.append(HT.Paragraph(mainForm)) - self.dict['body'] = str(TD_LR) + # We'll need access to thisTrait in the Jinja2 Template, so we put it inside self + self.thisTrait = thisTrait ########################################## ## Function to display header @@ -308,13 +314,13 @@ class DataEditingPage(templatePage): if snpurl: snpBrowserButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % snpurl) snpBrowserButton_img = HT.Image("/images/snp_icon.jpg", name="snpbrowser", alt=" View SNPs and Indels ", title=" View SNPs and Indels ", style="border:none;") - snpBrowserButton.append(snpBrowserButton_img) + #snpBrowserButton.append(snpBrowserButton_img) snpBrowserText = "SNPs" #XZ: Show GeneWiki for all species geneWikiButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE) + "?FormID=geneWiki&symbol=%s" % thisTrait.symbol)) geneWikiButton_img = HT.Image("/images/genewiki_icon.jpg", name="genewiki", alt=" Write or review comments about this gene ", title=" Write or review comments about this gene ", style="border:none;") - geneWikiButton.append(geneWikiButton_img) + #geneWikiButton.append(geneWikiButton_img) geneWikiText = 'GeneWiki' #XZ: display similar traits in other selected datasets @@ -323,15 +329,15 @@ class DataEditingPage(templatePage): similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.symbol, _Species) similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) similarButton_img = HT.Image("/images/find_icon.jpg", name="similar", alt=" Find similar expression data ", title=" Find similar expression data ", style="border:none;") - similarButton.append(similarButton_img) + #similarButton.append(similarButton_img) similarText = "Find" else: pass - tbl.append(HT.TR( - HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span('%s' % thisTrait.symbol, valign="top", Class="fs13 fsI"), valign="top", width=740) - )) + #tbl.append(HT.TR( + #HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on", width=90), + #HT.TD(width=10, valign="top"), + #HT.TD(HT.Span('%s' % thisTrait.symbol, valign="top", Class="fs13 fsI"), valign="top", width=740) + #)) else: tbl.append(HT.TR( HT.TD('Gene Symbol: ', Class="fwb fs13", valign="top", nowrap="on"), @@ -343,24 +349,16 @@ class DataEditingPage(templatePage): if thisTrait.alias: alias = string.replace(thisTrait.alias, ";", " ") alias = string.join(string.split(alias), ", ") - tbl.append(HT.TR( - HT.TD('Aliases: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(alias, Class="fs13 fsI"), valign="top") - )) + thisTrait.alias_fmt = alias + #XZ: Description if thisTrait.description: - tSpan = HT.Span(thisTrait.description, Class="fs13") + thisTrait.description_fmt = thisTrait.description if thisTrait.probe_target_description: - tSpan.append('; ', thisTrait.probe_target_description) + thisTrait.description_fmt += "; " + this.trait.probe_target_description else: - tSpan = HT.Span('Not available', Class="fs13") - tbl.append(HT.TR( - HT.TD('Description: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) + thisTrait.description_fmt = "Not available" #XZ: Location @@ -372,19 +370,19 @@ class DataEditingPage(templatePage): else: tSpan = HT.Span('Not available', Class="fs13") - #XZ: deal with direction - if thisTrait.strand_probe == '+': - tSpan.append(' on the plus strand ') - elif thisTrait.strand_probe == '-': - tSpan.append(' on the minus strand ') - else: - pass - - tbl.append(HT.TR( - HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) + ##XZ: deal with direction + #if thisTrait.strand_probe == '+': + # tSpan.append(' on the plus strand ') + #elif thisTrait.strand_probe == '-': + # tSpan.append(' on the minus strand ') + #else: + # pass + # + #tbl.append(HT.TR( + # HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(tSpan, valign="top") + # )) ##display Verify Location button try: @@ -473,7 +471,7 @@ class DataEditingPage(templatePage): % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), thisTrait.db, thisTrait.name, thisTrait.cellid, fd.RISet) probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") - probeButton.append(probeButton_img) + #probeButton.append(probeButton_img) probeText = "Probes" tSpan = HT.Span(Class="fs13") @@ -481,26 +479,28 @@ class DataEditingPage(templatePage): #XZ: deal with blat score and blat specificity. if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: if thisTrait.probe_set_specificity: - tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) + pass + #tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) if thisTrait.probe_set_blat_score: - tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) + pass + #tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) onClick="openNewWin('/blatInfo.html')" - tbl.append(HT.TR( - HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) - - tSpan = HT.Span(Class="fs13") - tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) - - tbl.append(HT.TR( - HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) + #tbl.append(HT.TR( + # HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(tSpan, valign="top") + # )) + + #tSpan = HT.Span(Class="fs13") + #tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) + # + #tbl.append(HT.TR( + # HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(tSpan, valign="top") + # )) if thisTrait.cellid: self.cursor.execute(""" @@ -515,12 +515,13 @@ class DataEditingPage(templatePage): HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") )) else: - tbl.append(HT.TR( - HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, - target='_blank', Class="fs13 fwn non_bold"), valign="top") - )) + #tbl.append(HT.TR( + # HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, + # target='_blank', Class="fs13 fwn non_bold"), valign="top") + # )) + pass #XZ: ID links if thisTrait.genbankid or thisTrait.geneid or thisTrait.unigeneid or thisTrait.omim or thisTrait.homologeneid: @@ -529,7 +530,7 @@ class DataEditingPage(templatePage): if thisTrait.geneid: gurl = HT.Href(text= 'Gene', target='_blank',\ url=webqtlConfig.NCBI_LOCUSID % thisTrait.geneid, Class="fs14 fwn", title="Info from NCBI Entrez Gene") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + #tSpan.append(HT.Span(gurl, style=idStyle), " "*2) if thisTrait.omim: gurl = HT.Href(text= 'OMIM', target='_blank', \ url= webqtlConfig.OMIM_ID % thisTrait.omim,Class="fs14 fwn", title="Summary from On Mendelian Inheritance in Man") @@ -538,7 +539,7 @@ class DataEditingPage(templatePage): try: gurl = HT.Href(text= 'UniGene',target='_blank',\ url= webqtlConfig.UNIGEN_ID % tuple(string.split(thisTrait.unigeneid,'.')[:2]),Class="fs14 fwn", title="UniGene ID") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + #tSpan.append(HT.Span(gurl, style=idStyle), " "*2) except: pass if thisTrait.genbankid: @@ -547,19 +548,19 @@ class DataEditingPage(templatePage): thisTrait.genbankid=thisTrait.genbankid[0:-1] gurl = HT.Href(text= 'GenBank', target='_blank', \ url= webqtlConfig.GENBANK_ID % thisTrait.genbankid,Class="fs14 fwn", title="Find the original GenBank sequence used to design the probes") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + #tSpan.append(HT.Span(gurl, style=idStyle), " "*2) if thisTrait.homologeneid: hurl = HT.Href(text= 'HomoloGene', target='_blank',\ url=webqtlConfig.HOMOLOGENE_ID % thisTrait.homologeneid, Class="fs14 fwn", title="Find similar genes in other species") - tSpan.append(HT.Span(hurl, style=idStyle), " "*2) + #tSpan.append(HT.Span(hurl, style=idStyle), " "*2) - tbl.append( - HT.TR(HT.TD(colspan=3,height=6)), - HT.TR( - HT.TD('Resource Links: ', Class="fwb fs13", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top") - )) + #tbl.append( + # HT.TR(HT.TD(colspan=3,height=6)), + # HT.TR( + # HT.TD('Resource Links: ', Class="fwb fs13", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(tSpan, valign="top") + # )) #XZ: Resource Links: if thisTrait.symbol: @@ -581,9 +582,9 @@ class DataEditingPage(templatePage): if chr and txst and txen and kgId: txst = int(txst*1000000) txen = int(txen*1000000) - tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ - title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('rn3',kgId,chr,txst,txen),Class="fs14 fwn"), style=linkStyle) - , " "*2) + #tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + # title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('rn3',kgId,chr,txst,txen),Class="fs14 fwn"), style=linkStyle) + # , " "*2) except: pass if _Species == "mouse": @@ -611,14 +612,15 @@ class DataEditingPage(templatePage): # % (thisTrait.symbol,symatlas_species),Class="fs14 fwn", \ # title="Expression across many tissues and cell types"), style=linkStyle), " "*2) if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): - tSpan.append(HT.Span(HT.Href(text= 'BioGPS',target="mainFrame",\ - url="http://biogps.gnf.org/?org=%s#goto=genereport&id=%s" \ - % (_Species, thisTrait.geneid),Class="fs14 fwn", \ - title="Expression across many tissues and cell types"), style=linkStyle), " "*2) - tSpan.append(HT.Span(HT.Href(text= 'STRING',target="mainFrame",\ - url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ - % thisTrait.symbol,Class="fs14 fwn", \ - title="Protein interactions: known and inferred"), style=linkStyle), " "*2) + #tSpan.append(HT.Span(HT.Href(text= 'BioGPS',target="mainFrame",\ + # url="http://biogps.gnf.org/?org=%s#goto=genereport&id=%s" \ + # % (_Species, thisTrait.geneid),Class="fs14 fwn", \ + # title="Expression across many tissues and cell types"), style=linkStyle), " "*2) + pass + #tSpan.append(HT.Span(HT.Href(text= 'STRING',target="mainFrame",\ + # url="http://string.embl.de/newstring_cgi/show_link_summary.pl?identifier=%s" \ + # % thisTrait.symbol,Class="fs14 fwn", \ + # title="Protein interactions: known and inferred"), style=linkStyle), " "*2) if thisTrait.symbol: #ZS: The "species scientific" converts the plain English species names we're using to their scientific names, which are needed for PANTHER's input #We should probably use the scientific name along with the English name (if not instead of) elsewhere as well, given potential non-English speaking users @@ -634,30 +636,30 @@ class DataEditingPage(templatePage): species_scientific = "all" species_scientific - tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ - url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ - % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ - title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) + #tSpan.append(HT.Span(HT.Href(text= 'PANTHER',target="mainFrame", \ + # url="http://www.pantherdb.org/genes/geneList.do?searchType=basic&fieldName=all&organism=%s&listType=1&fieldValue=%s" \ + # % (species_scientific, thisTrait.symbol),Class="fs14 fwn", \ + # title="Gene and protein data resources from Celera-ABI"), style=linkStyle), " "*2) else: pass #tSpan.append(HT.Span(HT.Href(text= 'BIND',target="mainFrame",\ # url="http://bind.ca/?textquery=%s" \ # % thisTrait.symbol,Class="fs14 fwn", \ # title="Protein interactions"), style=linkStyle), " "*2) - if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): - tSpan.append(HT.Span(HT.Href(text= 'Gemma',target="mainFrame",\ - url="http://www.chibi.ubc.ca/Gemma/gene/showGene.html?ncbiid=%s" \ - % thisTrait.geneid, Class="fs14 fwn", \ - title="Meta-analysis of gene expression data"), style=linkStyle), " "*2) - tSpan.append(HT.Span(HT.Href(text= 'SynDB',target="mainFrame",\ - url="http://lily.uthsc.edu:8080/20091027_GNInterfaces/20091027_redirectSynDB.jsp?query=%s" \ - % thisTrait.symbol, Class="fs14 fwn", \ - title="Brain synapse database"), style=linkStyle), " "*2) - if _Species == "mouse": - tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ - url="http://mouse.brain-map.org/brain/%s.html" \ - % thisTrait.symbol, Class="fs14 fwn", \ - title="Allen Brain Atlas"), style=linkStyle), " "*2) + #if thisTrait.geneid and (_Species == "mouse" or _Species == "rat" or _Species == "human"): + # tSpan.append(HT.Span(HT.Href(text= 'Gemma',target="mainFrame",\ + # url="http://www.chibi.ubc.ca/Gemma/gene/showGene.html?ncbiid=%s" \ + # % thisTrait.geneid, Class="fs14 fwn", \ + # title="Meta-analysis of gene expression data"), style=linkStyle), " "*2) + #tSpan.append(HT.Span(HT.Href(text= 'SynDB',target="mainFrame",\ + # url="http://lily.uthsc.edu:8080/20091027_GNInterfaces/20091027_redirectSynDB.jsp?query=%s" \ + # % thisTrait.symbol, Class="fs14 fwn", \ + # title="Brain synapse database"), style=linkStyle), " "*2) + #if _Species == "mouse": + # tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + # url="http://mouse.brain-map.org/brain/%s.html" \ + # % thisTrait.symbol, Class="fs14 fwn", \ + # title="Allen Brain Atlas"), style=linkStyle), " "*2) if thisTrait.geneid: #if _Species == "mouse": @@ -666,20 +668,22 @@ class DataEditingPage(templatePage): # % thisTrait.geneid, Class="fs14 fwn", \ # title="Allen Brain Atlas"), style=linkStyle), " "*2) if _Species == "human": - tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ - url="http://humancortex.alleninstitute.org/has/human/imageseries/search/1.html?searchSym=t&searchAlt=t&searchName=t&gene_term=&entrez_term=%s" \ - % thisTrait.geneid, Class="fs14 fwn", \ - title="Allen Brain Atlas"), style=linkStyle), " "*2) - tbl.append( - HT.TR(HT.TD(colspan=3,height=6)), - HT.TR( - HT.TD(' '), - HT.TD(width=10, valign="top"), - HT.TD(tSpan, valign="top"))) + #tSpan.append(HT.Span(HT.Href(text= 'ABA',target="mainFrame",\ + # url="http://humancortex.alleninstitute.org/has/human/imageseries/search/1.html?searchSym=t&searchAlt=t&searchName=t&gene_term=&entrez_term=%s" \ + # % thisTrait.geneid, Class="fs14 fwn", \ + # title="Allen Brain Atlas"), style=linkStyle), " "*2) + pass + + #tbl.append( + # HT.TR(HT.TD(colspan=3,height=6)), + # HT.TR( + # HT.TD(' '), + # HT.TD(width=10, valign="top"), + # HT.TD(tSpan, valign="top"))) - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="620", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(similarButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(geneWikiButton, align="center"),HT.TD(snpBrowserButton, align="center"),HT.TD(rnaseqButton, align="center"),HT.TD(probeButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(similarText, align="center"),HT.TD(verifyText, align="center"),HT.TD(geneWikiText, align="center"),HT.TD(snpBrowserText, align="center"),HT.TD(rnaseqText, align="center"),HT.TD(probeText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable = HT.TableLite(cellpadding=2, Class="collap", width="620", id="target1") + #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(similarButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(geneWikiButton, align="center"),HT.TD(snpBrowserButton, align="center"),HT.TD(rnaseqButton, align="center"),HT.TD(probeButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(similarText, align="center"),HT.TD(verifyText, align="center"),HT.TD(geneWikiText, align="center"),HT.TD(snpBrowserText, align="center"),HT.TD(rnaseqText, align="center"),HT.TD(probeText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) #for zhou mi's cliques, need to be removed @@ -690,91 +694,95 @@ class DataEditingPage(templatePage): #linkTable.append(HT.TR(linkTD)) #Info2Disp.append(linkTable) - title1Body.append(tbl, HT.BR(), menuTable) + #title1Body.append(tbl, HT.BR(), menuTable) elif thisTrait and thisTrait.db and thisTrait.db.type =='Publish': #Check if trait is phenotype if thisTrait.confidential: - tbl.append(HT.TR( - HT.TD('Pre-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.pre_publication_description, Class="fs13"), valign="top", width=740) - )) + pass + #tbl.append(HT.TR( + # HT.TD('Pre-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.pre_publication_description, Class="fs13"), valign="top", width=740) + # )) if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): - tbl.append(HT.TR( - HT.TD('Post-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Pre-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.pre_publication_abbreviation, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Post-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_abbreviation, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Lab code: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.lab_code, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Owner: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.owner, Class="fs13"), valign="top", width=740) - )) + #tbl.append(HT.TR( + # HT.TD('Post-publication Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + # )) + #tbl.append(HT.TR( + # HT.TD('Pre-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.pre_publication_abbreviation, Class="fs13"), valign="top", width=740) + # )) + #tbl.append(HT.TR( + # HT.TD('Post-publication Abbreviation: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.post_publication_abbreviation, Class="fs13"), valign="top", width=740) + # )) + #tbl.append(HT.TR( + # HT.TD('Lab code: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.lab_code, Class="fs13"), valign="top", width=740) + # )) + pass + #tbl.append(HT.TR( + # HT.TD('Owner: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.owner, Class="fs13"), valign="top", width=740) + # )) else: - tbl.append(HT.TR( - HT.TD('Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Authors: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.authors, Class="fs13"), - valign="top", width=740) - )) - tbl.append(HT.TR( - HT.TD('Title: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(thisTrait.title, Class="fs13"), - valign="top", width=740) - )) + pass + #tbl.append(HT.TR( + # HT.TD('Phenotype: ', Class="fs13 fwb", valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.post_publication_description, Class="fs13"), valign="top", width=740) + # )) + #tbl.append(HT.TR( + # HT.TD('Authors: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.authors, Class="fs13"), + # valign="top", width=740) + # )) + #tbl.append(HT.TR( + # HT.TD('Title: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(thisTrait.title, Class="fs13"), + # valign="top", width=740) + # )) if thisTrait.journal: journal = thisTrait.journal if thisTrait.year: journal = thisTrait.journal + " (%s)" % thisTrait.year - - tbl.append(HT.TR( - HT.TD('Journal: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(journal, Class="fs13"), - valign="top", width=740) - )) + # + #tbl.append(HT.TR( + # HT.TD('Journal: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(journal, Class="fs13"), + # valign="top", width=740) + # )) PubMedLink = "" if thisTrait.pubmed_id: PubMedLink = webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id if PubMedLink: - tbl.append(HT.TR( - HT.TD('Link: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(HT.Href(url=PubMedLink, text="PubMed",target='_blank',Class="fs14 fwn"), - style = "background:#cddcff;padding:2"), valign="top", width=740) - )) + #tbl.append(HT.TR( + # HT.TD('Link: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(HT.Href(url=PubMedLink, text="PubMed",target='_blank',Class="fs14 fwn"), + # style = "background:#cddcff;padding:2"), valign="top", width=740) + # )) + pass menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - title1Body.append(tbl, HT.BR(), menuTable) + #title1Body.append(tbl, HT.BR(), menuTable) elif thisTrait and thisTrait.db and thisTrait.db.type == 'Geno': #Check if trait is genotype @@ -808,32 +816,33 @@ class DataEditingPage(templatePage): rnaseqButton.append(rnaseqButtonImg) rnaseqText = "RNA-seq" - tbl.append(HT.TR( - HT.TD('Location: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span(location, Class="fs13"), valign="top", width=740) - ), - HT.TR( - HT.TD('SNP Search: ', Class="fs13 fwb", - valign="top", nowrap="on", width=90), - HT.TD(width=10, valign="top"), - HT.TD(HT.Href("http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=snp&cmd=search&term=%s" % thisTrait.name, 'NCBI',Class="fs13"), - valign="top", width=740) - )) + #tbl.append(HT.TR( + # HT.TD('Location: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span(location, Class="fs13"), valign="top", width=740) + # ), + # HT.TR( + # HT.TD('SNP Search: ', Class="fs13 fwb", + # valign="top", nowrap="on", width=90), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Href("http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=snp&cmd=search&term=%s" % thisTrait.name, 'NCBI',Class="fs13"), + # valign="top", width=740) + # )) menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - title1Body.append(tbl, HT.BR(), menuTable) + #title1Body.append(tbl, HT.BR(), menuTable) elif (thisTrait == None or thisTrait.db.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) - TempInfo = HT.Paragraph() + #TempInfo = HT.Paragraph() if thisTrait != None: if thisTrait.description: - tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),' %s ' % thisTrait.description,HT.BR()), colspan=3, height=15)) + pass + #tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),' %s ' % thisTrait.description,HT.BR()), colspan=3, height=15)) else: tbl.append(HT.TR(HT.TD(HT.Strong('Description: '),'not available',HT.BR(),HT.BR()), colspan=3, height=15)) @@ -842,10 +851,10 @@ class DataEditingPage(templatePage): else: menuTable = HT.TableLite(cellpadding=2, Class="collap", width="80", id="target1") - menuTable.append(HT.TR(HT.TD(addSelectionButton, align="right"),HT.TD(updateButton, align="right"), colspan=3, height=50, style="vertical-align:bottom;") ) - menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) - - title1Body.append(tbl, HT.BR(), menuTable) + #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="right"),HT.TD(updateButton, align="right"), colspan=3, height=50, style="vertical-align:bottom;") ) + #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) + # + #title1Body.append(tbl, HT.BR(), menuTable) else: pass diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 1325e4b0..fb2e373c 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -44,7 +44,7 @@ - Sall3 + {{ thisTrait.symbol }} @@ -52,7 +52,7 @@ - B130022O04Rik, Msal, Msal-1, Sal, Salt, Spalt + {{ thisTrait.alias_fmt }} @@ -60,7 +60,7 @@ - sal-like 3 (Drosophila) + {{ thisTrait.description_fmt }} @@ -5005,4 +5005,3 @@ {% endblock %} - diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3457f0ff..58eeddd3 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -26,4 +26,4 @@ def showDatabaseBXD(): # Here it's currently too complicated not to use an fd that is a webqtlFormData fd = webqtlFormData.webqtlFormData(request.args) template_vars = show_trait_page.ShowTraitPage(fd) - return render_template("trait_data_and_analysis.html") + return render_template("trait_data_and_analysis.html", **template_vars.__dict__) -- cgit v1.2.3 From 96cab107810b3a3ac8c804335e14c00b93e9061d Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Wed, 6 Jun 2012 01:54:06 -0400 Subject: Going to try and be a bit more object oriented --- wqflask/wqflask/show_trait/DataEditingPage.py | 10 +++++----- wqflask/wqflask/templates/trait_data_and_analysis.html | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 439797c5..1aef0349 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -350,7 +350,7 @@ class DataEditingPage(templatePage): alias = string.replace(thisTrait.alias, ";", " ") alias = string.join(string.split(alias), ", ") thisTrait.alias_fmt = alias - + #XZ: Description if thisTrait.description: @@ -364,11 +364,11 @@ class DataEditingPage(templatePage): #XZ: deal with Chr and Mb if thisTrait.chr and thisTrait.mb: - tSpan = HT.Span('Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb),Class="fs13") - elif (thisTrait.chr): - tSpan = HT.Span('Chr %s @ Unknown position' % (thisTrait.chr), Class="fs13") + thisTrait.location = 'Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb) + elif thisTrait.chr: + thisTrait.location = 'Chr %s @ Unknown position' % (thisTrait.chr) else: - tSpan = HT.Span('Not available', Class="fs13") + thisTrait.location = 'Not available' ##XZ: deal with direction #if thisTrait.strand_probe == '+': diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index fb2e373c..0eb1e012 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -68,7 +68,7 @@ - Chr 18 @ 81.163175 Mb on the minus strand
+ {{ thisTrait.location }}
-- cgit v1.2.3 From a6386179f0f94df749d7af232060ff10a68c42f6 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Wed, 6 Jun 2012 04:49:20 -0400 Subject: Most of the top fields working --- wqflask/base/webqtlTrait.py | 66 ++++++++++++++++ wqflask/wqflask/show_trait/DataEditingPage.py | 87 +++++++--------------- wqflask/wqflask/show_trait/show_trait_page.py | 1 + .../wqflask/templates/trait_data_and_analysis.html | 17 +++-- 4 files changed, 105 insertions(+), 66 deletions(-) diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 812d112a..23b98238 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -590,3 +590,69 @@ class webqtlTrait: setDescription.append( ' --- FROM : ') setDescription.append(self.db.genHTML(Class='cori')) return setDescription + + @property + def description_fmt(self): + '''Return a text formated description''' + if self.description: + formatted = self.description + if self.probe_target_description: + formatted += "; " + self.probe_target_description + else: + formatted = "Not available" + return formatted + + @property + def alias_fmt(self): + '''Return a text formatted alias''' + if self.alias: + alias = string.replace(self.alias, ";", " ") + alias = string.join(string.split(alias), ", ") + return alias + + + @property + def location_fmt(self): + '''Return a text formatted location + + While we're at it we set self.location in case we need it later (do we?) + + ''' + + if self.chr and self.mb: + self.location = 'Chr %s @ %s Mb' % (self.chr,self.mb) + elif self.chr: + self.location = 'Chr %s @ Unknown position' % (self.chr) + else: + self.location = 'Not available' + + fmt = self.location + ##XZ: deal with direction + if self.strand_probe == '+': + fmt += (' on the plus strand ') + elif self.strand_probe == '-': + fmt += (' on the minus strand ') + + return fmt + + + def get_database(self): + """ + Returns the database, and the url referring to the database if it exists + + We're going to to return two values here, and we don't want to have to call this twice from + the template. So it's not a property called from the template, but instead is called from the view + + """ + if self.cellid: + self.cursor.execute(""" + select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze + where + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Id = %d""" % thisTrait.db.id) + probeDBName = self.cursor.fetchone()[0] + return dict(name = probeDBName, + url = None) + else: + return dict(name = self.db.fullname, + url = webqtlConfig.INFOPAGEHREF % self.db.name) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 1aef0349..fda26322 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -345,44 +345,7 @@ class DataEditingPage(templatePage): HT.TD(HT.Span('Not available', Class="fs13 fsI"), valign="top") )) - #XZ: Gene Alias - if thisTrait.alias: - alias = string.replace(thisTrait.alias, ";", " ") - alias = string.join(string.split(alias), ", ") - thisTrait.alias_fmt = alias - - - #XZ: Description - if thisTrait.description: - thisTrait.description_fmt = thisTrait.description - if thisTrait.probe_target_description: - thisTrait.description_fmt += "; " + this.trait.probe_target_description - else: - thisTrait.description_fmt = "Not available" - - #XZ: Location - - #XZ: deal with Chr and Mb - if thisTrait.chr and thisTrait.mb: - thisTrait.location = 'Chr %s @ %s Mb' % (thisTrait.chr,thisTrait.mb) - elif thisTrait.chr: - thisTrait.location = 'Chr %s @ Unknown position' % (thisTrait.chr) - else: - thisTrait.location = 'Not available' - ##XZ: deal with direction - #if thisTrait.strand_probe == '+': - # tSpan.append(' on the plus strand ') - #elif thisTrait.strand_probe == '-': - # tSpan.append(' on the minus strand ') - #else: - # pass - # - #tbl.append(HT.TR( - # HT.TD('Location: ', Class="fwb fs13", valign="top", nowrap="on"), - # HT.TD(width=10, valign="top"), - # HT.TD(tSpan, valign="top") - # )) ##display Verify Location button try: @@ -474,18 +437,18 @@ class DataEditingPage(templatePage): #probeButton.append(probeButton_img) probeText = "Probes" - tSpan = HT.Span(Class="fs13") + #tSpan = HT.Span(Class="fs13") #XZ: deal with blat score and blat specificity. - if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: - if thisTrait.probe_set_specificity: - pass - #tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) - if thisTrait.probe_set_blat_score: - pass - #tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) + #if thisTrait.probe_set_specificity or thisTrait.probe_set_blat_score: + # if thisTrait.probe_set_specificity: + # pass + # #tSpan.append(HT.Href(url="/blatInfo.html", target="_blank", title="Values higher than 2 for the specificity are good", text="BLAT specificity", Class="non_bold"),": %.1f" % float(thisTrait.probe_set_specificity), " "*3) + # if thisTrait.probe_set_blat_score: + # pass + # #tSpan.append("Score: %s" % int(thisTrait.probe_set_blat_score), " "*2) - onClick="openNewWin('/blatInfo.html')" + #onClick="openNewWin('/blatInfo.html')" #tbl.append(HT.TR( # HT.TD('Target Score: ', Class="fwb fs13", valign="top", nowrap="on"), @@ -502,26 +465,28 @@ class DataEditingPage(templatePage): # HT.TD(tSpan, valign="top") # )) - if thisTrait.cellid: - self.cursor.execute(""" - select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze - where - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Id = %d""" % thisTrait.db.id) - probeDBName = self.cursor.fetchone()[0] - tbl.append(HT.TR( - HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), - HT.TD(width=10, valign="top"), - HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") - )) - else: + #if thisTrait.cellid: + # self.cursor.execute(""" + # select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze + # where + # ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + # ProbeSetFreeze.Id = %d""" % thisTrait.db.id) + # probeDBName = self.cursor.fetchone()[0] + # tbl.append(HT.TR( + # HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), + # HT.TD(width=10, valign="top"), + # HT.TD(HT.Span('%s' % probeDBName, Class="non_bold"), valign="top") + # )) + #else: #tbl.append(HT.TR( # HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), # HT.TD(width=10, valign="top"), # HT.TD(HT.Href(text=thisTrait.db.fullname, url = webqtlConfig.INFOPAGEHREF % thisTrait.db.name, # target='_blank', Class="fs13 fwn non_bold"), valign="top") # )) - pass + #pass + + thisTrait.database = thisTrait.get_database() #XZ: ID links if thisTrait.genbankid or thisTrait.geneid or thisTrait.unigeneid or thisTrait.omim or thisTrait.homologeneid: @@ -534,7 +499,7 @@ class DataEditingPage(templatePage): if thisTrait.omim: gurl = HT.Href(text= 'OMIM', target='_blank', \ url= webqtlConfig.OMIM_ID % thisTrait.omim,Class="fs14 fwn", title="Summary from On Mendelian Inheritance in Man") - tSpan.append(HT.Span(gurl, style=idStyle), " "*2) + #tSpan.append(HT.Span(gurl, style=idStyle), " "*2) if thisTrait.unigeneid: try: gurl = HT.Href(text= 'UniGene',target='_blank',\ diff --git a/wqflask/wqflask/show_trait/show_trait_page.py b/wqflask/wqflask/show_trait/show_trait_page.py index 57c68a1c..b1f71e55 100644 --- a/wqflask/wqflask/show_trait/show_trait_page.py +++ b/wqflask/wqflask/show_trait/show_trait_page.py @@ -43,6 +43,7 @@ class ShowTraitPage(DataEditingPage): def __init__(self, fd, traitInfos = None): #templatePage.__init__(self, fd) + self.fd = fd if not self.openMysql(): return diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 0eb1e012..1e67834c 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -68,7 +68,7 @@ - {{ thisTrait.location }}
+ {{ thisTrait.location_fmt }}
@@ -76,8 +76,14 @@ - BLAT specificity: 12.0   Score: 240   + + + + BLAT specificity + : {{ "%.1f" % (thisTrait.probe_set_specificity) }}    + Score: {{ "%i" % (thisTrait.probe_set_blat_score) }}   + + @@ -93,8 +99,9 @@ - Hippocampus Consortium M430v2 (Jun06) - PDNN + + {{ thisTrait.database.name }} + -- cgit v1.2.3 From f3733aa972a3b1ab2eb1ab9d02d859eb75cebbb9 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 7 Jun 2012 04:10:16 -0400 Subject: Before generating hidden fields in the template --- wqflask/wqflask/show_trait/DataEditingPage.py | 68 +++++++++++---------- .../wqflask/templates/trait_data_and_analysis.html | 71 +++++++++++++++------- 2 files changed, 86 insertions(+), 53 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index fda26322..20840975 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -1,6 +1,7 @@ import string import os import cPickle +from collections import OrderedDict #import pyXLWriter as xl from htmlgen import HTMLgen2 as HT @@ -77,37 +78,37 @@ class DataEditingPage(templatePage): ############################# # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery - hddn = { - 'FormID':fmID, - 'RISet':fd.RISet, - 'submitID':'', - 'scale':'physic', - 'additiveCheck':'ON', - 'showSNP':'ON', - 'showGenes':'ON', - 'method':None, - 'parentsf14regression':'OFF', - 'stats_method':'1', - 'chromosomes':'-1', - 'topten':'', - 'viewLegend':'ON', - 'intervalAnalystCheck':'ON', - 'valsHidden':'OFF', - 'database':'', - 'criteria':None, - 'MDPChoice':None, - 'bootCheck':None, - 'permCheck':None, - 'applyVarianceSE':None, - 'strainNames':'_', - 'strainVals':'_', - 'strainVars':'_', - 'otherStrainNames':'_', - 'otherStrainVals':'_', - 'otherStrainVars':'_', - 'extra_attributes':'_', - 'other_extra_attributes':'_' - } + hddn = OrderedDict( + FormID = fmID, + RISet = fd.RISet, + submitID = '', + scale = 'physic', + additiveCheck = 'ON', + showSNP = 'ON', + showGenes = 'ON', + method = None, + parentsf14regression = 'OFF', + stats_method = '1', + chromosomes = '-1', + topten = '', + viewLegend = 'ON', + intervalAnalystCheck = 'ON', + valsHidden = 'OFF', + database = '', + criteria = None, + MDPChoice = None, + bootCheck = None, + permCheck = None, + applyVarianceSE = None, + strainNames = '_', + strainVals = '_', + strainVars = '_', + otherStrainNames = '_', + otherStrainVals = '_', + otherStrainVars = '_', + extra_attributes = '_', + other_extra_attributes = '_' + ) if fd.enablevariance: hddn['enablevariance']='ON' @@ -486,6 +487,7 @@ class DataEditingPage(templatePage): # )) #pass + thisTrait.species = _Species # We need this in the template, so we tuck it into thisTrait thisTrait.database = thisTrait.get_database() #XZ: ID links @@ -1683,8 +1685,10 @@ class DataEditingPage(templatePage): or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): fd.allstrainlist = allstrainlist_neworder + # Sam - is this correct? if nCols == 6 and fd.varianceDispName != 'Variance': - mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) + #mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) + hddn['isSE'] = "yes" primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values container.append(primary_div) diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 1e67834c..81d6540f 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -9,23 +9,46 @@
- - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -91,7 +114,7 @@ - Mouse, BXD + {{ thisTrait.species.capitalize() }}, {{fd.RISet}} @@ -113,9 +136,15 @@ - Gene   + + + + Gene + + +   UniGene   0) and (len(primary_strains) + len(other_strains) > 3): - MDP_menu.append(('All Cases','0')) - MDP_menu.append(('%s Only' % fd.RISet,'1')) - MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) - stats_row.append("Include: ", MDP_menu, " "*3) + #MDP_menu.append(('All Cases','0')) + #MDP_menu.append(('%s Only' % fd.RISet,'1')) + #MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + #stats_row.append("Include: ", MDP_menu, " "*3) all_strains = primary_strains all_strains.sort(key=webqtlUtil.natsort_key) all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains @@ -887,8 +892,8 @@ class DataEditingPage(templatePage): all_strains = all_strains + other_strains pass - update_button = HT.Input(type='button',value=' Update Figures ', Class="button update") #This is used to reload the page and update the Basic Statistics figures with user-edited data - stats_row.append(update_button, HT.BR(), HT.BR()) + #update_button = HT.Input(type='button',value=' Update Figures ', Class="button update") #This is used to reload the page and update the Basic Statistics figures with user-edited data + #stats_row.append(update_button, HT.BR(), HT.BR()) if (len(other_strains)) > 0 and (len(primary_strains) + len(other_strains) > 4): #One set of vals for all, selected strain only, and non-selected only @@ -903,7 +908,7 @@ class DataEditingPage(templatePage): try: thisval = thisTrait.data[strainName].val thisvar = thisTrait.data[strainName].var - thisValFull = [strainName,thisval,thisvar] + thisValFull = [strainName, thisval, thisvar] except: continue @@ -955,14 +960,14 @@ class DataEditingPage(templatePage): vals_set = [vals] - stats_script = HT.Script(language="Javascript") #script needed for tabs + #stats_script = HT.Script(language="Javascript") #script needed for tabs for i, vals in enumerate(vals_set): if i == 0 and len(vals) < 4: stats_container = HT.Div(id="stats_tabs", style="padding:10px;", Class="ui-tabs") #Needed for tabs; notice the "stats_script_text" below referring to this element stats_container.append(HT.Div(HT.Italic("Fewer than 4 case data were entered. No statistical analysis has been attempted."))) stats_script_text = """$(function() { $("#stats_tabs").tabs();});""" - stats_cell.append(stats_container) + #stats_cell.append(stats_container) break elif (i == 1 and len(primary_strains) < 4): stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") @@ -972,19 +977,19 @@ class DataEditingPage(templatePage): stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" else: - stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") + #stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" if len(vals) > 4: stats_tab_list = [HT.Href(text="Basic Table", url="#statstabs-1", Class="stats_tab"),HT.Href(text="Probability Plot", url="#statstabs-5", Class="stats_tab"), HT.Href(text="Bar Graph (by name)", url="#statstabs-3", Class="stats_tab"), HT.Href(text="Bar Graph (by rank)", url="#statstabs-4", Class="stats_tab"), HT.Href(text="Box Plot", url="#statstabs-2", Class="stats_tab")] - stats_tabs = HT.List(stats_tab_list) - stats_container.append(stats_tabs) - - table_div = HT.Div(id="statstabs-1") - table_container = HT.Paragraph() - - statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + #stats_tabs = HT.List(stats_tab_list) + #stats_container.append(stats_tabs) + # + #table_div = HT.Div(id="statstabs-1") + #table_container = HT.Paragraph() + # + #statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") if thisTrait.db: if thisTrait.cellid: @@ -994,15 +999,15 @@ class DataEditingPage(templatePage): else: statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals) - statsTable.append(HT.TR(HT.TD(statsTableCell))) - - table_container.append(statsTable) - table_div.append(table_container) - stats_container.append(table_div) + #statsTable.append(HT.TR(HT.TD(statsTableCell))) - normalplot_div = HT.Div(id="statstabs-5") - normalplot_container = HT.Paragraph() - normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + #table_container.append(statsTable) + #table_div.append(table_container) + #stats_container.append(table_div) + # + #normalplot_div = HT.Div(id="statstabs-5") + #normalplot_container = HT.Paragraph() + #normalplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") try: plotTitle = thisTrait.symbol @@ -1011,55 +1016,55 @@ class DataEditingPage(templatePage): except: plotTitle = str(thisTrait.name) - normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) - normalplot.append(HT.TR(HT.TD(normalplot_img))) - normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ - normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), - "More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", - target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) - normalplot_container.append(normalplot) - normalplot_div.append(normalplot_container) - stats_container.append(normalplot_div) - - boxplot_div = HT.Div(id="statstabs-2") - boxplot_container = HT.Paragraph() - boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) - boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) - boxplot_container.append(boxplot) - boxplot_div.append(boxplot_container) - stats_container.append(boxplot_div) - - - barName_div = HT.Div(id="statstabs-3") - barName_container = HT.Paragraph() - barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") - barName.append(HT.TR(HT.TD(barName_img))) - barName_container.append(barName) - barName_div.append(barName_container) - stats_container.append(barName_div) - - barRank_div = HT.Div(id="statstabs-4") - barRank_container = HT.Paragraph() - barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") - barRank.append(HT.TR(HT.TD(barRank_img))) - barRank_container.append(barRank) - barRank_div.append(barRank_container) - stats_container.append(barRank_div) - - stats_cell.append(stats_container) - - stats_script.append(stats_script_text) - - submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") - stats_row.append(stats_cell) + #normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + #normalplot.append(HT.TR(HT.TD(normalplot_img))) + #normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ + #normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), + #"More about ", HT.Href(url="http://en.wikipedia.org/wiki/Normal_probability_plot", + # target="_blank", text="Normal Probability Plots"), " and more about interpreting these plots from the ", HT.Href(url="/glossary.html#normal_probability", target="_blank", text="glossary")))) + #normalplot_container.append(normalplot) + #normalplot_div.append(normalplot_container) + #stats_container.append(normalplot_div) + + #boxplot_div = HT.Div(id="statstabs-2") + #boxplot_container = HT.Paragraph() + #boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + #boxplot_img, boxplot_link = BasicStatisticsFunctions.plotBoxPlot(vals) + #boxplot.append(HT.TR(HT.TD(boxplot_img, HT.P(), boxplot_link, align="left"))) + #boxplot_container.append(boxplot) + #boxplot_div.append(boxplot_container) + #stats_container.append(boxplot_div) + + + #barName_div = HT.Div(id="statstabs-3") + #barName_container = HT.Paragraph() + #barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + #barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + #barName.append(HT.TR(HT.TD(barName_img))) + #barName_container.append(barName) + #barName_div.append(barName_container) + #stats_container.append(barName_div) + # + #barRank_div = HT.Div(id="statstabs-4") + #barRank_container = HT.Paragraph() + #barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") + #barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + #barRank.append(HT.TR(HT.TD(barRank_img))) + #barRank_container.append(barRank) + #barRank_div.append(barRank_container) + #stats_container.append(barRank_div) + + # stats_cell.append(stats_container) + # + #stats_script.append(stats_script_text) + # + #submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") + #stats_row.append(stats_cell) - submitTable.append(stats_row) - submitTable.append(stats_script) + #submitTable.append(stats_row) + #submitTable.append(stats_script) - title2Body.append(submitTable) + #title2Body.append(submitTable) def dispCorrelationTools(self, fd, title3Body, thisTrait): @@ -1566,10 +1571,11 @@ class DataEditingPage(templatePage): dropdown_menus = [] #ZS: list of dropdown menus with the distinct values of each attribute (contained in DIVs so the style parameter can be edited and they can be hidden) for attribute in self.cursor.fetchall(): - attribute_ids.append(attribute[0]) - attribute_names.append(attribute[1]) + #attribute_ids.append(attribute[0]) + #attribute_names.append(attribute[1]) + pass for this_attr_name in attribute_names: - exclude_menu.append((this_attr_name.capitalize(), this_attr_name)) + #exclude_menu.append((this_attr_name.capitalize(), this_attr_name)) self.cursor.execute("""SELECT DISTINCT CaseAttributeXRef.Value FROM CaseAttribute, CaseAttributeXRef WHERE CaseAttribute.Name = '%s' AND @@ -1578,11 +1584,12 @@ class DataEditingPage(templatePage): distinct_values = self.cursor.fetchall() attr_value_menu_div = HT.Div(style="display:none;", Class="attribute_values") #container used to show/hide dropdown menus attr_value_menu = HT.Select(name=this_attr_name) - attr_value_menu.append(("None", "show_all")) + #attr_value_menu.append(("None", "show_all")) for value in distinct_values: - attr_value_menu.append((str(value[0]), value[0])) - attr_value_menu_div.append(attr_value_menu) - dropdown_menus.append(attr_value_menu_div) + #attr_value_menu.append((str(value[0]), value[0])) + pass + #attr_value_menu_div.append(attr_value_menu) + #dropdown_menus.append(attr_value_menu_div) except: pass except: @@ -1591,46 +1598,51 @@ class DataEditingPage(templatePage): other_strains = [] for strain in thisTrait.data.keys(): if strain not in allstrainlist_neworder: - other_strains.append(strain) + pass + #other_strains.append(strain) if other_strains: - blockMenu.append(('%s Only' % fd.RISet,'1')) - blockMenu.append(('Non-%s Only' % fd.RISet,'0')) - blockMenuSpan.append(blockMenu) + #blockMenu.append(('%s Only' % fd.RISet,'1')) + #blockMenu.append(('Non-%s Only' % fd.RISet,'0')) + #blockMenuSpan.append(blockMenu) + pass else: pass showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") if other_strains: - showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) + pass + #showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) else: - showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) + pass + #showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') if len(attribute_names) > 0: excludeButton = HT.Input(type='button', name='excludeGroup', value=' Block ', Class='button') - showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) + #showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) for menu in dropdown_menus: - showHideMenuOptions.append(menu) - showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) - showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) - - traitTableOptions.append(showHideMenuOptions,HT.BR(),HT.BR()) - traitTableOptions.append(HT.Span("  Outliers highlighted in ", HT.Bold(" yellow ", style="background-color:yellow;"), " can be hidden using the ", - HT.Strong(" Hide Outliers "), " button,",HT.BR(),"  and samples with no value (x) can be hidden by clicking ", - HT.Strong(" Hide No Value "), "."), HT.BR()) - + pass + #showHideMenuOptions.append(menu) + #showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) + #showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) - dispintro = HT.Paragraph("Edit or delete values in the Trait Data boxes, and use the ", HT.Strong("Reset"), " option as needed.",Class="fs12", style="margin-left:20px;") + #traitTableOptions.append(showHideMenuOptions,HT.BR(),HT.BR()) + #traitTableOptions.append(HT.Span("  Outliers highlighted in ", HT.Bold(" yellow ", style="background-color:yellow;"), " can be hidden using the ", + # HT.Strong(" Hide Outliers "), " button,",HT.BR(),"  and samples with no value (x) can be hidden by clicking ", + # HT.Strong(" Hide No Value "), "."), HT.BR()) - table = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target5") #Everything needs to be inside this table object in order for the toggle to work - container = HT.Div() #This will contain everything and be put into a cell of the table defined above - container.append(dispintro, traitTableOptions, HT.BR()) + #dispintro = HT.Paragraph("Edit or delete values in the Trait Data boxes, and use the ", HT.Strong("Reset"), " option as needed.",Class="fs12", style="margin-left:20px;") + # + #table = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target5") #Everything needs to be inside this table object in order for the toggle to work + #container = HT.Div() #This will contain everything and be put into a cell of the table defined above + # + #container.append(dispintro, traitTableOptions, HT.BR()) - primary_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable1", Class="tablesorter") - primary_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for primary table object + #primary_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable1", Class="tablesorter") + #primary_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for primary table object other_strainsExist = False for strain in thisTrait.data.keys(): @@ -1640,15 +1652,17 @@ class DataEditingPage(templatePage): primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') - primary_table.append(primary_header) + #primary_table.append(primary_header) for i in range(len(primary_body)): - primary_table.append(primary_body[i]) + pass + #primary_table.append(primary_body[i]) other_strains = [] for strain in thisTrait.data.keys(): if strain not in allstrainlist_neworder: - allstrainlist_neworder.append(strain) - other_strains.append(strain) + pass + #allstrainlist_neworder.append(strain) + #other_strains.append(strain) if other_strains: other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits @@ -1660,24 +1674,25 @@ class DataEditingPage(templatePage): MDPMenu1 = HT.Select(name='MDPChoice1') MDPMenu2 = HT.Select(name='MDPChoice2') MDPMenu3 = HT.Select(name='MDPChoice3') - MDPMenu1.append(('%s Only' % fd.RISet,'1')) - MDPMenu2.append(('%s Only' % fd.RISet,'1')) - MDPMenu3.append(('%s Only' % fd.RISet,'1')) - MDPMenu1.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu2.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu3.append(('Non-%s Only' % fd.RISet,'2')) - MDPMenu1.append(('All Cases','0')) - MDPMenu2.append(('All Cases','0')) - MDPMenu3.append(('All Cases','0')) - self.MDPRow1.append(HT.TD(MDPText),HT.TD(MDPMenu1)) - self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) - self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) + #MDPMenu1.append(('%s Only' % fd.RISet,'1')) + #MDPMenu2.append(('%s Only' % fd.RISet,'1')) + #MDPMenu3.append(('%s Only' % fd.RISet,'1')) + #MDPMenu1.append(('Non-%s Only' % fd.RISet,'2')) + #MDPMenu2.append(('Non-%s Only' % fd.RISet,'2')) + #MDPMenu3.append(('Non-%s Only' % fd.RISet,'2')) + #MDPMenu1.append(('All Cases','0')) + #MDPMenu2.append(('All Cases','0')) + #MDPMenu3.append(('All Cases','0')) + #self.MDPRow1.append(HT.TD(MDPText),HT.TD(MDPMenu1)) + #self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) + #self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) other_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') - other_table.append(other_header) + #other_table.append(other_header) for i in range(len(other_body)): - other_table.append(other_body[i]) + pass + #other_table.append(other_body[i]) else: pass @@ -1685,21 +1700,21 @@ class DataEditingPage(templatePage): or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): fd.allstrainlist = allstrainlist_neworder - # Sam - is this correct? - if nCols == 6 and fd.varianceDispName != 'Variance': - #mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) - hddn['isSE'] = "yes" + ## We put isSE into hddn + #if nCols == 6 and fd.varianceDispName != 'Variance': + # #mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) + # hddn['isSE'] = "yes" primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values - container.append(primary_div) + #container.append(primary_div) if other_strains: other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values - container.append(HT.Div(' ', height=30)) - container.append(other_div) + #container.append(HT.Div(' ', height=30)) + #container.append(other_div) table.append(HT.TR(HT.TD(container))) - title5Body.append(table) + #title5Body.append(table) def addTrait2Table(self, fd, varianceDataPage, strainlist, mainForm, thisTrait, other_strainsExist=None, attribute_ids=[], attribute_names=[], strains='primary'): #XZ, Aug 23, 2010: I commented the code related to the display of animal case diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index b00355a6..09094fc6 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -172,7 +172,7 @@ - - + {# - #} {{ thisTrait.name.upper() }} diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 81d6540f..122bafd9 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -9,7 +9,7 @@ - + {# @@ -50,7 +50,10 @@ - + #} + {% for key in hddn %} + + {% endfor %}
Trait Data and Analysis  for Record ID 1441186_at -- cgit v1.2.3 From eb2e4311de82d8b97450d5114f8b75e112d32ba3 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 10 Jun 2012 03:45:14 -0400 Subject: Added uncustomized pylintrc --- wqflask/other_config/pylintrc | 249 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 wqflask/other_config/pylintrc diff --git a/wqflask/other_config/pylintrc b/wqflask/other_config/pylintrc new file mode 100644 index 00000000..c42acc35 --- /dev/null +++ b/wqflask/other_config/pylintrc @@ -0,0 +1,249 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). +#disable= + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html +output-format=text + +# Include message's id in output +include-ids=no + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +comment=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + + +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=80 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,string,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branchs=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception -- cgit v1.2.3 From 893164a15a18030715167c45f0d114d13e37aadb Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 10 Jun 2012 05:33:44 -0400 Subject: Modified pylintrc --- wqflask/other_config/dot.pylintrc | 249 ++++++++++++++++++++++++++++++++++++++ wqflask/other_config/pylintrc | 249 -------------------------------------- 2 files changed, 249 insertions(+), 249 deletions(-) create mode 100644 wqflask/other_config/dot.pylintrc delete mode 100644 wqflask/other_config/pylintrc diff --git a/wqflask/other_config/dot.pylintrc b/wqflask/other_config/dot.pylintrc new file mode 100644 index 00000000..2774300a --- /dev/null +++ b/wqflask/other_config/dot.pylintrc @@ -0,0 +1,249 @@ +[MASTER] + +# Specify a configuration file. +#rcfile= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Profiled execution. +profile=no + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Pickle collected data for later comparisons. +persistent=yes + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + + +[MESSAGES CONTROL] + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time. +#enable= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). +#disable= + + +[REPORTS] + +# Set the output format. Available formats are text, parseable, colorized, msvs +# (visual studio) and html +output-format=colorized + +# Include message's id in output +include-ids=no + +# Put messages in a separate file for each module / package specified on the +# command line instead of printing them on stdout. Reports (if any) will be +# written in a file name "pylint_global.[txt|html]". +files-output=no + +# Tells whether to display a full report or only the messages +reports=yes + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Add a comment according to your evaluation note. This is used by the global +# evaluation report (RP0004). +comment=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME,XXX,TODO + + +[TYPECHECK] + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# List of classes names for which member attributes should not be checked +# (useful for classes with attributes dynamically set). +ignored-classes=SQLObject + +# When zope mode is activated, add a predefined set of Zope acquired attributes +# to generated-members. +zope=no + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E0201 when accessed. Python regular +# expressions are accepted. +generated-members=REQUEST,acl_users,aq_parent + + +[SIMILARITIES] + +# Minimum lines number of a similarity. +min-similarity-lines=4 + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + + +[BASIC] + +# Required attributes for module, separated by a comma +required-attributes= + +# List of builtins function names that should not be used, separated by a comma +bad-functions=map,filter,apply,input + +# Regular expression which should only match correct module names +module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ + +# Regular expression which should only match correct module level names +const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ + +# Regular expression which should only match correct class names +class-rgx=[A-Z_][a-zA-Z0-9]+$ + +# Regular expression which should only match correct function names +function-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct method names +method-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct instance attribute names +attr-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct argument names +argument-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct variable names +variable-rgx=[a-z_][a-z0-9_]{2,30}$ + +# Regular expression which should only match correct list comprehension / +# generator expression variable names +inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ + +# Good variable names which should always be accepted, separated by a comma +good-names=i,j,k,ex,Run,_ + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo,bar,baz,toto,tutu,tata + +# Regular expression which should only match functions or classes name which do +# not require a docstring +no-docstring-rgx=__.*__ + + +[VARIABLES] + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# A regular expression matching the beginning of the name of dummy variables +# (i.e. not used). +dummy-variables-rgx=_|dummy + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + + +[IMPORTS] + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub,string,TERMIOS,Bastion,rexec + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.* + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of branch for function / method body +max-branchs=12 + +# Maximum number of statements in function / method body +max-statements=50 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + + +[CLASSES] + +# List of interface methods to ignore, separated by a comma. This is used for +# instance to not check methods defines in Zope's Interface base class. +ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__,__new__,setUp + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/wqflask/other_config/pylintrc b/wqflask/other_config/pylintrc deleted file mode 100644 index c42acc35..00000000 --- a/wqflask/other_config/pylintrc +++ /dev/null @@ -1,249 +0,0 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Profiled execution. -profile=no - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - - -[MESSAGES CONTROL] - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). -#disable= - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html -output-format=text - -# Include message's id in output -include-ids=no - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". -files-output=no - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Add a comment according to your evaluation note. This is used by the global -# evaluation report (RP0004). -comment=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of classes names for which member attributes should not be checked -# (useful for classes with attributes dynamically set). -ignored-classes=SQLObject - -# When zope mode is activated, add a predefined set of Zope acquired attributes -# to generated-members. -zope=no - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E0201 when accessed. Python regular -# expressions are accepted. -generated-members=REQUEST,acl_users,aq_parent - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - - -[BASIC] - -# Required attributes for module, separated by a comma -required-attributes= - -# List of builtins function names that should not be used, separated by a comma -bad-functions=map,filter,apply,input - -# Regular expression which should only match correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression which should only match correct module level names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression which should only match correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression which should only match correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct instance attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match correct list comprehension / -# generator expression variable names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Regular expression which should only match functions or classes name which do -# not require a docstring -no-docstring-rgx=__.*__ - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the beginning of the name of dummy variables -# (i.e. not used). -dummy-variables-rgx=_|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=80 - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,string,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branchs=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - - -[CLASSES] - -# List of interface methods to ignore, separated by a comma. This is used for -# instance to not check methods defines in Zope's Interface base class. -ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception -- cgit v1.2.3 From be2baf17cba5468d901f8e2d8818fe558e2ee5fe Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 10 Jun 2012 06:02:11 -0400 Subject: Debug messages for trying to understand code --- wqflask/basicStatistics/BasicStatisticsFunctions.py | 4 ++++ wqflask/wqflask/show_trait/DataEditingPage.py | 1 + 2 files changed, 5 insertions(+) diff --git a/wqflask/basicStatistics/BasicStatisticsFunctions.py b/wqflask/basicStatistics/BasicStatisticsFunctions.py index d2584bdd..74784853 100755 --- a/wqflask/basicStatistics/BasicStatisticsFunctions.py +++ b/wqflask/basicStatistics/BasicStatisticsFunctions.py @@ -4,6 +4,7 @@ from __future__ import print_function from math import * #import piddle as pid #import os +import traceback from pprint import pformat as pf @@ -18,6 +19,7 @@ from base import webqtlConfig from dbFunction import webqtlDatabaseFunction def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None): + print("basicStatsTable called - len of vals", len(vals)) st = {} # This is the dictionary where we'll put everything for the template valsOnly = [] dataXZ = vals[:] @@ -48,6 +50,8 @@ def basicStatsTable(vals, trait_type=None, cellid=None, heritability=None): at75 = stats.percentile(75) at25 = stats.percentile(25) + print("should get a stack") + traceback.print_stack() print("Interquartile:", at75 - at25) #tbl.append(HT.TR(HT.TD("Statistic",align="left", Class="fs14 fwb ffl b1 cw cbrb", width = 180), diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index d82c47d5..a496a919 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -175,6 +175,7 @@ class DataEditingPage(templatePage): else: pass # We'll get this part working later + print("Calling dispBasicStatistics") self.dispBasicStatistics(fd, thisTrait) #self.dispMappingTools(fd, title4Body, thisTrait) -- cgit v1.2.3 From b4c536fa8e94643f8cbd37f9fb1db18b2ab52263 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Tue, 12 Jun 2012 04:36:47 -0400 Subject: More progress on data trait and analysis --- wqflask/other_config/nginx.conf | 6 ++++- wqflask/wqflask/show_trait/DataEditingPage.py | 25 +++++++++++-------- .../wqflask/templates/trait_data_and_analysis.html | 28 ++++++++++++---------- wqflask/wqflask/views.py | 1 + 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/wqflask/other_config/nginx.conf b/wqflask/other_config/nginx.conf index 93e6af10..65ee768c 100644 --- a/wqflask/other_config/nginx.conf +++ b/wqflask/other_config/nginx.conf @@ -49,6 +49,10 @@ http { root /home/sam/gene/wqflask/wqflask/static/; } +# location ^~ /image/ { +# root /home/sam/gene/wqflask/wqflask/static/; +# } + location ^~ /images/ { root /home/sam/gene/wqflask/wqflask/static/; } @@ -60,7 +64,7 @@ http { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - } + } } diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index a496a919..d5238828 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -853,6 +853,8 @@ class DataEditingPage(templatePage): primary_strains = [] #XZ: strain of primary group, e.g., BXD, LXS #MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') + MDP_menu = [] # We're going to use the same named data structure as in the old version + # but repurpose it for Jinja2 as an array for strain in thisTrait.data.keys(): strainName = strain.replace("_2nd_", "") @@ -872,21 +874,24 @@ class DataEditingPage(templatePage): primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains #XZ: note that fd.f1list and fd.parlist are added. all_strains = primary_strains + other_strains other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #XZ: note that fd.f1list and fd.parlist are added. - #MDP_menu.append(('All Cases','0')) - #MDP_menu.append(('%s Only' % fd.RISet,'1')) - #MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + print("ac1") # This is the one used for first sall3 + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet, '1')) + MDP_menu.append(('Non-%s Only' % fd.RISet, '2')) #stats_row.append("Include: ", MDP_menu, HT.BR(), HT.BR()) else: if (len(other_strains) > 0) and (len(primary_strains) + len(other_strains) > 3): - #MDP_menu.append(('All Cases','0')) - #MDP_menu.append(('%s Only' % fd.RISet,'1')) - #MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + print("ac2") + MDP_menu.append(('All Cases','0')) + MDP_menu.append(('%s Only' % fd.RISet,'1')) + MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) #stats_row.append("Include: ", MDP_menu, " "*3) all_strains = primary_strains all_strains.sort(key=webqtlUtil.natsort_key) all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains primary_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + primary_strains else: + print("ac3") all_strains = strainlist other_strains.sort(key=webqtlUtil.natsort_key) @@ -962,7 +967,7 @@ class DataEditingPage(templatePage): vals_set = [vals] #stats_script = HT.Script(language="Javascript") #script needed for tabs - + self.stats_data = [] for i, vals in enumerate(vals_set): if i == 0 and len(vals) < 4: stats_container = HT.Div(id="stats_tabs", style="padding:10px;", Class="ui-tabs") #Needed for tabs; notice the "stats_script_text" below referring to this element @@ -994,11 +999,11 @@ class DataEditingPage(templatePage): if thisTrait.db: if thisTrait.cellid: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type, cellid=thisTrait.cellid) + self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type, cellid=thisTrait.cellid)) else: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type) + self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=thisTrait.db.type)) else: - statsTableCell = BasicStatisticsFunctions.basicStatsTable(vals=vals) + self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals)) #statsTable.append(HT.TR(HT.TD(statsTableCell))) diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 122bafd9..f77d22d4 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -267,7 +267,8 @@ - + - + - + - + - + - + - + - + - + - +
-
+ {% for sd in stats_data %} +
N of Samples99{{ sd.N }}
Mean6.129{{ "%2.3f" % sd.traitmean }}
Median6.105{{ "%2.3f" % sd.traitmedian }}
Standard Error (SE)0.018{{ "%2.3f" % sd.traitsem }}
Standard Deviation (SD)0.182{{ "%2.3f" % sd.traitstdev }}
Minimum5.782{{ "%2.3f" % sd.min }}
Maximum6.579{{ "%2.3f" % sd.max }}
Range (log2)0.797{{ "%2.3f" % sd.range_log2 }}
Range (fold)1.74{{ "%2.3f" % sd.range_fold }}
Interquartile Range1.18{{ "%2.3f" % sd.interquartile }}
@@ -402,7 +403,8 @@
- + {% endfor %} + {# Not used now - Todo: Delete after we're sure this is right.
+ + #}
  • Basic Table
  • diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 58eeddd3..c15f4ba1 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -26,4 +26,5 @@ def showDatabaseBXD(): # Here it's currently too complicated not to use an fd that is a webqtlFormData fd = webqtlFormData.webqtlFormData(request.args) template_vars = show_trait_page.ShowTraitPage(fd) + print("showDatabaseBXD template_vars:", pf(template_vars.__dict__)) return render_template("trait_data_and_analysis.html", **template_vars.__dict__) -- cgit v1.2.3 From 0f9faba03699387f866f59000e33767ef93035f5 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Tue, 12 Jun 2012 05:08:30 -0400 Subject: More stats now working --- wqflask/wqflask/show_trait/DataEditingPage.py | 20 ++++++++++---------- .../wqflask/templates/trait_data_and_analysis.html | 14 ++++---------- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index d5238828..0194a7d9 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -852,8 +852,8 @@ class DataEditingPage(templatePage): all_strains = [] primary_strains = [] #XZ: strain of primary group, e.g., BXD, LXS - #MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') - MDP_menu = [] # We're going to use the same named data structure as in the old version + #self.MDP_menu = HT.Select(name='stats_mdp', Class='stats_mdp') + self.MDP_menu = [] # We're going to use the same named data structure as in the old version # but repurpose it for Jinja2 as an array for strain in thisTrait.data.keys(): @@ -875,17 +875,17 @@ class DataEditingPage(templatePage): all_strains = primary_strains + other_strains other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #XZ: note that fd.f1list and fd.parlist are added. print("ac1") # This is the one used for first sall3 - MDP_menu.append(('All Cases','0')) - MDP_menu.append(('%s Only' % fd.RISet, '1')) - MDP_menu.append(('Non-%s Only' % fd.RISet, '2')) - #stats_row.append("Include: ", MDP_menu, HT.BR(), HT.BR()) + self.MDP_menu.append(('All Cases','0')) + self.MDP_menu.append(('%s Only' % fd.RISet, '1')) + self.MDP_menu.append(('Non-%s Only' % fd.RISet, '2')) + #stats_row.append("Include: ", self.MDP_menu, HT.BR(), HT.BR()) else: if (len(other_strains) > 0) and (len(primary_strains) + len(other_strains) > 3): print("ac2") - MDP_menu.append(('All Cases','0')) - MDP_menu.append(('%s Only' % fd.RISet,'1')) - MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) - #stats_row.append("Include: ", MDP_menu, " "*3) + self.MDP_menu.append(('All Cases','0')) + self.MDP_menu.append(('%s Only' % fd.RISet,'1')) + self.MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + #stats_row.append("Include: ", self.MDP_menu, " "*3) all_strains = primary_strains all_strains.sort(key=webqtlUtil.natsort_key) all_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_strains diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index f77d22d4..ca191313 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -241,17 +241,11 @@

      Basic Statistics

    Include:


    -- cgit v1.2.3 From e054dc538873ce5f500494aa26ffa50e0ec35e06 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Tue, 12 Jun 2012 05:08:59 -0400 Subject: Added corestats temporarily --- wqflask/basicStatistics/corestats.py | 103 +++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 wqflask/basicStatistics/corestats.py diff --git a/wqflask/basicStatistics/corestats.py b/wqflask/basicStatistics/corestats.py new file mode 100644 index 00000000..4f2d122f --- /dev/null +++ b/wqflask/basicStatistics/corestats.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python + +# corestats.py (COREy STATS) +# Copyright (c) 2006-2007, Corey Goldberg (corey@goldb.org) +# +# statistical calculation class +# for processing numeric sequences +# +# license: GNU LGPL +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + + + +import sys + + +class Stats: + + def __init__(self, sequence): + # sequence of numbers we will process + # convert all items to floats for numerical processing + self.sequence = [float(item) for item in sequence] + + + def sum(self): + if len(self.sequence) < 1: + return None + else: + return sum(self.sequence) + + + def count(self): + return len(self.sequence) + + + def min(self): + if len(self.sequence) < 1: + return None + else: + return min(self.sequence) + + + def max(self): + if len(self.sequence) < 1: + return None + else: + return max(self.sequence) + + + def avg(self): + if len(self.sequence) < 1: + return None + else: + return sum(self.sequence) / len(self.sequence) + + + def median(self): + if len(self.sequence) < 1: + return None + else: + self.sequence.sort() + return self.sequence[len(self.sequence) // 2] + + + def stdev(self): + if len(self.sequence) < 1: + return None + else: + avg = self.avg() + sdsq = sum([(i - avg) ** 2 for i in self.sequence]) + stdev = (sdsq / (len(self.sequence) - 1)) ** .5 + return stdev + + + def percentile(self, percentile): + if len(self.sequence) < 1: + value = None + elif (percentile >= 100): + sys.stderr.write('ERROR: percentile must be < 100. you supplied: %s\n'% percentile) + value = None + else: + element_idx = int(len(self.sequence) * (percentile / 100.0)) + self.sequence.sort() + value = self.sequence[element_idx] + return value + + + + +# Sample script using this class: +# ------------------------------------------- +# #!/usr/bin/env python +# import corestats +# +# sequence = [1, 2.5, 7, 13.4, 8.0] +# stats = corestats.Stats(sequence) +# print stats.avg() +# print stats.percentile(90) +# ------------------------------------------- -- cgit v1.2.3 From 02e022348c5b865d03a446cdd19c7c920bb3c2c5 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 14 Jun 2012 06:02:11 -0400 Subject: Changing tabs now works in data trait and analysis --- .../new/javascript/trait_data_and_analysis.coffee | 26 ++++++++++++++++++ .../new/javascript/trait_data_and_analysis.js | 32 ++++++++++++++++++++++ .../wqflask/templates/trait_data_and_analysis.html | 20 ++++++++++---- 3 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee create mode 100644 wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee new file mode 100644 index 00000000..118be8ec --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee @@ -0,0 +1,26 @@ +console.log("start_b") + +$ -> + hide_tabs = (start) -> + for x in [start..10] + $("#stats_tabs" + x).hide() + console.log("hidden:", x) + + console.log("start_a") + hide_tabs(1) + + + console.log("hidden?") + + + stats_mdp_change = -> + console.log("In stats_mdp_change") + selected = $(this).val() + console.log("Change was:", selected) + hide_tabs(0) + $("#stats_tabs" + selected).show() + + $(".stats_mdp").change(stats_mdp_change) + + console.log("tape") + diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js new file mode 100644 index 00000000..e59edbdb --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js @@ -0,0 +1,32 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + + console.log("start_b"); + + $(function() { + var hide_tabs, stats_mdp_change; + hide_tabs = function(start) { + var x, _i, _results; + _results = []; + for (x = _i = start; start <= 10 ? _i <= 10 : _i >= 10; x = start <= 10 ? ++_i : --_i) { + $("#stats_tabs" + x).hide(); + _results.push(console.log("hidden:", x)); + } + return _results; + }; + console.log("start_a"); + hide_tabs(1); + console.log("hidden?"); + stats_mdp_change = function() { + var selected; + console.log("In stats_mdp_change"); + selected = $(this).val(); + console.log("Change was:", selected); + hide_tabs(0); + return $("#stats_tabs" + selected).show(); + }; + $(".stats_mdp").change(stats_mdp_change); + return console.log("tape"); + }); + +}).call(this); diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index ca191313..39174425 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -537,7 +537,7 @@
    - #} +
    • Basic Table
    • @@ -675,6 +675,7 @@ + #}

        Calculate Correlations

      @@ -1266,7 +1267,7 @@ Return: - @@ -1906,7 +1907,7 @@ Return: - @@ -2545,7 +2546,7 @@ Return: - @@ -5040,5 +5041,14 @@ - + + + + + + {% endblock %} -- cgit v1.2.3 From 5ab5ede79ee823f7fbb70016809c887a78732472 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Fri, 22 Jun 2012 23:35:30 -0400 Subject: Working my way through getting the review and edit data dynamically generated in Jinja2 --- wqflask/utility/Plot.py | 868 +++++++++++++------------- wqflask/wqflask/show_trait/DataEditingPage.py | 109 ++-- 2 files changed, 497 insertions(+), 480 deletions(-) diff --git a/wqflask/utility/Plot.py b/wqflask/utility/Plot.py index 04fe85bf..086f3d57 100755 --- a/wqflask/utility/Plot.py +++ b/wqflask/utility/Plot.py @@ -487,440 +487,440 @@ def plotSecurity(canvas, text="12345"): # parameter: data is either object returned by reaper permutation function (called by MarkerRegressionPage.py) # or the first object returned by direct (pair-scan) permu function (called by DirectPlotPage.py) -def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): - - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - - if len(data) < 2: - return - - max_D = max(data) - min_D = min(data) - #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong - if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: - max_D=webqtlConfig.MAXLRS #maximum LRS value - - xLow, xTop, stepX = detScale(min_D, max_D) - - #reduce data - step = ceil((xTop-xLow)/50.0) - j = xLow - dataXY = [] - Count = [] - while j <= xTop: - dataXY.append(j) - Count.append(0) - j += step - - for i, item in enumerate(data): - if item == float('inf') or item>webqtlConfig.MAXLRS: - item = webqtlConfig.MAXLRS #maximum LRS value - j = int((item-xLow)/step) - Count[j] += 1 - - yLow, yTop, stepY=detScale(0,max(Count)) - - #draw data - xScale = plotWidth/(xTop-xLow) - yScale = plotHeight/(yTop-yLow) - barWidth = xScale*step - - for i, count in enumerate(Count): - if count: - xc = (dataXY[i]-xLow)*xScale+xLeftOffset - yc =-(count-yLow)*yScale+yTopOffset+plotHeight - canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) - - #draw drawing region - canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) - - #draw scale - scaleFont=pid.Font(ttf="cour",size=11,bold=1) - x=xLow - for i in range(stepX+1): - xc=xLeftOffset+(x-xLow)*xScale - canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) - strX = cformat(d=x, rank=0) - canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) - x+= (xTop - xLow)/stepX - - y=yLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-yLow)*yScale - canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) - strY = "%d" %y - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) - y+= (yTop - yLow)/stepY - - #draw label - labelFont=pid.Font(ttf="tahoma",size=17,bold=0) - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, - yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, - font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=16,bold=0) - if title: - canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, - 20,font=labelFont,color=labelColor) - -def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, sLabel = None, offset= (80, 20, 40, 100), barSpace = 2, zoom = 1): - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - - NNN = len(data) - if NNN < 2 or NNN != len(label): - return - if variance and len(variance)!=NNN: - variance = [] - - Y2 = data[:] - if variance: - for i in range(NNN): - if variance[i]: - Y2 += [data[i]-variance[i]] - - #Y axis - YLow, YTop, stepY = detScale(min(Y2), max(Y2)) - YScale = plotHeight/(YTop - YLow) - - if YLow < 0 and YTop > 0: - drawZero = 1 - else: - drawZero = 0 - - #X axis - X = range(NNN) - Xll= 0 - Xur= NNN-1 - - - if drawZero: - YZero = yTopOffset+plotHeight-YScale*(0-YLow) - canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) - else: - YZero = yTopOffset+plotHeight - #draw data - spaceWidth = barSpace - if spaceWidth < 1: - spaceWidth = 1 - barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) - - xc= xLeftOffset - scaleFont=pid.Font(ttf="verdana",size=11,bold=0) - for i in range(NNN): - yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale - canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) - if variance and variance[i]: - varlen = variance[i]*YScale - if yc-varlen < yTopOffset: - topYd = yTopOffset - else: - topYd = yc-varlen - canvas.drawLine(xc+barWidth/2-2,yc-varlen,xc+barWidth/2+2,yc-varlen,color=pid.red) - canvas.drawLine(xc+barWidth/2,yc+varlen,xc+barWidth/2,topYd,color=pid.red) - canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) - strX = label[i] - canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) - xc += barWidth + spaceWidth - - #draw drawing region - canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) - - #draw Y scale - scaleFont=pid.Font(ttf="cour",size=16,bold=1) - y=YLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-YLow)*YScale - canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) - strY = cformat(d=y, rank=0) - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) - y+= (YTop - YLow)/stepY - - #draw label - labelFont=pid.Font(ttf="verdana",size=17,bold=0) - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=18,bold=0) - if title: - canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) - - return - -def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, axesColor=pid.black, labelColor=pid.black, lineSize="thin", lineColor=pid.grey, idFont="arial", idColor=pid.blue, idSize="14", symbolColor=pid.black, symbolType="circle", filled="yes", symbolSize="tiny", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1, bufferSpace = 15): - 'displayR : correlation scatter plot, loadings : loading plot' - - dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) - - #get ID font size - idFontSize = int(idSize) - - #If filled is yes, set fill color - if filled == "yes": - fillColor = symbolColor - else: - fillColor = None - - if symbolSize == "large": - sizeModifier = 7 - fontModifier = 12 - elif symbolSize == "medium": - sizeModifier = 5 - fontModifier = 8 - elif symbolSize == "small": - sizeModifier = 3 - fontModifier = 3 - else: - sizeModifier = 1 - fontModifier = -1 - - if rank == 0: # Pearson correlation - bufferSpace = 0 - dataXPrimary = dataX - dataYPrimary = dataY - dataXAlt = dataXRanked #Values used just for printing the other corr type to the graph image - dataYAlt = dataYRanked #Values used just for printing the other corr type to the graph image - else: # Spearman correlation: Switching Ranked and Unranked X and Y values - dataXPrimary = dataXRanked - dataYPrimary = dataYRanked - dataXAlt = dataX #Values used just for printing the other corr type to the graph image - dataYAlt = dataY #Values used just for printing the other corr type to the graph image - - xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset - plotWidth = canvas.size[0] - xLeftOffset - xRightOffset - plotHeight = canvas.size[1] - yTopOffset - yBottomOffset - if plotHeight<=0 or plotWidth<=0: - return - if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): - return - - max_X=max(dataXPrimary) - min_X=min(dataXPrimary) - max_Y=max(dataYPrimary) - min_Y=min(dataYPrimary) - - #for some reason I forgot why I need to do this - if loadingPlot: - min_X = min(-0.1,min_X) - max_X = max(0.1,max_X) - min_Y = min(-0.1,min_Y) - max_Y = max(0.1,max_Y) - - xLow, xTop, stepX=detScale(min_X,max_X) - yLow, yTop, stepY=detScale(min_Y,max_Y) - xScale = plotWidth/(xTop-xLow) - yScale = plotHeight/(yTop-yLow) - - #draw drawing region - canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) - canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) - - #calculate data points - data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) - xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) - - labelFont=pid.Font(ttf=idFont,size=idFontSize,bold=0) - - if loadingPlot: - xZero = -xLow*xScale+xLeftOffset - yZero = yTopOffset+plotHeight+yLow*yScale - for point in xCoord: - canvas.drawLine(xZero,yZero,point[0],point[1],color=pid.red) - else: - if connectdot: - canvas.drawPolygon(xCoord,edgeColor=plotColor,closed=0) - else: - pass - - symbolFont = pid.Font(ttf="fnt_bs", size=12+fontModifier,bold=0) - - for i, item in enumerate(xCoord): - if dataLabel and dataLabel[i] in specialCases: - canvas.drawRect(item[0]-3, item[1]-3, item[0]+3, item[1]+3, edgeColor=pid.green) - #canvas.drawCross(item[0],item[1],color=pid.blue,size=5) - else: - if symbolType == "vertRect": - canvas.drawRect(x1=item[0]-sizeModifier+2,y1=item[1]-sizeModifier-2, x2=item[0]+sizeModifier-1,y2=item[1]+sizeModifier+2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "circle" and filled != "yes"): - canvas.drawString(":", item[0]-canvas.stringWidth(":",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) - elif (symbolType == "circle" and filled == "yes"): - canvas.drawString("5", item[0]-canvas.stringWidth("5",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) - elif symbolType == "horiRect": - canvas.drawRect(x1=item[0]-sizeModifier-1,y1=item[1]-sizeModifier+3, x2=item[0]+sizeModifier+3,y2=item[1]+sizeModifier-2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "square"): - canvas.drawRect(x1=item[0]-sizeModifier+1,y1=item[1]-sizeModifier-4, x2=item[0]+sizeModifier+2,y2=item[1]+sizeModifier-3, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) - elif (symbolType == "diamond" and filled != "yes"): - canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) - elif (symbolType == "diamond" and filled == "yes"): - canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) - elif symbolType == "4-star": - canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) - elif symbolType == "3-star": - canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) - else: - canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) - - if showLabel and dataLabel: - if (symbolType == "vertRect" or symbolType == "diamond"): - labelGap = 15 - elif (symbolType == "4-star" or symbolType == "3-star"): - labelGap = 12 - else: - labelGap = 11 - canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], - font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) - - #draw scale - scaleFont=pid.Font(ttf="cour",size=16,bold=1) - - - x=xLow - for i in range(stepX+1): - xc=xLeftOffset+(x-xLow)*xScale - if ((x == 0) & (rank == 1)): - pass - else: - canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) - strX = cformat(d=x, rank=rank) - if ((strX == "0") & (rank == 1)): - pass - else: - canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) - x+= (xTop - xLow)/stepX - - y=yLow - for i in range(stepY+1): - yc=yTopOffset+plotHeight-(y-yLow)*yScale - if ((y == 0) & (rank == 1)): - pass - else: - canvas.drawLine(xLeftOffset - bufferSpace,yc,xLeftOffset-5 - bufferSpace,yc, color=axesColor) - strY = cformat(d=y, rank=rank) - if ((strY == "0") & (rank == 1)): - pass - else: - canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) - y+= (yTop - yLow)/stepY - - #draw label - - labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) - titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) - - if (rank == 1 and not title): - canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, - 25,font=titleFont,color=labelColor) - elif (rank == 0 and not title): - canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, - 25,font=titleFont,color=labelColor) - - if XLabel: - canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, - yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) - - if YLabel: - canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, - font=labelFont,color=labelColor,angle=90) - - labelFont=pid.Font(ttf="verdana",size=20,bold=0) - if title: - canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, - 20,font=labelFont,color=labelColor) - - if fitcurve: - import sys - sys.argv = [ "mod_python" ] - #from numarray import linear_algebra as la - #from numarray import ones, array, dot, swapaxes - fitYY = array(dataYPrimary) - fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) - AA = dot(fitXX,swapaxes(fitXX,0,1)) - BB = dot(fitXX,fitYY) - bb = la.linear_least_squares(AA,BB)[0] - - xc1 = xLeftOffset - yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale - if yc1 > yTopOffset+plotHeight: - yc1 = yTopOffset+plotHeight - xc1 = (yLow-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - elif yc1 < yTopOffset: - yc1 = yTopOffset - xc1 = (yTop-bb[0])/bb[1] - xc1=(xc1-xLow)*xScale+xLeftOffset - else: - pass - - xc2 = xLeftOffset + plotWidth - yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale - if yc2 > yTopOffset+plotHeight: - yc2 = yTopOffset+plotHeight - xc2 = (yLow-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - elif yc2 < yTopOffset: - yc2 = yTopOffset - xc2 = (yTop-bb[0])/bb[1] - xc2=(xc2-xLow)*xScale+xLeftOffset - else: - pass - - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace,xc2,yc2,color=lineColor) - if lineSize == "medium": - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) - if lineSize == "thick": - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) - canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) - - - if displayR: - labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) - NNN = len(dataX) - corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] - - if NNN < 3: - corrPValue = 1.0 - else: - if abs(corr) >= 1.0: - corrPValue = 0.0 - else: - ZValue = 0.5*log((1.0+corr)/(1.0-corr)) - ZValue = ZValue*sqrt(NNN-3) - corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) - - NStr = "N = %d" % NNN - strLenN = canvas.stringWidth(NStr,font=labelFont) - - if rank == 1: - if corrPValue < 0.0000000000000001: - corrStr = "Rho = %1.3f P < 1.00 E-16" % (corr) - else: - corrStr = "Rho = %1.3f P = %3.2E" % (corr, corrPValue) - else: - if corrPValue < 0.0000000000000001: - corrStr = "r = %1.3f P < 1.00 E-16" % (corr) - else: - corrStr = "r = %1.3f P = %3.2E" % (corr, corrPValue) - strLen = canvas.stringWidth(corrStr,font=labelFont) - - canvas.drawString(NStr,xLeftOffset,yTopOffset-10,font=labelFont,color=labelColor) - canvas.drawString(corrStr,xLeftOffset+plotWidth-strLen,yTopOffset-10,font=labelFont,color=labelColor) - - return xCoord +#def plotBar(canvas, data, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, offset= (60, 20, 40, 40), zoom = 1): +# +# xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset +# +# plotWidth = canvas.size[0] - xLeftOffset - xRightOffset +# plotHeight = canvas.size[1] - yTopOffset - yBottomOffset +# if plotHeight<=0 or plotWidth<=0: +# return +# +# if len(data) < 2: +# return +# +# max_D = max(data) +# min_D = min(data) +# #add by NL 06-20-2011: fix the error: when max_D is infinite, log function in detScale will go wrong +# if max_D == float('inf') or max_D>webqtlConfig.MAXLRS: +# max_D=webqtlConfig.MAXLRS #maximum LRS value +# +# xLow, xTop, stepX = detScale(min_D, max_D) +# +# #reduce data +# step = ceil((xTop-xLow)/50.0) +# j = xLow +# dataXY = [] +# Count = [] +# while j <= xTop: +# dataXY.append(j) +# Count.append(0) +# j += step +# +# for i, item in enumerate(data): +# if item == float('inf') or item>webqtlConfig.MAXLRS: +# item = webqtlConfig.MAXLRS #maximum LRS value +# j = int((item-xLow)/step) +# Count[j] += 1 +# +# yLow, yTop, stepY=detScale(0,max(Count)) +# +# #draw data +# xScale = plotWidth/(xTop-xLow) +# yScale = plotHeight/(yTop-yLow) +# barWidth = xScale*step +# +# for i, count in enumerate(Count): +# if count: +# xc = (dataXY[i]-xLow)*xScale+xLeftOffset +# yc =-(count-yLow)*yScale+yTopOffset+plotHeight +# canvas.drawRect(xc+2,yc,xc+barWidth-2,yTopOffset+plotHeight,edgeColor=barColor,fillColor=barColor) +# +# #draw drawing region +# canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) +# +# #draw scale +# scaleFont=pid.Font(ttf="cour",size=11,bold=1) +# x=xLow +# for i in range(stepX+1): +# xc=xLeftOffset+(x-xLow)*xScale +# canvas.drawLine(xc,yTopOffset+plotHeight,xc,yTopOffset+plotHeight+5, color=axesColor) +# strX = cformat(d=x, rank=0) +# canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+14,font=scaleFont) +# x+= (xTop - xLow)/stepX +# +# y=yLow +# for i in range(stepY+1): +# yc=yTopOffset+plotHeight-(y-yLow)*yScale +# canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) +# strY = "%d" %y +# canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) +# y+= (yTop - yLow)/stepY +# +# #draw label +# labelFont=pid.Font(ttf="tahoma",size=17,bold=0) +# if XLabel: +# canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, +# yTopOffset+plotHeight+yBottomOffset-10,font=labelFont,color=labelColor) +# +# if YLabel: +# canvas.drawString(YLabel, 19, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, +# font=labelFont,color=labelColor,angle=90) +# +# labelFont=pid.Font(ttf="verdana",size=16,bold=0) +# if title: +# canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, +# 20,font=labelFont,color=labelColor) +# +#def plotBarText(canvas, data, label, variance=None, barColor=pid.blue, axesColor=pid.black, labelColor=pid.black, XLabel=None, YLabel=None, title=None, sLabel = None, offset= (80, 20, 40, 100), barSpace = 2, zoom = 1): +# xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset +# plotWidth = canvas.size[0] - xLeftOffset - xRightOffset +# plotHeight = canvas.size[1] - yTopOffset - yBottomOffset +# if plotHeight<=0 or plotWidth<=0: +# return +# +# NNN = len(data) +# if NNN < 2 or NNN != len(label): +# return +# if variance and len(variance)!=NNN: +# variance = [] +# +# Y2 = data[:] +# if variance: +# for i in range(NNN): +# if variance[i]: +# Y2 += [data[i]-variance[i]] +# +# #Y axis +# YLow, YTop, stepY = detScale(min(Y2), max(Y2)) +# YScale = plotHeight/(YTop - YLow) +# +# if YLow < 0 and YTop > 0: +# drawZero = 1 +# else: +# drawZero = 0 +# +# #X axis +# X = range(NNN) +# Xll= 0 +# Xur= NNN-1 +# +# +# if drawZero: +# YZero = yTopOffset+plotHeight-YScale*(0-YLow) +# canvas.drawLine(xLeftOffset, YZero, xLeftOffset+plotWidth, YZero) +# else: +# YZero = yTopOffset+plotHeight +# #draw data +# spaceWidth = barSpace +# if spaceWidth < 1: +# spaceWidth = 1 +# barWidth = int((plotWidth - (NNN-1.0)*spaceWidth)/NNN) +# +# xc= xLeftOffset +# scaleFont=pid.Font(ttf="verdana",size=11,bold=0) +# for i in range(NNN): +# yc = yTopOffset+plotHeight-(data[i]-YLow)*YScale +# canvas.drawRect(xc,YZero,xc+barWidth-1, yc, edgeColor=barColor,fillColor=barColor) +# if variance and variance[i]: +# varlen = variance[i]*YScale +# if yc-varlen < yTopOffset: +# topYd = yTopOffset +# else: +# topYd = yc-varlen +# canvas.drawLine(xc+barWidth/2-2,yc-varlen,xc+barWidth/2+2,yc-varlen,color=pid.red) +# canvas.drawLine(xc+barWidth/2,yc+varlen,xc+barWidth/2,topYd,color=pid.red) +# canvas.drawLine(xc+barWidth/2-2,yc+varlen,xc+barWidth/2+2,yc+varlen,color=pid.red) +# strX = label[i] +# canvas.drawString(strX,xc+barWidth/2.0+2,yTopOffset+plotHeight+2+canvas.stringWidth(strX,font=scaleFont),font=scaleFont,angle=90) +# xc += barWidth + spaceWidth +# +# #draw drawing region +# canvas.drawRect(xLeftOffset, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight) +# +# #draw Y scale +# scaleFont=pid.Font(ttf="cour",size=16,bold=1) +# y=YLow +# for i in range(stepY+1): +# yc=yTopOffset+plotHeight-(y-YLow)*YScale +# canvas.drawLine(xLeftOffset,yc,xLeftOffset-5,yc, color=axesColor) +# strY = cformat(d=y, rank=0) +# canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)-6,yc+5,font=scaleFont) +# y+= (YTop - YLow)/stepY +# +# #draw label +# labelFont=pid.Font(ttf="verdana",size=17,bold=0) +# if XLabel: +# canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0,yTopOffset+plotHeight+65,font=labelFont,color=labelColor) +# +# if YLabel: +# canvas.drawString(YLabel,xLeftOffset-50, yTopOffset+plotHeight-(plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0,font=labelFont,color=labelColor,angle=90) +# +# labelFont=pid.Font(ttf="verdana",size=18,bold=0) +# if title: +# canvas.drawString(title,xLeftOffset,yTopOffset-15,font=labelFont,color=labelColor) +# +# return +# +#def plotXY(canvas, dataX, dataY, rank=0, dataLabel=[], plotColor = pid.black, axesColor=pid.black, labelColor=pid.black, lineSize="thin", lineColor=pid.grey, idFont="arial", idColor=pid.blue, idSize="14", symbolColor=pid.black, symbolType="circle", filled="yes", symbolSize="tiny", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1, bufferSpace = 15): +# 'displayR : correlation scatter plot, loadings : loading plot' +# +# dataXRanked, dataYRanked = webqtlUtil.calRank(dataX, dataY, len(dataX)) +# +# #get ID font size +# idFontSize = int(idSize) +# +# #If filled is yes, set fill color +# if filled == "yes": +# fillColor = symbolColor +# else: +# fillColor = None +# +# if symbolSize == "large": +# sizeModifier = 7 +# fontModifier = 12 +# elif symbolSize == "medium": +# sizeModifier = 5 +# fontModifier = 8 +# elif symbolSize == "small": +# sizeModifier = 3 +# fontModifier = 3 +# else: +# sizeModifier = 1 +# fontModifier = -1 +# +# if rank == 0: # Pearson correlation +# bufferSpace = 0 +# dataXPrimary = dataX +# dataYPrimary = dataY +# dataXAlt = dataXRanked #Values used just for printing the other corr type to the graph image +# dataYAlt = dataYRanked #Values used just for printing the other corr type to the graph image +# else: # Spearman correlation: Switching Ranked and Unranked X and Y values +# dataXPrimary = dataXRanked +# dataYPrimary = dataYRanked +# dataXAlt = dataX #Values used just for printing the other corr type to the graph image +# dataYAlt = dataY #Values used just for printing the other corr type to the graph image +# +# xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset +# plotWidth = canvas.size[0] - xLeftOffset - xRightOffset +# plotHeight = canvas.size[1] - yTopOffset - yBottomOffset +# if plotHeight<=0 or plotWidth<=0: +# return +# if len(dataXPrimary) < 1 or len(dataXPrimary) != len(dataYPrimary) or (dataLabel and len(dataXPrimary) != len(dataLabel)): +# return +# +# max_X=max(dataXPrimary) +# min_X=min(dataXPrimary) +# max_Y=max(dataYPrimary) +# min_Y=min(dataYPrimary) +# +# #for some reason I forgot why I need to do this +# if loadingPlot: +# min_X = min(-0.1,min_X) +# max_X = max(0.1,max_X) +# min_Y = min(-0.1,min_Y) +# max_Y = max(0.1,max_Y) +# +# xLow, xTop, stepX=detScale(min_X,max_X) +# yLow, yTop, stepY=detScale(min_Y,max_Y) +# xScale = plotWidth/(xTop-xLow) +# yScale = plotHeight/(yTop-yLow) +# +# #draw drawing region +# canvas.drawRect(xLeftOffset-bufferSpace, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace) +# canvas.drawRect(xLeftOffset-bufferSpace+1, yTopOffset, xLeftOffset+plotWidth, yTopOffset+plotHeight+bufferSpace-1) +# +# #calculate data points +# data = map(lambda X, Y: (X, Y), dataXPrimary, dataYPrimary) +# xCoord = map(lambda X, Y: ((X-xLow)*xScale + xLeftOffset, yTopOffset+plotHeight-(Y-yLow)*yScale), dataXPrimary, dataYPrimary) +# +# labelFont=pid.Font(ttf=idFont,size=idFontSize,bold=0) +# +# if loadingPlot: +# xZero = -xLow*xScale+xLeftOffset +# yZero = yTopOffset+plotHeight+yLow*yScale +# for point in xCoord: +# canvas.drawLine(xZero,yZero,point[0],point[1],color=pid.red) +# else: +# if connectdot: +# canvas.drawPolygon(xCoord,edgeColor=plotColor,closed=0) +# else: +# pass +# +# symbolFont = pid.Font(ttf="fnt_bs", size=12+fontModifier,bold=0) +# +# for i, item in enumerate(xCoord): +# if dataLabel and dataLabel[i] in specialCases: +# canvas.drawRect(item[0]-3, item[1]-3, item[0]+3, item[1]+3, edgeColor=pid.green) +# #canvas.drawCross(item[0],item[1],color=pid.blue,size=5) +# else: +# if symbolType == "vertRect": +# canvas.drawRect(x1=item[0]-sizeModifier+2,y1=item[1]-sizeModifier-2, x2=item[0]+sizeModifier-1,y2=item[1]+sizeModifier+2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) +# elif (symbolType == "circle" and filled != "yes"): +# canvas.drawString(":", item[0]-canvas.stringWidth(":",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) +# elif (symbolType == "circle" and filled == "yes"): +# canvas.drawString("5", item[0]-canvas.stringWidth("5",font=symbolFont)/2+1,item[1]+2,color=symbolColor, font=symbolFont) +# elif symbolType == "horiRect": +# canvas.drawRect(x1=item[0]-sizeModifier-1,y1=item[1]-sizeModifier+3, x2=item[0]+sizeModifier+3,y2=item[1]+sizeModifier-2, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) +# elif (symbolType == "square"): +# canvas.drawRect(x1=item[0]-sizeModifier+1,y1=item[1]-sizeModifier-4, x2=item[0]+sizeModifier+2,y2=item[1]+sizeModifier-3, edgeColor=symbolColor, edgeWidth=1, fillColor=fillColor) +# elif (symbolType == "diamond" and filled != "yes"): +# canvas.drawString(",", item[0]-canvas.stringWidth(",",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) +# elif (symbolType == "diamond" and filled == "yes"): +# canvas.drawString("D", item[0]-canvas.stringWidth("D",font=symbolFont)/2+2, item[1]+6, font=symbolFont, color=symbolColor) +# elif symbolType == "4-star": +# canvas.drawString("l", item[0]-canvas.stringWidth("l",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) +# elif symbolType == "3-star": +# canvas.drawString("k", item[0]-canvas.stringWidth("k",font=symbolFont)/2+1, item[1]+3, font=symbolFont, color=symbolColor) +# else: +# canvas.drawCross(item[0],item[1]-2,color=symbolColor, size=sizeModifier+2) +# +# if showLabel and dataLabel: +# if (symbolType == "vertRect" or symbolType == "diamond"): +# labelGap = 15 +# elif (symbolType == "4-star" or symbolType == "3-star"): +# labelGap = 12 +# else: +# labelGap = 11 +# canvas.drawString(dataLabel[i], item[0]- canvas.stringWidth(dataLabel[i], +# font=labelFont)/2 + 1, item[1]+(labelGap+sizeModifier+(idFontSize-12)), font=labelFont, color=idColor) +# +# #draw scale +# scaleFont=pid.Font(ttf="cour",size=16,bold=1) +# +# +# x=xLow +# for i in range(stepX+1): +# xc=xLeftOffset+(x-xLow)*xScale +# if ((x == 0) & (rank == 1)): +# pass +# else: +# canvas.drawLine(xc,yTopOffset+plotHeight + bufferSpace,xc,yTopOffset+plotHeight+5 + bufferSpace, color=axesColor) +# strX = cformat(d=x, rank=rank) +# if ((strX == "0") & (rank == 1)): +# pass +# else: +# canvas.drawString(strX,xc-canvas.stringWidth(strX,font=scaleFont)/2,yTopOffset+plotHeight+20 + bufferSpace,font=scaleFont) +# x+= (xTop - xLow)/stepX +# +# y=yLow +# for i in range(stepY+1): +# yc=yTopOffset+plotHeight-(y-yLow)*yScale +# if ((y == 0) & (rank == 1)): +# pass +# else: +# canvas.drawLine(xLeftOffset - bufferSpace,yc,xLeftOffset-5 - bufferSpace,yc, color=axesColor) +# strY = cformat(d=y, rank=rank) +# if ((strY == "0") & (rank == 1)): +# pass +# else: +# canvas.drawString(strY,xLeftOffset-canvas.stringWidth(strY,font=scaleFont)- 10 - bufferSpace,yc+4,font=scaleFont) +# y+= (yTop - yLow)/stepY +# +# #draw label +# +# labelFont=pid.Font(ttf="verdana",size=canvas.size[0]/45,bold=0) +# titleFont=pid.Font(ttf="verdana",size=canvas.size[0]/40,bold=0) +# +# if (rank == 1 and not title): +# canvas.drawString("Spearman Rank Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Spearman Rank Correlation",font=titleFont))/2.0, +# 25,font=titleFont,color=labelColor) +# elif (rank == 0 and not title): +# canvas.drawString("Pearson Correlation", xLeftOffset-canvas.size[0]*.025+(plotWidth-canvas.stringWidth("Pearson Correlation",font=titleFont))/2.0, +# 25,font=titleFont,color=labelColor) +# +# if XLabel: +# canvas.drawString(XLabel,xLeftOffset+(plotWidth-canvas.stringWidth(XLabel,font=labelFont))/2.0, +# yTopOffset+plotHeight+yBottomOffset-25,font=labelFont,color=labelColor) +# +# if YLabel: +# canvas.drawString(YLabel, xLeftOffset-65, yTopOffset+plotHeight- (plotHeight-canvas.stringWidth(YLabel,font=labelFont))/2.0, +# font=labelFont,color=labelColor,angle=90) +# +# labelFont=pid.Font(ttf="verdana",size=20,bold=0) +# if title: +# canvas.drawString(title,xLeftOffset+(plotWidth-canvas.stringWidth(title,font=labelFont))/2.0, +# 20,font=labelFont,color=labelColor) +# +# if fitcurve: +# import sys +# sys.argv = [ "mod_python" ] +# #from numarray import linear_algebra as la +# #from numarray import ones, array, dot, swapaxes +# fitYY = array(dataYPrimary) +# fitXX = array([ones(len(dataXPrimary)),dataXPrimary]) +# AA = dot(fitXX,swapaxes(fitXX,0,1)) +# BB = dot(fitXX,fitYY) +# bb = la.linear_least_squares(AA,BB)[0] +# +# xc1 = xLeftOffset +# yc1 = yTopOffset+plotHeight-(bb[0]+bb[1]*xLow-yLow)*yScale +# if yc1 > yTopOffset+plotHeight: +# yc1 = yTopOffset+plotHeight +# xc1 = (yLow-bb[0])/bb[1] +# xc1=(xc1-xLow)*xScale+xLeftOffset +# elif yc1 < yTopOffset: +# yc1 = yTopOffset +# xc1 = (yTop-bb[0])/bb[1] +# xc1=(xc1-xLow)*xScale+xLeftOffset +# else: +# pass +# +# xc2 = xLeftOffset + plotWidth +# yc2 = yTopOffset+plotHeight-(bb[0]+bb[1]*xTop-yLow)*yScale +# if yc2 > yTopOffset+plotHeight: +# yc2 = yTopOffset+plotHeight +# xc2 = (yLow-bb[0])/bb[1] +# xc2=(xc2-xLow)*xScale+xLeftOffset +# elif yc2 < yTopOffset: +# yc2 = yTopOffset +# xc2 = (yTop-bb[0])/bb[1] +# xc2=(xc2-xLow)*xScale+xLeftOffset +# else: +# pass +# +# canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace,xc2,yc2,color=lineColor) +# if lineSize == "medium": +# canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) +# if lineSize == "thick": +# canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace+1,xc2,yc2+1,color=lineColor) +# canvas.drawLine(xc1 - bufferSpace,yc1 + bufferSpace-1,xc2,yc2-1,color=lineColor) +# +# +# if displayR: +# labelFont=pid.Font(ttf="trebuc",size=canvas.size[0]/60,bold=0) +# NNN = len(dataX) +# corr = webqtlUtil.calCorrelation(dataXPrimary,dataYPrimary,NNN)[0] +# +# if NNN < 3: +# corrPValue = 1.0 +# else: +# if abs(corr) >= 1.0: +# corrPValue = 0.0 +# else: +# ZValue = 0.5*log((1.0+corr)/(1.0-corr)) +# ZValue = ZValue*sqrt(NNN-3) +# corrPValue = 2.0*(1.0 - reaper.normp(abs(ZValue))) +# +# NStr = "N = %d" % NNN +# strLenN = canvas.stringWidth(NStr,font=labelFont) +# +# if rank == 1: +# if corrPValue < 0.0000000000000001: +# corrStr = "Rho = %1.3f P < 1.00 E-16" % (corr) +# else: +# corrStr = "Rho = %1.3f P = %3.2E" % (corr, corrPValue) +# else: +# if corrPValue < 0.0000000000000001: +# corrStr = "r = %1.3f P < 1.00 E-16" % (corr) +# else: +# corrStr = "r = %1.3f P = %3.2E" % (corr, corrPValue) +# strLen = canvas.stringWidth(corrStr,font=labelFont) +# +# canvas.drawString(NStr,xLeftOffset,yTopOffset-10,font=labelFont,color=labelColor) +# canvas.drawString(corrStr,xLeftOffset+plotWidth-strLen,yTopOffset-10,font=labelFont,color=labelColor) +# +# return xCoord def plotXYSVG(drawSpace, dataX, dataY, rank=0, dataLabel=[], plotColor = "black", axesColor="black", labelColor="black", symbolColor="red", XLabel=None, YLabel=None, title=None, fitcurve=None, connectdot=1, displayR=None, loadingPlot = 0, offset= (80, 20, 40, 60), zoom = 1, specialCases=[], showLabel = 1): 'displayR : correlation scatter plot, loadings : loading plot' diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 0194a7d9..38ab8c90 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -7,7 +7,7 @@ from collections import OrderedDict from htmlgen import HTMLgen2 as HT from base import webqtlConfig -from utility import webqtlUtil #, Plot +from utility import webqtlUtil, Plot from base.webqtlTrait import webqtlTrait from dbFunction import webqtlDatabaseFunction from base.templatePage import templatePage @@ -183,7 +183,7 @@ class DataEditingPage(templatePage): ## Trait Value Table ############################# # - #self.dispTraitValues(fd, title5Body, varianceDataPage, nCols, mainForm, thisTrait) + self.dispTraitValues(fd, varianceDataPage, nCols, thisTrait) # if fd.allstrainlist: hddn['allstrainlist'] = string.join(fd.allstrainlist, ' ') @@ -1549,14 +1549,15 @@ class DataEditingPage(templatePage): ########################################## ## Function to display trait tables ########################################## - def dispTraitValues(self, fd , title5Body, varianceDataPage, nCols, mainForm, thisTrait): - traitTableOptions = HT.Div(style="border: 3px solid #EEEEEE; -moz-border-radius: 10px; -webkit-border-radius: 10px; width: 625px; padding: 5px 5px 10px 8px; font-size: 12px; background: #DDDDDD;") - resetButton = HT.Input(type='button',name='resetButton',value=' Reset ',Class="button") - blockSamplesField = HT.Input(type="text",style="background-color:white;border: 1px solid black;font-size: 14px;", name="removeField") - blockSamplesButton = HT.Input(type='button',value=' Block ', name='blockSamples', Class="button") - showHideNoValue = HT.Input(type='button', name='showHideNoValue', value=' Hide No Value ',Class='button') - blockMenuSpan = HT.Span(Id="blockMenuSpan") - blockMenu = HT.Select(name='block_method') + def dispTraitValues(self, fd, varianceDataPage, nCols, thisTrait): + print("in dispTraitValues") + #traitTableOptions = HT.Div(style="border: 3px solid #EEEEEE; -moz-border-radius: 10px; -webkit-border-radius: 10px; width: 625px; padding: 5px 5px 10px 8px; font-size: 12px; background: #DDDDDD;") + #resetButton = HT.Input(type='button',name='resetButton',value=' Reset ',Class="button") + #blockSamplesField = HT.Input(type="text",style="background-color:white;border: 1px solid black;font-size: 14px;", name="removeField") + #blockSamplesButton = HT.Input(type='button',value=' Block ', name='blockSamples', Class="button") + #showHideNoValue = HT.Input(type='button', name='showHideNoValue', value=' Hide No Value ',Class='button') + #blockMenuSpan = HT.Span(Id="blockMenuSpan") + #blockMenu = HT.Select(name='block_method') if fd.genotype.type == "riset": allstrainlist_neworder = fd.f1list + fd.strainlist @@ -1615,21 +1616,21 @@ class DataEditingPage(templatePage): else: pass - showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') - showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") - if other_strains: - pass + #showHideOutliers = HT.Input(type='button', name='showHideOutliers', value=' Hide Outliers ', Class='button') + #showHideMenuOptions = HT.Span(Id="showHideOptions", style="line-height:225%;") + #if other_strains: + # pass #showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockMenuSpan, "   ", blockSamplesButton, HT.BR()) - else: - pass + #else: + # pass #showHideMenuOptions.append(HT.Bold("  Block samples by index:    "), blockSamplesField, "   ", blockSamplesButton, HT.BR()) - exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') + #exportButton = HT.Input(type='button', name='export', value=' Export ', Class='button') if len(attribute_names) > 0: excludeButton = HT.Input(type='button', name='excludeGroup', value=' Block ', Class='button') #showHideMenuOptions.append(HT.Bold("  Block samples by group:"), " "*5, exclude_menu, " "*5) - for menu in dropdown_menus: - pass + #for menu in dropdown_menus: + # pass #showHideMenuOptions.append(menu) #showHideMenuOptions.append(" "*5, excludeButton, HT.BR()) #showHideMenuOptions.append(HT.Bold("  Options:"), " "*5, showHideNoValue, " "*5, showHideOutliers, " "*5, resetButton, " "*5, exportButton) @@ -1652,19 +1653,23 @@ class DataEditingPage(templatePage): other_strainsExist = False for strain in thisTrait.data.keys(): + print("hjl - strain is:", strain) if strain not in allstrainlist_neworder: other_strainsExist = True break + mainForm = None # Just trying to get things working primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') #primary_table.append(primary_header) for i in range(len(primary_body)): + print("hji") pass #primary_table.append(primary_body[i]) other_strains = [] for strain in thisTrait.data.keys(): + print("hjk - strain is:", strain) if strain not in allstrainlist_neworder: pass #allstrainlist_neworder.append(strain) @@ -1697,6 +1702,7 @@ class DataEditingPage(templatePage): #other_table.append(other_header) for i in range(len(other_body)): + print("hjn") pass #other_table.append(other_body[i]) else: @@ -1704,6 +1710,7 @@ class DataEditingPage(templatePage): if other_strains or (fd.f1list and thisTrait.data.has_key(fd.f1list[0])) \ or (fd.f1list and thisTrait.data.has_key(fd.f1list[1])): + print("hjs") fd.allstrainlist = allstrainlist_neworder ## We put isSE into hddn @@ -1711,7 +1718,7 @@ class DataEditingPage(templatePage): # #mainForm.append(HT.Input(name='isSE', value="yes", type='hidden')) # hddn['isSE'] = "yes" - primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values + #primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values #container.append(primary_div) if other_strains: @@ -1719,13 +1726,13 @@ class DataEditingPage(templatePage): #container.append(HT.Div(' ', height=30)) #container.append(other_div) - table.append(HT.TR(HT.TD(container))) + #table.append(HT.TR(HT.TD(container))) #title5Body.append(table) def addTrait2Table(self, fd, varianceDataPage, strainlist, mainForm, thisTrait, other_strainsExist=None, attribute_ids=[], attribute_names=[], strains='primary'): #XZ, Aug 23, 2010: I commented the code related to the display of animal case #strainInfo = thisTrait.has_key('strainInfo') and thisTrait.strainInfo - + print("in addTrait2Table") table_body = [] vals = [] @@ -1744,9 +1751,10 @@ class DataEditingPage(templatePage): upperBound, lowerBound = Plot.findOutliers(vals) # ZS: Values greater than upperBound or less than lowerBound are considered outliers. for i, strainNameOrig in enumerate(strainlist): - + strain = {} + print("zyt - strainNameOrig:", strainNameOrig) trId = strainNameOrig - selectCheck = HT.Input(type="checkbox", name="selectCheck", value=trId, Class="checkbox", onClick="highlight(this)") + #selectCheck = HT.Input(type="checkbox", name="selectCheck", value=trId, Class="checkbox", onClick="highlight(this)") strainName = strainNameOrig.replace("_2nd_", "") strainNameAdd = '' @@ -1769,6 +1777,7 @@ class DataEditingPage(templatePage): traitVal = '' dispVal = 'x' + strain['strain_name'] = StrainName strainNameDisp = HT.Span(strainName, Class='fs14 fwn ffl') if varianceDataPage: @@ -1806,38 +1815,46 @@ class DataEditingPage(templatePage): # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. ######################################################################################################################################################### - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, - onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, + # onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + pass + #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + # onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) else: - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) + pass + #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) + pass + #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) else: - valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, - onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + pass + #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, + #onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) if varianceDataPage: - seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + pass + #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + # onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) if (strains == 'primary'): - table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) + strain[the_id] = "Primary_" + str(i+1) + #table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) else: - table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) + strain[the_id] = "Other_" + str(i+1) + #table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) if varianceDataPage: - table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) - table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) - table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) - table_row.append(HT.TD("±", width=20, align='center', Class=className)) - table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) + #table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + #table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + #table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + #table_row.append(HT.TD("±", width=20, align='center', Class=className)) + #table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) + pass else: - table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) - table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) - table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) - + #table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) + #table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) + #table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) + pass if thisTrait and thisTrait.db and thisTrait.db.type =='ProbeSet': if len(attribute_ids) > 0: @@ -1876,7 +1893,7 @@ class DataEditingPage(templatePage): table_row.append(HT.TD(attr_container, align='right', Class=attr_className)) attr_counter += 1 - table_body.append(table_row) + #table_body.append(table_row) return table_body def getTableHeader(self, fd, thisTrait, nCols, attribute_names): -- cgit v1.2.3 From 5fdbe22fdec6f806984670e9251b29450803fd7d Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Sun, 24 Jun 2012 23:00:11 -0400 Subject: Before changing template for traits --- wqflask/wqflask/show_trait/DataEditingPage.py | 69 ++++++++++++++++----------- 1 file changed, 40 insertions(+), 29 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 38ab8c90..cbda3e41 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import, print_function, division + import string import os import cPickle @@ -13,6 +15,7 @@ from dbFunction import webqtlDatabaseFunction from base.templatePage import templatePage from basicStatistics import BasicStatisticsFunctions +from pprint import pformat as pf ######################################### # DataEditingPage @@ -1659,32 +1662,32 @@ class DataEditingPage(templatePage): break mainForm = None # Just trying to get things working - primary_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') + primary_strains = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=allstrainlist_neworder, mainForm=mainForm, thisTrait=thisTrait, other_strainsExist=other_strainsExist, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='primary') #primary_table.append(primary_header) - for i in range(len(primary_body)): - print("hji") - pass + #for i in range(len(primary_body)): + # print("hji") + # pass #primary_table.append(primary_body[i]) other_strains = [] for strain in thisTrait.data.keys(): print("hjk - strain is:", strain) if strain not in allstrainlist_neworder: - pass - #allstrainlist_neworder.append(strain) - #other_strains.append(strain) + #pass + allstrainlist_neworder.append(strain) + other_strains.append(strain) if other_strains: - other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits - other_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for other table object; same function is used as the one used for the primary table, since the header is the same + #other_table = HT.TableLite(cellspacing=0, cellpadding=0, Id="sortable2", Class="tablesorter") #Table object with other (for example, non-BXD / MDP) traits + #other_header = self.getTableHeader(fd=fd, thisTrait=thisTrait, nCols=nCols, attribute_names=attribute_names) #Generate header for other table object; same function is used as the one used for the primary table, since the header is the same other_strains.sort() #Sort other strains other_strains = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_strains #Append F1 and parent strains to the beginning of the sorted list of other strains - MDPText = HT.Span("Samples:", Class="ffl fwb fs12") - MDPMenu1 = HT.Select(name='MDPChoice1') - MDPMenu2 = HT.Select(name='MDPChoice2') - MDPMenu3 = HT.Select(name='MDPChoice3') + #MDPText = HT.Span("Samples:", Class="ffl fwb fs12") + #MDPMenu1 = HT.Select(name='MDPChoice1') + #MDPMenu2 = HT.Select(name='MDPChoice2') + #MDPMenu3 = HT.Select(name='MDPChoice3') #MDPMenu1.append(('%s Only' % fd.RISet,'1')) #MDPMenu2.append(('%s Only' % fd.RISet,'1')) #MDPMenu3.append(('%s Only' % fd.RISet,'1')) @@ -1698,12 +1701,12 @@ class DataEditingPage(templatePage): #self.MDPRow2.append(HT.TD(MDPText),HT.TD(MDPMenu2)) #self.MDPRow3.append(HT.TD(MDPText),HT.TD(MDPMenu3)) - other_body = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') + other_strains = self.addTrait2Table(fd=fd, varianceDataPage=varianceDataPage, strainlist=other_strains, mainForm=mainForm, thisTrait=thisTrait, attribute_ids=attribute_ids, attribute_names=attribute_names, strains='other') #other_table.append(other_header) - for i in range(len(other_body)): - print("hjn") - pass + #for i in range(len(other_body)): + # print("hjn") + # pass #other_table.append(other_body[i]) else: pass @@ -1721,11 +1724,13 @@ class DataEditingPage(templatePage): #primary_div = HT.Div(primary_table, Id="primary") #Container for table with primary (for example, BXD) strain values #container.append(primary_div) - if other_strains: - other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values + #if other_strains: + # other_div = HT.Div(other_table, Id="other") #Container for table with other (for example, Non-BXD/MDP) strain values #container.append(HT.Div(' ', height=30)) #container.append(other_div) + self.primary_strains = primary_strains + self.other_strains = other_strains #table.append(HT.TR(HT.TD(container))) #title5Body.append(table) @@ -1750,6 +1755,8 @@ class DataEditingPage(templatePage): upperBound, lowerBound = Plot.findOutliers(vals) # ZS: Values greater than upperBound or less than lowerBound are considered outliers. + the_strains = [] + for i, strainNameOrig in enumerate(strainlist): strain = {} print("zyt - strainNameOrig:", strainNameOrig) @@ -1777,7 +1784,7 @@ class DataEditingPage(templatePage): traitVal = '' dispVal = 'x' - strain['strain_name'] = StrainName + strain['strain_name'] = strainName strainNameDisp = HT.Span(strainName, Class='fs14 fwn ffl') if varianceDataPage: @@ -1836,25 +1843,28 @@ class DataEditingPage(templatePage): #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, # onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) - if (strains == 'primary'): - strain[the_id] = "Primary_" + str(i+1) + if strains == 'primary': + strain['the_id'] = "Primary_" + str(i+1) #table_row = HT.TR(Id="Primary_"+str(i+1), Class=rowClassName) else: - strain[the_id] = "Other_" + str(i+1) + strain['the_id'] = "Other_" + str(i+1) #table_row = HT.TR(Id="Other_"+str(i+1), Class=rowClassName) - if varianceDataPage: + strain['value'] = traitVal + + strain['se'] = dispVar + #if varianceDataPage: #table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) #table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) #table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) #table_row.append(HT.TD("±", width=20, align='center', Class=className)) #table_row.append(HT.TD(seField, width=80, align='right', Id="SE_"+str(i)+"_"+strains, Class=className)) - pass - else: + #pass + #else: #table_row.append(HT.TD(str(i+1), selectCheck, width=45, align='right', Class=className)) #table_row.append(HT.TD(strainNameDisp, strainNameAdd, align='right', width=100, Class=className)) #table_row.append(HT.TD(valueField, width=70, align='right', Id="value_"+str(i)+"_"+strains, Class=className)) - pass + #pass if thisTrait and thisTrait.db and thisTrait.db.type =='ProbeSet': if len(attribute_ids) > 0: @@ -1892,9 +1902,10 @@ class DataEditingPage(templatePage): attr_className = str(attributeValue) + " " + className table_row.append(HT.TD(attr_container, align='right', Class=attr_className)) attr_counter += 1 - + the_strains.append(strain) #table_body.append(table_row) - return table_body + print("*the_strains are [%i]: %s" % (len(the_strains), pf(the_strains))) + return the_strains def getTableHeader(self, fd, thisTrait, nCols, attribute_names): -- cgit v1.2.3 From 9ab5aa849d344ab49f48b6629eebf95177a6b530 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 25 Jun 2012 00:29:16 -0400 Subject: Outlier support added --- wqflask/wqflask/show_trait/DataEditingPage.py | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index cbda3e41..39aa19ae 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -1798,22 +1798,24 @@ class DataEditingPage(templatePage): if thisval == 'x': traitVar = '' #ZS: Used to be 0, but it doesn't seem like a good idea for values of 0 to *always* be at the bottom when you sort; it makes more sense to put "nothing" - className = 'fs13 b1 c222 ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = 'novalue ' + #className = 'fs13 b1 c222 ' + #valueClassName = 'fs13 b1 c222 valueField ' + #rowClassName = 'novalue ' else: if (thisval >= upperBound) or (thisval <= lowerBound): - className = 'fs13 b1 c222 outlier ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = 'outlier' + strain['outlier'] = True + #className = 'fs13 b1 c222 outlier ' + #valueClassName = 'fs13 b1 c222 valueField ' + #rowClassName = 'outlier' else: - className = 'fs13 b1 c222 ' - valueClassName = 'fs13 b1 c222 valueField ' - rowClassName = ' ' - - if varianceDataPage: - varClassName = valueClassName + str(traitVar) - valueClassName += str(traitVal) + strain['outlier'] = False + #className = 'fs13 b1 c222 ' + #valueClassName = 'fs13 b1 c222 valueField ' + #rowClassName = ' ' + # + #if varianceDataPage: + # varClassName = valueClassName + str(traitVar) + #valueClassName += str(traitVal) if strainNameOrig == strainName: if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): -- cgit v1.2.3 From 47fdfa932d900ec9d235840ca17e06035f877fd3 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 25 Jun 2012 02:22:33 -0400 Subject: Creating a new css file for use with flask --- web/css/general_flask.css | 244 ++++ wqflask/wqflask/show_trait/DataEditingPage.py | 4 +- wqflask/wqflask/templates/base.html | 2 +- .../wqflask/templates/trait_data_and_analysis.html | 1489 +------------------- 4 files changed, 274 insertions(+), 1465 deletions(-) create mode 100755 web/css/general_flask.css diff --git a/web/css/general_flask.css b/web/css/general_flask.css new file mode 100755 index 00000000..7a54e7b8 --- /dev/null +++ b/web/css/general_flask.css @@ -0,0 +1,244 @@ +@import url(import.css); + +body +{ + font-family : verdana, geneva, lucida, 'lucida grande', arial, helvetica; + font-weight : Normal; +} + +Blockquote { + margin : 14px 18px 14px 18px; +} + +/*Font size*/ +.fs10 {font-size : 10px} +.fs11 {font-size : 11px} +.fs12 {font-size : 12px} +.fs13 {font-size : 13px} +.fs14 {font-size : 14px} +.fs15 {font-size : 15px} +.fs16 {font-size : 16px} +.fs17 {font-size : 17px} + +/*Font Weight*/ +.fwb {font-weight : Bold} +.fwn {font-weight : Normal} + +/*Font Style*/ +.fsI {font-style : Italic} + +/*Font family*/ +.ffv {font-family : verdana, geneva, lucida, 'lucida grande', arial, helvetica;} +.ffl {font-family : lucida, verdana, 'lucida grande', helvetica, arial, geneva;} +.ffmono {font-family : "CourierNew", Courier, mono;} + +/*Color*/ +.cr {color : #f00} +.cg {color : #0f0} +.cdg {color : darkgreen} +.cb {color : #00f} +.c222 {color : #222} +.c999 {color : #999} +.c00d {color : #00d} +.cori {color : #CC9933} +.crb {color : royalblue} +.cw {color : #fff} +.cbl {color : #000000} +.cydull {color : #cfcf32} +.cdefault {color : #503A7D} + +/*backColor*/ +.cbr {background-color : #f00} +.cbg {background-color : #0f0} +.cbdg {background-color : darkgreen} +.cbb {background-color : #00f} +.cb222 {background-color : #222} +.cbg22t {background-color : #FF6} +.cbg22c {background-color : #5CB3FF} +.cbg2C {background-color : #1569C7} +.cbg22a {background-color : #F66} +.cbg22g {background-color : #CF9} +.cb00d {background-color : #00d} +.cb222 {background-color : #222} +.cbeee {background-color : #eee} +.cbori {background-color : #CC9933} +.cbrb {background-color : royalblue} +.cbdb {background-color : #2D2DB5} +.cbw {background-color : #fff} +.cbydull {background-color : #cfcf32} +.cbrdull {background-color : #c33232} +.cbgdull {background-color : #32c332} +.cbbdull {background-color : #1569C7} +.cbpdull {background-color : #c332c3} +.cbccc {background-color : #ccc} +.cbddf {background-color : #ddf} + +.nowrap {white-space: nowrap;} + +/*Table Cell*/ +.collap {border-collapse : collapse;} + +TH.header { + background-image: url(/images/bg.gif); + background-color: #4169E1; + cursor: pointer; + background-repeat: no-repeat; + background-position: center left; + padding-left: 20px; + margin-left: -1px; +} +TH.headerSortUp { + background-image: url(/images/desc.gif); + background-color: #4169E1; +} +TH.headerSortDown { + background-image: url(/images/asc.gif); + background-color: #4169E1; +} + +TD, P {color : #222222; font-size : 13px} +TD.b1 {border : 1px solid #999999; padding : 3px;} +TH.b1 {border : 1px solid #999999; padding : 3px;} +TD.bt1 {border-top : 1px solid #999999; padding : 3px;} +TD.bb1 {border-bottom : 1px solid #999999; padding : 3px;} + +.b2 {border : 2px solid royalblue; padding : 3px;} + +.bd1 {border : 1px dashed #999999; padding : 6px;} + +TD.outlier {background-color : yellow;} + +TR.alt td { + background: #e6e8fa; +} + +TR.over td { + background: #82CFFD; +} + +/*Table Row*/ +.toggleShowHide { color : #0000DD; cursor: pointer;} +.invisible {display: none;} + +/*Link*/ +A.font_black:link {color: #000000; text-decoration : None} +A.font_black:active {color: #000000; text-decoration : None} +A.font_black:hover {color: #000000; text-decoration : None} +A.font_black:visited {color: #000000; text-decoration : None} + +A {font-family : lucida, 'lucida grande', verdana, helvetica, arial, geneva; + font-weight : Bold; font-size : 13px; text-decoration : None} + +A:link, A:visited {color : #0000DD; text-decoration : None} + +A:active {color : #FF0000; text-decoration : None} + +A:hover {color : #FF0000; text-decoration : None} + +A.background_grey {background:#dddddd;padding:2;} + +A.non_bold {font-weight : Normal; color : #0000DD;} + +/*Border Style*/ +.solidBorder {border : 1px solid #CCCCCC; padding : 2px;} +.doubleBorder {border : double #AAAAAA; padding : 2px;} + +/*Title style*/ +.title {font-weight:Bold; color:#222222; font-size:16px} + +.subtitle {font-family : lucida, verdana, 'lucida grande', helvetica, arial, geneva; + font-weight:Bold; font-size:14px; color:#000082} + +.sectionheader {font-family : arial, verdana, 'lucida grande', helvetica, lucida, geneva; + font-weight:Bold; font-size:14px; vertical-align: middle; display:block; color:#000000; background-color:#DDDDDD; line-height:24px; height:24px;} + +/*drop shadow*/ +#v3 .wrap1 {background:url(/images/shadow/shadow.gif) right bottom no-repeat;} +#v3 .wrap2 {background:url(/images/shadow/corner_bl.gif) -12px 100% no-repeat;} +#v3 .wrap3 { + padding:0 9px 9px 0; + background:url(/images/shadow/corner_tr.gif) 100% -12px no-repeat;} + + +/*steal from google*/ + + .tabsTableBox { + width:100%; + border-spacing:0; + border-collapse:collapse; + margin-top:5px; + font-size:smaller; + text-align:center; + } + .tabsTableBox td { + padding-right:5px; + padding-left:5px; + padding-bottom:3px; + } + +/*For making the Custom Strain box in snpBrowser.py a default width, instead of looking weird always*/ +.customBoxWidth { + width: 143px; +} + .selectedBox { + border-top:1px solid #676767; + border-right:1px solid #676767; + border-left:1px solid #676767; + width:80; + font-weight:bolder; + color:#3366cc; + font-size:12px; + } + .unselectedBox { + background-color:#dddddd; + border-top:1px solid #aaaaaa; + width:80; + border-right:1px solid #aaaaaa; + border-left:1px solid #aaaaaa; + border-bottom:1px solid #676767; + font-size:12px; + } + + .spacerTabBox { + border-bottom:1px solid #676767; + width:5px; + } + + .emptyTabBox { + border-bottom:1px solid #676767; + } + +/*For font color of 'Get Any' and 'Combined' in the main page*/ +.searchtip +{ +color: #999999; +} + + +/*For font style and color of commands and keywords in the scriptable interface page*/ +.keywords +{ +font-family : "CourierNew", Courier, mono; +font-size : 15px; +color : #0000FF; +font-weight : Normal +} +/*For RIsample.html page*/ +.strains +{ +border:1px solid #999999; +border-top:1px solid #940; +border-bottom:1px solid #940; +padding:5; +background-color:#ddf; +font-family:verdana; +} +.values +{ +border:1px solid #999999; +border-top:1px solid #940; +border-bottom:1px solid #940; +padding:5; +background-color:#eee; +font-family:courier; +} diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index 39aa19ae..fa343535 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -1803,12 +1803,12 @@ class DataEditingPage(templatePage): #rowClassName = 'novalue ' else: if (thisval >= upperBound) or (thisval <= lowerBound): - strain['outlier'] = True + strain['outlier'] = "outlier" # We're going to use this as a class, so we want it to be a word #className = 'fs13 b1 c222 outlier ' #valueClassName = 'fs13 b1 c222 valueField ' #rowClassName = 'outlier' else: - strain['outlier'] = False + strain['outlier'] = "not_outlier" #className = 'fs13 b1 c222 ' #valueClassName = 'fs13 b1 c222 valueField ' #rowClassName = ' ' diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 117d26fb..6776a71c 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -11,7 +11,7 @@ - + diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 39174425..c3bdd787 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -3059,1469 +3059,34 @@ SE - - 1 - - B6D2F1 - - - - ± - - - - - - 2 - - D2B6F1 - - - - ± - - - - - - 3 - - C57BL/6J - - - - ± - - - - - - 4 - - DBA/2J - - - - ± - - - - - - 5 - - BXD1 - - - - ± - - - - - - 6 - - BXD2 - - - - ± - - - - - - 7 - - BXD5 - - - - ± - - - - - - 8 - - BXD6 - - - - ± - - - - - - 9 - - BXD8 - - - - ± - - - - - - 10 - - BXD9 - - - - ± - - - - - - 11 - - BXD11 - - - - ± - - - - - - 12 - - BXD12 - - - - ± - - - - - - 13 - - BXD13 - - - - ± - - - - - - 14 - - BXD14 - - - - ± - - - - - - 15 - - BXD15 - - - - ± - - - - - - 16 - - BXD16 - - - - ± - - - - - - 17 - - BXD18 - - - - ± - - - - - - 18 - - BXD19 - - - - ± - - - - - - 19 - - BXD20 - - - - ± - - - - - - 20 - - BXD21 - - - - ± - - - - - - 21 - - BXD22 - - - - ± - - - - - - 22 - - BXD23 - - - - ± - - - - - - 23 - - BXD24a - - - - ± - - - - - - 24 - - BXD24 - - - - ± - - - - - - 25 - - BXD25 - - - - ± - - - - - - 26 - - BXD27 - - - - ± - - - - - - 27 - - BXD28 - - - - ± - - - - - - 28 - - BXD29 - - - - ± - - - - - - 29 - - BXD30 - - - - ± - - - - - - 30 - - BXD31 - - - - ± - - - - - - 31 - - BXD32 - - - - ± - - - - - - 32 - - BXD33 - - - - ± - - - - - - 33 - - BXD34 - - - - ± - - - - - - 34 - - BXD35 - - - - ± - - - - - - 35 - - BXD36 - - - - ± - - - - - - 36 - - BXD37 - - - - ± - - - - - - 37 - - BXD38 - - - - ± - - - - - - 38 - - BXD39 - - - - ± - - - - - - 39 - - BXD40 - - - - ± - - - - - - 40 - - BXD41 - - - - ± - - - - - - 41 - - BXD42 - - - - ± - - - - - - 42 - - BXD43 - - - - ± - - - - - - 43 - - BXD44 - - - - ± - - - - - - 44 - - BXD45 - - - - ± - - - - - - 45 - - BXD48 - - - - ± - - - - - - 46 - - BXD49 - - - - ± - - - - - - 47 - - BXD50 - - - - ± - - - - - - 48 - - BXD51 - - - - ± - - - - - - 49 - - BXD52 - - - - ± - - - - - - 50 - - BXD53 - - - - ± - - - - - - 51 - - BXD54 - - - - ± - - - - - - 52 - - BXD55 - - - - ± - - - - - - 53 - - BXD56 - - - - ± - - - - - - 54 - - BXD59 - - - - ± - - - - - - 55 - - BXD60 - - - - ± - - - - - - 56 - - BXD61 - - - - ± - - - - - - 57 - - BXD62 - - - - ± - - - - - - 58 - - BXD63 - - - - ± - - - - - - 59 - - BXD64 - - - - ± - - - - - - 60 - - BXD65 - - - - ± - - - - - - 61 - - BXD66 - - - - ± - - - - - - 62 - - BXD67 - - - - ± - - - - - - 63 - - BXD68 - - - - ± - - - - - - 64 - - BXD69 - - - - ± - - - - - - 65 - - BXD70 - - - - ± - - - - - - 66 - - BXD71 - - + {% for strain in primary_strains %} + + + {{ loop.index }} + + + + + {{ strain.strain_name }} + + + + + + + + ± + + + + + + {% endfor %} - ± - - - - - - 67 - - BXD72 - - - - ± - - - - - - 68 - - BXD73 - - - - ± - - - - - - 69 - - BXD74 - - - - ± - - - - - - 70 - - BXD75 - - - - ± - - - - - - 71 - - BXD76 - - - - ± - - - - - - 72 - - BXD77 - - - - ± - - - - - - 73 - - BXD78 - - - - ± - - - - - - 74 - - BXD79 - - - - ± - - - - - - 75 - - BXD80 - - - - ± - - - - - - 76 - - BXD81 - - - - ± - - - - - - 77 - - BXD83 - - - - ± - - - - - - 78 - - BXD84 - - - - ± - - - - - - 79 - - BXD85 - - - - ± - - - - - - 80 - - BXD86 - - - - ± - - - - - - 81 - - BXD87 - - - - ± - - - - - - 82 - - BXD88 - - - - ± - - - - - - 83 - - BXD89 - - - - ± - - - - - - 84 - - BXD90 - - - - ± - - - - - - 85 - - BXD91 - - - - ± - - - - - - 86 - - BXD92 - - - - ± - - - - - - 87 - - BXD93 - - - - ± - - - - - - 88 - - BXD94 - - - - ± - - - - - - 89 - - BXD95 - - - - ± - - - - - - 90 - - BXD96 - - - - ± - - - - - - 91 - - BXD97 - - - - ± - - - - - - 92 - - BXD98 - - - - ± - - - - - - 93 - - BXD99 - - - - ± - - - - - - 94 - - BXD100 - - - - ± - - - - - - 95 - - BXD101 - - - - ± - - - - - - 96 - - BXD102 - - - - ± - - - - - - 97 - - BXD103 - - - - ± - - -
    -- cgit v1.2.3 From f94b7e23d1026fec0b778e1754e01c5050d20444 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 25 Jun 2012 02:32:32 -0400 Subject: Modified css --- web/css/general_flask.css | 56 +++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/web/css/general_flask.css b/web/css/general_flask.css index 7a54e7b8..d0cffbc4 100755 --- a/web/css/general_flask.css +++ b/web/css/general_flask.css @@ -1,6 +1,6 @@ @import url(import.css); -body +body { font-family : verdana, geneva, lucida, 'lucida grande', arial, helvetica; font-weight : Normal; @@ -78,23 +78,23 @@ Blockquote { /*Table Cell*/ .collap {border-collapse : collapse;} -TH.header { +TH.header { background-image: url(/images/bg.gif); - background-color: #4169E1; - cursor: pointer; - background-repeat: no-repeat; - background-position: center left; - padding-left: 20px; - margin-left: -1px; -} -TH.headerSortUp { - background-image: url(/images/desc.gif); - background-color: #4169E1; -} -TH.headerSortDown { - background-image: url(/images/asc.gif); - background-color: #4169E1; -} + background-color: #4169E1; + cursor: pointer; + background-repeat: no-repeat; + background-position: center left; + padding-left: 20px; + margin-left: -1px; +} +TH.headerSortUp { + background-image: url(/images/desc.gif); + background-color: #4169E1; +} +TH.headerSortDown { + background-image: url(/images/asc.gif); + background-color: #4169E1; +} TD, P {color : #222222; font-size : 13px} TD.b1 {border : 1px solid #999999; padding : 3px;} @@ -106,7 +106,7 @@ TD.bb1 {border-bottom : 1px solid #999999; padding : 3px;} .bd1 {border : 1px dashed #999999; padding : 6px;} -TD.outlier {background-color : yellow;} +TR.outlier, TD.outlier {background-color : yellow;} TR.alt td { background: #e6e8fa; @@ -126,7 +126,7 @@ A.font_black:active {color: #000000; text-decoration : None} A.font_black:hover {color: #000000; text-decoration : None} A.font_black:visited {color: #000000; text-decoration : None} -A {font-family : lucida, 'lucida grande', verdana, helvetica, arial, geneva; +A {font-family : lucida, 'lucida grande', verdana, helvetica, arial, geneva; font-weight : Bold; font-size : 13px; text-decoration : None} A:link, A:visited {color : #0000DD; text-decoration : None} @@ -137,7 +137,7 @@ A:hover {color : #FF0000; text-decoration : None} A.background_grey {background:#dddddd;padding:2;} -A.non_bold {font-weight : Normal; color : #0000DD;} +A.non_bold {font-weight : Normal; color : #0000DD;} /*Border Style*/ .solidBorder {border : 1px solid #CCCCCC; padding : 2px;} @@ -146,10 +146,10 @@ A.non_bold {font-weight : Normal; color : #0000DD;} /*Title style*/ .title {font-weight:Bold; color:#222222; font-size:16px} -.subtitle {font-family : lucida, verdana, 'lucida grande', helvetica, arial, geneva; +.subtitle {font-family : lucida, verdana, 'lucida grande', helvetica, arial, geneva; font-weight:Bold; font-size:14px; color:#000082} - -.sectionheader {font-family : arial, verdana, 'lucida grande', helvetica, lucida, geneva; + +.sectionheader {font-family : arial, verdana, 'lucida grande', helvetica, lucida, geneva; font-weight:Bold; font-size:14px; vertical-align: middle; display:block; color:#000000; background-color:#DDDDDD; line-height:24px; height:24px;} /*drop shadow*/ @@ -174,7 +174,7 @@ A.non_bold {font-weight : Normal; color : #0000DD;} padding-right:5px; padding-left:5px; padding-bottom:3px; - } + } /*For making the Custom Strain box in snpBrowser.py a default width, instead of looking weird always*/ .customBoxWidth { @@ -186,7 +186,7 @@ A.non_bold {font-weight : Normal; color : #0000DD;} border-left:1px solid #676767; width:80; font-weight:bolder; - color:#3366cc; + color:#3366cc; font-size:12px; } .unselectedBox { @@ -198,16 +198,16 @@ A.non_bold {font-weight : Normal; color : #0000DD;} border-bottom:1px solid #676767; font-size:12px; } - + .spacerTabBox { border-bottom:1px solid #676767; width:5px; } - + .emptyTabBox { border-bottom:1px solid #676767; } - + /*For font color of 'Get Any' and 'Combined' in the main page*/ .searchtip { -- cgit v1.2.3 From 3a222b876cf291921194d9f0e2dd3fc8e6a999a2 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Mon, 25 Jun 2012 04:43:00 -0400 Subject: checkpoint --- wqflask/wqflask/show_trait/DataEditingPage.py | 54 +-- .../wqflask/templates/trait_data_and_analysis.html | 518 +-------------------- 2 files changed, 36 insertions(+), 536 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index fa343535..b1cf5a32 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -1817,33 +1817,33 @@ class DataEditingPage(templatePage): # varClassName = valueClassName + str(traitVar) #valueClassName += str(traitVal) - if strainNameOrig == strainName: - if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): - ######################################################################################################################################################## - # ZS: Append value and variance to the value and variance input fields' list of classes; this is so the javascript can update the value when the user - # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. - ######################################################################################################################################################### - - #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, - # onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) - if varianceDataPage: - pass - #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - # onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) - else: - pass - #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) - if varianceDataPage: - pass - #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) - else: - pass - #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, - #onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) - if varianceDataPage: - pass - #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, - # onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + #if strainNameOrig == strainName: + # if other_strainsExist and strainNameOrig in (fd.parlist + fd.f1list): + # ######################################################################################################################################################## + # # ZS: Append value and variance to the value and variance input fields' list of classes; this is so the javascript can update the value when the user + # # changes it. The updated value is then used when the table is sorted (tablesorter.js). This needs to be done because the "value" attribute is immutable. + # ######################################################################################################################################################### + # + # #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, + # # onChange= "javascript:this.form['_2nd_%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + # if varianceDataPage: + # pass + # #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + # # onChange= "javascript:this.form['V_2nd_%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) + # else: + # pass + # #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right; background-color:#FFFFFF;", value=dispVal, Class=valueClassName) + # if varianceDataPage: + # pass + # #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, Class=varClassName) + #else: + # pass + # #valueField = HT.Input(name=strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVal, + # #onChange= "javascript:this.form['%s'].value=this.form['%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=valueClassName) + # if varianceDataPage: + # pass + # #seField = HT.Input(name='V'+strainNameOrig, size=8, maxlength=8, style="text-align:right", value=dispVar, + # # onChange= "javascript:this.form['V%s'].value=this.form['V%s'].value;" % (strainNameOrig.replace("/", ""), strainNameOrig.replace("/", "")), Class=varClassName) if strains == 'primary': strain['the_id'] = "Primary_" + str(i+1) diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index c3bdd787..efd87acc 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -3045,8 +3045,11 @@   and samples with no value (x) can be hidden by clicking Hide No Value .

-
- + {% for strain_type in (primary_strains, other_strains) %} +
{# Slightly tortuous, but best way to get the id we need #} +
@@ -3059,7 +3062,7 @@ - {% for strain in primary_strains %} + {% for strain in strain_type %}
IndexSE
{{ loop.index }} @@ -3089,518 +3092,15 @@
-
 
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IndexSampleValue SE
1 B6D2F1±
2 D2B6F1±
3 C57BL/6J±
4 DBA/2J±
5 129S1/SvImJ±
6 A/J±
7 AKR/J±
8 BALB/cByJ±
9 BALB/cJ±
10 C3H/HeJ±
11 C57BL/6ByJ±
12 CAST/EiJ±
13 CXB1±
14 CXB10±
15 CXB11±
16 CXB12±
17 CXB13±
18 CXB2±
19 CXB3±
20 CXB4±
21 CXB5±
22 CXB6±
23 CXB7±
24 CXB8±
25 CXB9±
26 KK/HlJ±
27 LG/J±
28 NOD/ShiLtJ±
29 NZO/HlLtJ±
30 PWD/PhJ±
31 PWK/PhJ±
32 WSB/EiJ±
-
+ {% endfor %}
- + +
-- cgit v1.2.3 From 877e0832959c0ab9e7ad417cfdc233b450274a8d Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Fri, 29 Jun 2012 16:49:08 -0400 Subject: Added dataSharing to flask directory --- wqflask/dataSharing/SharingBody.py | 290 ++++++++++++++++++++++++++ wqflask/dataSharing/SharingInfo.py | 98 +++++++++ wqflask/dataSharing/SharingInfoAddPage.py | 47 +++++ wqflask/dataSharing/SharingInfoDeletePage.py | 55 +++++ wqflask/dataSharing/SharingInfoEditPage.py | 51 +++++ wqflask/dataSharing/SharingInfoPage.py | 52 +++++ wqflask/dataSharing/SharingInfoUpdatePage.py | 109 ++++++++++ wqflask/dataSharing/SharingListDataSetPage.py | 99 +++++++++ wqflask/dataSharing/SharingPage.py | 40 ++++ wqflask/dataSharing/__init__.py | 0 10 files changed, 841 insertions(+) create mode 100755 wqflask/dataSharing/SharingBody.py create mode 100755 wqflask/dataSharing/SharingInfo.py create mode 100755 wqflask/dataSharing/SharingInfoAddPage.py create mode 100755 wqflask/dataSharing/SharingInfoDeletePage.py create mode 100755 wqflask/dataSharing/SharingInfoEditPage.py create mode 100755 wqflask/dataSharing/SharingInfoPage.py create mode 100755 wqflask/dataSharing/SharingInfoUpdatePage.py create mode 100755 wqflask/dataSharing/SharingListDataSetPage.py create mode 100755 wqflask/dataSharing/SharingPage.py create mode 100755 wqflask/dataSharing/__init__.py diff --git a/wqflask/dataSharing/SharingBody.py b/wqflask/dataSharing/SharingBody.py new file mode 100755 index 00000000..4445e0d1 --- /dev/null +++ b/wqflask/dataSharing/SharingBody.py @@ -0,0 +1,290 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +sharing_body_string = """ + + +

Data Set Download

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Species: + + + +
+ Group: + + + +
+ Type: + + + +
+ Database: + + + +
+     +
+ + +
+ +

GeneNetwork Accession Number

+
+ + + + + + + + + + + + +
GN:  E.g. 112
+     +
+
+ + +""" + +sharinginfo_body_string = """ +List of DataSets
+

%s +modify this page +%s +

+ + + + + +
+ + + + + + + + + + + +
GN Accession: GN%s
GEO Series: %s
Title: %s
Organism: %s
Group: %s
Tissue: %s
Dataset Status: %s
Platforms: %s
Normalization: %s
+ See Contact Information
+
+
+ + + + + + + +
Download datasets and supplementary data files
%s
+
+
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Summary:
%s

About the cases used to generate this set of data:
%s

About the tissue used to generate this set of data:
%s

About downloading this data set:
%s

About the array platform:
%s

About data values and data processing:
%s

Data source acknowledgment:
%s

Experiment Type:
%s

Overall Design:
%s

Contributor:
%s

Citation:
%s

Submission Date:
%s

Laboratory:
%s

Samples:
%s

+

+ +""" + +sharinginfoedit_body_string = """ +

%s

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Principal Investigator

Contact Name:
Emails:
Phone:
URL:
Organization Name:
Department:
Laboratory:
Address:
City:
State:
ZIP:
Country:

Summary

Summary:

Biology

Experiment Design:
About the cases used to
generate this set of data:
About the tissue used to
generate this set of data:

Technique

About downloading this data set:
About the array platform:

Bioinformatics

About data values and
data processing:
Overall Design:

Misc

Contributor:
Citation:
Data source acknowledgment:

Administrator ONLY

GN Accesion Id:
DB Title in GN:
GEO Series:
Status:
Title:
Organism_Id (Taxonomy ID):
Organism:
Submission Date:
Platforms:
Species:
Tissue:
Normalization:
Inbred Set:
Info Page Name:
Samples:
Authorized Users:
Progress:
+""" diff --git a/wqflask/dataSharing/SharingInfo.py b/wqflask/dataSharing/SharingInfo.py new file mode 100755 index 00000000..10abcefa --- /dev/null +++ b/wqflask/dataSharing/SharingInfo.py @@ -0,0 +1,98 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import httplib + +from dbFunction import webqtlDatabaseFunction +import SharingBody + + +######################################### +# Sharing Info +######################################### +class SharingInfo: + + def __init__(self, GN_AccessionId, InfoPageName): + self.GN_AccessionId = GN_AccessionId + self.InfoPageName = InfoPageName + + def getInfo(self): + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + sql = "select Id, GEO_Series, Status, Title, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Normalization, InbredSet, InfoPageName, DB_Name, Organism_Id, InfoPageTitle, GN_AccesionId, Tissue, AuthorizedUsers, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, Progreso from InfoFiles where " + if(self.GN_AccessionId): + sql += "GN_AccesionId = %s" + cursor.execute(sql, self.GN_AccessionId) + elif (self.InfoPageName): + sql += "InfoPageName = %s" + cursor.execute(sql, self.InfoPageName) + else: + raise 'No correct parameter found' + info = cursor.fetchone() + # fetch datasets file list + try: + conn = httplib.HTTPConnection("atlas.uthsc.edu") + conn.request("GET", "/scandatasets.php?GN_AccesionId=%s" % (info[32])) + response = conn.getresponse() + data = response.read() + filelist = data.split() + conn.close() + except Exception: + filelist = [] + return info, filelist + + def getBody(self, infoupdate=""): + info, filelist = self.getInfo() + if filelist: + htmlfilelist = '
    \n' + for i in range(len(filelist)): + if i%2==0: + filename = filelist[i] + filesize = filelist[i+1] + htmlfilelist += "
  • " + htmlfilelist += '%s' % (self.GN_AccessionId, filename, filename) + htmlfilelist += '   ' + #r=re.compile(r'(?<=\d)(?=(\d\d\d)+(?!\d))') + #htmlfilelist += '[%s B]' % r.sub(r',',filesize) + if 12= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Adding Info" + detail = ["You don't have the permission to add new dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + self.dict['body'] = SharingBody.sharinginfoedit_body_string % ("Add new dataset", "-1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") diff --git a/wqflask/dataSharing/SharingInfoDeletePage.py b/wqflask/dataSharing/SharingInfoDeletePage.py new file mode 100755 index 00000000..edc0be7d --- /dev/null +++ b/wqflask/dataSharing/SharingInfoDeletePage.py @@ -0,0 +1,55 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Delete Page +######################################### +class SharingInfoDeletePage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Deleting Info" + detail = ["You don't have the permission to delete this dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') + sql = "delete from InfoFiles where GN_AccesionId=%s" + cursor.execute(sql, GN_AccessionId) + re = cursor.fetchone() + self.dict['body'] = "Delete dataset info record (GN_AccesionId=%s) successfully." % GN_AccessionId \ No newline at end of file diff --git a/wqflask/dataSharing/SharingInfoEditPage.py b/wqflask/dataSharing/SharingInfoEditPage.py new file mode 100755 index 00000000..266b8602 --- /dev/null +++ b/wqflask/dataSharing/SharingInfoEditPage.py @@ -0,0 +1,51 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +from base import webqtlConfig +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Edit Page +######################################### +class SharingInfoEditPage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to edit this dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') + InfoPageName = fd.formdata.getvalue('InfoPageName') + sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) + info, filelist = sharingInfoObject.getInfo() + self.dict['body'] = SharingBody.sharinginfoedit_body_string % (info[31], info[0], info[11], info[12], info[13], info[14], info[15], info[16], info[17], info[18], info[19], info[20], info[21], info[22], info[6], info[5], info[35], info[36], info[37], info[38], info[39], info[7], info[8], info[9], info[40], info[32], info[31], info[1], info[2], info[3], info[30], info[4], info[10], info[23], info[25], info[33], info[26], info[27], info[28], info[24], info[34], info[41]) diff --git a/wqflask/dataSharing/SharingInfoPage.py b/wqflask/dataSharing/SharingInfoPage.py new file mode 100755 index 00000000..230ba2f3 --- /dev/null +++ b/wqflask/dataSharing/SharingInfoPage.py @@ -0,0 +1,52 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Page +######################################### +class SharingInfoPage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') + InfoPageName = fd.formdata.getvalue('InfoPageName') + cursor = webqtlDatabaseFunction.getCursor() + if InfoPageName and not GN_AccessionId: + sql = "select GN_AccesionId from InfoFiles where InfoPageName = %s" + cursor.execute(sql, InfoPageName) + GN_AccessionId = cursor.fetchone() + url = webqtlConfig.CGIDIR + "main.py?FormID=sharinginfo&GN_AccessionId=%s" % GN_AccessionId + self.redirection = url + else: + sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) + self.dict['body'] = sharingInfoObject.getBody(infoupdate="") diff --git a/wqflask/dataSharing/SharingInfoUpdatePage.py b/wqflask/dataSharing/SharingInfoUpdatePage.py new file mode 100755 index 00000000..a70238b9 --- /dev/null +++ b/wqflask/dataSharing/SharingInfoUpdatePage.py @@ -0,0 +1,109 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import MySQLdb + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + +######################################### +# Sharing Info Update Page +######################################### +class SharingInfoUpdatePage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to modify this file"] + self.error(heading=heading,detail=detail,error="Error") + return + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + Id=fd.formdata.getvalue('Id') + GN_AccesionId=fd.formdata.getvalue('GN_AccesionId') + GEO_Series=fd.formdata.getvalue('GEO_Series') + Status=fd.formdata.getvalue('Status') + Title=fd.formdata.getvalue('Title') + Organism_Id=fd.formdata.getvalue('Organism_Id') + Organism=fd.formdata.getvalue('Organism') + Experiment_Type =fd.formdata.getvalue('Experiment_Type') + Summary=fd.formdata.getvalue('Summary') + Overall_Design=fd.formdata.getvalue('Overall_Design') + Contributor=fd.formdata.getvalue('Contributor') + Citation=fd.formdata.getvalue('Citation') + Submission_Date=fd.formdata.getvalue('Submission_Date') + Contact_Name=fd.formdata.getvalue('Contact_Name') + Emails=fd.formdata.getvalue('Emails') + Phone=fd.formdata.getvalue('Phone') + URL=fd.formdata.getvalue('URL') + Organization_Name=fd.formdata.getvalue('Organization_Name') + Department=fd.formdata.getvalue('Department') + Laboratory=fd.formdata.getvalue('Laboratory') + Street=fd.formdata.getvalue('Street') + City=fd.formdata.getvalue('City') + State=fd.formdata.getvalue('State') + ZIP=fd.formdata.getvalue('ZIP') + Country=fd.formdata.getvalue('Country') + Platforms=fd.formdata.getvalue('Platforms') + Samples=fd.formdata.getvalue('Samples') + Species=fd.formdata.getvalue('Species') + Tissue=fd.formdata.getvalue('Tissue') + Normalization=fd.formdata.getvalue('Normalization') + InbredSet=fd.formdata.getvalue('InbredSet') + InfoPageName=fd.formdata.getvalue('InfoPageName') + InfoPageTitle=fd.formdata.getvalue('InfoPageTitle') + About_Cases=fd.formdata.getvalue('About_Cases') + About_Tissue=fd.formdata.getvalue('About_Tissue') + About_Download=fd.formdata.getvalue('About_Download') + About_Array_Platform=fd.formdata.getvalue('About_Array_Platform') + About_Data_Values_Processing=fd.formdata.getvalue('About_Data_Values_Processing') + Data_Source_Acknowledge=fd.formdata.getvalue('Data_Source_Acknowledge') + AuthorizedUsers=fd.formdata.getvalue('AuthorizedUsers') + Progress=fd.formdata.getvalue('Progress') + if Id=='-1': + sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) + info, filelist = sharingInfoObject.getInfo() + if info: + heading = "Editing Info" + detail = ["The new dataset info record is duplicate."] + self.error(heading=heading, detail=detail, error="Error") + return + sql = """INSERT INTO InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s""" + cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress])) + infoupdate="This record has been succesfully added." + else: + sql = """UPDATE InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s WHERE Id=%s""" + cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress, Id])) + infoupdate="This record has been succesfully updated." + sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) + self.dict['body'] = sharingInfoObject.getBody(infoupdate=infoupdate) \ No newline at end of file diff --git a/wqflask/dataSharing/SharingListDataSetPage.py b/wqflask/dataSharing/SharingListDataSetPage.py new file mode 100755 index 00000000..ec90f5f3 --- /dev/null +++ b/wqflask/dataSharing/SharingListDataSetPage.py @@ -0,0 +1,99 @@ +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT +from base import webqtlConfig + +from base.templatePage import templatePage + + +######################################### +# Sharing List DataSet Page +######################################### +class SharingListDataSetPage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to list the datasets"] + self.error(heading=heading,detail=detail,error="Error") + return + + + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + query = """select GN_AccesionId, InfoPageTitle, Progreso from InfoFiles order by GN_AccesionId""" + self.cursor.execute(query) + result = self.cursor.fetchall() + + heading = HT.Paragraph('Dataset Table', Class="title") + + newrecord = HT.Href(text="New Record", url="/webqtl/main.py?FormID=sharinginfoadd") + + info = "Click the accession id to view the dataset info. Click the dataset name to edit the dataset info." + + datasetTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0, Class="collap", width="100%") + + tableHeaderRow = HT.TR() + tableHeaderRow.append(HT.TD("Accession Id", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Dataset name", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Progress", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Operation", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + datasetTable.append(tableHeaderRow) + + for one_row in result: + Accession_Id, InfoPage_title, Progress = one_row + datasetRow = HT.TR() + datasetRow.append(HT.TD(HT.Href(text="GN%s" % Accession_Id, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) + datasetRow.append(HT.TD(HT.Href(text="%s" % InfoPage_title, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) + datasetRow.append(HT.TD("%s" % Progress, Class='fs12 fwn ffl b1 c222')) + operation_edit = HT.Href(text="Edit", url="/webqtl/main.py?FormID=sharinginfoedit&GN_AccessionId=%s" % Accession_Id) + operation_delete = HT.Href(text="Delete", onClick="deleteRecord(%s); return false;" % Accession_Id) + operation = HT.TD(Class="fs12 fwn b1 c222", align="center") + operation.append(operation_edit) + operation.append("    ") + operation.append(operation_delete) + datasetRow.append(operation) + datasetTable.append(datasetRow) + + TD_LR.append(heading, HT.P(), newrecord, HT.P(), info, HT.P(), datasetTable) + + js1 = """ """ + self.dict['js1'] = js1 + self.dict['body'] = str(TD_LR) \ No newline at end of file diff --git a/wqflask/dataSharing/SharingPage.py b/wqflask/dataSharing/SharingPage.py new file mode 100755 index 00000000..cf1d9ac3 --- /dev/null +++ b/wqflask/dataSharing/SharingPage.py @@ -0,0 +1,40 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +import SharingBody + +######################################### +# SharingPage +######################################### + +class SharingPage(templatePage): + + def __init__(self, fd): + templatePage.__init__(self, fd) + self.dict['title'] = 'GeneNetwork Data Sharing Zone' + self.dict['body'] = SharingBody.sharing_body_string + self.dict['js2'] = 'onload="javascript:initialDatasetSelection();"' \ No newline at end of file diff --git a/wqflask/dataSharing/__init__.py b/wqflask/dataSharing/__init__.py new file mode 100755 index 00000000..e69de29b -- cgit v1.2.3 From d67019ce6d763b983d17b6bd2fb573f61618ea09 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Fri, 29 Jun 2012 18:23:39 -0400 Subject: working on data_sharing --- wqflask/wqflask/dataSharing/SharingBody.py | 290 +++++++ wqflask/wqflask/dataSharing/SharingInfo.py | 98 +++ wqflask/wqflask/dataSharing/SharingInfoAddPage.py | 47 ++ .../wqflask/dataSharing/SharingInfoDeletePage.py | 55 ++ wqflask/wqflask/dataSharing/SharingInfoEditPage.py | 51 ++ wqflask/wqflask/dataSharing/SharingInfoPage.py | 58 ++ .../wqflask/dataSharing/SharingInfoUpdatePage.py | 109 +++ .../wqflask/dataSharing/SharingListDataSetPage.py | 99 +++ wqflask/wqflask/dataSharing/SharingPage.py | 40 + wqflask/wqflask/dataSharing/__init__.py | 0 wqflask/wqflask/templates/data_sharing.html | 831 +++++++++++++++++++++ wqflask/wqflask/templates/index_page.html | 3 +- wqflask/wqflask/views.py | 19 +- 13 files changed, 1696 insertions(+), 4 deletions(-) create mode 100755 wqflask/wqflask/dataSharing/SharingBody.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfo.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfoAddPage.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfoDeletePage.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfoEditPage.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfoPage.py create mode 100755 wqflask/wqflask/dataSharing/SharingInfoUpdatePage.py create mode 100755 wqflask/wqflask/dataSharing/SharingListDataSetPage.py create mode 100755 wqflask/wqflask/dataSharing/SharingPage.py create mode 100755 wqflask/wqflask/dataSharing/__init__.py create mode 100644 wqflask/wqflask/templates/data_sharing.html diff --git a/wqflask/wqflask/dataSharing/SharingBody.py b/wqflask/wqflask/dataSharing/SharingBody.py new file mode 100755 index 00000000..880161f5 --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingBody.py @@ -0,0 +1,290 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +sharing_body_string = """ + + +

    Data Set Download

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + Species: + + + +
    + Group: + + + +
    + Type: + + + +
    + Database: + + + +
    +     +
    + + +
    + +

    GeneNetwork Accession Number

    +
    + + + + + + + + + + + + +
    GN:  E.g. 112
    +     +
    +
    + + +""" + +sharinginfo_body_string = """ +List of DataSets
    +

    %s +modify this page +%s +

    + + + + + +
    + + + + + + + + + + + +
    GN Accession: GN%s
    GEO Series: %s
    Title: %s
    Organism: %s
    Group: %s
    Tissue: %s
    Dataset Status: %s
    Platforms: %s
    Normalization: %s
    + See Contact Information
    +
    +
    + + + + + + + +
    Download datasets and supplementary data files
    %s
    +
    +
    +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Summary:
    %s

    About the cases used to generate this set of data:
    %s

    About the tissue used to generate this set of data:
    %s

    About downloading this data set:
    %s

    About the array platform:
    %s

    About data values and data processing:
    %s

    Data source acknowledgment:
    %s

    Experiment Type:
    %s

    Overall Design:
    %s

    Contributor:
    %s

    Citation:
    %s

    Submission Date:
    %s

    Laboratory:
    %s

    Samples:
    %s

    +

    + +""" + +sharinginfoedit_body_string = """ +

    %s

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

    Principal Investigator

    Contact Name:
    Emails:
    Phone:
    URL:
    Organization Name:
    Department:
    Laboratory:
    Address:
    City:
    State:
    ZIP:
    Country:

    Summary

    Summary:

    Biology

    Experiment Design:
    About the cases used to
    generate this set of data:
    About the tissue used to
    generate this set of data:

    Technique

    About downloading this data set:
    About the array platform:

    Bioinformatics

    About data values and
    data processing:
    Overall Design:

    Misc

    Contributor:
    Citation:
    Data source acknowledgment:

    Administrator ONLY

    GN Accesion Id:
    DB Title in GN:
    GEO Series:
    Status:
    Title:
    Organism_Id (Taxonomy ID):
    Organism:
    Submission Date:
    Platforms:
    Species:
    Tissue:
    Normalization:
    Inbred Set:
    Info Page Name:
    Samples:
    Authorized Users:
    Progress:
    +""" diff --git a/wqflask/wqflask/dataSharing/SharingInfo.py b/wqflask/wqflask/dataSharing/SharingInfo.py new file mode 100755 index 00000000..131a4551 --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingInfo.py @@ -0,0 +1,98 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import httplib + +from dbFunction import webqtlDatabaseFunction +import SharingBody + + +######################################### +# Sharing Info +######################################### +class SharingInfo: + + def __init__(self, GN_AccessionId, InfoPageName): + self.GN_AccessionId = GN_AccessionId + self.InfoPageName = InfoPageName + + def getInfo(self): + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + sql = "select Id, GEO_Series, Status, Title, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Normalization, InbredSet, InfoPageName, DB_Name, Organism_Id, InfoPageTitle, GN_AccesionId, Tissue, AuthorizedUsers, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, Progreso from InfoFiles where " + if(self.GN_AccessionId): + sql += "GN_AccesionId = %s" + cursor.execute(sql, self.GN_AccessionId) + elif (self.InfoPageName): + sql += "InfoPageName = %s" + cursor.execute(sql, self.InfoPageName) + else: + raise 'No correct parameter found' + info = cursor.fetchone() + # fetch datasets file list + try: + conn = httplib.HTTPConnection("atlas.uthsc.edu") + conn.request("GET", "/scandatasets.php?GN_AccesionId=%s" % (info[32])) + response = conn.getresponse() + data = response.read() + filelist = data.split() + conn.close() + except Exception: + filelist = [] + return info, filelist + + def getBody(self, infoupdate=""): + info, filelist = self.getInfo() + if filelist: + htmlfilelist = '
      \n' + for i in range(len(filelist)): + if i%2==0: + filename = filelist[i] + filesize = filelist[i+1] + htmlfilelist += "
    • " + htmlfilelist += '%s' % (self.GN_AccessionId, filename, filename) + htmlfilelist += '   ' + #r=re.compile(r'(?<=\d)(?=(\d\d\d)+(?!\d))') + #htmlfilelist += '[%s B]' % r.sub(r',',filesize) + if 12= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Adding Info" + detail = ["You don't have the permission to add new dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + self.dict['body'] = SharingBody.sharinginfoedit_body_string % ("Add new dataset", "-1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") diff --git a/wqflask/wqflask/dataSharing/SharingInfoDeletePage.py b/wqflask/wqflask/dataSharing/SharingInfoDeletePage.py new file mode 100755 index 00000000..a9c785c6 --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingInfoDeletePage.py @@ -0,0 +1,55 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Delete Page +######################################### +class SharingInfoDeletePage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Deleting Info" + detail = ["You don't have the permission to delete this dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') + sql = "delete from InfoFiles where GN_AccesionId=%s" + cursor.execute(sql, GN_AccessionId) + re = cursor.fetchone() + self.dict['body'] = "Delete dataset info record (GN_AccesionId=%s) successfully." % GN_AccessionId diff --git a/wqflask/wqflask/dataSharing/SharingInfoEditPage.py b/wqflask/wqflask/dataSharing/SharingInfoEditPage.py new file mode 100755 index 00000000..c5f4ed22 --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingInfoEditPage.py @@ -0,0 +1,51 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +from base import webqtlConfig +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Edit Page +######################################### +class SharingInfoEditPage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to edit this dataset"] + self.error(heading=heading,detail=detail,error="Error") + return + GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') + InfoPageName = fd.formdata.getvalue('InfoPageName') + sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) + info, filelist = sharingInfoObject.getInfo() + self.dict['body'] = SharingBody.sharinginfoedit_body_string % (info[31], info[0], info[11], info[12], info[13], info[14], info[15], info[16], info[17], info[18], info[19], info[20], info[21], info[22], info[6], info[5], info[35], info[36], info[37], info[38], info[39], info[7], info[8], info[9], info[40], info[32], info[31], info[1], info[2], info[3], info[30], info[4], info[10], info[23], info[25], info[33], info[26], info[27], info[28], info[24], info[34], info[41]) diff --git a/wqflask/wqflask/dataSharing/SharingInfoPage.py b/wqflask/wqflask/dataSharing/SharingInfoPage.py new file mode 100755 index 00000000..4e07e01b --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingInfoPage.py @@ -0,0 +1,58 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from __future__ import print_function, division + +from pprint import pformat as pf + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + + +######################################### +# Sharing Info Page +######################################### +class SharingInfoPage(templatePage): + + def __init__(self, fd): + templatePage.__init__(self, fd) + print("fd is:", pf(fd.__dict__)) + # Todo: Need a [0] in line below???? + GN_AccessionId = fd.get('GN_AccessionId') # Used under search datasharing + InfoPageName = fd['database'][0] + cursor = webqtlDatabaseFunction.getCursor() + if InfoPageName and not GN_AccessionId: + sql = "select GN_AccesionId from InfoFiles where InfoPageName = %s" + cursor.execute(sql, InfoPageName) + GN_AccessionId = cursor.fetchone() + url = webqtlConfig.CGIDIR + "main.py?FormID=sharinginfo&GN_AccessionId=%s" % GN_AccessionId + self.redirection = url + else: + sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) + self.dict['body'] = sharingInfoObject.getBody(infoupdate="") diff --git a/wqflask/wqflask/dataSharing/SharingInfoUpdatePage.py b/wqflask/wqflask/dataSharing/SharingInfoUpdatePage.py new file mode 100755 index 00000000..181f2eed --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingInfoUpdatePage.py @@ -0,0 +1,109 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import MySQLdb + +from base.templatePage import templatePage +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +import SharingBody +import SharingInfo + +######################################### +# Sharing Info Update Page +######################################### +class SharingInfoUpdatePage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to modify this file"] + self.error(heading=heading,detail=detail,error="Error") + return + cursor = webqtlDatabaseFunction.getCursor() + if (not cursor): + return + Id=fd.formdata.getvalue('Id') + GN_AccesionId=fd.formdata.getvalue('GN_AccesionId') + GEO_Series=fd.formdata.getvalue('GEO_Series') + Status=fd.formdata.getvalue('Status') + Title=fd.formdata.getvalue('Title') + Organism_Id=fd.formdata.getvalue('Organism_Id') + Organism=fd.formdata.getvalue('Organism') + Experiment_Type =fd.formdata.getvalue('Experiment_Type') + Summary=fd.formdata.getvalue('Summary') + Overall_Design=fd.formdata.getvalue('Overall_Design') + Contributor=fd.formdata.getvalue('Contributor') + Citation=fd.formdata.getvalue('Citation') + Submission_Date=fd.formdata.getvalue('Submission_Date') + Contact_Name=fd.formdata.getvalue('Contact_Name') + Emails=fd.formdata.getvalue('Emails') + Phone=fd.formdata.getvalue('Phone') + URL=fd.formdata.getvalue('URL') + Organization_Name=fd.formdata.getvalue('Organization_Name') + Department=fd.formdata.getvalue('Department') + Laboratory=fd.formdata.getvalue('Laboratory') + Street=fd.formdata.getvalue('Street') + City=fd.formdata.getvalue('City') + State=fd.formdata.getvalue('State') + ZIP=fd.formdata.getvalue('ZIP') + Country=fd.formdata.getvalue('Country') + Platforms=fd.formdata.getvalue('Platforms') + Samples=fd.formdata.getvalue('Samples') + Species=fd.formdata.getvalue('Species') + Tissue=fd.formdata.getvalue('Tissue') + Normalization=fd.formdata.getvalue('Normalization') + InbredSet=fd.formdata.getvalue('InbredSet') + InfoPageName=fd.formdata.getvalue('InfoPageName') + InfoPageTitle=fd.formdata.getvalue('InfoPageTitle') + About_Cases=fd.formdata.getvalue('About_Cases') + About_Tissue=fd.formdata.getvalue('About_Tissue') + About_Download=fd.formdata.getvalue('About_Download') + About_Array_Platform=fd.formdata.getvalue('About_Array_Platform') + About_Data_Values_Processing=fd.formdata.getvalue('About_Data_Values_Processing') + Data_Source_Acknowledge=fd.formdata.getvalue('Data_Source_Acknowledge') + AuthorizedUsers=fd.formdata.getvalue('AuthorizedUsers') + Progress=fd.formdata.getvalue('Progress') + if Id=='-1': + sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) + info, filelist = sharingInfoObject.getInfo() + if info: + heading = "Editing Info" + detail = ["The new dataset info record is duplicate."] + self.error(heading=heading, detail=detail, error="Error") + return + sql = """INSERT INTO InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s""" + cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress])) + infoupdate="This record has been succesfully added." + else: + sql = """UPDATE InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s WHERE Id=%s""" + cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress, Id])) + infoupdate="This record has been succesfully updated." + sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) + self.dict['body'] = sharingInfoObject.getBody(infoupdate=infoupdate) diff --git a/wqflask/wqflask/dataSharing/SharingListDataSetPage.py b/wqflask/wqflask/dataSharing/SharingListDataSetPage.py new file mode 100755 index 00000000..8685ac65 --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingListDataSetPage.py @@ -0,0 +1,99 @@ +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT +from base import webqtlConfig + +from base.templatePage import templatePage + + +######################################### +# Sharing List DataSet Page +######################################### +class SharingListDataSetPage(templatePage): + + def __init__(self, fd=None): + templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: + pass + else: + heading = "Editing Info" + detail = ["You don't have the permission to list the datasets"] + self.error(heading=heading,detail=detail,error="Error") + return + + + TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') + + query = """select GN_AccesionId, InfoPageTitle, Progreso from InfoFiles order by GN_AccesionId""" + self.cursor.execute(query) + result = self.cursor.fetchall() + + heading = HT.Paragraph('Dataset Table', Class="title") + + newrecord = HT.Href(text="New Record", url="/webqtl/main.py?FormID=sharinginfoadd") + + info = "Click the accession id to view the dataset info. Click the dataset name to edit the dataset info." + + datasetTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0, Class="collap", width="100%") + + tableHeaderRow = HT.TR() + tableHeaderRow.append(HT.TD("Accession Id", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Dataset name", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Progress", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + tableHeaderRow.append(HT.TD("Operation", Class='fs14 fwb ffl b1 cw cbrb', align="center")) + datasetTable.append(tableHeaderRow) + + for one_row in result: + Accession_Id, InfoPage_title, Progress = one_row + datasetRow = HT.TR() + datasetRow.append(HT.TD(HT.Href(text="GN%s" % Accession_Id, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) + datasetRow.append(HT.TD(HT.Href(text="%s" % InfoPage_title, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) + datasetRow.append(HT.TD("%s" % Progress, Class='fs12 fwn ffl b1 c222')) + operation_edit = HT.Href(text="Edit", url="/webqtl/main.py?FormID=sharinginfoedit&GN_AccessionId=%s" % Accession_Id) + operation_delete = HT.Href(text="Delete", onClick="deleteRecord(%s); return false;" % Accession_Id) + operation = HT.TD(Class="fs12 fwn b1 c222", align="center") + operation.append(operation_edit) + operation.append("    ") + operation.append(operation_delete) + datasetRow.append(operation) + datasetTable.append(datasetRow) + + TD_LR.append(heading, HT.P(), newrecord, HT.P(), info, HT.P(), datasetTable) + + js1 = """ """ + self.dict['js1'] = js1 + self.dict['body'] = str(TD_LR) diff --git a/wqflask/wqflask/dataSharing/SharingPage.py b/wqflask/wqflask/dataSharing/SharingPage.py new file mode 100755 index 00000000..b244a6bd --- /dev/null +++ b/wqflask/wqflask/dataSharing/SharingPage.py @@ -0,0 +1,40 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from base.templatePage import templatePage +import SharingBody + +######################################### +# SharingPage +######################################### + +class SharingPage(templatePage): + + def __init__(self, fd): + templatePage.__init__(self, fd) + self.dict['title'] = 'GeneNetwork Data Sharing Zone' + self.dict['body'] = SharingBody.sharing_body_string + self.dict['js2'] = 'onload="javascript:initialDatasetSelection();"' diff --git a/wqflask/wqflask/dataSharing/__init__.py b/wqflask/wqflask/dataSharing/__init__.py new file mode 100755 index 00000000..e69de29b diff --git a/wqflask/wqflask/templates/data_sharing.html b/wqflask/wqflask/templates/data_sharing.html new file mode 100644 index 00000000..e9d082d6 --- /dev/null +++ b/wqflask/wqflask/templates/data_sharing.html @@ -0,0 +1,831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        + + + + + + +
      + + + + + + + + + WebQTL +
      +
       
      + + + + + +
      +   |    + +Home +   |    + +Search +   |    + +Help +   |    + + +News +   |    + + +References +   |    + +Policies +   |    + + +Links +   |    + +Welcome! Login    +
      +
      + + + + + +
      +List of DataSets
      +

      Hippocampus Consortium M430v2 (Jun06) PDNN +modify this page + +

      + + + + + +
      + + + + + + + + + + + +
      GN Accession: GN112
      GEO Series: No GEO series number
      Title: Genetics of the hippocampal transcriptome in mouse: a systematic survey and online neurogenomics resource
      Organism: Mus musculus
      Group: BXD
      Tissue: Hippocampus
      Dataset Status: Public
      Platforms: GEO: GPL1261 Affymetrix GeneChip Mouse Genome 430 2.0 Array
      Normalization: PDNN
      + See Contact Information
      +
      +
      + + + + + + + +
      Download datasets and supplementary data files
      +
      +
      +

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Summary:
      MOST HIGHLY RECOMMENDED DATA SET (Overall et al., 2009): The Hippocampus Consortium data set provides estimates of mRNA expression in the adult hippocampus of 99 genetically diverse strains of mice including 67 BXD recombinant inbred strains, 13 CXB recombinant inbred strains, a diverse set of common inbred strains, and two reciprocal F1 hybrids. + + +

      The hippocampus is an important and intriguing part of the forebrain that is crucial in memory formation and retrieval, and that is often affected in epilepsy, Alzheimer's disease, and schizophrenia. Unlike most other parts of the brain, the hippocampus contains a remarkable population of stems cells that continue to generate neurons and glial cells even in adult mammals (Kempermann, 2005). This genetic analysis of transcript expression in the hippocampus (dentate gyrus, CA1-CA3) is a joint effort of 14 investigators that is supported by numerous agencies described in the acknowledgments section. + +

      About the cases used to generate this set of data:

      The BXD genetic reference panel of recombinant inbred strains consists of just over 80 strains. The BXDs in this data set include 27 of the BXD strains made by Benjamin Taylor at the Jackson Laboratory in the 1970s and 1990s (BXD1 through BXD42). All of these strains are fully inbred, many well beyond the 100th filial (F) generation of inbreeding. We have also included 39 inbred (25 strains at F20+) and nearly inbred (14 strains between F14 and F20) BXD lines generated by Lu and Peirce. All of these strains, including those between F14 and F20, have been genotyped at 13,377 SNPs. + +

      Mouse Diversity Panel (MDP). We have profiled a MDP consisting 16 inbred strains and a pair of reciprocal F1 hybrids; B6D2F1 and D2B6F1. These strains were selected for several reasons: +

        +
      • genetic and phenotypic diversity, including use by the Phenome Project +
      • their use in making genetic reference populations including recombinant inbred strains, cosomic strains, congenic and recombinant congenic strains +
      • their use by the Complex Trait Consortium to make the Collaborative Cross (Nairobi/Wellcome, Oak Ridge/DOE, and Perth/UWA) +
      • genome sequence data from three sources (NHGRI, Celera, and Perlegen-NIEHS) +
      • availability from The Jackson Laboratory +
      + +

      All eight parents of the Collaborative Cross (129, A, C57BL/6J, CAST, NOD, NZO, PWK, and WSB) have been included in the MDP (noted below in the list). Twelve MDP strains have been sequenced, or are currently being resequenced by Perlegen for the NIEHS. This panel will be extremely helpful in systems genetic analysis of a wide variety of traits, and will be a powerful adjunct in fine mapping modulators using what is essentially an association analysis of sequence variants. + +

        +
      1. 129S1/SvImJ +
        Collaborative Cross strain sequenced by NIEHS; background for many knockouts; Phenome Project A list + +
      2. A/J +
        Collaborative Cross strain sequenced by Perlegen/NIEHS; parent of the AXB/BXA panel + +
      3. AKR/J +
        Sequenced by NIEHS; Phenome Project B list + +
      4. BALB/cByJ +
        Sequenced by NIEHS; maternal parent of the CXB panel; Phenome Project A list + +
      5. BALB/cJ +
        Widely used strain with forebrain abnormalities (callosal defects); Phenome Project A list + +
      6. C3H/HeJ
        Sequenced by Perlegen/NIEHS; paternal parent of the BXH panel; Phenome Project A list + +
      7. C57BL/6J +
        Sequenced by NHGRI; parental strain of AXB/BXA, BXD, and BXH; Phenome Project A list + +
      8. C57BL/6ByJ +
        Paternal substrain of B6 used to generate the CXB panel + +
      9. CAST/Ei +
        Collaborative Cross strain sequenced by NIEHS; Phenome Project A list + +
      10. DBA/2J +
        Sequenced by Perlegen/NIEHS and Celera; paternal parent of the BXD panel; Phenome Project A list + +
      11. KK/HlJ +
        Sequenced by Perlegen/NIEHS + +
      12. LG/J +
        Paternal parent of the LGXSM panel + +
      13. NOD/LtJ +
        Collaborative Cross strain sequenced by NIEHS; Phenome Project B list; diabetic + +
      14. NZO/HlLtJ +
        Collaborative Cross strain + +
      15. PWD/PhJ +
        Sequenced by Perlegen/NIEHS; parental strain for a consomic set by Forjet and colleagues + +
      16. PWK/PhJ +
        Collaborative Cross strain; Phenome Project D list + +
      17. WSB/EiJ
        Collaborative Cross strain sequenced by NIEHS; Phenome Project C list + +
      18. B6D2F1 and D2B6F1 +
        F1 hybrids generated by crossing C57BL/6J with DBA/2J +
      + +

      We have not combined data from reciprocal F1s because they have different Y chromosome and mitochondrial haplotypes. Parent-of-origin effects (imprinting, maternal environment) may also lead to interesting differences in hippocampal transcript levels. + +

      These strains are available from The Jackson Laboratory. BXD43 through BXD100 strains are available from Lu Lu and colleagues at UTHSC.



      About the tissue used to generate this set of data:

      BXD animals were obtained from UTHSC, UAB, or directly from The Jackson Laboratory (see Table 1 below). Animals were housed at UTHSC, Beth Israel Deaconess, or the Jackson Laboratory before sacrifice. Virtually all CXB animals were obtained directly at the Jackson Laboratory by Lu Lu. We thank Muriel Davisson for making it possible to collect these cases on site. Standard inbred strain stock was from The Jackson Laboratory, but most animals were housed or reared at UTHSC. Mice were killed by cervical dislocation and brains were removed and placed in RNAlater prior to dissection. Cerebella and olfactory bulbs were removed; brains were hemisected, and both hippocampi were dissected whole by Hong Tao Zhang in the Lu lab. Hippocampal samples are very close to complete (see Lu et al., 2001) but probably include variable amounts of subiculum and fimbria. + +

      A great majority of animals used in this study were between 45 and 90 days of age (average of 66 days, maximum range from 41 to 196 days; see Table 1 below). All animals were sacrifice between 9 AM and 5 PM during the light phase. + + +

      A pool of dissected tissue typically from six hippocampi and three naive adults of the same strain, sex, and age was collected in one session and used to generate cRNA samples. Two-hundred and one RNA samples were extracted at UTHSC by Zhiping Jia, four samples by Shuhua Qi (R2331H1, R2332H1, P2350H1, R2349H1), and one by Siming Shou (R0129H2). + +

      RNA Extraction: In brief, we used the RNA STAT-60 protocol (TEL-TEST "B" Bulletin No. 1), steps 5.1A (homogenization of tissue), 5.2 (RNA extraction), 5.3 (RNA precipitation), and 5.4 (RNA wash). In Step 5.4 we stopped after adding 75% ethanol (1 ml per 1 ml RNA STAT-60) and stored the mix at -80°C until further use. Before RNA labeling we thawed samples and proceeded with the remainder of Step 5.4; pelleting, drying, and redissolving the pellet in RNase-free water. + +

      We finally purify RNA by using Na4OAc before running arrays. Here is the detailed method: + +

      Final RNA purification protocol + +

        +
      1. Add 1/10th volume of 3M Na4OAc , pH 5.2. If the sample was eluted with 100 µl nuclease-free water as suggested, this will be 10 µl of 3M Na4OAc. +
      2. Add 2.5 volumes of 100% ethanol (250 µl if the RNA was eluted in100 µl). Mix well and incubate at –20°C for 2 hrs. +
      3. Centrifuge at speed of 13,000 rpm for 20 min at 4°C. Carefully remove and discard the supernatant. +
      4. Wash the pellet with 800 µl 75% cold ethanol, centrifuge at speed of 8,600 rpm for 5 min, and remove the 75% ethanol. Wash again. +
      5. To remove the last traces of ethanol, quickly respin the tube, and aspirate any residual fluid. +
      6. Air dry the pellet. +
      7. Resuspend pellet in nuclease-free water. +
      +

      + + +

      Sample Processing: Samples were processed in the INIA Bioanalytical Core at the W. Harry Feinstone Center for Genomic Research, The University of Memphis, led by Thomas R. Sutter. All processing steps were performed by Shirlean Goodwin. In brief, RNA purity was evaluated using the 260/280 nm absorbance ratio, and values had to be greater than 1.8. The majority of samples were 1.9 to 2.1. RNA integrity was assessed using the Agilent Bioanalyzer 2100. We required an RNA integrity number (RIN) of greater than 8. This RIN value is based on the intensity ratio and amplitude of 18S and 28S rRNA signals. The standard Eberwine T7 polymerase method was used to catalyze the synthesis of cDNA template from polyA-tailed RNA using Superscript II reverse transcriptase (Invitrogen Inc.). The Enzo Life Sciences, Inc., BioArray High Yield RNA Transcript Labeling Kit (T7, Part No. 42655) was used to synthesize labeled cRNA. The cRNA was evaluated using both the 260/280 ratio (values of 2.0 or 2.1 are acceptable) and the Bioanalyzer output (a dark cRNA smear on the 2100 output centered roughly between 600 and 2000 nucleotides is required). Those samples that passed both QC steps (10% usually failed and new RNA samples had to be acquired and processed) were then sheared using a fragmentation buffer included in the Affymetrix GeneChip Sample Cleanup Module (Part No. 900371). Fragmented cRNA samples were either stored at -80°C until use or were immediately injected onto the array. The arrays were hybridized and washed following standard Affymetrix protocols. + +

      Replication and Sample Balance: Our goal was to obtain a male sample pool and female sample pool from each isogenic group. While almost all strains were orginally represented by matched male and female samples, not all data sets passed the final quality control steps. All but 5 of 99 strains (BXD55, BXD86, BXD94, BALB/cByJ, and CAST/EiJ) are represented by pairs or (rarely) trios of arrays. The first and last samples are technical replicates of a B6D2F1 hippocampal pool (aliquots R1291H3 and R1291H4). + + +

      Sex Balance: Based on the expression of Xist, probe set 1427262_at, DBA/2J and KK/HlJ are represented only by female samples, BXD55, and BALB/cByJ are only represented by a single male sample, BXD74 is represented by two male samples, and BXD86, BXD94, and CAST/EiJ are possibly mixed sex samples. One of the BXD9 samples, array R1523, may be a mixed sex sample pool because the expression of Xist is intermediate. + +

      Experimental Design and Batch Structure: This data set consists arrays processed in six groups over a three month period (May 2005 to August 2005). Each group consists of 32 to 34 arrays. Sex, strain, and strain type (BXD, CXB, and MDP) were interleaved among groups to ensure reasonable balance and to minimize group-by-strain statistical confounds in group normalization. The two independent samples from a single strain were always run in different groups. All arrays were processed using a single protocol by a single operator, Shirlean Goodwin. + +

      All samples in a group were labeled on one day, except for a few cases that failed QC on their first pass. The hybridization station accommodates up to 20 samples, and for this reason each group was split into a large first set of 20 samples and a second set of 12 to 14 samples. Samples were washed in groups of four and then held in at 4°C until all 20 (or 12-14) arrays were ready to scan. The last four samples out of the wash stations were scanned directly. Samples were scanned in sets of four. + + +

      COMPARISON with December 2005 Data Set: Both BXD14 arrays in the Dec05 data set were found to actually be from BXD23 cases. This error of strain identification has been corrected in the present data set. Four arrays in the Dec05 data set have been deleted because we judged them to be of poor quality (strain_sex_sample_firstreaction_group): +

        +
      1. BXD21_F_1_1_G1 +
      2. BXD23_M_1_1_G7 +
      3. BXD36_M_1_1_G2 +
      4. BXD36_F_1_1_G3 +
      + +

      +In the Dec05 data set there are a total of 1986 transcripts with QTLs that have LRS scores above 50, whereas in the corrected June06 data sets there are a total of 2074 transcripts with QTLs above 50. +

      +

      Data Table 1:

      +This table lists all arrays by file order (Index), tube/sample ID, age, sex, batch, and numbers of animals in each sample pool (pool size). The next columns (RMA outlier, scale factor, background average, present, absent, marginal, AFFY-b-ActinMur(3'/5'), AFFY-GapdhMur(3'/5')) are all Affymetrix QC data. Finally, source lists the source colony of the animals. (Final version, fully corrected, by Arthur Centeno, October 2008) + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      indextube IDstrainagesexbatch IDpool sizeRMA outlierscale factorback ground averagepresentabsentmarginalAFFX-b-ActinMur (3'/5')AFFX-GapdhMur (3'/5')source
      1R1289H2B6D2F164F630.022.40653.840.4920.4890.0191.610.96UTM RW
      2R1291H3B6D2F166M +130.013.52448.540.4870.4940.0191.211.52UTM RW
      3R1291H4B6D2F166M technical duplicate of above630.083.89146.690.5120.4690.0191.90.89UTM RW
      4R2045H2D2B6F165F120.014.40347.990.4970.4850.0181.091.53UTM RW
      5R1595H2D2B6F163F530.062.57958.490.5060.4750.0192.491.21UTM RW
      6R1551H1D2B6F172F630.022.6253.760.5060.4760.0181.370.76UTM RW
      7R1361H1C57BL/6J69F640.013.05851.870.4770.5030.021.670.76UTM RW
      8R2041H2C57BL/6J65M140.043.34149.260.5270.4560.0181.141.45UTM RW
      9R1449H2C57BL/6J71M530.093.59244.320.470.510.021.680.77UTM DG
      10R1290H2DBA/2J63F720.042.57659.60.5130.4680.0181.30.78JAX
      11R1468H1DBA/2J64F530.032.92953.80.5150.4650.0191.280.79UTM RW
      12R1507H1BXD158M330.024.05660.170.4780.5030.0191.150.76Glenn
      13R1542H1BXD159F730.031.79280.560.4920.4890.0181.570.79Glenn
      14R1520H1BXD256F440.091.71571.620.5150.4670.0182.361.6Glenn
      15R1516H1BXD261M140.012.23164.860.5080.4740.0191.31.53Glenn
      16R1593H2BXD560F1401.91359.960.4870.4930.020.981.44Glenn
      17R1692H1BXD560M320.073.76472.740.4650.5160.021.150.74Glenn
      18R1539H2BXD659F1402.48854.970.5180.4630.0181.081.33Glenn
      19R1538H1BXD659M430.012.58550.270.5050.4750.021.460.79Glenn
      20R1518H1BXD856F1302.9254.840.5150.4650.021.321.24Glenn
      21R1548H1BXD859M630.072.13259.370.5040.4770.0192.161.54Glenn
      22R1350H2BXD986F130.052.77160.620.50.4820.0181.011.28UMemphis
      23R1523H3BXD957MF (mixed)730.143.978.360.4350.5470.0181.360.77UTM RW
      24R1531H1BXD1156F630.062.22956.360.5050.4750.022.231.02Glenn
      25R1367H1BXD1156M130.012.1178.780.5030.4770.021.071.27Glenn
      26R1530H1BXD1258F1303.22753.770.5050.4770.0180.951.4Glenn
      27R2674H1BXD1259M730.031.92483.440.5190.4640.0181.210.78Glenn
      28R1529H1BXD1358F630.052.5559.050.4970.4850.01821.54Glenn
      29R1662H2BXD1360M130.034.60345.810.5090.4720.0191.30.82Glenn
      30R1304H2BXD1472F730.033.94661.870.4840.4980.0181.220.77UTM RW
      31R1278H2BXD1455M730.064.7567.520.4490.5320.0191.10.73UTM RW
      32R1524H1BXD1560F640.022.96150.930.4970.4840.0191.740.91Glenn
      33R1515H1BXD1561M130.013.31657.050.5030.4780.0191.321.21Glenn
      34R1661H1BXD1661F130.012.77859.810.5160.4660.0191.391.2Glenn
      35R1594H1BXD1661M430.032.63453.660.5040.4780.0181.961.51Glenn
      36R2666H1BXD1960F730.022.49876.20.4950.4860.0191.410.77Glenn
      37R1471H1BXD19157M130.023.16543.340.5190.4620.0181.011.29UTM JB
      38R1573H1BXD2059F130.023.74952.70.5130.4690.0181.011.27Glenn
      39R2507H1BXD2060M630.063.568570.4720.5080.021.290.76Glenn
      40R2668H1BXD2160M740.072.60544.90.5350.4490.0171.540.76Glenn
      41R1337H2BXD21102F2402.67358.050.4920.4890.0191.40.76UAB
      42R1848H3BXD22196F640.022.94351.70.4940.4850.0212.20.78UAB
      43R1525H1BXD2259M230.022.24855.760.5480.4330.0181.260.74Glenn
      44R1280H2BXD2356F130.013.18754.630.4580.5230.0190.961.2UTM RW
      45R1537H1BXD2358F530.13.71967.540.4680.5130.0191.510.96Glenn
      46R1343H2BXD2471F230.012.08365.070.5060.4740.0191.460.75UMemphis
      47R1517H1BXD2457M330.013.47153.660.5040.4760.0191.280.78Glenn
      48R1366H1BXD2760F2402.2648.460.5180.4630.0191.290.77Glenn
      49R1849H1BXD2770M530.068.80138.340.4680.5120.0192.421.08UAB
      50R1353H1BXD2879F340.013.2276.220.480.50.021.330.78UMemphis
      51R2332H1BXD2860M230.013.21763.680.4910.490.0191.370.79Glenn
      52R1532H1BXD2957F230.012.12259.180.5240.4560.0191.170.76Glenn
      53R1356H1BXD2976M530.014.03347.670.520.4630.0171.170.78UMemphis
      54R1240H2BXD3161M230.022.33565.170.5070.4740.0191.310.78UTM RW
      55R1526H2BXD3157F740.17.26789.540.4350.5470.0171.350.78UTM RW
      56R2675H1BXD3257F730.032.26878.010.5020.4780.021.220.78Glenn
      57R1508H2BXD3258M240.011.91767.780.5390.4420.0191.280.73Glenn
      58R1345H3BXD3365F220.012.09863.140.5220.4590.0191.270.73UMemphis
      59R1581H1BXD3359M330.013.22953.160.4960.4850.0191.190.78Glenn
      60R1527H1BXD3459F230.012.358.920.510.4710.0191.240.76Glenn
      61R1339H3BXD3474M530.122.88853.490.5060.4760.0182.391.35UMemphis
      62R1855H1BXD3855F340.013.53654.540.490.4920.0181.390.75Glenn
      63R1510H1BXD3859M230.012.18668.060.5210.460.0191.260.79Glenn
      64R1528H2BXD3959F230.034.71738.30.5110.470.021.120.75Glenn
      65R1514H1BXD3959M330.033.99256.060.4770.5040.0191.430.81Glenn
      66R1522H1BXD4059F4402.63167.160.490.4910.0181.560.77Glenn
      67R1359H1BXD4073M230.097.45839.860.4510.5270.0211.280.74UMemphis
      68R1541H2BXD4258F730.076.78452.120.4830.4990.0171.130.66Glenn
      69R1540H1BXD4258M740.032.42375.140.4920.4880.021.480.78Glenn
      70R1334H2BXD4359F1302.67254.360.4920.4910.0171.22.06UTM RW
      71R1303H1BXD4363M340.023.49751.90.4860.4950.0191.150.8UTM RW
      72R1326H1BXD4465F3403.41253.960.4960.4850.0181.350.78UTM RW
      73R1577H2BXD4456M130.022.15967.520.5120.4690.0191.181.71UTM RW
      74R1403H2BXD4563F720.033.14644.50.5240.4570.0181.410.78Glenn
      75R1472H1BXD4565M740.041.65173.310.5430.440.0181.630.74UTM RW
      76R1316H1BXD4858F4302.44568.590.5150.4670.0191.160.73UTM RW
      77R1575H3BXD4865M340.054.57755.780.4660.5140.0191.590.9UTM RW
      78R2521H1BXD5063F640.013.10957.280.4950.4850.021.230.78UTM RW
      79R1944H2BXD5081M130.012.54663.390.4950.4850.020.91.57UTM RW
      80R2331H1BXD5166F330.033.53444.420.5010.4810.0171.20.9UTM RW
      81R1582H1BXD5171M640.032.9247.870.4890.4910.021.360.75UTM RW
      82R2680H1BXD5565M730.071.70779.750.5030.480.0171.911.05UTM RW
      83R1331H1BXD6060F430.012.86750.330.4920.4870.0211.340.78UTM RW
      84R1281H2BXD6059M1302.3958.440.5110.4690.020.941.2UTM RW
      85R2667H1BXD6170F740.033.3659.040.4950.4880.0181.160.76UTM RW
      86R1856H2BXD6194M1203.50249.60.5010.480.0190.961.3UTM RW
      87R1246H1BXD6254F140.023.40551.470.5110.4710.0181.141.34UTM RW
      88R1585H2BXD6264M640.013.15655.770.5180.4640.0181.430.82UTM RW
      89R1945H1BXD63107F130.022.81152.650.5220.4590.0191.051.36UTM RW
      90R2093H3BXD6370M630.023.89442.850.5030.4770.0191.291.01UTM RW
      91R2062H2BXD6465F130.053.79578.480.5130.4680.0190.981.43UTM RW
      92R2061H1BXD6487M340.013.53661.570.4770.5040.0191.310.78UTM RW
      93R2054H2BXD6555F120.033.15980.960.480.5020.0181.091.24UTM RW
      94R2056H2BXD6589M6202.83659.60.5040.4770.0191.30.75UTM RW
      95R1941H2BXD6678F140.012.73450.930.4990.4810.021.181.29UTM RW
      96R1949H2BXD6696M420.042.82851.270.4740.5080.0192.051.12UTM RW
      97R2060H1BXD6754F630.012.56143.880.5020.4790.021.70.84UTM RW
      98R2052H1BXD6761M140.013.16143.230.5210.460.0181.091.31UTM RW
      99R2074H1BXD6860F530.026.52849.620.4790.5020.0191.480.83UTM RW
      100R1928H1BXD6872M220.012.40448.280.5210.4590.021.30.74UTM RW
      101R1439H3BXD6960F230.022.46359.140.5220.4590.0181.310.78UTM RW
      102R1559H1BXD6964M330.032.98767.740.4860.4960.0171.380.8UTM RW
      103R2134H1BXD7064F520.022.14858.640.5320.450.0191.40.85UTM RW
      104R2063H1BXD7055M230.023.48155.320.5130.4690.0181.280.71UTM RW
      105R1277H1BXD7360F420.012.57662.450.5020.4790.0191.350.79UTM RW
      106R1443H2BXD7376M230.012.31264.340.4990.4810.021.480.77UTM RW
      107R2055H2BXD7479M230.012.57656.840.5090.4730.0181.460.88UTM RW
      108R2316H1BXD74193M520.013.45755.350.5080.4710.021.170.78UTM RW
      109R1871H1BXD7561F230.041.72356.40.530.4510.0191.30.76UTM RW
      110R1844H2BXD7590M340.011.93456.230.520.4610.0191.620.86UTM RW
      111R1948H2BXD7681F230.011.50768.850.5530.4280.021.30.75UTM RW
      112R2094H1BXD7661M540.013.29942.690.5190.4620.0191.390.88UTM RW
      113R2262H1BXD7762F340.024.31747.160.4930.4880.0191.320.74UTM RW
      114R1423H1BXD7762M230.023.07154.150.510.4710.0191.260.74UTM RW
      115R1947H1BXD79108F220.012.59951.520.5240.4570.0191.350.74UTM RW
      116R2092H1BXD7986M540.063.73542.250.5140.4680.0182.941.06UTM RW
      117R1880H1BXD8068F530.064.85542.220.5010.4810.0182.171.36UTM RW
      118R1881H2BXD8068M230.022.07348.930.5240.4580.0191.340.83UTM RW
      119R2075H1BXD8360F230.012.45455.10.5020.480.0181.270.77UTM RW
      120R2076H2BXD8360M630.032.62455.650.4950.4880.0182.210.94UTM RW
      121R2077H2BXD8462F6202.171.870.5220.4590.0181.680.81UTM RW
      122R2135H3BXD8475M220.012.46764.460.5050.4760.0191.20.74UTM RW
      123R1473H1BXD8579F230.023.38455.340.4780.5020.021.240.77UTM RW
      124R1474H1BXD8557M130.012.83155.240.5220.4610.0181.041.29UTM RW
      125R1597H1BXD8586M440.092.02853.950.4870.4920.0211.280.83UTM RW
      126R1415H1BXD8677F430.022.52553.160.4950.4850.021.660.91UTM RW
      127R2669H2BXD8763F730.072.6157.590.5130.470.0181.60.91UTM RW
      128R1710H1BXD8784M240.012.69756.40.5120.4690.0191.280.79UTM RW
      129R1872H2BXD8990F220.023.01363.530.4920.4880.0211.220.72UTM RW
      130R1850H3BXD8982M440.032.73644.890.4980.4830.0191.50.83UTM RW
      131R2058H1BXD9061F230.013.38948.050.5020.4780.021.530.76UTM RW
      132R1600H2BXD9074M740.033.26151.310.5170.4650.0181.160.75Glenn
      133R1301H2BXD9258F230.023.54341.970.5220.460.0181.50.79UTM RW
      134R1309H1BXD9259M430.051.65566.340.4980.4810.0211.520.82UTM RW
      135R2057H1BXD9392F530.024.03344.410.5090.4710.021.220.78UTM RW
      136R2059H1BXD9358M1303.05860.290.4930.4880.0191.181.37UTM RW
      137R2313H1BXD9459F3303.09159.450.4870.4950.0181.340.73UTM RW
      138R1915H1BXD9665F520.045.14546.190.5020.4810.0171.370.74UTM RW
      139R1846H2BXD9663M1303.15955.850.4870.4930.020.921.26UTM RW
      140R2648H1BXD9774F740.021.66482.080.5180.4640.0191.40.78UTM RW
      141R1927H2BXD9767M130.042.62257.810.5390.4440.0171.451.32UTM RW
      142R1942H1BXD9862F530.043.10448.420.5280.4540.0192.221.08UTM RW
      143R1943H2BXD9862M330.024.0456.850.4840.4970.0191.180.76UTM RW
      144R2197H1BXD9970F330.024.28851.750.490.4920.0181.350.81UTM RW
      145R2315H1BXD9984M520.036.03643.050.4840.4970.0181.70.96UTM RW
      146R2028H2129S1/SvImJ66F530.14.36264.490.4970.4840.0192.781.13JAX
      147R2029H2129S1/SvImJ66M630.045.20841.210.490.490.021.620.95JAX
      148R2670H1A/J65F730.043.95146.80.4980.4850.0171.320.75UTM RW
      149R2030H1A/J57M520.063.30745.160.5270.4540.0181.630.99UTM RW
      150R2032H3AKR/J66F530.043.05461.030.510.4710.0181.460.79JAX
      151R2454H1AKR/J66M640.112.89258.550.4740.5070.0191.990.78JAX
      152R1675H1BALB/cByJ83M730.033.40548.130.5090.4740.0181.130.78JAX
      153R2036H3BALB/cJ51F530.122.61156.290.5180.4660.0173.31.23UTM RW
      154R2053H1BALB/cJ55M530.12.50563.270.4990.4830.0183.11.34UTM RW
      155R2037H2BALB/cJ51M640.012.54658.130.4970.4850.0181.260.77UTM RW
      156R2038H3C3H/HeJ63F630.022.67166.740.4760.5040.021.410.77UTM RW
      157R2039H1C3H/HeJ63M530.13.38444.150.5280.4540.0172.160.88UTM RW
      158R2137H1C57BL/6ByJ55F530.024.74647.010.4880.4930.0181.230.79JAX
      159R2673H1C57BL/6ByJ55M730.081.84267.690.5140.4690.0171.750.78JAX
      160R2619H1CAST/EiJ64F530.144.07751.870.4550.5280.0182.741.2JAX
      161R1683H1KK/HIJ72F630.023.91954.230.4910.4890.021.310.83JAX
      162R1687H3KK/HIJ72F530.043.88840.860.4990.4830.0191.860.88JAX
      163R2046H1LG/J63F520.032.82259.180.5140.4680.0181.680.8UTM RW
      164R2047H2LG/J63M630.072.03860.340.5090.4710.022.160.95UTM RW
      165R2048H1NOD/LtJ77F620.144.04550.210.4890.490.0212.890.95UTM RW
      166R2049H3NOD/LtJ76M530.12.32852.780.5190.4620.0193.091.35UTM RW
      167R2200H1NZO/HlLtJ62F520.032.64854.290.5430.4380.0191.270.8JAX
      168R2350H1NZO/HlLtJ96M620.192.39150.520.5180.4630.023.712.21JAX
      169R2677H1PWD/PhJ65M720.122.76465.490.4620.520.0181.891.16UTM RW
      170R2051H3PWD/PhJ64M530.073.26651.50.4750.5060.0192.81.01UTM RW
      171R2322H1PWK/PhJ63F520.092.9454.910.5110.470.0192.321.02JAX
      172R2349H1PWK/PhJ83M620.153.30654.930.4590.5220.0194.651.45JAX
      173R2198H2WSB/EiJ58F610.022.92257.970.5020.4790.0191.440.76JAX
      174R2199H1WSB/EiJ58M530.043.17154.950.4750.5050.021.320.81JAX
      175R2116H1CXB155F330.075.79251.590.4590.5210.021.170.8JAX
      176R2096H1CXB155M420.013.43553.780.4950.4850.021.220.79JAX
      177R2117H2CXB262F420.043.3945.970.5330.450.0172.050.89JAX
      178R2098H1CXB268M330.022.57254.220.4960.4850.0191.380.86JAX
      179R2118H1CXB347F330.033.64663.160.4780.5030.0191.220.77JAX
      180R2100H1CXB347M430.025.7651.380.480.5030.0171.240.81JAX
      181R2119H1CXB458F430.023.89749.210.4880.4940.0181.310.79JAX
      182R2101H1CXB458M330.137.37253.770.4330.5480.0191.20.97JAX
      183R2505H1CXB580F630.022.8349.60.4990.480.021.330.76UTM RW
      184R2131H1CXB542M430.15.57751.150.4340.5470.0191.70.89JAX
      185R0129H2CXB570M330.074.82945.420.4880.4930.0191.230.83UTM RW
      186R2676H1CXB647F720.052.14662.510.5070.4750.0181.520.78JAX
      187R2102H1CXB649M430.075.14851.630.4530.5290.0181.430.87JAX
      188R2121H1CXB763F420.064.90448.710.4640.5170.0191.190.92JAX
      189R2104H2CXB758M320.063.38948.790.5020.4790.0191.741.48JAX
      190R2122H1CXB854F330.044.12859.770.4510.5290.021.120.76JAX
      191R2105H1CXB841M430.163.14661.040.4510.530.0191.340.84JAX
      192R2123H1CXB954F330.085.70855.940.4380.5430.0191.320.78JAX
      193R2106H1CXB954M430.065.86846.550.4690.5120.0191.180.82JAX
      194R2124H1CXB1053F420.114.86739.880.4510.5280.021.550.8JAX
      195R2671H1CXB1053M730.092.34871.450.4880.4940.0182.21.14JAX
      196R2125H1CXB1158F330.033.25654.950.4610.5190.021.460.77JAX
      197R2128H1CXB1158M420.064.98654.130.4650.5150.021.110.83JAX
      198R2126H1CXB1247F430.113.93554.110.4690.5110.0211.50.79JAX
      199R2109H1CXB1247M330.074.51849.260.4880.4920.021.230.77JAX
      200R2672H1CXB1349F730.031.72279.520.5160.4650.0191.640.75JAX
      201R2110H1CXB1356M430.213.47848.080.4610.5170.0221.210.78JAX
      +


      About downloading this data set:

      All data links (right-most column above) will be made active as sooon as the global analysis of these data by the Consortium has been accepted for publication. Please see text on Data Sharing Policies, and Conditions and Limitations, and Contacts. Following publication, download a summary text file or Excel file of the PDNN probe set data. Contact RW Williams regarding data access problems. +



      About the array platform:

      Affymetrix Mouse Genome 430 2.0 array: The 430v2 array consists of 992936 useful 25-nucleotide probes that estimate the expression of approximately 39,000 transcripts and the majority of known genes and expressed sequence tags. The array sequences were selected late in 2002 using Unigene Build 107 by Affymetrix. The UTHSC group has recently reannotated all probe sets on this array, producing more accurate data on probe and probe set targets. All probes were aligned to the most recent assembly of the Mouse Genome (Build 34, mm6) using Jim Kent's BLAT program. Many of the probe sets have been manually curated by Jing Gu and Rob Williams.



      About data values and data processing:
      Harshlight was used to examine the image quality of the array (CEL files). Bad areas (bubbles, scratches, blemishes) of arrays were masked. + +

      First pass data quality control: Affymetrix GCOS provides useful array quality control data including: +

        +
      1. The scale factor used to normalize mean probe intensity. This averaged 3.3 for the 179 arrays that passed and 6.2 for arrays that were excluded. The scale factor is not a particular critical parameter. +
      2. The average background level. Values averaged 54.8 units for the data sets that passed and 55.8 for data sets that were excluded. This factor is not important for quality control. +
      3. The percentage of probe sets that are associated with good signal ("present" calls). This averaged 50% for the 179 data sets that passed and 42% for those that failed. Values for passing data sets extended from 43% to 55%. This is a particularly important criterion. +
      4. The 3':5' signal ratios of actin and Gapdh. Values for passing data sets averaged 1.5 for actin and 1.0 for Gapdh. Values for excluded data sets averaged 12.9 for actin and 9.6 for Gapdh. This is a highly discriminative QC criterion, although one must keep in mind that only two transcripts are being tested. Sequence variation among strains (particularly wild derivative strains such as CAST/Ei) may affect these ratios. +
      + +

      The second step in our post-processing QC involves a count of the number of probe sets in each array that are more than 2 standard deviations (z score units) from the mean across the entire 206 array data sets. This was the most important criterion used to eliminate "bad" data sets. All 206 arrays were processed togther using standard RMA and PDNN methods. The count and percentage of probe sets in each array that were beyond the 2 z theshold was computed. Using the RMA transform the average percentage of probe sets beyond the 2 z threshold for the 179 arrays that finally passed of QC procedure was 1.76% (median of 1.18%). In contrast the 2 z percentage was more than 10-fold higher (mean of 22.4% and median 20.2%) for those arrays that were excluded. This method is not very sensitive to the transformation method that is used. Using the PDNN transform, the average percent of probe sets exceeding was 1.31% for good arrays and was 22.6% for those that were excluded. In our opinion, this 2 z criterion is the most useful criterion for the final decision of whether or not to include arrays, although again, allowances need to be made for wild strains that one expects to be different from the majority of conventional inbred strains. For example, if a data set has excellent characteristics on all of the Affymetrix GCOS metrics listed above, but generates a high 2 z percentage, then one would include the sample if one can verify that there are no problems in sample and data set identification. + +

      The entire procedure can be reapplied once the initial outlier data sets have been eliminated to detect any remaining outlier data sets. + + +

      DataDesk was used to examine the statistical quality of the probe level (CEL) data after step 5 below. DataDesk allows the rapid detection of subsets of probes that are particularly sensitive to still unknown factors in array processing. Arrays can then be categorized at the probe level into "reaction classes." A reaction class is a group of arrays for which the expression of essentially all probes are colinear over the full range of log2 values. A single but large group of arrays (n = 32) processed in essentially the identical manner by a single operator can produce arrays belonging to as many as four different reaction classes. Reaction classes are NOT related to strain, age, sex, treatment, or any known biological parameter (technical replicates can belong to different reaction classes). We do not yet understand the technical origins of reaction classes. The number of probes that contribute to the definition of reaction classes is quite small (<10% of all probes). We have categorized all arrays in this data set into one of 5 reaction classes. These have then been treated as if they were separate batches. Probes in these data type "batches" have been aligned to a common mean as described below. + +

      Probe (cell) level data from the CEL file: These CEL values produced by GCOS are 75% quantiles from a set of 91 pixel values per cell. +

        + +
      1. We added an offset of 1.0 unit to each cell signal to ensure that all values could be logged without generating negative values. We then computed the log base 2 of each cell. + +
      2. We performed a quantile normalization of the log base 2 values for all arrays using the same initial steps used by the RMA transform. + +
      3. We computed the Z scores for each cell value. + +
      4. We multiplied all Z scores by 2. + +
      5. We added 8 to the value of all Z scores. The consequence of this simple set of transformations is to produce a set of Z scores that have a mean of 8, a variance of 4, and a standard deviation of 2. The advantage of this modified Z score is that a two-fold difference in expression level (probe brightness level) corresponds approximately to a 1 unit difference. + +
      6. Finally, we computed the arithmetic mean of the values for the set of microarrays for each strain. Technical replicates were averaged before computing the mean for independent biological samples. Note, that we have not (yet) corrected for variance introduced by differences in sex or any interaction terms. We have not corrected for background beyond the background correction implemented by Affymetrix in generating the CEL file. We eventually hope to add statistical controls and adjustments for some of these variables. +
      +

      Probe set data from the CHP file: The expression values were generated using PDNN. The same simple steps described above were also applied to these values. Every microarray data set therefore has a mean expression of 8 with a standard deviation of 2. A 1 unit difference represents roughly a two-fold difference in expression level. Expression levels below 5 are usually close to background noise levels. + + +

      Probe level QC: Log2 probe data of all arrays were inspected in DataDesk before and after quantile normalization. Inspection involved examining scatterplots of pairs of arrays for signal homogeneity (i.e., high correlation and linearity of the bivariate plots) and looking at all pairs of correlation coefficients. XY plots of probe expression and signal variance were also examined. Probe level array data sets were organized into reaction groups. Arrays with probe data that were not homogeneous when compared to other arrays were flagged. + +

      Probe set level QC: The final normalized individual array data were evaluated for outliers. This involved counting the number of times that the probe set value for a particular array was beyond two standard deviations of the mean. This outlier analysis was carried out using the PDNN, RMA and MAS5 transforms and outliers across different levels of expression. Arrays that were associated with an average of more than 8% outlier probe sets across all transforms and at all expression levels were eliminated. In contrast, most other arrays generated fewer than 5% outliers. + + +

      Validation of strains and sex of each array data set: A subset of probes and probe sets with a Mendelian pattern of inheritance were used to construct a expression correlation matrix for all arrays and the ideal Mendelian expectation for each strain constructed from the genotypes. There should naturally be a very high correlation in the expression patterns of transcripts with Mendelian phenotypes within each strain, as well as with the genotype strain distribution pattern of markers for the strain. + +

      Sex of the samples was validated using sex-specific probe sets such as Xist and Dby.

      Data source acknowledgment:

      Data were generated with funds provided by a variety of public and private source to members of the Consortium. All of us thank Muriel Davisson, Cathy Lutz, and colleagues at the Jackson Laboratory for making it possible for us to add all of the CXB strains, and one or more samples from KK/HIJ, WSB/Ei, NZO/HILtJ, LG/J, CAST/Ei, PWD/PhJ, and PWK/PhJ to this study. We thank Yan Cui at UTHSC for allowing us to use his Linux cluster to align all M430 2.0 probes and probe sets to the mouse genome. We thank Hui-Chen Hsu and John Mountz for providing us BXD tissue samples, as well as many strains of BXD stock. We thanks Douglas Matthews (UMem in Table 1) and John Boughter (JBo in Table 1) for sharing BXD stock with us. Members of the Hippocampus Consortium thank the following sources for financial support of this effort: + +

        +
      • David C. Airey, Ph.D. +
        Grant Support: Vanderbilt Institute for Integratie Genomics +
        Department of Pharmacology +
        david.airey at vanderbilt.edu + +
      • Lu Lu, M.D. +
        Grant Support: NIH U01AA13499, U24AA13513 + +
      • Fred H. Gage, Ph.D. +
        Grant Support: Lookout Foundation + +
      • Dan Goldowitz, Ph.D. +
        Grant Support: NIAAA INIA AA013503 +
        University of Tennessee Health Science Center +
        Dept. Anatomy and Neurobiology +
        email: dgold@nb.utmem.edu + +
      • Shirlean Goodwin, Ph.D. +
        Grant Support: NIAAA INIA U01AA013515 + +
      • Gerd Kempermann, M.D. +
        Grant Support: The Volkswagen Foundation Grant on Permissive and Persistent Factors in Neurogenesis in the Adult Central Nervous System +
        Humboldt-Universitat Berlin +
        Universitatsklinikum Charite +
        email: gerd.kempermann at mdc-berlin.de + +
      • Kenneth F. Manly, Ph.D. +
        Grant Support: NIH P20MH062009 and U01CA105417 + +
      • Richard S. Nowakowski, Ph.D. +
        Grant Support: R01 NS049445-01 + +
      • Glenn D. Rosen, Ph.D. +
        Grant Support: NIH P20 + +
      • Leonard C. Schalkwyk, Ph.D. +
        Grant Support: MRC Career Establishment Grant G0000170 +
        Social, Genetic and Developmental Psychiatry +
        Institute of Psychiatry,Kings College London +
        PO82, De Crespigny Park London SE5 8AF +
        L.Schalkwyk@iop.kcl.ac.uk + +
      • Guus Smit, Ph.D. +
        Dutch NeuroBsik Mouse Phenomics Consortium +
        Center for Neurogenomics & Cognitive Research +
        Vrije Universiteit Amsterdam, The Netherlands +
        e-mail: guus.smit at falw.vu.nl +
        Grant Support: BSIK 03053 + +
      • Thomas Sutter, Ph.D. +
        Grant Support: INIA U01 AA13515 and the W. Harry Feinstone Center for Genome Research + +
      • Stephen Whatley, Ph.D. +
        Grant Support: XXXX + +
      • Robert W. Williams, Ph.D. +
        Grant Support: NIH U01AA013499, P20MH062009, U01AA013499, U01AA013513 +
      +



      Experiment Type:

      Pooled RNA samples (usually one pool of male hippocampii and one pool of female hippocampii) were prepared using standard protocols. Samples were processed using a total of 206 Affymetrix GeneChip Mouse Expression 430 2.0 short oligomer arrays (MOE430 2.0 or M430v2; see GEO platform ID GPL1261), of which 201 passed quality control and error checking. This particular data set was processed using the PDNN protocol. To simplify comparisons among transforms, PDNN values of each array were adjusted to an average of 8 units and a standard deviation of 2 units. +

      Overall Design:

      Pooled RNA samples (usually one pool of male hippocampii and one pool of female hippocampii) were prepared using standard protocols. Samples were processed using a total of 206 Affymetrix GeneChip Mouse Expression 430 2.0 short oligomer arrays (MOE430 2.0 or M430v2; see GEO platform ID GPL1261), of which 201 passed quality control and error checking. This particular data set was processed using the PDNN protocol. To simplify comparisons among transforms, PDNN values of each array were adjusted to an average of 8 units and a standard deviation of 2 units. +

      Contributor:
        +
      • David C. Airey, Ph.D. +
        Grant Support: Vanderbilt Institute for Integratie Genomics +
        Department of Pharmacology +
        david.airey at vanderbilt.edu + +
      • Lu Lu, M.D. +
        Grant Support: NIH U01AA13499, U24AA13513 + +
      • Fred H. Gage, Ph.D. +
        Grant Support: Lookout Foundation + +
      • Dan Goldowitz, Ph.D. +
        Grant Support: NIAAA INIA AA013503 +
        University of Tennessee Health Science Center +
        Dept. Anatomy and Neurobiology +
        email: dgold@nb.utmem.edu + +
      • Shirlean Goodwin, Ph.D. +
        Grant Support: NIAAA INIA U01AA013515 + +
      • Gerd Kempermann, M.D. +
        Grant Support: The Volkswagen Foundation Grant on Permissive and Persistent Factors in Neurogenesis in the Adult Central Nervous System +
        Humboldt-Universitat Berlin +
        Universitatsklinikum Charite +
        email: gerd.kempermann at mdc-berlin.de + +
      • Kenneth F. Manly, Ph.D. +
        Grant Support: NIH P20MH062009 and U01CA105417 + +
      • Richard S. Nowakowski, Ph.D. +
        Grant Support: R01 NS049445-01 + +
      • Glenn D. Rosen, Ph.D. +
        Grant Support: NIH P20 + +
      • Leonard C. Schalkwyk, Ph.D. +
        Grant Support: MRC Career Establishment Grant G0000170 +
        Social, Genetic and Developmental Psychiatry +
        Institute of Psychiatry,Kings College London +
        PO82, De Crespigny Park London SE5 8AF +
        L.Schalkwyk@iop.kcl.ac.uk + +
      • Guus Smit, Ph.D. +
        Dutch NeuroBsik Mouse Phenomics Consortium +
        Center for Neurogenomics & Cognitive Research +
        Vrije Universiteit Amsterdam, The Netherlands +
        e-mail: guus.smit at falw.vu.nl +
        Grant Support: BSIK 03053 + +
      • Thomas Sutter, Ph.D. +
        Grant Support: INIA U01 AA13515 and the W. Harry Feinstone Center for Genome Research + +
      • Stephen Whatley, Ph.D. +
        Grant Support: XXXX + +
      • Robert W. Williams, Ph.D. +
        Grant Support: NIH U01AA013499, P20MH062009, U01AA013499, U01AA013513 +


      Citation:
      +

      Please cite: Overall RW, Kempermann G, Peirce J, Lu L, Goldowitz D, Gage FH, Goodwin S, Smit AB, Airey DC, Rosen GD, Schalkwyk LC, Sutter TR, Nowakowski RS, Whatley S, Williams RW (2009) Genetics of the hippocampal transcriptome in mice: a systematic survey and online neurogenomic resource. Front. Neurogen. 1:3 Full Text HTML doi:10.3389/neuro.15.003.2009 + +

      Submission Date:
      01 Jul. 2009

      Laboratory:
      Williams and Lu Labs

      Samples:
      None

      +

      +
      +
      + + + + + + + + + + + + + + +
      + + CITG + +WWW service initiated January, 1994 as The Portable Dictionary of the Mouse Genome and June 15, 2001 as WebQTL. + +This site is currently operated by + Rob Williams, + Lei Yan, + Zachary Sloan, + Arthur Centeno. Design and code by Sam Ockman, Xiaodong Zhou, Christian Fernandez, Ning Liu, Rudi Alberts, Elissa Chesler, Jintao Wang, Kenneth Manly, Robert W. Williams, and colleagues. + + + + + Python Powered + + + Registered with Nif +
      + GeneNetwork support from: + +
      +     It took 0.011 second(s) for spring211.uthsc.edu to generate this page +
      +
      + + + + + + + + + + diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index 89581075..8c6c016d 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -85,9 +85,8 @@ - diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index c15f4ba1..a2c68f13 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -7,6 +7,8 @@ from flask import render_template, request from wqflask import search_results from wqflask.show_trait import show_trait_page +from wqflask.dataSharing import SharingInfoPage + from base import webqtlFormData from pprint import pformat as pf @@ -18,8 +20,12 @@ def index_page(): @app.route("/search") def search(): - the_search = search_results.SearchResultPage(request.args) - return render_template("search_result_page.html", **the_search.__dict__) + if 'info_database' in request.args: + print("Going to data_sharing") + data_sharing() + else: + the_search = search_results.SearchResultPage(request.args) + return render_template("search_result_page.html", **the_search.__dict__) @app.route("/showDatabaseBXD") def showDatabaseBXD(): @@ -28,3 +34,12 @@ def showDatabaseBXD(): template_vars = show_trait_page.ShowTraitPage(fd) print("showDatabaseBXD template_vars:", pf(template_vars.__dict__)) return render_template("trait_data_and_analysis.html", **template_vars.__dict__) + +#@app.route("/data_sharing") +def data_sharing(): + print("In data_sharing") + fd = webqtlFormData.webqtlFormData(request.args) + print("Have fd") + template_vars = SharingInfoPage.SharingInfoPage(fd) + print("Made it to rendering") + return render_template("data_sharing.html", **template_vars.__dict__) -- cgit v1.2.3 From 243a0ff8a0926f9653d8196613d55fe8abdba871 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Fri, 29 Jun 2012 18:24:50 -0400 Subject: removed some previously deleted files --- wqflask/dataSharing/SharingBody.py | 290 -------------------------- wqflask/dataSharing/SharingInfo.py | 98 --------- wqflask/dataSharing/SharingInfoAddPage.py | 47 ----- wqflask/dataSharing/SharingInfoDeletePage.py | 55 ----- wqflask/dataSharing/SharingInfoEditPage.py | 51 ----- wqflask/dataSharing/SharingInfoPage.py | 52 ----- wqflask/dataSharing/SharingInfoUpdatePage.py | 109 ---------- wqflask/dataSharing/SharingListDataSetPage.py | 99 --------- wqflask/dataSharing/SharingPage.py | 40 ---- wqflask/dataSharing/__init__.py | 0 10 files changed, 841 deletions(-) delete mode 100755 wqflask/dataSharing/SharingBody.py delete mode 100755 wqflask/dataSharing/SharingInfo.py delete mode 100755 wqflask/dataSharing/SharingInfoAddPage.py delete mode 100755 wqflask/dataSharing/SharingInfoDeletePage.py delete mode 100755 wqflask/dataSharing/SharingInfoEditPage.py delete mode 100755 wqflask/dataSharing/SharingInfoPage.py delete mode 100755 wqflask/dataSharing/SharingInfoUpdatePage.py delete mode 100755 wqflask/dataSharing/SharingListDataSetPage.py delete mode 100755 wqflask/dataSharing/SharingPage.py delete mode 100755 wqflask/dataSharing/__init__.py diff --git a/wqflask/dataSharing/SharingBody.py b/wqflask/dataSharing/SharingBody.py deleted file mode 100755 index 4445e0d1..00000000 --- a/wqflask/dataSharing/SharingBody.py +++ /dev/null @@ -1,290 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -sharing_body_string = """ - - -

      Data Set Download

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - Species: - - - -
      - Group: - - - -
      - Type: - - - -
      - Database: - - - -
      -     -
      - - -
      - -

      GeneNetwork Accession Number

      -
      - - - - - - - - - - - - -
      GN:  E.g. 112
      -     -
      -
      - - -""" - -sharinginfo_body_string = """ -List of DataSets
      -

      %s -modify this page -%s -

      - - - - - -
      - - - - - - - - - - - -
      GN Accession: GN%s
      GEO Series: %s
      Title: %s
      Organism: %s
      Group: %s
      Tissue: %s
      Dataset Status: %s
      Platforms: %s
      Normalization: %s
      - See Contact Information
      -
      -
      - - - - - - - -
      Download datasets and supplementary data files
      %s
      -
      -
      -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Summary:
      %s

      About the cases used to generate this set of data:
      %s

      About the tissue used to generate this set of data:
      %s

      About downloading this data set:
      %s

      About the array platform:
      %s

      About data values and data processing:
      %s

      Data source acknowledgment:
      %s

      Experiment Type:
      %s

      Overall Design:
      %s

      Contributor:
      %s

      Citation:
      %s

      Submission Date:
      %s

      Laboratory:
      %s

      Samples:
      %s

      -

      - -""" - -sharinginfoedit_body_string = """ -

      %s

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

      Principal Investigator

      Contact Name:
      Emails:
      Phone:
      URL:
      Organization Name:
      Department:
      Laboratory:
      Address:
      City:
      State:
      ZIP:
      Country:

      Summary

      Summary:

      Biology

      Experiment Design:
      About the cases used to
      generate this set of data:
      About the tissue used to
      generate this set of data:

      Technique

      About downloading this data set:
      About the array platform:

      Bioinformatics

      About data values and
      data processing:
      Overall Design:

      Misc

      Contributor:
      Citation:
      Data source acknowledgment:

      Administrator ONLY

      GN Accesion Id:
      DB Title in GN:
      GEO Series:
      Status:
      Title:
      Organism_Id (Taxonomy ID):
      Organism:
      Submission Date:
      Platforms:
      Species:
      Tissue:
      Normalization:
      Inbred Set:
      Info Page Name:
      Samples:
      Authorized Users:
      Progress:
      -""" diff --git a/wqflask/dataSharing/SharingInfo.py b/wqflask/dataSharing/SharingInfo.py deleted file mode 100755 index 10abcefa..00000000 --- a/wqflask/dataSharing/SharingInfo.py +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -import httplib - -from dbFunction import webqtlDatabaseFunction -import SharingBody - - -######################################### -# Sharing Info -######################################### -class SharingInfo: - - def __init__(self, GN_AccessionId, InfoPageName): - self.GN_AccessionId = GN_AccessionId - self.InfoPageName = InfoPageName - - def getInfo(self): - cursor = webqtlDatabaseFunction.getCursor() - if (not cursor): - return - sql = "select Id, GEO_Series, Status, Title, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Normalization, InbredSet, InfoPageName, DB_Name, Organism_Id, InfoPageTitle, GN_AccesionId, Tissue, AuthorizedUsers, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, Progreso from InfoFiles where " - if(self.GN_AccessionId): - sql += "GN_AccesionId = %s" - cursor.execute(sql, self.GN_AccessionId) - elif (self.InfoPageName): - sql += "InfoPageName = %s" - cursor.execute(sql, self.InfoPageName) - else: - raise 'No correct parameter found' - info = cursor.fetchone() - # fetch datasets file list - try: - conn = httplib.HTTPConnection("atlas.uthsc.edu") - conn.request("GET", "/scandatasets.php?GN_AccesionId=%s" % (info[32])) - response = conn.getresponse() - data = response.read() - filelist = data.split() - conn.close() - except Exception: - filelist = [] - return info, filelist - - def getBody(self, infoupdate=""): - info, filelist = self.getInfo() - if filelist: - htmlfilelist = '
        \n' - for i in range(len(filelist)): - if i%2==0: - filename = filelist[i] - filesize = filelist[i+1] - htmlfilelist += "
      • " - htmlfilelist += '%s' % (self.GN_AccessionId, filename, filename) - htmlfilelist += '   ' - #r=re.compile(r'(?<=\d)(?=(\d\d\d)+(?!\d))') - #htmlfilelist += '[%s B]' % r.sub(r',',filesize) - if 12= webqtlConfig.USERDICT['admin']: - pass - else: - heading = "Adding Info" - detail = ["You don't have the permission to add new dataset"] - self.error(heading=heading,detail=detail,error="Error") - return - self.dict['body'] = SharingBody.sharinginfoedit_body_string % ("Add new dataset", "-1", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "") diff --git a/wqflask/dataSharing/SharingInfoDeletePage.py b/wqflask/dataSharing/SharingInfoDeletePage.py deleted file mode 100755 index edc0be7d..00000000 --- a/wqflask/dataSharing/SharingInfoDeletePage.py +++ /dev/null @@ -1,55 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from base.templatePage import templatePage -from base import webqtlConfig -from dbFunction import webqtlDatabaseFunction -import SharingBody -import SharingInfo - - -######################################### -# Sharing Info Delete Page -######################################### -class SharingInfoDeletePage(templatePage): - - def __init__(self, fd=None): - templatePage.__init__(self, fd) - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: - pass - else: - heading = "Deleting Info" - detail = ["You don't have the permission to delete this dataset"] - self.error(heading=heading,detail=detail,error="Error") - return - cursor = webqtlDatabaseFunction.getCursor() - if (not cursor): - return - GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') - sql = "delete from InfoFiles where GN_AccesionId=%s" - cursor.execute(sql, GN_AccessionId) - re = cursor.fetchone() - self.dict['body'] = "Delete dataset info record (GN_AccesionId=%s) successfully." % GN_AccessionId \ No newline at end of file diff --git a/wqflask/dataSharing/SharingInfoEditPage.py b/wqflask/dataSharing/SharingInfoEditPage.py deleted file mode 100755 index 266b8602..00000000 --- a/wqflask/dataSharing/SharingInfoEditPage.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from base.templatePage import templatePage -from base import webqtlConfig -import SharingBody -import SharingInfo - - -######################################### -# Sharing Info Edit Page -######################################### -class SharingInfoEditPage(templatePage): - - def __init__(self, fd=None): - templatePage.__init__(self, fd) - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: - pass - else: - heading = "Editing Info" - detail = ["You don't have the permission to edit this dataset"] - self.error(heading=heading,detail=detail,error="Error") - return - GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') - InfoPageName = fd.formdata.getvalue('InfoPageName') - sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) - info, filelist = sharingInfoObject.getInfo() - self.dict['body'] = SharingBody.sharinginfoedit_body_string % (info[31], info[0], info[11], info[12], info[13], info[14], info[15], info[16], info[17], info[18], info[19], info[20], info[21], info[22], info[6], info[5], info[35], info[36], info[37], info[38], info[39], info[7], info[8], info[9], info[40], info[32], info[31], info[1], info[2], info[3], info[30], info[4], info[10], info[23], info[25], info[33], info[26], info[27], info[28], info[24], info[34], info[41]) diff --git a/wqflask/dataSharing/SharingInfoPage.py b/wqflask/dataSharing/SharingInfoPage.py deleted file mode 100755 index 230ba2f3..00000000 --- a/wqflask/dataSharing/SharingInfoPage.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from base.templatePage import templatePage -from base import webqtlConfig -from dbFunction import webqtlDatabaseFunction -import SharingBody -import SharingInfo - - -######################################### -# Sharing Info Page -######################################### -class SharingInfoPage(templatePage): - - def __init__(self, fd=None): - templatePage.__init__(self, fd) - GN_AccessionId = fd.formdata.getvalue('GN_AccessionId') - InfoPageName = fd.formdata.getvalue('InfoPageName') - cursor = webqtlDatabaseFunction.getCursor() - if InfoPageName and not GN_AccessionId: - sql = "select GN_AccesionId from InfoFiles where InfoPageName = %s" - cursor.execute(sql, InfoPageName) - GN_AccessionId = cursor.fetchone() - url = webqtlConfig.CGIDIR + "main.py?FormID=sharinginfo&GN_AccessionId=%s" % GN_AccessionId - self.redirection = url - else: - sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) - self.dict['body'] = sharingInfoObject.getBody(infoupdate="") diff --git a/wqflask/dataSharing/SharingInfoUpdatePage.py b/wqflask/dataSharing/SharingInfoUpdatePage.py deleted file mode 100755 index a70238b9..00000000 --- a/wqflask/dataSharing/SharingInfoUpdatePage.py +++ /dev/null @@ -1,109 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -import MySQLdb - -from base.templatePage import templatePage -from base import webqtlConfig -from dbFunction import webqtlDatabaseFunction -import SharingBody -import SharingInfo - -######################################### -# Sharing Info Update Page -######################################### -class SharingInfoUpdatePage(templatePage): - - def __init__(self, fd=None): - templatePage.__init__(self, fd) - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: - pass - else: - heading = "Editing Info" - detail = ["You don't have the permission to modify this file"] - self.error(heading=heading,detail=detail,error="Error") - return - cursor = webqtlDatabaseFunction.getCursor() - if (not cursor): - return - Id=fd.formdata.getvalue('Id') - GN_AccesionId=fd.formdata.getvalue('GN_AccesionId') - GEO_Series=fd.formdata.getvalue('GEO_Series') - Status=fd.formdata.getvalue('Status') - Title=fd.formdata.getvalue('Title') - Organism_Id=fd.formdata.getvalue('Organism_Id') - Organism=fd.formdata.getvalue('Organism') - Experiment_Type =fd.formdata.getvalue('Experiment_Type') - Summary=fd.formdata.getvalue('Summary') - Overall_Design=fd.formdata.getvalue('Overall_Design') - Contributor=fd.formdata.getvalue('Contributor') - Citation=fd.formdata.getvalue('Citation') - Submission_Date=fd.formdata.getvalue('Submission_Date') - Contact_Name=fd.formdata.getvalue('Contact_Name') - Emails=fd.formdata.getvalue('Emails') - Phone=fd.formdata.getvalue('Phone') - URL=fd.formdata.getvalue('URL') - Organization_Name=fd.formdata.getvalue('Organization_Name') - Department=fd.formdata.getvalue('Department') - Laboratory=fd.formdata.getvalue('Laboratory') - Street=fd.formdata.getvalue('Street') - City=fd.formdata.getvalue('City') - State=fd.formdata.getvalue('State') - ZIP=fd.formdata.getvalue('ZIP') - Country=fd.formdata.getvalue('Country') - Platforms=fd.formdata.getvalue('Platforms') - Samples=fd.formdata.getvalue('Samples') - Species=fd.formdata.getvalue('Species') - Tissue=fd.formdata.getvalue('Tissue') - Normalization=fd.formdata.getvalue('Normalization') - InbredSet=fd.formdata.getvalue('InbredSet') - InfoPageName=fd.formdata.getvalue('InfoPageName') - InfoPageTitle=fd.formdata.getvalue('InfoPageTitle') - About_Cases=fd.formdata.getvalue('About_Cases') - About_Tissue=fd.formdata.getvalue('About_Tissue') - About_Download=fd.formdata.getvalue('About_Download') - About_Array_Platform=fd.formdata.getvalue('About_Array_Platform') - About_Data_Values_Processing=fd.formdata.getvalue('About_Data_Values_Processing') - Data_Source_Acknowledge=fd.formdata.getvalue('Data_Source_Acknowledge') - AuthorizedUsers=fd.formdata.getvalue('AuthorizedUsers') - Progress=fd.formdata.getvalue('Progress') - if Id=='-1': - sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) - info, filelist = sharingInfoObject.getInfo() - if info: - heading = "Editing Info" - detail = ["The new dataset info record is duplicate."] - self.error(heading=heading, detail=detail, error="Error") - return - sql = """INSERT INTO InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s""" - cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress])) - infoupdate="This record has been succesfully added." - else: - sql = """UPDATE InfoFiles SET GN_AccesionId=%s, GEO_Series=%s, Status=%s, Title=%s, Organism_Id=%s, Organism=%s, Experiment_Type=%s, Summary=%s, Overall_Design=%s, Contributor=%s, Citation=%s, Submission_Date=%s, Contact_Name=%s, Emails=%s, Phone=%s, URL=%s, Organization_Name=%s, Department=%s, Laboratory=%s, Street=%s, City=%s, State=%s, ZIP=%s, Country=%s, Platforms=%s, Samples=%s, Species=%s, Tissue=%s, Normalization=%s, InbredSet=%s, InfoPageName=%s, InfoPageTitle=%s, About_Cases=%s, About_Tissue=%s, About_Download=%s, About_Array_Platform=%s, About_Data_Values_Processing=%s, Data_Source_Acknowledge=%s, AuthorizedUsers=%s, Progreso=%s WHERE Id=%s""" - cursor.execute(sql, tuple([GN_AccesionId, GEO_Series, Status, Title, Organism_Id, Organism, Experiment_Type, Summary, Overall_Design, Contributor, Citation, Submission_Date, Contact_Name, Emails, Phone, URL, Organization_Name, Department, Laboratory, Street, City, State, ZIP, Country, Platforms, Samples, Species, Tissue, Normalization, InbredSet, InfoPageName, InfoPageTitle, About_Cases, About_Tissue, About_Download, About_Array_Platform, About_Data_Values_Processing, Data_Source_Acknowledge, AuthorizedUsers, Progress, Id])) - infoupdate="This record has been succesfully updated." - sharingInfoObject = SharingInfo.SharingInfo(GN_AccesionId, InfoPageName) - self.dict['body'] = sharingInfoObject.getBody(infoupdate=infoupdate) \ No newline at end of file diff --git a/wqflask/dataSharing/SharingListDataSetPage.py b/wqflask/dataSharing/SharingListDataSetPage.py deleted file mode 100755 index ec90f5f3..00000000 --- a/wqflask/dataSharing/SharingListDataSetPage.py +++ /dev/null @@ -1,99 +0,0 @@ -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from htmlgen import HTMLgen2 as HT -from base import webqtlConfig - -from base.templatePage import templatePage - - -######################################### -# Sharing List DataSet Page -######################################### -class SharingListDataSetPage(templatePage): - - def __init__(self, fd=None): - templatePage.__init__(self, fd) - - if not self.openMysql(): - return - - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['admin']: - pass - else: - heading = "Editing Info" - detail = ["You don't have the permission to list the datasets"] - self.error(heading=heading,detail=detail,error="Error") - return - - - TD_LR = HT.TD(height=200,width="100%",bgColor='#eeeeee') - - query = """select GN_AccesionId, InfoPageTitle, Progreso from InfoFiles order by GN_AccesionId""" - self.cursor.execute(query) - result = self.cursor.fetchall() - - heading = HT.Paragraph('Dataset Table', Class="title") - - newrecord = HT.Href(text="New Record", url="/webqtl/main.py?FormID=sharinginfoadd") - - info = "Click the accession id to view the dataset info. Click the dataset name to edit the dataset info." - - datasetTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0, Class="collap", width="100%") - - tableHeaderRow = HT.TR() - tableHeaderRow.append(HT.TD("Accession Id", Class='fs14 fwb ffl b1 cw cbrb', align="center")) - tableHeaderRow.append(HT.TD("Dataset name", Class='fs14 fwb ffl b1 cw cbrb', align="center")) - tableHeaderRow.append(HT.TD("Progress", Class='fs14 fwb ffl b1 cw cbrb', align="center")) - tableHeaderRow.append(HT.TD("Operation", Class='fs14 fwb ffl b1 cw cbrb', align="center")) - datasetTable.append(tableHeaderRow) - - for one_row in result: - Accession_Id, InfoPage_title, Progress = one_row - datasetRow = HT.TR() - datasetRow.append(HT.TD(HT.Href(text="GN%s" % Accession_Id, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) - datasetRow.append(HT.TD(HT.Href(text="%s" % InfoPage_title, url="/webqtl/main.py?FormID=sharinginfo&GN_AccessionId=%s" % Accession_Id, Class='fs12 fwn'), Class="fs12 fwn b1 c222")) - datasetRow.append(HT.TD("%s" % Progress, Class='fs12 fwn ffl b1 c222')) - operation_edit = HT.Href(text="Edit", url="/webqtl/main.py?FormID=sharinginfoedit&GN_AccessionId=%s" % Accession_Id) - operation_delete = HT.Href(text="Delete", onClick="deleteRecord(%s); return false;" % Accession_Id) - operation = HT.TD(Class="fs12 fwn b1 c222", align="center") - operation.append(operation_edit) - operation.append("    ") - operation.append(operation_delete) - datasetRow.append(operation) - datasetTable.append(datasetRow) - - TD_LR.append(heading, HT.P(), newrecord, HT.P(), info, HT.P(), datasetTable) - - js1 = """ """ - self.dict['js1'] = js1 - self.dict['body'] = str(TD_LR) \ No newline at end of file diff --git a/wqflask/dataSharing/SharingPage.py b/wqflask/dataSharing/SharingPage.py deleted file mode 100755 index cf1d9ac3..00000000 --- a/wqflask/dataSharing/SharingPage.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from base.templatePage import templatePage -import SharingBody - -######################################### -# SharingPage -######################################### - -class SharingPage(templatePage): - - def __init__(self, fd): - templatePage.__init__(self, fd) - self.dict['title'] = 'GeneNetwork Data Sharing Zone' - self.dict['body'] = SharingBody.sharing_body_string - self.dict['js2'] = 'onload="javascript:initialDatasetSelection();"' \ No newline at end of file diff --git a/wqflask/dataSharing/__init__.py b/wqflask/dataSharing/__init__.py deleted file mode 100755 index e69de29b..00000000 -- cgit v1.2.3 From 275174497daa6d0dae64124addb360cb8c71c658 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Wed, 4 Jul 2012 21:41:34 -0400 Subject: Changes around trait data editing --- wqflask/wqflask/dataSharing/SharingInfoPage.py | 13 +- .../new/javascript/trait_data_and_analysis.coffee | 48 +++++- .../new/javascript/trait_data_and_analysis.js | 54 +++++- wqflask/wqflask/templates/base.html | 4 +- wqflask/wqflask/templates/data_sharing.html | 190 +-------------------- .../wqflask/templates/trait_data_and_analysis.html | 20 ++- wqflask/wqflask/views.py | 33 +++- 7 files changed, 153 insertions(+), 209 deletions(-) diff --git a/wqflask/wqflask/dataSharing/SharingInfoPage.py b/wqflask/wqflask/dataSharing/SharingInfoPage.py index 4e07e01b..91538a07 100755 --- a/wqflask/wqflask/dataSharing/SharingInfoPage.py +++ b/wqflask/wqflask/dataSharing/SharingInfoPage.py @@ -28,6 +28,8 @@ from __future__ import print_function, division from pprint import pformat as pf +import flask + from base.templatePage import templatePage from base import webqtlConfig from dbFunction import webqtlDatabaseFunction @@ -42,8 +44,9 @@ class SharingInfoPage(templatePage): def __init__(self, fd): templatePage.__init__(self, fd) + self.redirect_url = None # Set if you want a redirect print("fd is:", pf(fd.__dict__)) - # Todo: Need a [0] in line below???? + # Todo: Need a [0] in line below????d GN_AccessionId = fd.get('GN_AccessionId') # Used under search datasharing InfoPageName = fd['database'][0] cursor = webqtlDatabaseFunction.getCursor() @@ -51,8 +54,12 @@ class SharingInfoPage(templatePage): sql = "select GN_AccesionId from InfoFiles where InfoPageName = %s" cursor.execute(sql, InfoPageName) GN_AccessionId = cursor.fetchone() - url = webqtlConfig.CGIDIR + "main.py?FormID=sharinginfo&GN_AccessionId=%s" % GN_AccessionId - self.redirection = url + self.redirect_url = "http://23.21.59.238:5001/data_sharing&GN_AccessionId=%s" % GN_AccessionId + #self.redirect_url = flask.url_for('data_sharing', GN_AccessionId=GN_AccessionId[0]) + print("set self.redirect_url") + #print("before redirect") + #return flask.redirect(url) + #print("after redirect") else: sharingInfoObject = SharingInfo.SharingInfo(GN_AccessionId, InfoPageName) self.dict['body'] = sharingInfoObject.getBody(infoupdate="") diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee index 118be8ec..d3b1051d 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee @@ -1,5 +1,15 @@ console.log("start_b") +isNumber = (o) -> + return ! isNaN (o-0) && o != null + +console.log("isNumber 7:", isNumber(7)) +console.log("isNumber 13.1:", isNumber(13.1)) +console.log("isNumber x:", isNumber("x")) +console.log("isNumber '9':", isNumber('9')) +console.log("isNumber:", isNumber()) + + $ -> hide_tabs = (start) -> for x in [start..10] @@ -12,7 +22,7 @@ $ -> console.log("hidden?") - + # Changes stats table between all, bxd only and non-bxd, etc. stats_mdp_change = -> console.log("In stats_mdp_change") selected = $(this).val() @@ -24,3 +34,39 @@ $ -> console.log("tape") + + mean = (the_values)-> + total = 0 + total += value for value in the_values + console.log("yeap") + console.log(total) + the_mean = total / the_values.length + return the_mean.toFixed(2) + + + + edit_data_change = -> + console.log("In edit_data_change") + the_values = [] + #console.log($(this)) + #$(this).each (counter, element) => + # #console.log("counter is:" + counter) + # console.log("element is:") + # console.log(element) + console.log("foo") + values = $('#primary').find(".edit_strain_value") + console.log("values are:", values) + for value in values + console.log(value) + real_value = $(value).val() + #if real_value + console.log(real_value) + if isNumber(real_value) and real_value != "" + the_values.push(parseFloat(real_value)) + console.log(the_values) + the_mean = mean(the_values) + console.log(the_mean) + $("#mean_value").html(the_mean) + + $('#primary').change(edit_data_change) + console.log("loaded") diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js index e59edbdb..eecc630f 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js @@ -1,10 +1,25 @@ // Generated by CoffeeScript 1.3.3 (function() { + var isNumber; console.log("start_b"); + isNumber = function(o) { + return !isNaN((o - 0) && o !== null); + }; + + console.log("isNumber 7:", isNumber(7)); + + console.log("isNumber 13.1:", isNumber(13.1)); + + console.log("isNumber x:", isNumber("x")); + + console.log("isNumber '9':", isNumber('9')); + + console.log("isNumber:", isNumber()); + $(function() { - var hide_tabs, stats_mdp_change; + var edit_data_change, hide_tabs, mean, stats_mdp_change; hide_tabs = function(start) { var x, _i, _results; _results = []; @@ -26,7 +41,42 @@ return $("#stats_tabs" + selected).show(); }; $(".stats_mdp").change(stats_mdp_change); - return console.log("tape"); + console.log("tape"); + mean = function(the_values) { + var the_mean, total, value, _i, _len; + total = 0; + for (_i = 0, _len = the_values.length; _i < _len; _i++) { + value = the_values[_i]; + total += value; + } + console.log("yeap"); + console.log(total); + the_mean = total / the_values.length; + return the_mean.toFixed(2); + }; + edit_data_change = function() { + var real_value, the_mean, the_values, value, values, _i, _len; + console.log("In edit_data_change"); + the_values = []; + console.log("foo"); + values = $('#primary').find(".edit_strain_value"); + console.log("values are:", values); + for (_i = 0, _len = values.length; _i < _len; _i++) { + value = values[_i]; + console.log(value); + real_value = $(value).val(); + console.log(real_value); + if (isNumber(real_value) && real_value !== "") { + the_values.push(parseFloat(real_value)); + } + } + console.log(the_values); + the_mean = mean(the_values); + console.log(the_mean); + return $("#mean_value").html(the_mean); + }; + $('#primary').change(edit_data_change); + return console.log("loaded"); }); }).call(this); diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 6776a71c..d7154a5b 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -18,11 +18,11 @@ - + - + diff --git a/wqflask/wqflask/templates/data_sharing.html b/wqflask/wqflask/templates/data_sharing.html index e9d082d6..e6942504 100644 --- a/wqflask/wqflask/templates/data_sharing.html +++ b/wqflask/wqflask/templates/data_sharing.html @@ -1,112 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{% extends "base.html" %} +{% block title %}Search Results{% endblock %} +{% block content %} @@ -752,80 +646,4 @@ This table lists all arrays by file order (Index), tube/sample ID, age, s - - - - - - -
          - - - - - - -
        - - - - - - - - - WebQTL -
        -
         
        - - - - - -
        -   |    - -Home -   |    - -Search -   |    - -Help -   |    - - -News -   |    - - -References -   |    - -Policies -   |    - - -Links -   |    - -Welcome! Login    -
        -
        - - - - - - - - - - - - - - -
        - - CITG - -WWW service initiated January, 1994 as The Portable Dictionary of the Mouse Genome and June 15, 2001 as WebQTL. - -This site is currently operated by - Rob Williams, - Lei Yan, - Zachary Sloan, - Arthur Centeno. Design and code by Sam Ockman, Xiaodong Zhou, Christian Fernandez, Ning Liu, Rudi Alberts, Elissa Chesler, Jintao Wang, Kenneth Manly, Robert W. Williams, and colleagues. - - - - - Python Powered - - - Registered with Nif -
        - GeneNetwork support from: - -
        -     It took 0.011 second(s) for spring211.uthsc.edu to generate this page -
        -
        - - - - - - - - - - +{% endblock %} diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index efd87acc..c27ab092 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -295,7 +295,7 @@ Mean - {{ "%2.3f" % sd.traitmean }} + {{ "%2.3f" % sd.traitmean }} @@ -3047,7 +3047,7 @@ {% for strain_type in (primary_strains, other_strains) %}
        {# Slightly tortuous, but best way to get the id we need #} - @@ -3063,18 +3063,19 @@ {% for strain in strain_type %} - + - @@ -3083,8 +3084,9 @@ ± - diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index a2c68f13..55d6ffe2 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, division, print_function +import flask + from wqflask import app from flask import render_template, request @@ -13,6 +15,8 @@ from base import webqtlFormData from pprint import pformat as pf +print("latest blue") + @app.route("/") def index_page(): return render_template("index_page.html") @@ -21,12 +25,26 @@ def index_page(): @app.route("/search") def search(): if 'info_database' in request.args: - print("Going to data_sharing") - data_sharing() + print("Going to sharing_info_page") + template_vars = sharing_info_page() + if template_vars.redirect_url: + return flask.redirect(template_vars.redirect_url) + else: + return render_template("data_sharing.html", **template_vars.__dict__) else: the_search = search_results.SearchResultPage(request.args) return render_template("search_result_page.html", **the_search.__dict__) +@app.route("/data_sharing") +def data_sharing(): + print("In data_sharing") + fd = webqtlFormData.webqtlFormData(request.args) + print("Have fd") + template_vars = SharingInfoPage.SharingInfoPage(fd) + print("Made it to rendering") + return template_vars + + @app.route("/showDatabaseBXD") def showDatabaseBXD(): # Here it's currently too complicated not to use an fd that is a webqtlFormData @@ -35,11 +53,14 @@ def showDatabaseBXD(): print("showDatabaseBXD template_vars:", pf(template_vars.__dict__)) return render_template("trait_data_and_analysis.html", **template_vars.__dict__) -#@app.route("/data_sharing") -def data_sharing(): - print("In data_sharing") + + +# Todo: Can we simplify this? -Sam +def sharing_info_page(): + print("In sharing_info_page") fd = webqtlFormData.webqtlFormData(request.args) print("Have fd") + print("SharingInfoPage is:", SharingInfoPage) template_vars = SharingInfoPage.SharingInfoPage(fd) print("Made it to rendering") - return render_template("data_sharing.html", **template_vars.__dict__) + return template_vars -- cgit v1.2.3 From d726a9e8299477a7cf2d3433d5f80c6e02a3df50 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Wed, 4 Jul 2012 22:48:53 -0400 Subject: Before making checkmarks the default --- .../new/javascript/trait_data_and_analysis.coffee | 40 ++++------------------ .../new/javascript/trait_data_and_analysis.js | 39 +++++---------------- 2 files changed, 16 insertions(+), 63 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee index d3b1051d..63d327b8 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee @@ -3,70 +3,44 @@ console.log("start_b") isNumber = (o) -> return ! isNaN (o-0) && o != null -console.log("isNumber 7:", isNumber(7)) -console.log("isNumber 13.1:", isNumber(13.1)) -console.log("isNumber x:", isNumber("x")) -console.log("isNumber '9':", isNumber('9')) -console.log("isNumber:", isNumber()) - - $ -> hide_tabs = (start) -> for x in [start..10] $("#stats_tabs" + x).hide() - console.log("hidden:", x) - console.log("start_a") hide_tabs(1) - console.log("hidden?") - # Changes stats table between all, bxd only and non-bxd, etc. stats_mdp_change = -> - console.log("In stats_mdp_change") selected = $(this).val() - console.log("Change was:", selected) hide_tabs(0) $("#stats_tabs" + selected).show() $(".stats_mdp").change(stats_mdp_change) - console.log("tape") - mean = (the_values)-> total = 0 total += value for value in the_values - console.log("yeap") - console.log(total) the_mean = total / the_values.length - return the_mean.toFixed(2) - + the_mean = the_mean.toFixed(2) + current_mean = parseFloat($("#mean_value").html).toFixed(2) + if the_mean != current_mean + $("#mean_value").html(the_mean).effect("highlight") edit_data_change = -> - console.log("In edit_data_change") the_values = [] - #console.log($(this)) - #$(this).each (counter, element) => - # #console.log("counter is:" + counter) - # console.log("element is:") - # console.log(element) - console.log("foo") values = $('#primary').find(".edit_strain_value") - console.log("values are:", values) + #console.log("values are:", values) for value in values - console.log(value) real_value = $(value).val() - #if real_value - console.log(real_value) + console.log("parent is:", $(value).closest("tr")) if isNumber(real_value) and real_value != "" the_values.push(parseFloat(real_value)) - console.log(the_values) the_mean = mean(the_values) - console.log(the_mean) - $("#mean_value").html(the_mean) + $('#primary').change(edit_data_change) console.log("loaded") diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js index eecc630f..c7fc428e 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js @@ -8,72 +8,51 @@ return !isNaN((o - 0) && o !== null); }; - console.log("isNumber 7:", isNumber(7)); - - console.log("isNumber 13.1:", isNumber(13.1)); - - console.log("isNumber x:", isNumber("x")); - - console.log("isNumber '9':", isNumber('9')); - - console.log("isNumber:", isNumber()); - $(function() { var edit_data_change, hide_tabs, mean, stats_mdp_change; hide_tabs = function(start) { var x, _i, _results; _results = []; for (x = _i = start; start <= 10 ? _i <= 10 : _i >= 10; x = start <= 10 ? ++_i : --_i) { - $("#stats_tabs" + x).hide(); - _results.push(console.log("hidden:", x)); + _results.push($("#stats_tabs" + x).hide()); } return _results; }; - console.log("start_a"); hide_tabs(1); - console.log("hidden?"); stats_mdp_change = function() { var selected; - console.log("In stats_mdp_change"); selected = $(this).val(); - console.log("Change was:", selected); hide_tabs(0); return $("#stats_tabs" + selected).show(); }; $(".stats_mdp").change(stats_mdp_change); - console.log("tape"); mean = function(the_values) { - var the_mean, total, value, _i, _len; + var current_mean, the_mean, total, value, _i, _len; total = 0; for (_i = 0, _len = the_values.length; _i < _len; _i++) { value = the_values[_i]; total += value; } - console.log("yeap"); - console.log(total); the_mean = total / the_values.length; - return the_mean.toFixed(2); + the_mean = the_mean.toFixed(2); + current_mean = parseFloat($("#mean_value").html).toFixed(2); + if (the_mean !== current_mean) { + return $("#mean_value").html(the_mean).effect("highlight"); + } }; edit_data_change = function() { var real_value, the_mean, the_values, value, values, _i, _len; - console.log("In edit_data_change"); the_values = []; - console.log("foo"); values = $('#primary').find(".edit_strain_value"); - console.log("values are:", values); for (_i = 0, _len = values.length; _i < _len; _i++) { value = values[_i]; - console.log(value); real_value = $(value).val(); - console.log(real_value); + console.log("parent is:", $(value).closest("tr")); if (isNumber(real_value) && real_value !== "") { the_values.push(parseFloat(real_value)); } } - console.log(the_values); - the_mean = mean(the_values); - console.log(the_mean); - return $("#mean_value").html(the_mean); + return the_mean = mean(the_values); }; $('#primary').change(edit_data_change); return console.log("loaded"); -- cgit v1.2.3 From 30758c9aa11f494c6e566a9e7775fe0f0e27f45a Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Wed, 4 Jul 2012 23:58:55 -0400 Subject: Before rethinking tables --- .../new/javascript/trait_data_and_analysis.coffee | 18 +++++++++++++++-- .../new/javascript/trait_data_and_analysis.js | 23 +++++++++++++++++----- .../wqflask/templates/trait_data_and_analysis.html | 6 +++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee index 63d327b8..380d0a5a 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.coffee @@ -29,6 +29,14 @@ $ -> if the_mean != current_mean $("#mean_value").html(the_mean).effect("highlight") + n_of_samples = the_values.length + current_n_of_samples = $("#n_of_samples_value").html() + console.log("cnos:", current_n_of_samples) + console.log("n_of_samples:", n_of_samples) + if n_of_samples != current_n_of_samples + $("#n_of_samples_value").html(current_n_of_samples).effect("highlight") + + edit_data_change = -> the_values = [] @@ -36,10 +44,16 @@ $ -> #console.log("values are:", values) for value in values real_value = $(value).val() - console.log("parent is:", $(value).closest("tr")) + #console.log("parent is:", $(value).closest("tr")) + row = $(value).closest("tr") + checkbox = $(row).find(".edit_strain_checkbox") + checked = $(checkbox).attr('checked') + if not checked + console.log("Not checked") + continue if isNumber(real_value) and real_value != "" the_values.push(parseFloat(real_value)) - the_mean = mean(the_values) + mean(the_values) $('#primary').change(edit_data_change) diff --git a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js index c7fc428e..1ea224b4 100644 --- a/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js +++ b/wqflask/wqflask/static/new/javascript/trait_data_and_analysis.js @@ -27,7 +27,7 @@ }; $(".stats_mdp").change(stats_mdp_change); mean = function(the_values) { - var current_mean, the_mean, total, value, _i, _len; + var current_mean, current_n_of_samples, n_of_samples, the_mean, total, value, _i, _len; total = 0; for (_i = 0, _len = the_values.length; _i < _len; _i++) { value = the_values[_i]; @@ -37,22 +37,35 @@ the_mean = the_mean.toFixed(2); current_mean = parseFloat($("#mean_value").html).toFixed(2); if (the_mean !== current_mean) { - return $("#mean_value").html(the_mean).effect("highlight"); + $("#mean_value").html(the_mean).effect("highlight"); + } + n_of_samples = the_values.length; + current_n_of_samples = $("#n_of_samples_value").html(); + console.log("cnos:", current_n_of_samples); + console.log("n_of_samples:", n_of_samples); + if (n_of_samples !== current_n_of_samples) { + return $("#n_of_samples_value").html(current_n_of_samples).effect("highlight"); } }; edit_data_change = function() { - var real_value, the_mean, the_values, value, values, _i, _len; + var checkbox, checked, real_value, row, the_values, value, values, _i, _len; the_values = []; values = $('#primary').find(".edit_strain_value"); for (_i = 0, _len = values.length; _i < _len; _i++) { value = values[_i]; real_value = $(value).val(); - console.log("parent is:", $(value).closest("tr")); + row = $(value).closest("tr"); + checkbox = $(row).find(".edit_strain_checkbox"); + checked = $(checkbox).attr('checked'); + if (!checked) { + console.log("Not checked"); + continue; + } if (isNumber(real_value) && real_value !== "") { the_values.push(parseFloat(real_value)); } } - return the_mean = mean(the_values); + return mean(the_values); }; $('#primary').change(edit_data_change); return console.log("loaded"); diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index c27ab092..1916a10c 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -289,7 +289,7 @@ - + @@ -301,7 +301,7 @@ - + @@ -3066,7 +3066,7 @@ - + + - + {% endblock %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 55d6ffe2..caad811f 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -22,12 +22,22 @@ def index_page(): return render_template("index_page.html") +@app.route("/data_sharing") +def data_sharing(): + print("In data_sharing") + fd = webqtlFormData.webqtlFormData(request.args) + print("1Have fd") + template_vars = SharingInfoPage.SharingInfoPage(fd) + print("1 Made it to rendering") + return template_vars + @app.route("/search") def search(): if 'info_database' in request.args: print("Going to sharing_info_page") template_vars = sharing_info_page() if template_vars.redirect_url: + print("Going to redirect") return flask.redirect(template_vars.redirect_url) else: return render_template("data_sharing.html", **template_vars.__dict__) @@ -35,14 +45,7 @@ def search(): the_search = search_results.SearchResultPage(request.args) return render_template("search_result_page.html", **the_search.__dict__) -@app.route("/data_sharing") -def data_sharing(): - print("In data_sharing") - fd = webqtlFormData.webqtlFormData(request.args) - print("Have fd") - template_vars = SharingInfoPage.SharingInfoPage(fd) - print("Made it to rendering") - return template_vars + @app.route("/showDatabaseBXD") @@ -59,8 +62,7 @@ def showDatabaseBXD(): def sharing_info_page(): print("In sharing_info_page") fd = webqtlFormData.webqtlFormData(request.args) - print("Have fd") - print("SharingInfoPage is:", SharingInfoPage) + print("2Have fd") template_vars = SharingInfoPage.SharingInfoPage(fd) - print("Made it to rendering") + print("2 Made it to rendering") return template_vars -- cgit v1.2.3 From d4085c3f85e392427067d2c004a0b15449fbc0d9 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 5 Jul 2012 16:53:51 -0400 Subject: Added DataTables --- .../new/packages/DataTables/css/demo_page.css | 107 + .../new/packages/DataTables/css/demo_table.css | 576 + .../new/packages/DataTables/css/demo_table_jui.css | 526 + .../packages/DataTables/css/jquery.dataTables.css | 220 + .../css/jquery.dataTables_themeroller.css | 245 + .../packages/DataTables/images/Sorting icons.psd | Bin 0 -> 27490 bytes .../packages/DataTables/images/back_disabled.png | Bin 0 -> 1361 bytes .../packages/DataTables/images/back_enabled.png | Bin 0 -> 1379 bytes .../DataTables/images/back_enabled_hover.png | Bin 0 -> 1375 bytes .../new/packages/DataTables/images/favicon.ico | Bin 0 -> 894 bytes .../DataTables/images/forward_disabled.png | Bin 0 -> 1363 bytes .../packages/DataTables/images/forward_enabled.png | Bin 0 -> 1380 bytes .../DataTables/images/forward_enabled_hover.png | Bin 0 -> 1379 bytes .../new/packages/DataTables/images/sort_asc.png | Bin 0 -> 1118 bytes .../DataTables/images/sort_asc_disabled.png | Bin 0 -> 1050 bytes .../new/packages/DataTables/images/sort_both.png | Bin 0 -> 1136 bytes .../new/packages/DataTables/images/sort_desc.png | Bin 0 -> 1127 bytes .../DataTables/images/sort_desc_disabled.png | Bin 0 -> 1045 bytes .../packages/DataTables/js/jquery.dataTables.js | 11863 +++++++++++++++++++ .../DataTables/js/jquery.dataTables.min.js | 154 + .../static/new/packages/DataTables/js/jquery.js | 4 + .../new/packages/DataTables/src/DataTables.js | 259 + .../packages/DataTables/src/api/api.internal.js | 128 + .../new/packages/DataTables/src/api/api.methods.js | 1276 ++ .../new/packages/DataTables/src/api/api.static.js | 98 + .../new/packages/DataTables/src/core/core.ajax.js | 185 + .../packages/DataTables/src/core/core.columns.js | 365 + .../DataTables/src/core/core.constructor.js | 439 + .../new/packages/DataTables/src/core/core.data.js | 546 + .../new/packages/DataTables/src/core/core.draw.js | 788 ++ .../packages/DataTables/src/core/core.filter.js | 405 + .../new/packages/DataTables/src/core/core.info.js | 117 + .../new/packages/DataTables/src/core/core.init.js | 153 + .../packages/DataTables/src/core/core.length.js | 122 + .../new/packages/DataTables/src/core/core.page.js | 119 + .../DataTables/src/core/core.processing.js | 44 + .../packages/DataTables/src/core/core.scrolling.js | 495 + .../packages/DataTables/src/core/core.sizing.js | 405 + .../new/packages/DataTables/src/core/core.sort.js | 460 + .../new/packages/DataTables/src/core/core.state.js | 201 + .../packages/DataTables/src/core/core.support.js | 316 + .../new/packages/DataTables/src/ext/ext.classes.js | 112 + .../new/packages/DataTables/src/ext/ext.paging.js | 257 + .../new/packages/DataTables/src/ext/ext.sorting.js | 86 + .../new/packages/DataTables/src/ext/ext.types.js | 88 + .../packages/DataTables/src/model/model.column.js | 248 + .../DataTables/src/model/model.defaults.columns.js | 737 ++ .../DataTables/src/model/model.defaults.js | 1944 +++ .../new/packages/DataTables/src/model/model.ext.js | 528 + .../new/packages/DataTables/src/model/model.row.js | 64 + .../packages/DataTables/src/model/model.search.js | 40 + .../DataTables/src/model/model.settings.js | 868 ++ .../packages/DataTables/unit_testing/controller.js | 94 + .../DataTables/unit_testing/controller.php | 100 + .../packages/DataTables/unit_testing/index.html | 7 + .../DataTables/unit_testing/performance/draw.html | 482 + .../DataTables/unit_testing/performance/large.php | 108 + .../DataTables/unit_testing/performance/page.html | 477 + .../DataTables/unit_testing/performance/sort.html | 477 + .../unit_testing/templates/-complex_header.php | 469 + .../DataTables/unit_testing/templates/2512.php | 464 + .../DataTables/unit_testing/templates/6776.php | 116 + .../unit_testing/templates/complex_header_2.php | 485 + .../unit_testing/templates/deferred_table.php | 132 + .../DataTables/unit_testing/templates/dom_data.php | 465 + .../unit_testing/templates/dom_data_th.php | 465 + .../templates/dom_data_two_headers.php | 472 + .../unit_testing/templates/dymanic_table.php | 45 + .../unit_testing/templates/empty_table.php | 55 + .../unit_testing/templates/html_table.php | 66 + .../DataTables/unit_testing/templates/js_data.php | 124 + .../unit_testing/templates/js_data_mixed_types.php | 124 + .../unit_testing/templates/two_tables.php | 227 + .../unit_testing/tests/1_dom/_zero_config.js | 437 + .../tests_onhold/1_dom/-complex_header.js | 52 + .../unit_testing/tests_onhold/1_dom/-iDraw.js | 41 + .../unit_testing/tests_onhold/1_dom/2512.js | 17 + .../unit_testing/tests_onhold/1_dom/2530-2.js | 15 + .../unit_testing/tests_onhold/1_dom/2530.js | 29 + .../unit_testing/tests_onhold/1_dom/2569.js | 36 + .../unit_testing/tests_onhold/1_dom/2600.js | 44 + .../unit_testing/tests_onhold/1_dom/2608.js | 54 + .../unit_testing/tests_onhold/1_dom/2635.js | 40 + .../tests_onhold/1_dom/2746-stable-sort.js | 199 + .../unit_testing/tests_onhold/1_dom/2799.js | 14 + .../tests_onhold/1_dom/2840-restore-table-width.js | 19 + .../tests_onhold/1_dom/2914-state-save-sort.js | 39 + .../tests_onhold/1_dom/5396-fnUpdate-arrays.js | 103 + .../1_dom/5508-xscroll-zero-content.js | 23 + .../1_dom/6776-scrolling-table-grows.js | 64 + .../tests_onhold/1_dom/_zero_config.js | 437 + .../unit_testing/tests_onhold/1_dom/aaSorting.js | 183 + .../tests_onhold/1_dom/aaSortingFixed.js | 60 + .../tests_onhold/1_dom/aoColumns.bSearchable.js | 67 + .../tests_onhold/1_dom/aoColumns.bSortable.js | 105 + .../tests_onhold/1_dom/aoColumns.bUseRendered.js | 145 + .../tests_onhold/1_dom/aoColumns.bVisible.js | 132 + .../tests_onhold/1_dom/aoColumns.bVisible2.js | 268 + .../tests_onhold/1_dom/aoColumns.fnRender.js | 176 + .../tests_onhold/1_dom/aoColumns.iDataSort.js | 88 + .../tests_onhold/1_dom/aoColumns.sClass.js | 111 + .../tests_onhold/1_dom/aoColumns.sName.js | 27 + .../tests_onhold/1_dom/aoColumns.sTitle.js | 78 + .../tests_onhold/1_dom/aoColumns.sWidth.js | 84 + .../tests_onhold/1_dom/aoSearchCols.js | 112 + .../tests_onhold/1_dom/asStripClasses.js | 106 + .../unit_testing/tests_onhold/1_dom/bAutoWidth.js | 138 + .../unit_testing/tests_onhold/1_dom/bFilter.js | 40 + .../tests_onhold/1_dom/bInfiniteScroll.js | 130 + .../unit_testing/tests_onhold/1_dom/bInfo.js | 40 + .../unit_testing/tests_onhold/1_dom/bJQueryUI.js | 40 + .../tests_onhold/1_dom/bLengthChange.js | 71 + .../unit_testing/tests_onhold/1_dom/bPaginate.js | 55 + .../unit_testing/tests_onhold/1_dom/bProcessing.js | 99 + .../unit_testing/tests_onhold/1_dom/bServerSide.js | 18 + .../unit_testing/tests_onhold/1_dom/bSort.js | 101 + .../tests_onhold/1_dom/bSortCellsTop.js | 77 + .../tests_onhold/1_dom/bSortClasses.js | 128 + .../tests_onhold/1_dom/fnCookieCallback.js | 97 + .../tests_onhold/1_dom/fnCreatedCell.js | 151 + .../tests_onhold/1_dom/fnCreatedRow.js | 115 + .../unit_testing/tests_onhold/1_dom/fnDeleteRow.js | 30 + .../tests_onhold/1_dom/fnDrawCallback.js | 80 + .../unit_testing/tests_onhold/1_dom/fnFilter.js | 16 + .../tests_onhold/1_dom/fnFooterCallback.js | 227 + .../tests_onhold/1_dom/fnHeaderCallback.js | 227 + .../tests_onhold/1_dom/fnInfoCallback.js | 115 + .../tests_onhold/1_dom/fnInitComplete.js | 94 + .../tests_onhold/1_dom/fnRowCallback.js | 105 + .../tests_onhold/1_dom/fnSetColumnVis.js | 120 + .../tests_onhold/1_dom/fnSetColumnVis2.js | 236 + .../tests_onhold/1_dom/html-autodetect-sort.js | 57 + .../tests_onhold/1_dom/iDisplayLength.js | 76 + .../tests_onhold/1_dom/oLanguage.oPaginate.js | 80 + .../tests_onhold/1_dom/oLanguage.sInfo.js | 109 + .../tests_onhold/1_dom/oLanguage.sInfoEmpty.js | 75 + .../tests_onhold/1_dom/oLanguage.sInfoPostFix.js | 73 + .../tests_onhold/1_dom/oLanguage.sLengthMenu.js | 106 + .../tests_onhold/1_dom/oLanguage.sProcessing.js | 47 + .../tests_onhold/1_dom/oLanguage.sSearch.js | 66 + .../tests_onhold/1_dom/oLanguage.sUrl.js | 59 + .../tests_onhold/1_dom/oLanguage.sZeroRecords.js | 45 + .../unit_testing/tests_onhold/1_dom/oSearch.js | 101 + .../unit_testing/tests_onhold/1_dom/sAjaxSource.js | 18 + .../unit_testing/tests_onhold/1_dom/sDom.js | 319 + .../tests_onhold/1_dom/sPaginationType.js | 122 + .../unit_testing/tests_onhold/1_dom/sScrollXY.js | 63 + .../unit_testing/tests_onhold/1_dom/th_in_body.js | 437 + .../2_js/6872-default-content-missing-props.js | 285 + .../2_js/8549--string-sorting-nonstrings.js | 47 + .../unit_testing/tests_onhold/2_js/_zero_config.js | 440 + .../unit_testing/tests_onhold/2_js/aaSorting.js | 198 + .../tests_onhold/2_js/aaSortingFixed.js | 64 + .../tests_onhold/2_js/aoColumns.bSearchable.js | 71 + .../tests_onhold/2_js/aoColumns.bSortable.js | 109 + .../tests_onhold/2_js/aoColumns.bUseRendered.js | 148 + .../tests_onhold/2_js/aoColumns.bVisible.js | 110 + .../tests_onhold/2_js/aoColumns.fnRender.js | 156 + .../tests_onhold/2_js/aoColumns.iDataSort.js | 90 + .../tests_onhold/2_js/aoColumns.sClass.js | 115 + .../tests_onhold/2_js/aoColumns.sName.js | 28 + .../tests_onhold/2_js/aoColumns.sTitle.js | 82 + .../tests_onhold/2_js/aoColumns.sWidth.js | 87 + .../unit_testing/tests_onhold/2_js/aoSearchCols.js | 119 + .../tests_onhold/2_js/asStripClasses.js | 100 + .../unit_testing/tests_onhold/2_js/bAutoWidth.js | 142 + .../unit_testing/tests_onhold/2_js/bFilter.js | 44 + .../unit_testing/tests_onhold/2_js/bInfo.js | 44 + .../tests_onhold/2_js/bLengthChange.js | 75 + .../unit_testing/tests_onhold/2_js/bPaginate.js | 59 + .../unit_testing/tests_onhold/2_js/bProcessing.js | 103 + .../unit_testing/tests_onhold/2_js/bServerSide.js | 20 + .../unit_testing/tests_onhold/2_js/bSort.js | 99 + .../unit_testing/tests_onhold/2_js/bSortClasses.js | 132 + .../tests_onhold/2_js/fnCreatedCell.js | 158 + .../unit_testing/tests_onhold/2_js/fnCreatedRow.js | 121 + .../tests_onhold/2_js/fnDrawCallback.js | 85 + .../tests_onhold/2_js/fnFooterCallback.js | 240 + .../tests_onhold/2_js/fnHeaderCallback.js | 240 + .../tests_onhold/2_js/fnInitComplete.js | 83 + .../tests_onhold/2_js/fnRowCallback.js | 112 + .../tests_onhold/2_js/iDisplayLength.js | 81 + .../tests_onhold/2_js/js_data_mixed_types.js | 392 + .../tests_onhold/2_js/oLanguage.oPaginate.js | 84 + .../tests_onhold/2_js/oLanguage.sInfo.js | 117 + .../tests_onhold/2_js/oLanguage.sInfoEmpty.js | 79 + .../tests_onhold/2_js/oLanguage.sInfoPostFix.js | 78 + .../tests_onhold/2_js/oLanguage.sLengthMenu.js | 111 + .../tests_onhold/2_js/oLanguage.sProcessing.js | 49 + .../tests_onhold/2_js/oLanguage.sSearch.js | 70 + .../tests_onhold/2_js/oLanguage.sUrl.js | 62 + .../tests_onhold/2_js/oLanguage.sZeroRecords.js | 48 + .../unit_testing/tests_onhold/2_js/oSearch.js | 108 + .../unit_testing/tests_onhold/2_js/sAjaxSource.js | 20 + .../unit_testing/tests_onhold/2_js/sDom.js | 262 + .../tests_onhold/2_js/sPaginationType.js | 125 + .../tests_onhold/3_ajax/_zero_config.js | 440 + .../unit_testing/tests_onhold/3_ajax/aaSorting.js | 198 + .../tests_onhold/3_ajax/aaSortingFixed.js | 67 + .../tests_onhold/3_ajax/aoColumns.bSearchable.js | 76 + .../tests_onhold/3_ajax/aoColumns.bSortable.js | 109 + .../tests_onhold/3_ajax/aoColumns.bUseRendered.js | 148 + .../tests_onhold/3_ajax/aoColumns.bVisible.js | 124 + .../tests_onhold/3_ajax/aoColumns.fnRender.js | 156 + .../tests_onhold/3_ajax/aoColumns.iDataSort.js | 90 + .../tests_onhold/3_ajax/aoColumns.sClass.js | 115 + .../tests_onhold/3_ajax/aoColumns.sName.js | 28 + .../tests_onhold/3_ajax/aoColumns.sTitle.js | 82 + .../tests_onhold/3_ajax/aoColumns.sWidth.js | 87 + .../tests_onhold/3_ajax/aoSearchCols.js | 119 + .../tests_onhold/3_ajax/asStripClasses.js | 105 + .../unit_testing/tests_onhold/3_ajax/bAutoWidth.js | 142 + .../unit_testing/tests_onhold/3_ajax/bFilter.js | 44 + .../unit_testing/tests_onhold/3_ajax/bInfo.js | 44 + .../tests_onhold/3_ajax/bLengthChange.js | 75 + .../unit_testing/tests_onhold/3_ajax/bPaginate.js | 59 + .../tests_onhold/3_ajax/bProcessing.js | 103 + .../tests_onhold/3_ajax/bServerSide.js | 20 + .../unit_testing/tests_onhold/3_ajax/bSort.js | 99 + .../tests_onhold/3_ajax/bSortClasses.js | 132 + .../tests_onhold/3_ajax/fnCreatedCell.js | 183 + .../tests_onhold/3_ajax/fnCreatedRow.js | 142 + .../tests_onhold/3_ajax/fnDrawCallback.js | 98 + .../tests_onhold/3_ajax/fnHeaderCallback.js | 191 + .../tests_onhold/3_ajax/fnInitComplete.js | 100 + .../tests_onhold/3_ajax/fnRowCallback.js | 112 + .../tests_onhold/3_ajax/fnServerData.js | 64 + .../tests_onhold/3_ajax/iDisplayLength.js | 81 + .../tests_onhold/3_ajax/oLanguage.oPaginate.js | 84 + .../tests_onhold/3_ajax/oLanguage.sInfo.js | 117 + .../tests_onhold/3_ajax/oLanguage.sInfoEmpty.js | 79 + .../tests_onhold/3_ajax/oLanguage.sInfoPostFix.js | 78 + .../tests_onhold/3_ajax/oLanguage.sLengthMenu.js | 111 + .../3_ajax/oLanguage.sLoadingRecords.js | 65 + .../tests_onhold/3_ajax/oLanguage.sProcessing.js | 49 + .../tests_onhold/3_ajax/oLanguage.sSearch.js | 70 + .../tests_onhold/3_ajax/oLanguage.sUrl.js | 62 + .../tests_onhold/3_ajax/oLanguage.sZeroRecords.js | 48 + .../unit_testing/tests_onhold/3_ajax/oSearch.js | 108 + .../tests_onhold/3_ajax/sAjaxDataProp.js | 139 + .../tests_onhold/3_ajax/sAjaxDataProp2.js | 139 + .../tests_onhold/3_ajax/sAjaxSource.js | 22 + .../unit_testing/tests_onhold/3_ajax/sDom.js | 262 + .../tests_onhold/3_ajax/sPaginationType.js | 134 + .../tests_onhold/4_server-side/-iDraw.js | 44 + .../tests_onhold/4_server-side/2440.js | 32 + .../tests_onhold/4_server-side/2569.js | 47 + .../tests_onhold/4_server-side/2600.js | 47 + .../tests_onhold/4_server-side/_zero_config.js | 424 + .../tests_onhold/4_server-side/aaSorting.js | 212 + .../tests_onhold/4_server-side/aaSortingFixed.js | 67 + .../4_server-side/aoColumns.bSearchable.js | 25 + .../4_server-side/aoColumns.bSortable.js | 112 + .../4_server-side/aoColumns.bUseRendered.js | 43 + .../4_server-side/aoColumns.bVisible.js | 123 + .../4_server-side/aoColumns.fnRender.js | 162 + .../tests_onhold/4_server-side/aoColumns.sClass.js | 118 + .../tests_onhold/4_server-side/aoColumns.sName.js | 29 + .../tests_onhold/4_server-side/aoColumns.sTitle.js | 85 + .../tests_onhold/4_server-side/aoColumns.sWidth.js | 90 + .../tests_onhold/4_server-side/aoSearchCols.js | 70 + .../tests_onhold/4_server-side/asStripClasses.js | 109 + .../tests_onhold/4_server-side/bAutoWidth.js | 145 + .../tests_onhold/4_server-side/bFilter.js | 47 + .../tests_onhold/4_server-side/bInfiniteScroll.js | 168 + .../tests_onhold/4_server-side/bInfo.js | 47 + .../tests_onhold/4_server-side/bLengthChange.js | 78 + .../tests_onhold/4_server-side/bPaginate.js | 62 + .../tests_onhold/4_server-side/bProcessing.js | 106 + .../tests_onhold/4_server-side/bServerSide.js | 21 + .../tests_onhold/4_server-side/bSort.js | 102 + .../tests_onhold/4_server-side/bSortClasses.js | 135 + .../tests_onhold/4_server-side/fnCreatedCell.js | 190 + .../tests_onhold/4_server-side/fnCreatedRow.js | 148 + .../tests_onhold/4_server-side/fnDrawCallback.js | 89 + .../tests_onhold/4_server-side/fnHeaderCallback.js | 191 + .../tests_onhold/4_server-side/fnInitComplete.js | 89 + .../tests_onhold/4_server-side/fnRowCallback.js | 118 + .../tests_onhold/4_server-side/iDeferLoading.js | 95 + .../tests_onhold/4_server-side/iDisplayLength.js | 85 + .../4_server-side/oLanguage.oPaginate.js | 86 + .../tests_onhold/4_server-side/oLanguage.sInfo.js | 124 + .../4_server-side/oLanguage.sInfoEmpty.js | 82 + .../4_server-side/oLanguage.sInfoPostFix.js | 82 + .../4_server-side/oLanguage.sLengthMenu.js | 115 + .../4_server-side/oLanguage.sProcessing.js | 51 + .../4_server-side/oLanguage.sSearch.js | 73 + .../tests_onhold/4_server-side/oLanguage.sUrl.js | 64 + .../4_server-side/oLanguage.sZeroRecords.js | 58 + .../tests_onhold/4_server-side/oSearch.js | 100 + .../tests_onhold/4_server-side/sAjaxDataProp.js | 146 + .../tests_onhold/4_server-side/sAjaxSource.js | 23 + .../tests_onhold/4_server-side/sDom.js | 269 + .../tests_onhold/4_server-side/sPaginationType.js | 138 + .../tests_onhold/5_ajax_objects/_zero_config.js | 847 ++ .../_zero_config_arrays_subobjects.js | 961 ++ .../5_ajax_objects/_zero_config_deep.js | 1075 ++ .../5_ajax_objects/_zero_config_null_source.js | 458 + .../5_ajax_objects/_zero_config_objects.js | 847 ++ .../_zero_config_objects_subarrays.js | 961 ++ .../tests_onhold/5_ajax_objects/aaSorting.js | 296 + .../tests_onhold/5_ajax_objects/aaSortingFixed.js | 88 + .../5_ajax_objects/aoColumns.bSearchable.js | 83 + .../5_ajax_objects/aoColumns.bSortable.js | 116 + .../5_ajax_objects/aoColumns.bUseRendered.js | 155 + .../5_ajax_objects/aoColumns.bVisible.js | 131 + .../5_ajax_objects/aoColumns.fnRender.js | 177 + .../5_ajax_objects/aoColumns.iDataSort.js | 90 + .../5_ajax_objects/aoColumns.sClass.js | 122 + .../tests_onhold/5_ajax_objects/aoColumns.sName.js | 28 + .../5_ajax_objects/aoColumns.sTitle.js | 89 + .../5_ajax_objects/aoColumns.sWidth.js | 87 + .../tests_onhold/5_ajax_objects/aoSearchCols.js | 161 + .../tests_onhold/5_ajax_objects/asStripClasses.js | 133 + .../tests_onhold/5_ajax_objects/bAutoWidth.js | 163 + .../tests_onhold/5_ajax_objects/bFilter.js | 65 + .../tests_onhold/5_ajax_objects/bInfo.js | 65 + .../tests_onhold/5_ajax_objects/bLengthChange.js | 96 + .../tests_onhold/5_ajax_objects/bPaginate.js | 80 + .../tests_onhold/5_ajax_objects/bProcessing.js | 124 + .../tests_onhold/5_ajax_objects/bServerSide.js | 27 + .../tests_onhold/5_ajax_objects/bSort.js | 120 + .../tests_onhold/5_ajax_objects/bSortClasses.js | 153 + .../tests_onhold/5_ajax_objects/fnDrawCallback.js | 126 + .../5_ajax_objects/fnHeaderCallback.js | 254 + .../tests_onhold/5_ajax_objects/fnInitComplete.js | 135 + .../tests_onhold/5_ajax_objects/fnRowCallback.js | 154 + .../tests_onhold/5_ajax_objects/fnServerData.js | 92 + .../tests_onhold/5_ajax_objects/iDisplayLength.js | 109 + .../5_ajax_objects/oLanguage.oPaginate.js | 98 + .../tests_onhold/5_ajax_objects/oLanguage.sInfo.js | 166 + .../5_ajax_objects/oLanguage.sInfoEmpty.js | 100 + .../5_ajax_objects/oLanguage.sInfoPostFix.js | 106 + .../5_ajax_objects/oLanguage.sLengthMenu.js | 139 + .../5_ajax_objects/oLanguage.sProcessing.js | 63 + .../5_ajax_objects/oLanguage.sSearch.js | 91 + .../tests_onhold/5_ajax_objects/oLanguage.sUrl.js | 76 + .../5_ajax_objects/oLanguage.sZeroRecords.js | 62 + .../tests_onhold/5_ajax_objects/oSearch.js | 150 + .../tests_onhold/5_ajax_objects/sAjaxSource.js | 29 + .../tests_onhold/5_ajax_objects/sDom.js | 311 + .../tests_onhold/5_ajax_objects/sPaginationType.js | 148 + .../6_delayed_rendering/_zero_config.js | 403 + .../tests_onhold/6_delayed_rendering/aaSorting.js | 212 + .../6_delayed_rendering/aaSortingFixed.js | 70 + .../6_delayed_rendering/aoColumns.bSearchable.js | 79 + .../6_delayed_rendering/aoColumns.bSortable.js | 112 + .../6_delayed_rendering/aoColumns.bUseRendered.js | 151 + .../6_delayed_rendering/aoColumns.bVisible.js | 127 + .../6_delayed_rendering/aoColumns.fnRender.js | 190 + .../6_delayed_rendering/aoColumns.iDataSort.js | 92 + .../6_delayed_rendering/aoColumns.sClass.js | 118 + .../6_delayed_rendering/aoColumns.sName.js | 29 + .../6_delayed_rendering/aoColumns.sTitle.js | 85 + .../6_delayed_rendering/aoColumns.sWidth.js | 90 + .../6_delayed_rendering/aoSearchCols.js | 125 + .../6_delayed_rendering/asStripClasses.js | 109 + .../tests_onhold/6_delayed_rendering/bAutoWidth.js | 145 + .../tests_onhold/6_delayed_rendering/bFilter.js | 47 + .../tests_onhold/6_delayed_rendering/bInfo.js | 47 + .../6_delayed_rendering/bLengthChange.js | 78 + .../tests_onhold/6_delayed_rendering/bPaginate.js | 62 + .../6_delayed_rendering/bProcessing.js | 106 + .../6_delayed_rendering/bServerSide.js | 21 + .../tests_onhold/6_delayed_rendering/bSort.js | 102 + .../6_delayed_rendering/bSortClasses.js | 135 + .../6_delayed_rendering/fnDrawCallback.js | 102 + .../6_delayed_rendering/fnHeaderCallback.js | 200 + .../6_delayed_rendering/fnInitComplete.js | 105 + .../6_delayed_rendering/fnRowCallback.js | 118 + .../6_delayed_rendering/fnServerData.js | 68 + .../6_delayed_rendering/iDisplayLength.js | 85 + .../6_delayed_rendering/oLanguage.oPaginate.js | 86 + .../6_delayed_rendering/oLanguage.sInfo.js | 124 + .../6_delayed_rendering/oLanguage.sInfoEmpty.js | 82 + .../6_delayed_rendering/oLanguage.sInfoPostFix.js | 82 + .../6_delayed_rendering/oLanguage.sLengthMenu.js | 115 + .../6_delayed_rendering/oLanguage.sProcessing.js | 51 + .../6_delayed_rendering/oLanguage.sSearch.js | 73 + .../6_delayed_rendering/oLanguage.sUrl.js | 64 + .../6_delayed_rendering/oLanguage.sZeroRecords.js | 50 + .../tests_onhold/6_delayed_rendering/oSearch.js | 114 + .../6_delayed_rendering/sAjaxDataProp.js | 140 + .../6_delayed_rendering/sAjaxDataProp2.js | 140 + .../6_delayed_rendering/sAjaxSource.js | 23 + .../tests_onhold/6_delayed_rendering/sDom.js | 269 + .../6_delayed_rendering/sPaginationType.js | 136 + .../packages/DataTables/unit_testing/unit_test.js | 409 + 388 files changed, 70486 insertions(+) create mode 100644 wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css create mode 100644 wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css create mode 100644 wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css create mode 100644 wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css create mode 100644 wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/Sorting icons.psd create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/back_disabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/back_enabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/back_enabled_hover.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/favicon.ico create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/forward_disabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled_hover.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/sort_asc.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/sort_asc_disabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/sort_both.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/sort_desc.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/images/sort_desc_disabled.png create mode 100644 wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.min.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/js/jquery.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/DataTables.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/api/api.internal.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/api/api.methods.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/api/api.static.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.ajax.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.columns.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.constructor.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.data.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.draw.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.filter.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.info.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.init.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.length.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.page.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.processing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.scrolling.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.sizing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.sort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.state.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/core/core.support.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.classes.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.paging.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.sorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.types.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.column.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.columns.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.ext.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.row.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.search.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/src/model/model.settings.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/index.html create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/draw.html create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/large.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/page.html create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/sort.html create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/-complex_header.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/2512.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/6776.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/complex_header_2.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/deferred_table.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_th.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_two_headers.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dymanic_table.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/empty_table.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/html_table.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data_mixed_types.php create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/two_tables.php create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests/1_dom/_zero_config.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-complex_header.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-iDraw.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2512.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530-2.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2569.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2600.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2608.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2635.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2746-stable-sort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2799.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2840-restore-table-width.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2914-state-save-sort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5396-fnUpdate-arrays.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5508-xscroll-zero-content.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/6776-scrolling-table-grows.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/_zero_config.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSorting.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible2.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.iDataSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sWidth.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoSearchCols.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/asStripClasses.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bAutoWidth.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bFilter.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfiniteScroll.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfo.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bJQueryUI.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bLengthChange.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bPaginate.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bProcessing.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bServerSide.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortCellsTop.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortClasses.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCookieCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedCell.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedRow.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDeleteRow.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDrawCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFilter.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFooterCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnHeaderCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnInfoCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnInitComplete.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnRowCallback.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnSetColumnVis.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnSetColumnVis2.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/html-autodetect-sort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/iDisplayLength.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.oPaginate.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sInfo.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sInfoEmpty.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sInfoPostFix.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sLengthMenu.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sProcessing.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sSearch.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sUrl.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oLanguage.sZeroRecords.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/oSearch.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sAjaxSource.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sDom.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sPaginationType.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sScrollXY.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/th_in_body.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/6872-default-content-missing-props.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/8549--string-sorting-nonstrings.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/_zero_config.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.iDataSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoSearchCols.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/asStripClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bAutoWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bFilter.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bLengthChange.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bServerSide.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSortClasses.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedCell.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedRow.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnDrawCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnFooterCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnHeaderCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnInitComplete.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnRowCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/iDisplayLength.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/js_data_mixed_types.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.oPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sInfoEmpty.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sInfoPostFix.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sLengthMenu.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sUrl.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oLanguage.sZeroRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/oSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/sAjaxSource.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/sDom.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/sPaginationType.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/_zero_config.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aaSorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.iDataSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoColumns.sWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoSearchCols.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/asStripClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bAutoWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bFilter.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bLengthChange.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bServerSide.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSortClasses.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedCell.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedRow.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnDrawCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnHeaderCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnInitComplete.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnRowCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnServerData.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/iDisplayLength.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.oPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoEmpty.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoPostFix.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLengthMenu.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLoadingRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sUrl.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sZeroRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp2.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxSource.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sDom.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sPaginationType.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/-iDraw.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/2440.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/2569.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/2600.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/_zero_config.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aaSorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoColumns.sWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/aoSearchCols.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/asStripClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bAutoWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bFilter.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bInfiniteScroll.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bLengthChange.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bServerSide.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bSort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/bSortClasses.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnCreatedCell.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnCreatedRow.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnDrawCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnHeaderCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnInitComplete.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/fnRowCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/iDeferLoading.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/iDisplayLength.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.oPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sInfoEmpty.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sInfoPostFix.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sLengthMenu.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sUrl.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oLanguage.sZeroRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/oSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/sAjaxDataProp.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/sAjaxSource.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/sDom.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/4_server-side/sPaginationType.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config_arrays_subobjects.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config_deep.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config_null_source.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config_objects.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/_zero_config_objects_subarrays.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aaSorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.iDataSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoColumns.sWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/aoSearchCols.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/asStripClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bAutoWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bFilter.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bLengthChange.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bServerSide.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bSort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/bSortClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/fnDrawCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/fnHeaderCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/fnInitComplete.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/fnRowCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/fnServerData.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/iDisplayLength.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.oPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sInfoEmpty.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sInfoPostFix.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sLengthMenu.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sUrl.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oLanguage.sZeroRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/oSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/sAjaxSource.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/sDom.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/5_ajax_objects/sPaginationType.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/_zero_config.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aaSorting.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aaSortingFixed.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.bSearchable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.bSortable.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.bUseRendered.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.bVisible.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.fnRender.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.iDataSort.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.sClass.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.sName.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.sTitle.js create mode 100755 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoColumns.sWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/aoSearchCols.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/asStripClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bAutoWidth.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bFilter.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bLengthChange.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bServerSide.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bSort.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/bSortClasses.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/fnDrawCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/fnHeaderCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/fnInitComplete.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/fnRowCallback.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/fnServerData.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/iDisplayLength.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.oPaginate.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sInfo.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sInfoEmpty.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sInfoPostFix.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sLengthMenu.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sProcessing.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sUrl.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oLanguage.sZeroRecords.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/oSearch.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/sAjaxDataProp.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/sAjaxDataProp2.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/sAjaxSource.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/sDom.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/6_delayed_rendering/sPaginationType.js create mode 100644 wqflask/wqflask/static/new/packages/DataTables/unit_testing/unit_test.js diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css new file mode 100644 index 00000000..89c62bb7 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_page.css @@ -0,0 +1,107 @@ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * General page setup + */ +#dt_example { + font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; + margin: 0; + padding: 0; + color: #333; + background-color: #fff; +} + + +#dt_example #container { + width: 800px; + margin: 30px auto; + padding: 0; +} + + +#dt_example #footer { + margin: 50px auto 0 auto; + padding: 0; +} + +#dt_example #demo { + margin: 30px auto 0 auto; +} + +#dt_example .demo_jui { + margin: 30px auto 0 auto; +} + +#dt_example .big { + font-size: 1.3em; + font-weight: bold; + line-height: 1.6em; + color: #4E6CA3; +} + +#dt_example .spacer { + height: 20px; + clear: both; +} + +#dt_example .clear { + clear: both; +} + +#dt_example pre { + padding: 15px; + background-color: #F5F5F5; + border: 1px solid #CCCCCC; +} + +#dt_example h1 { + margin-top: 2em; + font-size: 1.3em; + font-weight: normal; + line-height: 1.6em; + color: #4E6CA3; + border-bottom: 1px solid #B0BED9; + clear: both; +} + +#dt_example h2 { + font-size: 1.2em; + font-weight: normal; + line-height: 1.6em; + color: #4E6CA3; + clear: both; +} + +#dt_example a { + color: #0063DC; + text-decoration: none; +} + +#dt_example a:hover { + text-decoration: underline; +} + +#dt_example ul { + color: #4E6CA3; +} + +.css_right { + float: right; +} + +.css_left { + float: left; +} + +.demo_links { + float: left; + width: 50%; + margin-bottom: 1em; +} + +#demo_info { + padding: 5px; + border: 1px solid #B0BED9; + height: 100px; + width: 100%; + overflow: auto; +} \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css new file mode 100644 index 00000000..f41a0042 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table.css @@ -0,0 +1,576 @@ +/* + * File: demo_table.css + * CVS: $Id$ + * Description: CSS descriptions for DataTables demo pages + * Author: Allan Jardine + * Created: Tue May 12 06:47:22 BST 2009 + * Modified: $Date$ by $Author$ + * Language: CSS + * Project: DataTables + * + * Copyright 2009 Allan Jardine. All Rights Reserved. + * + * *************************************************************************** + * DESCRIPTION + * + * The styles given here are suitable for the demos that are used with the standard DataTables + * distribution (see www.datatables.net). You will most likely wish to modify these styles to + * meet the layout requirements of your site. + * + * Common issues: + * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is + * no conflict between the two pagination types. If you want to use full_numbers pagination + * ensure that you either have "example_alt_pagination" as a body class name, or better yet, + * modify that selector. + * Note that the path used for Images is relative. All images are by default located in + * ../images/ - relative to this CSS file. + */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables features + */ + +.dataTables_wrapper { + position: relative; + clear: both; + zoom: 1; /* Feeling sorry for IE */ +} + +.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 250px; + height: 30px; + margin-left: -125px; + margin-top: -15px; + padding: 14px 0 2px 0; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 14px; + background-color: white; +} + +.dataTables_length { + width: 40%; + float: left; +} + +.dataTables_filter { + width: 50%; + float: right; + text-align: right; +} + +.dataTables_info { + width: 60%; + float: left; +} + +.dataTables_paginate { + float: right; + text-align: right; +} + +/* Pagination nested */ +.paginate_disabled_previous, .paginate_enabled_previous, +.paginate_disabled_next, .paginate_enabled_next { + height: 19px; + float: left; + cursor: pointer; + *cursor: hand; + color: #111 !important; +} +.paginate_disabled_previous:hover, .paginate_enabled_previous:hover, +.paginate_disabled_next:hover, .paginate_enabled_next:hover { + text-decoration: none !important; +} +.paginate_disabled_previous:active, .paginate_enabled_previous:active, +.paginate_disabled_next:active, .paginate_enabled_next:active { + outline: none; +} + +.paginate_disabled_previous, +.paginate_disabled_next { + color: #666 !important; +} +.paginate_disabled_previous, .paginate_enabled_previous { + padding-left: 23px; +} +.paginate_disabled_next, .paginate_enabled_next { + padding-right: 23px; + margin-left: 10px; +} + +.paginate_disabled_previous { + background: url('../images/back_disabled.png') no-repeat top left; +} + +.paginate_enabled_previous { + background: url('../images/back_enabled.png') no-repeat top left; +} +.paginate_enabled_previous:hover { + background: url('../images/back_enabled_hover.png') no-repeat top left; +} + +.paginate_disabled_next { + background: url('../images/forward_disabled.png') no-repeat top right; +} + +.paginate_enabled_next { + background: url('../images/forward_enabled.png') no-repeat top right; +} +.paginate_enabled_next:hover { + background: url('../images/forward_enabled_hover.png') no-repeat top right; +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables display + */ +table.display { + margin: 0 auto; + clear: both; + width: 100%; + + /* Note Firefox 3.5 and before have a bug with border-collapse + * ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 ) + * border-spacing: 0; is one possible option. Conditional-css.com is + * useful for this kind of thing + * + * Further note IE 6/7 has problems when calculating widths with border width. + * It subtracts one px relative to the other browsers from the first column, and + * adds one to the end... + * + * If you want that effect I'd suggest setting a border-top/left on th/td's and + * then filling in the gaps with other borders. + */ +} + +table.display thead th { + padding: 3px 18px 3px 10px; + border-bottom: 1px solid black; + font-weight: bold; + cursor: pointer; + * cursor: hand; +} + +table.display tfoot th { + padding: 3px 18px 3px 10px; + border-top: 1px solid black; + font-weight: bold; +} + +table.display tr.heading2 td { + border-bottom: 1px solid #aaa; +} + +table.display td { + padding: 3px 10px; +} + +table.display td.center { + text-align: center; +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables sorting + */ + +.sorting_asc { + background: url('../images/sort_asc.png') no-repeat center right; +} + +.sorting_desc { + background: url('../images/sort_desc.png') no-repeat center right; +} + +.sorting { + background: url('../images/sort_both.png') no-repeat center right; +} + +.sorting_asc_disabled { + background: url('../images/sort_asc_disabled.png') no-repeat center right; +} + +.sorting_desc_disabled { + background: url('../images/sort_desc_disabled.png') no-repeat center right; +} + +th:active { + outline: none; +} + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables row classes + */ +table.display tr.odd.gradeA { + background-color: #ddffdd; +} + +table.display tr.even.gradeA { + background-color: #eeffee; +} + +table.display tr.odd.gradeC { + background-color: #ddddff; +} + +table.display tr.even.gradeC { + background-color: #eeeeff; +} + +table.display tr.odd.gradeX { + background-color: #ffdddd; +} + +table.display tr.even.gradeX { + background-color: #ffeeee; +} + +table.display tr.odd.gradeU { + background-color: #ddd; +} + +table.display tr.even.gradeU { + background-color: #eee; +} + + +tr.odd { + background-color: #E2E4FF; +} + +tr.even { + background-color: white; +} + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Misc + */ +.dataTables_scroll { + clear: both; +} + +.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} + +.top, .bottom { + padding: 15px; + background-color: #F5F5F5; + border: 1px solid #CCCCCC; +} + +.top .dataTables_info { + float: none; +} + +.clear { + clear: both; +} + +.dataTables_empty { + text-align: center; +} + +tfoot input { + margin: 0.5em 0; + width: 100%; + color: #444; +} + +tfoot input.search_init { + color: #999; +} + +td.group { + background-color: #d1cfd0; + border-bottom: 2px solid #A19B9E; + border-top: 2px solid #A19B9E; +} + +td.details { + background-color: #d1cfd0; + border: 2px solid #A19B9E; +} + + +.example_alt_pagination div.dataTables_info { + width: 40%; +} + +.paging_full_numbers { + width: 400px; + height: 22px; + line-height: 22px; +} + +.paging_full_numbers a:active { + outline: none +} + +.paging_full_numbers a:hover { + text-decoration: none; +} + +.paging_full_numbers a.paginate_button, + .paging_full_numbers a.paginate_active { + border: 1px solid #aaa; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + padding: 2px 5px; + margin: 0 3px; + cursor: pointer; + *cursor: hand; + color: #333 !important; +} + +.paging_full_numbers a.paginate_button { + background-color: #ddd; +} + +.paging_full_numbers a.paginate_button:hover { + background-color: #ccc; + text-decoration: none !important; +} + +.paging_full_numbers a.paginate_active { + background-color: #99B3FF; +} + +table.display tr.even.row_selected td { + background-color: #B0BED9; +} + +table.display tr.odd.row_selected td { + background-color: #9FAFD1; +} + + +/* + * Sorting classes for columns + */ +/* For the standard odd/even */ +tr.odd td.sorting_1 { + background-color: #D3D6FF; +} + +tr.odd td.sorting_2 { + background-color: #DADCFF; +} + +tr.odd td.sorting_3 { + background-color: #E0E2FF; +} + +tr.even td.sorting_1 { + background-color: #EAEBFF; +} + +tr.even td.sorting_2 { + background-color: #F2F3FF; +} + +tr.even td.sorting_3 { + background-color: #F9F9FF; +} + + +/* For the Conditional-CSS grading rows */ +/* + Colour calculations (based off the main row colours) + Level 1: + dd > c4 + ee > d5 + Level 2: + dd > d1 + ee > e2 + */ +tr.odd.gradeA td.sorting_1 { + background-color: #c4ffc4; +} + +tr.odd.gradeA td.sorting_2 { + background-color: #d1ffd1; +} + +tr.odd.gradeA td.sorting_3 { + background-color: #d1ffd1; +} + +tr.even.gradeA td.sorting_1 { + background-color: #d5ffd5; +} + +tr.even.gradeA td.sorting_2 { + background-color: #e2ffe2; +} + +tr.even.gradeA td.sorting_3 { + background-color: #e2ffe2; +} + +tr.odd.gradeC td.sorting_1 { + background-color: #c4c4ff; +} + +tr.odd.gradeC td.sorting_2 { + background-color: #d1d1ff; +} + +tr.odd.gradeC td.sorting_3 { + background-color: #d1d1ff; +} + +tr.even.gradeC td.sorting_1 { + background-color: #d5d5ff; +} + +tr.even.gradeC td.sorting_2 { + background-color: #e2e2ff; +} + +tr.even.gradeC td.sorting_3 { + background-color: #e2e2ff; +} + +tr.odd.gradeX td.sorting_1 { + background-color: #ffc4c4; +} + +tr.odd.gradeX td.sorting_2 { + background-color: #ffd1d1; +} + +tr.odd.gradeX td.sorting_3 { + background-color: #ffd1d1; +} + +tr.even.gradeX td.sorting_1 { + background-color: #ffd5d5; +} + +tr.even.gradeX td.sorting_2 { + background-color: #ffe2e2; +} + +tr.even.gradeX td.sorting_3 { + background-color: #ffe2e2; +} + +tr.odd.gradeU td.sorting_1 { + background-color: #c4c4c4; +} + +tr.odd.gradeU td.sorting_2 { + background-color: #d1d1d1; +} + +tr.odd.gradeU td.sorting_3 { + background-color: #d1d1d1; +} + +tr.even.gradeU td.sorting_1 { + background-color: #d5d5d5; +} + +tr.even.gradeU td.sorting_2 { + background-color: #e2e2e2; +} + +tr.even.gradeU td.sorting_3 { + background-color: #e2e2e2; +} + + +/* + * Row highlighting example + */ +.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted { + background-color: #ECFFB3; +} + +.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted { + background-color: #E6FF99; +} + +.ex_highlight_row #example tr.even:hover { + background-color: #ECFFB3; +} + +.ex_highlight_row #example tr.even:hover td.sorting_1 { + background-color: #DDFF75; +} + +.ex_highlight_row #example tr.even:hover td.sorting_2 { + background-color: #E7FF9E; +} + +.ex_highlight_row #example tr.even:hover td.sorting_3 { + background-color: #E2FF89; +} + +.ex_highlight_row #example tr.odd:hover { + background-color: #E6FF99; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_1 { + background-color: #D6FF5C; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_2 { + background-color: #E0FF84; +} + +.ex_highlight_row #example tr.odd:hover td.sorting_3 { + background-color: #DBFF70; +} + + +/* + * KeyTable + */ +table.KeyTable td { + border: 3px solid transparent; +} + +table.KeyTable td.focus { + border: 3px solid #3366FF; +} + +table.display tr.gradeA { + background-color: #eeffee; +} + +table.display tr.gradeC { + background-color: #ddddff; +} + +table.display tr.gradeX { + background-color: #ffdddd; +} + +table.display tr.gradeU { + background-color: #ddd; +} + +div.box { + height: 100px; + padding: 10px; + overflow: auto; + border: 1px solid #8080FF; + background-color: #E5E5FF; +} diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css new file mode 100644 index 00000000..de7c8426 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/css/demo_table_jui.css @@ -0,0 +1,526 @@ +/* + * File: demo_table_jui.css + * CVS: $Id$ + * Description: CSS descriptions for DataTables demo pages + * Author: Allan Jardine + * Created: Tue May 12 06:47:22 BST 2009 + * Modified: $Date$ by $Author$ + * Language: CSS + * Project: DataTables + * + * Copyright 2009 Allan Jardine. All Rights Reserved. + * + * *************************************************************************** + * DESCRIPTION + * + * The styles given here are suitable for the demos that are used with the standard DataTables + * distribution (see www.datatables.net). You will most likely wish to modify these styles to + * meet the layout requirements of your site. + * + * Common issues: + * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is + * no conflict between the two pagination types. If you want to use full_numbers pagination + * ensure that you either have "example_alt_pagination" as a body class name, or better yet, + * modify that selector. + * Note that the path used for Images is relative. All images are by default located in + * ../images/ - relative to this CSS file. + */ + + +/* + * jQuery UI specific styling + */ + +.paging_two_button .ui-button { + float: left; + cursor: pointer; + * cursor: hand; +} + +.paging_full_numbers .ui-button { + padding: 2px 6px; + margin: 0; + cursor: pointer; + * cursor: hand; + color: #333 !important; +} + +.dataTables_paginate .ui-button { + margin-right: -0.1em !important; +} + +.paging_full_numbers { + width: 350px !important; +} + +.dataTables_wrapper .ui-toolbar { + padding: 5px; +} + +.dataTables_paginate { + width: auto; +} + +.dataTables_info { + padding-top: 3px; +} + +table.display thead th { + padding: 3px 0px 3px 10px; + cursor: pointer; + * cursor: hand; +} + +div.dataTables_wrapper .ui-widget-header { + font-weight: normal; +} + + +/* + * Sort arrow icon positioning + */ +table.display thead th div.DataTables_sort_wrapper { + position: relative; + padding-right: 20px; + padding-right: 20px; +} + +table.display thead th div.DataTables_sort_wrapper span { + position: absolute; + top: 50%; + margin-top: -8px; + right: 0; +} + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Everything below this line is the same as demo_table.css. This file is + * required for 'cleanliness' of the markup + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables features + */ + +.dataTables_wrapper { + position: relative; + clear: both; +} + +.dataTables_processing { + position: absolute; + top: 0px; + left: 50%; + width: 250px; + margin-left: -125px; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 11px; + padding: 2px 0; +} + +.dataTables_length { + width: 40%; + float: left; +} + +.dataTables_filter { + width: 50%; + float: right; + text-align: right; +} + +.dataTables_info { + width: 50%; + float: left; +} + +.dataTables_paginate { + float: right; + text-align: right; +} + +/* Pagination nested */ +.paginate_disabled_previous, .paginate_enabled_previous, .paginate_disabled_next, .paginate_enabled_next { + height: 19px; + width: 19px; + margin-left: 3px; + float: left; +} + +.paginate_disabled_previous { + background-image: url('../images/back_disabled.jpg'); +} + +.paginate_enabled_previous { + background-image: url('../images/back_enabled.jpg'); +} + +.paginate_disabled_next { + background-image: url('../images/forward_disabled.jpg'); +} + +.paginate_enabled_next { + background-image: url('../images/forward_enabled.jpg'); +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables display + */ +table.display { + margin: 0 auto; + width: 100%; + clear: both; + border-collapse: collapse; +} + +table.display tfoot th { + padding: 3px 0px 3px 10px; + font-weight: bold; + font-weight: normal; +} + +table.display tr.heading2 td { + border-bottom: 1px solid #aaa; +} + +table.display td { + padding: 3px 10px; +} + +table.display td.center { + text-align: center; +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables sorting + */ + +.sorting_asc { + background: url('../images/sort_asc.png') no-repeat center right; +} + +.sorting_desc { + background: url('../images/sort_desc.png') no-repeat center right; +} + +.sorting { + background: url('../images/sort_both.png') no-repeat center right; +} + +.sorting_asc_disabled { + background: url('../images/sort_asc_disabled.png') no-repeat center right; +} + +.sorting_desc_disabled { + background: url('../images/sort_desc_disabled.png') no-repeat center right; +} + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * DataTables row classes + */ +table.display tr.odd.gradeA { + background-color: #ddffdd; +} + +table.display tr.even.gradeA { + background-color: #eeffee; +} + + + + +table.display tr.odd.gradeA { + background-color: #ddffdd; +} + +table.display tr.even.gradeA { + background-color: #eeffee; +} + +table.display tr.odd.gradeC { + background-color: #ddddff; +} + +table.display tr.even.gradeC { + background-color: #eeeeff; +} + +table.display tr.odd.gradeX { + background-color: #ffdddd; +} + +table.display tr.even.gradeX { + background-color: #ffeeee; +} + +table.display tr.odd.gradeU { + background-color: #ddd; +} + +table.display tr.even.gradeU { + background-color: #eee; +} + + +tr.odd { + background-color: #E2E4FF; +} + +tr.even { + background-color: white; +} + + + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Misc + */ +.dataTables_scroll { + clear: both; +} + +.dataTables_scrollBody { + -webkit-overflow-scrolling: touch; +} + +.top, .bottom { + padding: 15px; + background-color: #F5F5F5; + border: 1px solid #CCCCCC; +} + +.top .dataTables_info { + float: none; +} + +.clear { + clear: both; +} + +.dataTables_empty { + text-align: center; +} + +tfoot input { + margin: 0.5em 0; + width: 100%; + color: #444; +} + +tfoot input.search_init { + color: #999; +} + +td.group { + background-color: #d1cfd0; + border-bottom: 2px solid #A19B9E; + border-top: 2px solid #A19B9E; +} + +td.details { + background-color: #d1cfd0; + border: 2px solid #A19B9E; +} + + +.example_alt_pagination div.dataTables_info { + width: 40%; +} + +.paging_full_numbers a.paginate_button, + .paging_full_numbers a.paginate_active { + border: 1px solid #aaa; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + padding: 2px 5px; + margin: 0 3px; + cursor: pointer; + *cursor: hand; + color: #333 !important; +} + +.paging_full_numbers a.paginate_button { + background-color: #ddd; +} + +.paging_full_numbers a.paginate_button:hover { + background-color: #ccc; + text-decoration: none !important; +} + +.paging_full_numbers a.paginate_active { + background-color: #99B3FF; +} + +table.display tr.even.row_selected td { + background-color: #B0BED9; +} + +table.display tr.odd.row_selected td { + background-color: #9FAFD1; +} + + +/* + * Sorting classes for columns + */ +/* For the standard odd/even */ +tr.odd td.sorting_1 { + background-color: #D3D6FF; +} + +tr.odd td.sorting_2 { + background-color: #DADCFF; +} + +tr.odd td.sorting_3 { + background-color: #E0E2FF; +} + +tr.even td.sorting_1 { + background-color: #EAEBFF; +} + +tr.even td.sorting_2 { + background-color: #F2F3FF; +} + +tr.even td.sorting_3 { + background-color: #F9F9FF; +} + + +/* For the Conditional-CSS grading rows */ +/* + Colour calculations (based off the main row colours) + Level 1: + dd > c4 + ee > d5 + Level 2: + dd > d1 + ee > e2 + */ +tr.odd.gradeA td.sorting_1 { + background-color: #c4ffc4; +} + +tr.odd.gradeA td.sorting_2 { + background-color: #d1ffd1; +} + +tr.odd.gradeA td.sorting_3 { + background-color: #d1ffd1; +} + +tr.even.gradeA td.sorting_1 { + background-color: #d5ffd5; +} + +tr.even.gradeA td.sorting_2 { + background-color: #e2ffe2; +} + +tr.even.gradeA td.sorting_3 { + background-color: #e2ffe2; +} + +tr.odd.gradeC td.sorting_1 { + background-color: #c4c4ff; +} + +tr.odd.gradeC td.sorting_2 { + background-color: #d1d1ff; +} + +tr.odd.gradeC td.sorting_3 { + background-color: #d1d1ff; +} + +tr.even.gradeC td.sorting_1 { + background-color: #d5d5ff; +} + +tr.even.gradeC td.sorting_2 { + background-color: #e2e2ff; +} + +tr.even.gradeC td.sorting_3 { + background-color: #e2e2ff; +} + +tr.odd.gradeX td.sorting_1 { + background-color: #ffc4c4; +} + +tr.odd.gradeX td.sorting_2 { + background-color: #ffd1d1; +} + +tr.odd.gradeX td.sorting_3 { + background-color: #ffd1d1; +} + +tr.even.gradeX td.sorting_1 { + background-color: #ffd5d5; +} + +tr.even.gradeX td.sorting_2 { + background-color: #ffe2e2; +} + +tr.even.gradeX td.sorting_3 { + background-color: #ffe2e2; +} + +tr.odd.gradeU td.sorting_1 { + background-color: #c4c4c4; +} + +tr.odd.gradeU td.sorting_2 { + background-color: #d1d1d1; +} + +tr.odd.gradeU td.sorting_3 { + background-color: #d1d1d1; +} + +tr.even.gradeU td.sorting_1 { + background-color: #d5d5d5; +} + +tr.even.gradeU td.sorting_2 { + background-color: #e2e2e2; +} + +tr.even.gradeU td.sorting_3 { + background-color: #e2e2e2; +} + + +/* + * Row highlighting example + */ +.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted { + background-color: #ECFFB3; +} + +.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted { + background-color: #E6FF99; +} \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css new file mode 100644 index 00000000..83df98ea --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables.css @@ -0,0 +1,220 @@ + +/* + * Table + */ +table.dataTable { + margin: 0 auto; + clear: both; + width: 100%; +} + +table.dataTable thead th { + padding: 3px 18px 3px 10px; + border-bottom: 1px solid black; + font-weight: bold; + cursor: pointer; + *cursor: hand; +} + +table.dataTable tfoot th { + padding: 3px 18px 3px 10px; + border-top: 1px solid black; + font-weight: bold; +} + +table.dataTable td { + padding: 3px 10px; +} + +table.dataTable td.center, +table.dataTable td.dataTables_empty { + text-align: center; +} + +table.dataTable tr.odd { background-color: #E2E4FF; } +table.dataTable tr.even { background-color: white; } + +table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } +table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } +table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } +table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } +table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } +table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } + + +/* + * Table wrapper + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; +} + + +/* + * Page length menu + */ +.dataTables_length { + float: left; +} + + +/* + * Filter + */ +.dataTables_filter { + float: right; + text-align: right; +} + + +/* + * Table information + */ +.dataTables_info { + clear: both; + float: left; +} + + +/* + * Pagination + */ +.dataTables_paginate { + float: right; + text-align: right; +} + +/* Two button pagination - previous / next */ +.paginate_disabled_previous, +.paginate_enabled_previous, +.paginate_disabled_next, +.paginate_enabled_next { + height: 19px; + float: left; + cursor: pointer; + *cursor: hand; + color: #111 !important; +} +.paginate_disabled_previous:hover, +.paginate_enabled_previous:hover, +.paginate_disabled_next:hover, +.paginate_enabled_next:hover { + text-decoration: none !important; +} +.paginate_disabled_previous:active, +.paginate_enabled_previous:active, +.paginate_disabled_next:active, +.paginate_enabled_next:active { + outline: none; +} + +.paginate_disabled_previous, +.paginate_disabled_next { + color: #666 !important; +} +.paginate_disabled_previous, +.paginate_enabled_previous { + padding-left: 23px; +} +.paginate_disabled_next, +.paginate_enabled_next { + padding-right: 23px; + margin-left: 10px; +} + +.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; } +.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; } +.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; } + +.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; } +.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; } +.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; } + +/* Full number pagination */ +.paging_full_numbers { + height: 22px; + line-height: 22px; +} +.paging_full_numbers a:active { + outline: none +} +.paging_full_numbers a:hover { + text-decoration: none; +} + +.paging_full_numbers a.paginate_button, +.paging_full_numbers a.paginate_active { + border: 1px solid #aaa; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + padding: 2px 5px; + margin: 0 3px; + cursor: pointer; + *cursor: hand; + color: #333 !important; +} + +.paging_full_numbers a.paginate_button { + background-color: #ddd; +} + +.paging_full_numbers a.paginate_button:hover { + background-color: #ccc; + text-decoration: none !important; +} + +.paging_full_numbers a.paginate_active { + background-color: #99B3FF; +} + + +/* + * Processing indicator + */ +.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 250px; + height: 30px; + margin-left: -125px; + margin-top: -15px; + padding: 14px 0 2px 0; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 14px; + background-color: white; +} + + +/* + * Sorting + */ +.sorting { background: url('../images/sort_both.png') no-repeat center right; } +.sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; } +.sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; } + +.sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } +.sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } + +table.dataTable th:active { + outline: none; +} + + +/* + * Scrolling + */ +.dataTables_scroll { + clear: both; +} + +.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css new file mode 100644 index 00000000..55661c6d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/css/jquery.dataTables_themeroller.css @@ -0,0 +1,245 @@ + + +/* + * Table + */ +table.dataTable { + margin: 0 auto; + clear: both; + width: 100%; + border-collapse: collapse; +} + +table.dataTable thead th { + padding: 3px 0px 3px 10px; + cursor: pointer; + *cursor: hand; +} + +table.dataTable tfoot th { + padding: 3px 10px; +} + +table.dataTable td { + padding: 3px 10px; +} + +table.dataTable td.center, +table.dataTable td.dataTables_empty { + text-align: center; +} + +table.dataTable tr.odd { background-color: #E2E4FF; } +table.dataTable tr.even { background-color: white; } + +table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } +table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } +table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } +table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } +table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } +table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } + + +/* + * Table wrapper + */ +.dataTables_wrapper { + position: relative; + clear: both; + *zoom: 1; +} +.dataTables_wrapper .ui-widget-header { + font-weight: normal; +} +.dataTables_wrapper .ui-toolbar { + padding: 5px; +} + + +/* + * Page length menu + */ +.dataTables_length { + float: left; +} + + +/* + * Filter + */ +.dataTables_filter { + float: right; + text-align: right; +} + + +/* + * Table information + */ +.dataTables_info { + padding-top: 3px; + clear: both; + float: left; +} + + +/* + * Pagination + */ +.dataTables_paginate { + float: right; + text-align: right; +} + +.dataTables_paginate .ui-button { + margin-right: -0.1em !important; +} + +.paging_two_button .ui-button { + float: left; + cursor: pointer; + * cursor: hand; +} + +.paging_full_numbers .ui-button { + padding: 2px 6px; + margin: 0; + cursor: pointer; + * cursor: hand; + color: #333 !important; +} + +/* Two button pagination - previous / next */ +.paginate_disabled_previous, +.paginate_enabled_previous, +.paginate_disabled_next, +.paginate_enabled_next { + height: 19px; + float: left; + cursor: pointer; + *cursor: hand; + color: #111 !important; +} +.paginate_disabled_previous:hover, +.paginate_enabled_previous:hover, +.paginate_disabled_next:hover, +.paginate_enabled_next:hover { + text-decoration: none !important; +} +.paginate_disabled_previous:active, +.paginate_enabled_previous:active, +.paginate_disabled_next:active, +.paginate_enabled_next:active { + outline: none; +} + +.paginate_disabled_previous, +.paginate_disabled_next { + color: #666 !important; +} +.paginate_disabled_previous, +.paginate_enabled_previous { + padding-left: 23px; +} +.paginate_disabled_next, +.paginate_enabled_next { + padding-right: 23px; + margin-left: 10px; +} + +.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; } +.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; } +.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; } + +.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; } +.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; } +.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; } + +/* Full number pagination */ +.paging_full_numbers a:active { + outline: none +} +.paging_full_numbers a:hover { + text-decoration: none; +} + +.paging_full_numbers a.paginate_button, +.paging_full_numbers a.paginate_active { + border: 1px solid #aaa; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + padding: 2px 5px; + margin: 0 3px; + cursor: pointer; + *cursor: hand; + color: #333 !important; +} + +.paging_full_numbers a.paginate_button { + background-color: #ddd; +} + +.paging_full_numbers a.paginate_button:hover { + background-color: #ccc; + text-decoration: none !important; +} + +.paging_full_numbers a.paginate_active { + background-color: #99B3FF; +} + + +/* + * Processing indicator + */ +.dataTables_processing { + position: absolute; + top: 50%; + left: 50%; + width: 250px; + height: 30px; + margin-left: -125px; + margin-top: -15px; + padding: 14px 0 2px 0; + border: 1px solid #ddd; + text-align: center; + color: #999; + font-size: 14px; + background-color: white; +} + + +/* + * Sorting + */ +table.dataTable thead th div.DataTables_sort_wrapper { + position: relative; + padding-right: 20px; + padding-right: 20px; +} + +table.dataTable thead th div.DataTables_sort_wrapper span { + position: absolute; + top: 50%; + margin-top: -8px; + right: 0; +} + +table.dataTable th:active { + outline: none; +} + + +/* + * Scrolling + */ +.dataTables_scroll { + clear: both; +} + +.dataTables_scrollBody { + *margin-top: -1px; + -webkit-overflow-scrolling: touch; +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/Sorting icons.psd b/wqflask/wqflask/static/new/packages/DataTables/images/Sorting icons.psd new file mode 100644 index 00000000..53b2e068 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/Sorting icons.psd differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/back_disabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/back_disabled.png new file mode 100644 index 00000000..881de797 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/back_disabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled.png new file mode 100644 index 00000000..c608682b Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled_hover.png b/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled_hover.png new file mode 100644 index 00000000..d300f106 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/back_enabled_hover.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/favicon.ico b/wqflask/wqflask/static/new/packages/DataTables/images/favicon.ico new file mode 100644 index 00000000..6eeaa2a0 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/favicon.ico differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/forward_disabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/forward_disabled.png new file mode 100644 index 00000000..6a6ded7d Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/forward_disabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled.png new file mode 100644 index 00000000..a4e6b538 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled_hover.png b/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled_hover.png new file mode 100644 index 00000000..fc46c5eb Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/forward_enabled_hover.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc.png b/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc.png new file mode 100644 index 00000000..a88d7975 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc_disabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc_disabled.png new file mode 100644 index 00000000..4e144cf0 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/sort_asc_disabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/sort_both.png b/wqflask/wqflask/static/new/packages/DataTables/images/sort_both.png new file mode 100644 index 00000000..18670406 Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/sort_both.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc.png b/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc.png new file mode 100644 index 00000000..def071ed Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc_disabled.png b/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc_disabled.png new file mode 100644 index 00000000..7824973c Binary files /dev/null and b/wqflask/wqflask/static/new/packages/DataTables/images/sort_desc_disabled.png differ diff --git a/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js b/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js new file mode 100644 index 00000000..ae5d1750 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/js/jquery.dataTables.js @@ -0,0 +1,11863 @@ +/** + * @summary DataTables + * @description Paginate, search and sort HTML tables + * @version 1.9.2 + * @file jquery.dataTables.js + * @author Allan Jardine (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * + * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, available at: + * http://datatables.net/license_gpl2 + * http://datatables.net/license_bsd + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/ + +(/** @lends */function($, window, document, undefined) { + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a + * highly flexible tool, based upon the foundations of progressive + * enhancement, which will add advanced interaction controls to any + * HTML table. For a full list of features please refer to + * DataTables.net. + * + * Note that the DataTable object is not a global variable but is + * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which + * it may be accessed. + * + * @class + * @param {object} [oInit={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.3+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "bPaginate": false, + * "bSort": false + * } ); + * } ); + */ + var DataTable = function( oInit ) + { + + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + var oDefaults = DataTable.defaults.columns; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "sSortingClass": oSettings.oClasses.sSortable, + "sSortingClassJUI": oSettings.oClasses.sSortJUI, + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol + } ); + oSettings.aoColumns.push( oCol ); + + /* Add a column specific filter */ + if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) + { + oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); + } + else + { + var oPre = oSettings.aoPreSearchCols[ iCol ]; + + /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ + if ( oPre.bRegex === undefined ) + { + oPre.bRegex = true; + } + + if ( oPre.bSmart === undefined ) + { + oPre.bSmart = true; + } + + if ( oPre.bCaseInsensitive === undefined ) + { + oPre.bCaseInsensitive = true; + } + } + + /* Use the column options function to initialise classes etc */ + _fnColumnOptions( oSettings, iCol, null ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + if ( oOptions.sType !== undefined ) + { + oCol.sType = oOptions.sType; + oCol._bAutoType = false; + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp ); + oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp ); + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + } + + /* Check that the class assignment is correct for sorting */ + if ( !oCol.bSortable || + ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( oCol.bSortable || + ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + { + oCol.sSortingClass = oSettings.oClasses.sSortable; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; + } + else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableAsc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; + } + else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableDesc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( oSettings ) + { + /* Not interested in doing column width calculation if autowidth is disabled */ + if ( oSettings.oFeatures.bAutoWidth === false ) + { + return false; + } + + _fnCalculateColumnWidths( oSettings ); + for ( var i=0 , iLen=oSettings.aoColumns.length ; i
        {{ loop.index }} - + - {{ strain.strain_name }} + {{ strain.strain_name }} - + - +
        N of Samples{{ sd.N }}{{ sd.N }}
        Median{{ "%2.3f" % sd.traitmedian }}{{ "%2.3f" % sd.traitmedian }}
        {{ loop.index }} - + -- cgit v1.2.3 From 9515b97ae134ab923f935fa66b6a378056d616d0 Mon Sep 17 00:00:00 2001 From: Sam Ockman Date: Thu, 5 Jul 2012 16:53:19 -0400 Subject: Working with Zach --- wqflask/wqflask/show_trait/DataEditingPage.py | 24 ++++++++++++++++++++++ .../wqflask/templates/trait_data_and_analysis.html | 11 +++++----- wqflask/wqflask/views.py | 24 ++++++++++++---------- 3 files changed, 42 insertions(+), 17 deletions(-) diff --git a/wqflask/wqflask/show_trait/DataEditingPage.py b/wqflask/wqflask/show_trait/DataEditingPage.py index b1cf5a32..81bb3a92 100755 --- a/wqflask/wqflask/show_trait/DataEditingPage.py +++ b/wqflask/wqflask/show_trait/DataEditingPage.py @@ -6,6 +6,8 @@ import cPickle from collections import OrderedDict #import pyXLWriter as xl +import yaml + from htmlgen import HTMLgen2 as HT from base import webqtlConfig @@ -210,6 +212,28 @@ class DataEditingPage(templatePage): self.thisTrait = thisTrait self.hddn = hddn + self.basic_table = {} + self.basic_table['rows'] = yaml.load(""" + - N of Samples + - Mean + - Median + - Standard Error (SE) + - Standard Deviation (SD) + - Minimum + - Maximum + - Range (log2) + - Range (fold) + - Interquartile Range + """) + + self.basic_table['columns'] = yaml.load(""" + - All Cases + - BXD Only + - Non-BXD Only + """) + + print(pf(self.basic_table)) + ########################################## ## Function to display header ########################################## diff --git a/wqflask/wqflask/templates/trait_data_and_analysis.html b/wqflask/wqflask/templates/trait_data_and_analysis.html index 1916a10c..0304aa03 100644 --- a/wqflask/wqflask/templates/trait_data_and_analysis.html +++ b/wqflask/wqflask/templates/trait_data_and_analysis.html @@ -258,6 +258,8 @@ //--> +
        +
        @@ -3109,13 +3111,10 @@
        a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
        "+""+"
        ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
        t
        ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
        ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

        ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
        ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
        ","
        "],thead:[1,"","
        "],tr:[2,"","
        "],td:[3,"","
        "],col:[2,"","
        "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
        ","
        "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
        ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/DataTables.js b/wqflask/wqflask/static/new/packages/DataTables/src/DataTables.js new file mode 100644 index 00000000..a72368f8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/DataTables.js @@ -0,0 +1,259 @@ +/** + * @summary DataTables + * @description Paginate, search and sort HTML tables + * @version 1.9.2 + * @file jquery.dataTables.js + * @author Allan Jardine (www.sprymedia.co.uk) + * @contact www.sprymedia.co.uk/contact + * + * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. + * + * This source file is free software, under either the GPL v2 license or a + * BSD style license, available at: + * http://datatables.net/license_gpl2 + * http://datatables.net/license_bsd + * + * This source file is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. + * + * For details please refer to: http://www.datatables.net + */ + +/*jslint evil: true, undef: true, browser: true */ +/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex,_fnInfoMacros*/ + +(/** @lends */function($, window, document, undefined) { + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a + * highly flexible tool, based upon the foundations of progressive + * enhancement, which will add advanced interaction controls to any + * HTML table. For a full list of features please refer to + * DataTables.net. + * + * Note that the DataTable object is not a global variable but is + * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which + * it may be accessed. + * + * @class + * @param {object} [oInit={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.3+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "bPaginate": false, + * "bSort": false + * } ); + * } ); + */ + var DataTable = function( oInit ) + { + require('core.columns.js'); + require('core.data.js'); + require('core.draw.js'); + require('core.ajax.js'); + require('core.filter.js'); + require('core.info.js'); + require('core.init.js'); + require('core.length.js'); + require('core.page.js'); + require('core.processing.js'); + require('core.scrolling.js'); + require('core.sizing.js'); + require('core.sort.js'); + require('core.state.js'); + require('core.support.js'); + + require('api.methods.js'); + require('api.internal.js'); + + var _that = this; + return this.each(function() { + require('core.constructor.js'); + } ); + }; + + require('api.static.js'); + + /** + * Version string for plug-ins to check compatibility. Allowed format is + * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and + * e are optional + * @member + * @type string + * @default Version number + */ + DataTable.version = "1.9.2"; + + /** + * Private data store, containing all of the settings objects that are created for the + * tables on a given page. + * + * Note that the DataTable.settings object is aliased to jQuery.fn.dataTableExt + * through which it may be accessed and manipulated, or jQuery.fn.dataTable.settings. + * @member + * @type array + * @default [] + * @private + */ + DataTable.settings = []; + + /** + * Object models container, for the various models that DataTables has available + * to it. These models define the objects that are used to hold the active state + * and configuration of the table. + * @namespace + */ + DataTable.models = {}; + require('model.ext.js'); + require('model.search.js'); + require('model.row.js'); + require('model.column.js'); + require('model.defaults.js'); + require('model.defaults.columns.js'); + require('model.settings.js'); + + /** + * Extension object for DataTables that is used to provide all extension options. + * + * Note that the DataTable.ext object is available through + * jQuery.fn.dataTable.ext where it may be accessed and manipulated. It is + * also aliased to jQuery.fn.dataTableExt for historic reasons. + * @namespace + * @extends DataTable.models.ext + */ + DataTable.ext = $.extend( true, {}, DataTable.models.ext ); + require('ext.classes.js'); + require('ext.paging.js'); + require('ext.sorting.js'); + require('ext.types.js'); + + // jQuery aliases + $.fn.DataTable = DataTable; + $.fn.dataTable = DataTable; + $.fn.dataTableSettings = DataTable.settings; + $.fn.dataTableExt = DataTable.ext; + + + // Information about events fired by DataTables - for documentation. + /** + * Draw event, fired whenever the table is redrawn on the page, at the same point as + * fnDrawCallback. This may be useful for binding events or performing calculations when + * the table is altered at all. + * @name DataTable#draw + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Filter event, fired when the filtering applied to the table (using the build in global + * global filter, or column filters) is altered. + * @name DataTable#filter + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Page change event, fired when the paging of the table is altered. + * @name DataTable#page + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Sort event, fired when the sorting applied to the table is altered. + * @name DataTable#sort + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * DataTables initialisation complete event, fired when the table is fully drawn, + * including Ajax data loaded, if Ajax data is required. + * @name DataTable#init + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The JSON object request from the server - only + * present if client-side Ajax sourced data is used + */ + + /** + * State save event, fired when the table has changed state a new state save is required. + * This method allows modification of the state saving object prior to actually doing the + * save, including addition or other state properties (for plug-ins) or modification + * of a DataTables core property. + * @name DataTable#stateSaveParams + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The state information to be saved + */ + + /** + * State load event, fired when the table is loading state from the stored data, but + * prior to the settings object being modified by the saved state - allowing modification + * of the saved state is required or loading of state for a plug-in. + * @name DataTable#stateLoadParams + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The saved state information + */ + + /** + * State loaded event, fired when state has been loaded from stored data and the settings + * object has been modified by the loaded data. + * @name DataTable#stateLoaded + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {object} json The saved state information + */ + + /** + * Processing event, fired when DataTables is doing some kind of processing (be it, + * sort, filter or anything else). Can be used to indicate to the end user that + * there is something happening, or that something has finished. + * @name DataTable#processing + * @event + * @param {event} e jQuery event object + * @param {object} oSettings DataTables settings object + * @param {boolean} bShow Flag for if DataTables is doing processing or not + */ + + /** + * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to + * made to the server for new data (note that this trigger is called in fnServerData, + * if you override fnServerData and which to use this event, you need to trigger it in + * you success function). + * @name DataTable#xhr + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ + + /** + * Destroy event, fired when the DataTable is destroyed by calling fnDestroy or passing + * the bDestroy:true parameter in the initialisation object. This can be used to remove + * bound events, added DOM nodes, etc. + * @name DataTable#destroy + * @event + * @param {event} e jQuery event object + * @param {object} o DataTables settings object {@link DataTable.models.oSettings} + */ +}(jQuery, window, document, undefined)); diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/api/api.internal.js b/wqflask/wqflask/static/new/packages/DataTables/src/api/api.internal.js new file mode 100644 index 00000000..1cbc8ee1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/api/api.internal.js @@ -0,0 +1,128 @@ + +/* + * This is really a good bit rubbish this method of exposing the internal methods + * publically... - To be fixed in 2.0 using methods on the prototype + */ + + +/** + * Create a wrapper function for exporting an internal functions to an external API. + * @param {string} sFunc API function name + * @returns {function} wrapped function + * @memberof DataTable#oApi + */ +function _fnExternApiFunc (sFunc) +{ + return function() { + var aArgs = [_fnSettingsFromNode(this[DataTable.ext.iApiIndex])].concat( + Array.prototype.slice.call(arguments) ); + return DataTable.ext.oApi[sFunc].apply( this, aArgs ); + }; +} + + +/** + * Reference to internal functions for use by plug-in developers. Note that these + * methods are references to internal functions and are considered to be private. + * If you use these methods, be aware that they are liable to change between versions + * (check the upgrade notes). + * @namespace + */ +this.oApi = { + "_fnExternApiFunc": _fnExternApiFunc, + "_fnInitialise": _fnInitialise, + "_fnInitComplete": _fnInitComplete, + "_fnLanguageCompat": _fnLanguageCompat, + "_fnAddColumn": _fnAddColumn, + "_fnColumnOptions": _fnColumnOptions, + "_fnAddData": _fnAddData, + "_fnCreateTr": _fnCreateTr, + "_fnGatherData": _fnGatherData, + "_fnBuildHead": _fnBuildHead, + "_fnDrawHead": _fnDrawHead, + "_fnDraw": _fnDraw, + "_fnReDraw": _fnReDraw, + "_fnAjaxUpdate": _fnAjaxUpdate, + "_fnAjaxParameters": _fnAjaxParameters, + "_fnAjaxUpdateDraw": _fnAjaxUpdateDraw, + "_fnServerParams": _fnServerParams, + "_fnAddOptionsHtml": _fnAddOptionsHtml, + "_fnFeatureHtmlTable": _fnFeatureHtmlTable, + "_fnScrollDraw": _fnScrollDraw, + "_fnAdjustColumnSizing": _fnAdjustColumnSizing, + "_fnFeatureHtmlFilter": _fnFeatureHtmlFilter, + "_fnFilterComplete": _fnFilterComplete, + "_fnFilterCustom": _fnFilterCustom, + "_fnFilterColumn": _fnFilterColumn, + "_fnFilter": _fnFilter, + "_fnBuildSearchArray": _fnBuildSearchArray, + "_fnBuildSearchRow": _fnBuildSearchRow, + "_fnFilterCreateSearch": _fnFilterCreateSearch, + "_fnDataToSearch": _fnDataToSearch, + "_fnSort": _fnSort, + "_fnSortAttachListener": _fnSortAttachListener, + "_fnSortingClasses": _fnSortingClasses, + "_fnFeatureHtmlPaginate": _fnFeatureHtmlPaginate, + "_fnPageChange": _fnPageChange, + "_fnFeatureHtmlInfo": _fnFeatureHtmlInfo, + "_fnUpdateInfo": _fnUpdateInfo, + "_fnFeatureHtmlLength": _fnFeatureHtmlLength, + "_fnFeatureHtmlProcessing": _fnFeatureHtmlProcessing, + "_fnProcessingDisplay": _fnProcessingDisplay, + "_fnVisibleToColumnIndex": _fnVisibleToColumnIndex, + "_fnColumnIndexToVisible": _fnColumnIndexToVisible, + "_fnNodeToDataIndex": _fnNodeToDataIndex, + "_fnVisbleColumns": _fnVisbleColumns, + "_fnCalculateEnd": _fnCalculateEnd, + "_fnConvertToWidth": _fnConvertToWidth, + "_fnCalculateColumnWidths": _fnCalculateColumnWidths, + "_fnScrollingWidthAdjust": _fnScrollingWidthAdjust, + "_fnGetWidestNode": _fnGetWidestNode, + "_fnGetMaxLenString": _fnGetMaxLenString, + "_fnStringToCss": _fnStringToCss, + "_fnDetectType": _fnDetectType, + "_fnSettingsFromNode": _fnSettingsFromNode, + "_fnGetDataMaster": _fnGetDataMaster, + "_fnGetTrNodes": _fnGetTrNodes, + "_fnGetTdNodes": _fnGetTdNodes, + "_fnEscapeRegex": _fnEscapeRegex, + "_fnDeleteIndex": _fnDeleteIndex, + "_fnReOrderIndex": _fnReOrderIndex, + "_fnColumnOrdering": _fnColumnOrdering, + "_fnLog": _fnLog, + "_fnClearTable": _fnClearTable, + "_fnSaveState": _fnSaveState, + "_fnLoadState": _fnLoadState, + "_fnCreateCookie": _fnCreateCookie, + "_fnReadCookie": _fnReadCookie, + "_fnDetectHeader": _fnDetectHeader, + "_fnGetUniqueThs": _fnGetUniqueThs, + "_fnScrollBarWidth": _fnScrollBarWidth, + "_fnApplyToChildren": _fnApplyToChildren, + "_fnMap": _fnMap, + "_fnGetRowData": _fnGetRowData, + "_fnGetCellData": _fnGetCellData, + "_fnSetCellData": _fnSetCellData, + "_fnGetObjectDataFn": _fnGetObjectDataFn, + "_fnSetObjectDataFn": _fnSetObjectDataFn, + "_fnApplyColumnDefs": _fnApplyColumnDefs, + "_fnBindAction": _fnBindAction, + "_fnExtend": _fnExtend, + "_fnCallbackReg": _fnCallbackReg, + "_fnCallbackFire": _fnCallbackFire, + "_fnJsonString": _fnJsonString, + "_fnRender": _fnRender, + "_fnNodeToColumnIndex": _fnNodeToColumnIndex, + "_fnInfoMacros": _fnInfoMacros +}; + +$.extend( DataTable.ext.oApi, this.oApi ); + +for ( var sFunc in DataTable.ext.oApi ) +{ + if ( sFunc ) + { + this[sFunc] = _fnExternApiFunc(sFunc); + } +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/api/api.methods.js b/wqflask/wqflask/static/new/packages/DataTables/src/api/api.methods.js new file mode 100644 index 00000000..9e33c3f8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/api/api.methods.js @@ -0,0 +1,1276 @@ + + +/** + * Perform a jQuery selector action on the table's TR elements (from the tbody) and + * return the resulting jQuery object. + * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on + * @param {object} [oOpts] Optional parameters for modifying the rows to be included + * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter + * criterion ("applied") or all TR elements (i.e. no filter). + * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. + * Can be either 'current', whereby the current sorting of the table is used, or + * 'original' whereby the original order the data was read into the table is used. + * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page + * ("current") or not ("all"). If 'current' is given, then order is assumed to be + * 'current' and filter is 'applied', regardless of what they might be given as. + * @returns {object} jQuery object, filtered by the given selector. + * @dtopt API + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Highlight every second row + * oTable.$('tr:odd').css('backgroundColor', 'blue'); + * } ); + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable(); + * + * // Filter to rows with 'Webkit' in them, add a background colour and then + * // remove the filter, thus highlighting the 'Webkit' rows only. + * oTable.fnFilter('Webkit'); + * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue'); + * oTable.fnFilter(''); + * } ); + */ +this.$ = function ( sSelector, oOpts ) +{ + var i, iLen, a = [], tr; + var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); + var aoData = oSettings.aoData; + var aiDisplay = oSettings.aiDisplay; + var aiDisplayMaster = oSettings.aiDisplayMaster; + + if ( !oOpts ) + { + oOpts = {}; + } + + oOpts = $.extend( {}, { + "filter": "none", // applied + "order": "current", // "original" + "page": "all" // current + }, oOpts ); + + // Current page implies that order=current and fitler=applied, since it is fairly + // senseless otherwise + if ( oOpts.page == 'current' ) + { + for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i + *
      • 1D array of data - add a single row with the data provided
      • + *
      • 2D array of arrays - add multiple rows in a single call
      • + *
      • object - data object when using mDataProp
      • + *
      • array of objects - multiple data objects when using mDataProp
      • + * + * @param {bool} [bRedraw=true] redraw the table or not + * @returns {array} An array of integers, representing the list of indexes in + * aoData ({@link DataTable.models.oSettings}) that have been added to + * the table. + * @dtopt API + * + * @example + * // Global var for counter + * var giCount = 2; + * + * $(document).ready(function() { + * $('#example').dataTable(); + * } ); + * + * function fnClickAddRow() { + * $('#example').dataTable().fnAddData( [ + * giCount+".1", + * giCount+".2", + * giCount+".3", + * giCount+".4" ] + * ); + * + * giCount++; + * } + */ +this.fnAddData = function( mData, bRedraw ) +{ + if ( mData.length === 0 ) + { + return []; + } + + var aiReturn = []; + var iTest; + + /* Find settings from table node */ + var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); + + /* Check if we want to add multiple rows or not */ + if ( typeof mData[0] === "object" && mData[0] !== null ) + { + for ( var i=0 ; i= oSettings.fnRecordsDisplay() ) + { + oSettings._iDisplayStart -= oSettings._iDisplayLength; + if ( oSettings._iDisplayStart < 0 ) + { + oSettings._iDisplayStart = 0; + } + } + + if ( bRedraw === undefined || bRedraw ) + { + _fnCalculateEnd( oSettings ); + _fnDraw( oSettings ); + } + + return oData; +}; + + +/** + * Restore the table to it's original state in the DOM by removing all of DataTables + * enhancements, alterations to the DOM structure of the table and event listeners. + * @param {boolean} [bRemove=false] Completely remove the table from the DOM + * @dtopt API + * + * @example + * $(document).ready(function() { + * // This example is fairly pointless in reality, but shows how fnDestroy can be used + * var oTable = $('#example').dataTable(); + * oTable.fnDestroy(); + * } ); + */ +this.fnDestroy = function ( bRemove ) +{ + var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); + var nOrig = oSettings.nTableWrapper.parentNode; + var nBody = oSettings.nTBody; + var i, iLen; + + bRemove = (bRemove===undefined) ? false : true; + + /* Flag to note that the table is currently being destroyed - no action should be taken */ + oSettings.bDestroying = true; + + /* Fire off the destroy callbacks for plug-ins etc */ + _fnCallbackFire( oSettings, "aoDestroyCallback", "destroy", [oSettings] ); + + /* Restore hidden columns */ + for ( i=0, iLen=oSettings.aoColumns.length ; itr>td.'+oSettings.oClasses.sRowEmpty, oSettings.nTable).parent().remove(); + + /* When scrolling we had to break the table up - restore it */ + if ( oSettings.nTable != oSettings.nTHead.parentNode ) + { + $(oSettings.nTable).children('thead').remove(); + oSettings.nTable.appendChild( oSettings.nTHead ); + } + + if ( oSettings.nTFoot && oSettings.nTable != oSettings.nTFoot.parentNode ) + { + $(oSettings.nTable).children('tfoot').remove(); + oSettings.nTable.appendChild( oSettings.nTFoot ); + } + + /* Remove the DataTables generated nodes, events and classes */ + oSettings.nTable.parentNode.removeChild( oSettings.nTable ); + $(oSettings.nTableWrapper).remove(); + + oSettings.aaSorting = []; + oSettings.aaSortingFixed = []; + _fnSortingClasses( oSettings ); + + $(_fnGetTrNodes( oSettings )).removeClass( oSettings.asStripeClasses.join(' ') ); + + $('th, td', oSettings.nTHead).removeClass( [ + oSettings.oClasses.sSortable, + oSettings.oClasses.sSortableAsc, + oSettings.oClasses.sSortableDesc, + oSettings.oClasses.sSortableNone ].join(' ') + ); + if ( oSettings.bJUI ) + { + $('th span.'+oSettings.oClasses.sSortIcon + + ', td span.'+oSettings.oClasses.sSortIcon, oSettings.nTHead).remove(); + + $('th, td', oSettings.nTHead).each( function () { + var jqWrapper = $('div.'+oSettings.oClasses.sSortJUIWrapper, this); + var kids = jqWrapper.contents(); + $(this).append( kids ); + jqWrapper.remove(); + } ); + } + + /* Add the TR elements back into the table in their original order */ + if ( !bRemove && oSettings.nTableReinsertBefore ) + { + nOrig.insertBefore( oSettings.nTable, oSettings.nTableReinsertBefore ); + } + else if ( !bRemove ) + { + nOrig.appendChild( oSettings.nTable ); + } + + for ( i=0, iLen=oSettings.aoData.length ; i
        ')[0]; + oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable ); + + /* + * All DataTables are wrapped in a div + */ + oSettings.nTableWrapper = $('
        ')[0]; + oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; + + /* Track where we want to insert the option */ + var nInsertNode = oSettings.nTableWrapper; + + /* Loop over the user set positioning and place the elements as needed */ + var aDom = oSettings.sDom.split(''); + var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j; + for ( var i=0 ; i')[0]; + + /* Check to see if we should append an id and/or a class name to the container */ + cNext = aDom[i+1]; + if ( cNext == "'" || cNext == '"' ) + { + sAttr = ""; + j = 2; + while ( aDom[i+j] != cNext ) + { + sAttr += aDom[i+j]; + j++; + } + + /* Replace jQuery UI constants */ + if ( sAttr == "H" ) + { + sAttr = oSettings.oClasses.sJUIHeader; + } + else if ( sAttr == "F" ) + { + sAttr = oSettings.oClasses.sJUIFooter; + } + + /* The attribute can be in the format of "#id.class", "#id" or "class" This logic + * breaks the string into parts and applies them as needed + */ + if ( sAttr.indexOf('.') != -1 ) + { + var aSplit = sAttr.split('.'); + nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); + nNewNode.className = aSplit[1]; + } + else if ( sAttr.charAt(0) == "#" ) + { + nNewNode.id = sAttr.substr(1, sAttr.length-1); + } + else + { + nNewNode.className = sAttr; + } + + i += j; /* Move along the position array */ + } + + nInsertNode.appendChild( nNewNode ); + nInsertNode = nNewNode; + } + else if ( cOption == '>' ) + { + /* End container div */ + nInsertNode = nInsertNode.parentNode; + } + else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange ) + { + /* Length */ + nTmp = _fnFeatureHtmlLength( oSettings ); + iPushFeature = 1; + } + else if ( cOption == 'f' && oSettings.oFeatures.bFilter ) + { + /* Filter */ + nTmp = _fnFeatureHtmlFilter( oSettings ); + iPushFeature = 1; + } + else if ( cOption == 'r' && oSettings.oFeatures.bProcessing ) + { + /* pRocessing */ + nTmp = _fnFeatureHtmlProcessing( oSettings ); + iPushFeature = 1; + } + else if ( cOption == 't' ) + { + /* Table */ + nTmp = _fnFeatureHtmlTable( oSettings ); + iPushFeature = 1; + } + else if ( cOption == 'i' && oSettings.oFeatures.bInfo ) + { + /* Info */ + nTmp = _fnFeatureHtmlInfo( oSettings ); + iPushFeature = 1; + } + else if ( cOption == 'p' && oSettings.oFeatures.bPaginate ) + { + /* Pagination */ + nTmp = _fnFeatureHtmlPaginate( oSettings ); + iPushFeature = 1; + } + else if ( DataTable.ext.aoFeatures.length !== 0 ) + { + /* Plug-in features */ + var aoFeatures = DataTable.ext.aoFeatures; + for ( var k=0, kLen=aoFeatures.length ; k') : + sSearchStr==="" ? '' : sSearchStr+' '; + + var nFilter = document.createElement( 'div' ); + nFilter.className = oSettings.oClasses.sFilter; + nFilter.innerHTML = ''; + if ( !oSettings.aanFeatures.f ) + { + nFilter.id = oSettings.sTableId+'_filter'; + } + + var jqFilter = $('input[type="text"]', nFilter); + + // Store a reference to the input element, so other input elements could be + // added to the filter wrapper if needed (submit button for example) + nFilter._DT_Input = jqFilter[0]; + + jqFilter.val( oPreviousSearch.sSearch.replace('"','"') ); + jqFilter.bind( 'keyup.DT', function(e) { + /* Update all other filter input elements for the new display */ + var n = oSettings.aanFeatures.f; + var val = this.value==="" ? "" : this.value; // mental IE8 fix :-( + + for ( var i=0, iLen=n.length ; i=0 ; i-- ) + { + var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), + oSettings.aoColumns[iColumn].sType ); + if ( ! rpSearch.test( sData ) ) + { + oSettings.aiDisplay.splice( i, 1 ); + iIndexCorrector++; + } + } +} + + +/** + * Filter the data table based on user input and draw the table + * @param {object} oSettings dataTables settings object + * @param {string} sInput string to filter on + * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0) + * @param {bool} bRegex treat as a regular expression or not + * @param {bool} bSmart perform smart filtering or not + * @param {bool} bCaseInsensitive Do case insenstive matching or not + * @memberof DataTable#oApi + */ +function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive ) +{ + var i; + var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); + var oPrevSearch = oSettings.oPreviousSearch; + + /* Check if we are forcing or not - optional parameter */ + if ( !iForce ) + { + iForce = 0; + } + + /* Need to take account of custom filtering functions - always filter */ + if ( DataTable.ext.afnFiltering.length !== 0 ) + { + iForce = 1; + } + + /* + * If the input is blank - we want the full data set + */ + if ( sInput.length <= 0 ) + { + oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); + oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); + } + else + { + /* + * We are starting a new search or the new search string is smaller + * then the old one (i.e. delete). Search from the master array + */ + if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length || + oPrevSearch.sSearch.length > sInput.length || iForce == 1 || + sInput.indexOf(oPrevSearch.sSearch) !== 0 ) + { + /* Nuke the old display array - we are going to rebuild it */ + oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); + + /* Force a rebuild of the search array */ + _fnBuildSearchArray( oSettings, 1 ); + + /* Search through all records to populate the search array + * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 + * mapping + */ + for ( i=0 ; i tag - remove it */ + sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,""); + } + + return sSearch; +} + +/** + * Build a regular expression object suitable for searching a table + * @param {string} sSearch string to search for + * @param {bool} bRegex treat as a regular expression or not + * @param {bool} bSmart perform smart filtering or not + * @param {bool} bCaseInsensitive Do case insenstive matching or not + * @returns {RegExp} constructed object + * @memberof DataTable#oApi + */ +function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive ) +{ + var asSearch, sRegExpString; + + if ( bSmart ) + { + /* Generate the regular expression to use. Something along the lines of: + * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$ + */ + asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' ); + sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; + return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); + } + else + { + sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch ); + return new RegExp( sSearch, bCaseInsensitive ? "i" : "" ); + } +} + + +/** + * Convert raw data into something that the user can search on + * @param {string} sData data to be modified + * @param {string} sType data type + * @returns {string} search string + * @memberof DataTable#oApi + */ +function _fnDataToSearch ( sData, sType ) +{ + if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) + { + return DataTable.ext.ofnSearch[sType]( sData ); + } + else if ( sData === null ) + { + return ''; + } + else if ( sType == "html" ) + { + return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); + } + else if ( typeof sData === "string" ) + { + return sData.replace(/[\r\n]/g," "); + } + return sData; +} + + +/** + * scape a string stuch that it can be used in a regular expression + * @param {string} sVal string to escape + * @returns {string} escaped string + * @memberof DataTable#oApi + */ +function _fnEscapeRegex ( sVal ) +{ + var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '-' ]; + var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' ); + return sVal.replace(reReplace, '\\$1'); +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/core/core.info.js b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.info.js new file mode 100644 index 00000000..da8f35f3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.info.js @@ -0,0 +1,117 @@ + + +/** + * Generate the node required for the info display + * @param {object} oSettings dataTables settings object + * @returns {node} Information element + * @memberof DataTable#oApi + */ +function _fnFeatureHtmlInfo ( oSettings ) +{ + var nInfo = document.createElement( 'div' ); + nInfo.className = oSettings.oClasses.sInfo; + + /* Actions that are to be taken once only for this feature */ + if ( !oSettings.aanFeatures.i ) + { + /* Add draw callback */ + oSettings.aoDrawCallback.push( { + "fn": _fnUpdateInfo, + "sName": "information" + } ); + + /* Add id */ + nInfo.id = oSettings.sTableId+'_info'; + } + oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); + + return nInfo; +} + + +/** + * Update the information elements in the display + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ +function _fnUpdateInfo ( oSettings ) +{ + /* Show information about the table */ + if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) + { + return; + } + + var + oLang = oSettings.oLanguage, + iStart = oSettings._iDisplayStart+1, + iEnd = oSettings.fnDisplayEnd(), + iMax = oSettings.fnRecordsTotal(), + iTotal = oSettings.fnRecordsDisplay(), + sOut; + + if ( iTotal === 0 && iTotal == iMax ) + { + /* Empty record set */ + sOut = oLang.sInfoEmpty; + } + else if ( iTotal === 0 ) + { + /* Empty record set after filtering */ + sOut = oLang.sInfoEmpty +' '+ oLang.sInfoFiltered; + } + else if ( iTotal == iMax ) + { + /* Normal record set */ + sOut = oLang.sInfo; + } + else + { + /* Record set after filtering */ + sOut = oLang.sInfo +' '+ oLang.sInfoFiltered; + } + + // Convert the macros + sOut += oLang.sInfoPostFix; + sOut = _fnInfoMacros( oSettings, sOut ); + + if ( oLang.fnInfoCallback !== null ) + { + sOut = oLang.fnInfoCallback.call( oSettings.oInstance, + oSettings, iStart, iEnd, iMax, iTotal, sOut ); + } + + var n = oSettings.aanFeatures.i; + for ( var i=0, iLen=n.length ; i'; + var i, iLen; + var aLengthMenu = oSettings.aLengthMenu; + + if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && + typeof aLengthMenu[1] === 'object' ) + { + for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+''; + } + } + else + { + for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+''; + } + } + sStdMenu += ''; + + var nLength = document.createElement( 'div' ); + if ( !oSettings.aanFeatures.l ) + { + nLength.id = oSettings.sTableId+'_length'; + } + nLength.className = oSettings.oClasses.sLength; + nLength.innerHTML = ''; + + /* + * Set the length to the current display length - thanks to Andrea Pavlovic for this fix, + * and Stefan Skopnik for fixing the fix! + */ + $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true); + + $('select', nLength).bind( 'change.DT', function(e) { + var iVal = $(this).val(); + + /* Update all other length options for the new display */ + var n = oSettings.aanFeatures.l; + for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length || + oSettings._iDisplayLength == -1 ) + { + oSettings._iDisplayEnd = oSettings.aiDisplay.length; + } + else + { + oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength; + } + } +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/core/core.page.js b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.page.js new file mode 100644 index 00000000..c652da8c --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.page.js @@ -0,0 +1,119 @@ + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Note that most of the paging logic is done in + * DataTable.ext.oPagination + */ + +/** + * Generate the node required for default pagination + * @param {object} oSettings dataTables settings object + * @returns {node} Pagination feature node + * @memberof DataTable#oApi + */ +function _fnFeatureHtmlPaginate ( oSettings ) +{ + if ( oSettings.oScroll.bInfinite ) + { + return null; + } + + var nPaginate = document.createElement( 'div' ); + nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType; + + DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate, + function( oSettings ) { + _fnCalculateEnd( oSettings ); + _fnDraw( oSettings ); + } + ); + + /* Add a draw callback for the pagination on first instance, to update the paging display */ + if ( !oSettings.aanFeatures.p ) + { + oSettings.aoDrawCallback.push( { + "fn": function( oSettings ) { + DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) { + _fnCalculateEnd( oSettings ); + _fnDraw( oSettings ); + } ); + }, + "sName": "pagination" + } ); + } + return nPaginate; +} + + +/** + * Alter the display settings to change the page + * @param {object} oSettings dataTables settings object + * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" + * or page number to jump to (integer) + * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1 + * @memberof DataTable#oApi + */ +function _fnPageChange ( oSettings, mAction ) +{ + var iOldStart = oSettings._iDisplayStart; + + if ( typeof mAction === "number" ) + { + oSettings._iDisplayStart = mAction * oSettings._iDisplayLength; + if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() ) + { + oSettings._iDisplayStart = 0; + } + } + else if ( mAction == "first" ) + { + oSettings._iDisplayStart = 0; + } + else if ( mAction == "previous" ) + { + oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? + oSettings._iDisplayStart - oSettings._iDisplayLength : + 0; + + /* Correct for underrun */ + if ( oSettings._iDisplayStart < 0 ) + { + oSettings._iDisplayStart = 0; + } + } + else if ( mAction == "next" ) + { + if ( oSettings._iDisplayLength >= 0 ) + { + /* Make sure we are not over running the display array */ + if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) + { + oSettings._iDisplayStart += oSettings._iDisplayLength; + } + } + else + { + oSettings._iDisplayStart = 0; + } + } + else if ( mAction == "last" ) + { + if ( oSettings._iDisplayLength >= 0 ) + { + var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1; + oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength; + } + else + { + oSettings._iDisplayStart = 0; + } + } + else + { + _fnLog( oSettings, 0, "Unknown paging action: "+mAction ); + } + $(oSettings.oInstance).trigger('page', oSettings); + + return iOldStart != oSettings._iDisplayStart; +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/core/core.processing.js b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.processing.js new file mode 100644 index 00000000..8d29f6f5 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.processing.js @@ -0,0 +1,44 @@ + + +/** + * Generate the node required for the processing node + * @param {object} oSettings dataTables settings object + * @returns {node} Processing element + * @memberof DataTable#oApi + */ +function _fnFeatureHtmlProcessing ( oSettings ) +{ + var nProcessing = document.createElement( 'div' ); + + if ( !oSettings.aanFeatures.r ) + { + nProcessing.id = oSettings.sTableId+'_processing'; + } + nProcessing.innerHTML = oSettings.oLanguage.sProcessing; + nProcessing.className = oSettings.oClasses.sProcessing; + oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); + + return nProcessing; +} + + +/** + * Display or hide the processing indicator + * @param {object} oSettings dataTables settings object + * @param {bool} bShow Show the processing indicator (true) or not (false) + * @memberof DataTable#oApi + */ +function _fnProcessingDisplay ( oSettings, bShow ) +{ + if ( oSettings.oFeatures.bProcessing ) + { + var an = oSettings.aanFeatures.r; + for ( var i=0, iLen=an.length ; i 0 ) + { + nCaption = nCaption[0]; + if ( nCaption._captionSide === "top" ) + { + nScrollHeadTable.appendChild( nCaption ); + } + else if ( nCaption._captionSide === "bottom" && nTfoot ) + { + nScrollFootTable.appendChild( nCaption ); + } + } + + /* + * Sizing + */ + /* When xscrolling add the width and a scroller to move the header with the body */ + if ( oSettings.oScroll.sX !== "" ) + { + nScrollHead.style.width = _fnStringToCss( oSettings.oScroll.sX ); + nScrollBody.style.width = _fnStringToCss( oSettings.oScroll.sX ); + + if ( nTfoot !== null ) + { + nScrollFoot.style.width = _fnStringToCss( oSettings.oScroll.sX ); + } + + /* When the body is scrolled, then we also want to scroll the headers */ + $(nScrollBody).scroll( function (e) { + nScrollHead.scrollLeft = this.scrollLeft; + + if ( nTfoot !== null ) + { + nScrollFoot.scrollLeft = this.scrollLeft; + } + } ); + } + + /* When yscrolling, add the height */ + if ( oSettings.oScroll.sY !== "" ) + { + nScrollBody.style.height = _fnStringToCss( oSettings.oScroll.sY ); + } + + /* Redraw - align columns across the tables */ + oSettings.aoDrawCallback.push( { + "fn": _fnScrollDraw, + "sName": "scrolling" + } ); + + /* Infinite scrolling event handlers */ + if ( oSettings.oScroll.bInfinite ) + { + $(nScrollBody).scroll( function() { + /* Use a blocker to stop scrolling from loading more data while other data is still loading */ + if ( !oSettings.bDrawing && $(this).scrollTop() !== 0 ) + { + /* Check if we should load the next data set */ + if ( $(this).scrollTop() + $(this).height() > + $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap ) + { + /* Only do the redraw if we have to - we might be at the end of the data */ + if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() ) + { + _fnPageChange( oSettings, 'next' ); + _fnCalculateEnd( oSettings ); + _fnDraw( oSettings ); + } + } + } + } ); + } + + oSettings.nScrollHead = nScrollHead; + oSettings.nScrollFoot = nScrollFoot; + + return nScroller; +} + + +/** + * Update the various tables for resizing. It's a bit of a pig this function, but + * basically the idea to: + * 1. Re-create the table inside the scrolling div + * 2. Take live measurements from the DOM + * 3. Apply the measurements + * 4. Clean up + * @param {object} o dataTables settings object + * @returns {node} Node to add to the DOM + * @memberof DataTable#oApi + */ +function _fnScrollDraw ( o ) +{ + var + nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0], + nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0], + nScrollBody = o.nTable.parentNode, + i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, + nTheadSize, nTfootSize, + iWidth, aApplied=[], iSanityWidth, + nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, + nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, + ie67 = $.browser.msie && $.browser.version <= 7; + + /* + * 1. Re-create the table inside the scrolling div + */ + + /* Remove the old minimised thead and tfoot elements in the inner table */ + $(o.nTable).children('thead, tfoot').remove(); + + /* Clone the current header and footer elements and then place it into the inner table */ + nTheadSize = $(o.nTHead).clone()[0]; + o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); + + if ( o.nTFoot !== null ) + { + nTfootSize = $(o.nTFoot).clone()[0]; + o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); + } + + /* + * 2. Take live measurements from the DOM - do not alter the DOM itself! + */ + + /* Remove old sizing and apply the calculated column widths + * Get the unique column headers in the newly created (cloned) header. We want to apply the + * calclated sizes to this header + */ + if ( o.oScroll.sX === "" ) + { + nScrollBody.style.width = '100%'; + nScrollHeadInner.parentNode.style.width = '100%'; + } + + var nThs = _fnGetUniqueThs( o, nTheadSize ); + for ( i=0, iLen=nThs.length ; i nScrollBody.offsetHeight || + $(nScrollBody).css('overflow-y') == "scroll") ) + { + o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth() - o.oScroll.iBarWidth); + } + } + else + { + if ( o.oScroll.sXInner !== "" ) + { + /* x scroll inner has been given - use it */ + o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner); + } + else if ( iSanityWidth == $(nScrollBody).width() && + $(nScrollBody).height() < $(o.nTable).height() ) + { + /* There is y-scrolling - try to take account of the y scroll bar */ + o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth ); + if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth ) + { + /* Not possible to take account of it */ + o.nTable.style.width = _fnStringToCss( iSanityWidth ); + } + } + else + { + /* All else fails */ + o.nTable.style.width = _fnStringToCss( iSanityWidth ); + } + } + + /* Recalculate the sanity width - now that we've applied the required width, before it was + * a temporary variable. This is required because the column width calculation is done + * before this table DOM is created. + */ + iSanityWidth = $(o.nTable).outerWidth(); + + /* We want the hidden header to have zero height, so remove padding and borders. Then + * set the width based on the real headers + */ + anHeadToSize = o.nTHead.getElementsByTagName('tr'); + anHeadSizers = nTheadSize.getElementsByTagName('tr'); + + _fnApplyToChildren( function(nSizer, nToSize) { + oStyle = nSizer.style; + oStyle.paddingTop = "0"; + oStyle.paddingBottom = "0"; + oStyle.borderTopWidth = "0"; + oStyle.borderBottomWidth = "0"; + oStyle.height = 0; + + iWidth = $(nSizer).width(); + nToSize.style.width = _fnStringToCss( iWidth ); + aApplied.push( iWidth ); + }, anHeadSizers, anHeadToSize ); + $(anHeadSizers).height(0); + + if ( o.nTFoot !== null ) + { + /* Clone the current footer and then place it into the body table as a "hidden header" */ + anFootSizers = nTfootSize.getElementsByTagName('tr'); + anFootToSize = o.nTFoot.getElementsByTagName('tr'); + + _fnApplyToChildren( function(nSizer, nToSize) { + oStyle = nSizer.style; + oStyle.paddingTop = "0"; + oStyle.paddingBottom = "0"; + oStyle.borderTopWidth = "0"; + oStyle.borderBottomWidth = "0"; + oStyle.height = 0; + + iWidth = $(nSizer).width(); + nToSize.style.width = _fnStringToCss( iWidth ); + aApplied.push( iWidth ); + }, anFootSizers, anFootToSize ); + $(anFootSizers).height(0); + } + + /* + * 3. Apply the measurements + */ + + /* "Hide" the header and footer that we used for the sizing. We want to also fix their width + * to what they currently are + */ + _fnApplyToChildren( function(nSizer) { + nSizer.innerHTML = ""; + nSizer.style.width = _fnStringToCss( aApplied.shift() ); + }, anHeadSizers ); + + if ( o.nTFoot !== null ) + { + _fnApplyToChildren( function(nSizer) { + nSizer.innerHTML = ""; + nSizer.style.width = _fnStringToCss( aApplied.shift() ); + }, anFootSizers ); + } + + /* Sanity check that the table is of a sensible width. If not then we are going to get + * misalignment - try to prevent this by not allowing the table to shrink below its min width + */ + if ( $(o.nTable).outerWidth() < iSanityWidth ) + { + /* The min width depends upon if we have a vertical scrollbar visible or not */ + var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight || + $(nScrollBody).css('overflow-y') == "scroll")) ? + iSanityWidth+o.oScroll.iBarWidth : iSanityWidth; + + /* IE6/7 are a law unto themselves... */ + if ( ie67 && (nScrollBody.scrollHeight > + nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") ) + { + o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth ); + } + + /* Apply the calculated minimum width to the table wrappers */ + nScrollBody.style.width = _fnStringToCss( iCorrection ); + nScrollHeadInner.parentNode.style.width = _fnStringToCss( iCorrection ); + + if ( o.nTFoot !== null ) + { + nScrollFootInner.parentNode.style.width = _fnStringToCss( iCorrection ); + } + + /* And give the user a warning that we've stopped the table getting too small */ + if ( o.oScroll.sX === "" ) + { + _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ + " misalignment. The table has been drawn at its minimum possible width." ); + } + else if ( o.oScroll.sXInner !== "" ) + { + _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ + " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+ + " calculation" ); + } + } + else + { + nScrollBody.style.width = _fnStringToCss( '100%' ); + nScrollHeadInner.parentNode.style.width = _fnStringToCss( '100%' ); + + if ( o.nTFoot !== null ) + { + nScrollFootInner.parentNode.style.width = _fnStringToCss( '100%' ); + } + } + + + /* + * 4. Clean up + */ + if ( o.oScroll.sY === "" ) + { + /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting + * the scrollbar height from the visible display, rather than adding it on. We need to + * set the height in order to sort this. Don't want to do it in any other browsers. + */ + if ( ie67 ) + { + nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth ); + } + } + + if ( o.oScroll.sY !== "" && o.oScroll.bCollapse ) + { + nScrollBody.style.height = _fnStringToCss( o.oScroll.sY ); + + var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ? + o.oScroll.iBarWidth : 0; + if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) + { + nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+iExtra ); + } + } + + /* Finally set the width's of the header and footer tables */ + var iOuterWidth = $(o.nTable).outerWidth(); + nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth ); + nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth ); + + // Figure out if there are scrollbar present - if so then we need a the header and footer to + // provide a bit more space to allow "overflow" scrolling (i.e. past the scrollbar) + var bScrolling = $(o.nTable).height() > nScrollBody.clientHeight || $(nScrollBody).css('overflow-y') == "scroll"; + nScrollHeadInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; + + if ( o.nTFoot !== null ) + { + nScrollFootTable.style.width = _fnStringToCss( iOuterWidth ); + nScrollFootInner.style.width = _fnStringToCss( iOuterWidth ); + nScrollFootInner.style.paddingRight = bScrolling ? o.oScroll.iBarWidth+"px" : "0px"; + } + + /* Adjust the position of the header incase we loose the y-scrollbar */ + $(nScrollBody).scroll(); + + /* If sorting or filtering has occurred, jump the scrolling back to the top */ + if ( o.bSorted || o.bFiltered ) + { + nScrollBody.scrollTop = 0; + } +} + + +/** + * Apply a given function to the display child nodes of an element array (typically + * TD children of TR rows + * @param {function} fn Method to apply to the objects + * @param array {nodes} an1 List of elements to look through for display children + * @param array {nodes} an2 Another list (identical structure to the first) - optional + * @memberof DataTable#oApi + */ +function _fnApplyToChildren( fn, an1, an2 ) +{ + for ( var i=0, iLen=an1.length ; itd', nCalcTmp); + } + + /* Apply custom sizing to the cloned header */ + var nThs = _fnGetUniqueThs( oSettings, nTheadClone ); + iCorrector = 0; + for ( i=0 ; i 0 ) + { + oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth ); + } + iCorrector++; + } + } + + var cssWidth = $(nCalcTmp).css('width'); + oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ? + cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() ); + nCalcTmp.parentNode.removeChild( nCalcTmp ); + } + + if ( widthAttr ) + { + oSettings.nTable.style.width = _fnStringToCss( widthAttr ); + } +} + + +/** + * Adjust a table's width to take account of scrolling + * @param {object} oSettings dataTables settings object + * @param {node} n table node + * @memberof DataTable#oApi + */ +function _fnScrollingWidthAdjust ( oSettings, n ) +{ + if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" ) + { + /* When y-scrolling only, we want to remove the width of the scroll bar so the table + * + scroll bar will fit into the area avaialble. + */ + var iOrigWidth = $(n).width(); + n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth ); + } + else if ( oSettings.oScroll.sX !== "" ) + { + /* When x-scrolling both ways, fix the table at it's current size, without adjusting */ + n.style.width = _fnStringToCss( $(n).outerWidth() ); + } +} + + +/** + * Get the widest node + * @param {object} oSettings dataTables settings object + * @param {int} iCol column of interest + * @returns {string} max strlens for each column + * @memberof DataTable#oApi + */ +function _fnGetWidestNode( oSettings, iCol ) +{ + var iMaxIndex = _fnGetMaxLenString( oSettings, iCol ); + if ( iMaxIndex < 0 ) + { + return null; + } + + if ( oSettings.aoData[iMaxIndex].nTr === null ) + { + var n = document.createElement('td'); + n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' ); + return n; + } + return _fnGetTdNodes(oSettings, iMaxIndex)[iCol]; +} + + +/** + * Get the maximum strlen for each data column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column of interest + * @returns {string} max strlens for each column + * @memberof DataTable#oApi + */ +function _fnGetMaxLenString( oSettings, iCol ) +{ + var iMax = -1; + var iMaxIndex = -1; + + for ( var i=0 ; i/g, "" ); + if ( s.length > iMax ) + { + iMax = s.length; + iMaxIndex = i; + } + } + + return iMaxIndex; +} + + +/** + * Append a CSS unit (only if required) to a string + * @param {array} aArray1 first array + * @param {array} aArray2 second array + * @returns {int} 0 if match, 1 if length is different, 2 if no match + * @memberof DataTable#oApi + */ +function _fnStringToCss( s ) +{ + if ( s === null ) + { + return "0px"; + } + + if ( typeof s == 'number' ) + { + if ( s < 0 ) + { + return "0px"; + } + return s+"px"; + } + + /* Check if the last character is not 0-9 */ + var c = s.charCodeAt( s.length-1 ); + if (c < 0x30 || c > 0x39) + { + return s; + } + return s+"px"; +} + + +/** + * Get the width of a scroll bar in this browser being used + * @returns {int} width in pixels + * @memberof DataTable#oApi + */ +function _fnScrollBarWidth () +{ + var inner = document.createElement('p'); + var style = inner.style; + style.width = "100%"; + style.height = "200px"; + style.padding = "0px"; + + var outer = document.createElement('div'); + style = outer.style; + style.position = "absolute"; + style.top = "0px"; + style.left = "0px"; + style.visibility = "hidden"; + style.width = "200px"; + style.height = "150px"; + style.padding = "0px"; + style.overflow = "hidden"; + outer.appendChild(inner); + + document.body.appendChild(outer); + var w1 = inner.offsetWidth; + outer.style.overflow = 'scroll'; + var w2 = inner.offsetWidth; + if ( w1 == w2 ) + { + w2 = outer.clientWidth; + } + + document.body.removeChild(outer); + return (w1 - w2); +} + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/core/core.sort.js b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.sort.js new file mode 100644 index 00000000..f6cf11ad --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/core/core.sort.js @@ -0,0 +1,460 @@ + + +/** + * Change the order of the table + * @param {object} oSettings dataTables settings object + * @param {bool} bApplyClasses optional - should we apply classes or not + * @memberof DataTable#oApi + */ +function _fnSort ( oSettings, bApplyClasses ) +{ + var + i, iLen, j, jLen, k, kLen, + sDataType, nTh, + aaSort = [], + aiOrig = [], + oSort = DataTable.ext.oSort, + aoData = oSettings.aoData, + aoColumns = oSettings.aoColumns, + oAria = oSettings.oLanguage.oAria; + + /* No sorting required if server-side or no sorting array */ + if ( !oSettings.oFeatures.bServerSide && + (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) ) + { + aaSort = ( oSettings.aaSortingFixed !== null ) ? + oSettings.aaSortingFixed.concat( oSettings.aaSorting ) : + oSettings.aaSorting.slice(); + + /* If there is a sorting data type, and a fuction belonging to it, then we need to + * get the data from the developer's function and apply it for this column + */ + for ( i=0 ; i/g, "" ); + nTh = aoColumns[i].nTh; + nTh.removeAttribute('aria-sort'); + nTh.removeAttribute('aria-label'); + + /* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */ + if ( aoColumns[i].bSortable ) + { + if ( aaSort.length > 0 && aaSort[0][0] == i ) + { + nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" ); + + var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? + aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; + nTh.setAttribute('aria-label', sTitle+ + (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); + } + else + { + nTh.setAttribute('aria-label', sTitle+ + (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); + } + } + else + { + nTh.setAttribute('aria-label', sTitle); + } + } + + /* Tell the draw function that we have sorted the data */ + oSettings.bSorted = true; + $(oSettings.oInstance).trigger('sort', oSettings); + + /* Copy the master data into the draw array and re-draw */ + if ( oSettings.oFeatures.bFilter ) + { + /* _fnFilter() will redraw the table for us */ + _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 ); + } + else + { + oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); + oSettings._iDisplayStart = 0; /* reset display back to page 0 */ + _fnCalculateEnd( oSettings ); + _fnDraw( oSettings ); + } +} + + +/** + * Attach a sort handler (click) to a node + * @param {object} oSettings dataTables settings object + * @param {node} nNode node to attach the handler to + * @param {int} iDataIndex column sorting index + * @param {function} [fnCallback] callback function + * @memberof DataTable#oApi + */ +function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) +{ + _fnBindAction( nNode, {}, function (e) { + /* If the column is not sortable - don't to anything */ + if ( oSettings.aoColumns[iDataIndex].bSortable === false ) + { + return; + } + + /* + * This is a little bit odd I admit... I declare a temporary function inside the scope of + * _fnBuildHead and the click handler in order that the code presented here can be used + * twice - once for when bProcessing is enabled, and another time for when it is + * disabled, as we need to perform slightly different actions. + * Basically the issue here is that the Javascript engine in modern browsers don't + * appear to allow the rendering engine to update the display while it is still excuting + * it's thread (well - it does but only after long intervals). This means that the + * 'processing' display doesn't appear for a table sort. To break the js thread up a bit + * I force an execution break by using setTimeout - but this breaks the expected + * thread continuation for the end-developer's point of view (their code would execute + * too early), so we on;y do it when we absolutely have to. + */ + var fnInnerSorting = function () { + var iColumn, iNextSort; + + /* If the shift key is pressed then we are multipe column sorting */ + if ( e.shiftKey ) + { + /* Are we already doing some kind of sort on this column? */ + var bFound = false; + for ( var i=0 ; i= iColumns ) + { + for ( i=0 ; i 4096 ) /* Magic 10 for padding */ + { + var aCookies =document.cookie.split(';'); + for ( var i=0, iLen=aCookies.length ; i=0 ; i-- ) + { + aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); + } + + if ( sTrigger !== null ) + { + $(oSettings.oInstance).trigger(sTrigger, aArgs); + } + + return aRet; +} + + +/** + * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other + * library, then we use that as it is fast, safe and accurate. If the function isn't + * available then we need to built it ourselves - the insperation for this function comes + * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is + * not perfect and absolutely should not be used as a replacement to json2.js - but it does + * do what we need, without requiring a dependency for DataTables. + * @param {object} o JSON object to be converted + * @returns {string} JSON string + * @memberof DataTable#oApi + */ +var _fnJsonString = (window.JSON) ? JSON.stringify : function( o ) +{ + /* Not an object or array */ + var sType = typeof o; + if (sType !== "object" || o === null) + { + // simple data type + if (sType === "string") + { + o = '"'+o+'"'; + } + return o+""; + } + + /* If object or array, need to recurse over it */ + var + sProp, mValue, + json = [], + bArr = $.isArray(o); + + for (sProp in o) + { + mValue = o[sProp]; + sType = typeof mValue; + + if (sType === "string") + { + mValue = '"'+mValue+'"'; + } + else if (sType === "object" && mValue !== null) + { + mValue = _fnJsonString(mValue); + } + + json.push((bArr ? "" : '"'+sProp+'":') + mValue); + } + + return (bArr ? "[" : "{") + json + (bArr ? "]" : "}"); +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.classes.js b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.classes.js new file mode 100644 index 00000000..c87ca0c4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.classes.js @@ -0,0 +1,112 @@ + +$.extend( DataTable.ext.oStdClasses, { + "sTable": "dataTable", + + /* Two buttons buttons */ + "sPagePrevEnabled": "paginate_enabled_previous", + "sPagePrevDisabled": "paginate_disabled_previous", + "sPageNextEnabled": "paginate_enabled_next", + "sPageNextDisabled": "paginate_disabled_next", + "sPageJUINext": "", + "sPageJUIPrev": "", + + /* Full numbers paging buttons */ + "sPageButton": "paginate_button", + "sPageButtonActive": "paginate_active", + "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled", + "sPageFirst": "first", + "sPagePrevious": "previous", + "sPageNext": "next", + "sPageLast": "last", + + /* Striping classes */ + "sStripeOdd": "odd", + "sStripeEven": "even", + + /* Empty row */ + "sRowEmpty": "dataTables_empty", + + /* Features */ + "sWrapper": "dataTables_wrapper", + "sFilter": "dataTables_filter", + "sInfo": "dataTables_info", + "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ + "sLength": "dataTables_length", + "sProcessing": "dataTables_processing", + + /* Sorting */ + "sSortAsc": "sorting_asc", + "sSortDesc": "sorting_desc", + "sSortable": "sorting", /* Sortable in both directions */ + "sSortableAsc": "sorting_asc_disabled", + "sSortableDesc": "sorting_desc_disabled", + "sSortableNone": "sorting_disabled", + "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ + "sSortJUIAsc": "", + "sSortJUIDesc": "", + "sSortJUI": "", + "sSortJUIAscAllowed": "", + "sSortJUIDescAllowed": "", + "sSortJUIWrapper": "", + "sSortIcon": "", + + /* Scrolling */ + "sScrollWrapper": "dataTables_scroll", + "sScrollHead": "dataTables_scrollHead", + "sScrollHeadInner": "dataTables_scrollHeadInner", + "sScrollBody": "dataTables_scrollBody", + "sScrollFoot": "dataTables_scrollFoot", + "sScrollFootInner": "dataTables_scrollFootInner", + + /* Misc */ + "sFooterTH": "", + "sJUIHeader": "", + "sJUIFooter": "" +} ); + + +$.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, { + /* Two buttons buttons */ + "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left", + "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled", + "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right", + "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled", + "sPageJUINext": "ui-icon ui-icon-circle-arrow-e", + "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w", + + /* Full numbers paging buttons */ + "sPageButton": "fg-button ui-button ui-state-default", + "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled", + "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled", + "sPageFirst": "first ui-corner-tl ui-corner-bl", + "sPageLast": "last ui-corner-tr ui-corner-br", + + /* Features */ + "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ + "ui-buttonset-multi paging_", /* Note that the type is postfixed */ + + /* Sorting */ + "sSortAsc": "ui-state-default", + "sSortDesc": "ui-state-default", + "sSortable": "ui-state-default", + "sSortableAsc": "ui-state-default", + "sSortableDesc": "ui-state-default", + "sSortableNone": "ui-state-default", + "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n", + "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s", + "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s", + "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n", + "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s", + "sSortJUIWrapper": "DataTables_sort_wrapper", + "sSortIcon": "DataTables_sort_icon", + + /* Scrolling */ + "sScrollHead": "dataTables_scrollHead ui-state-default", + "sScrollFoot": "dataTables_scrollFoot ui-state-default", + + /* Misc */ + "sFooterTH": "ui-state-default", + "sJUIHeader": "fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix", + "sJUIFooter": "fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix" +} ); + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.paging.js b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.paging.js new file mode 100644 index 00000000..195a5797 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.paging.js @@ -0,0 +1,257 @@ + +/* + * Variable: oPagination + * Purpose: + * Scope: jQuery.fn.dataTableExt + */ +$.extend( DataTable.ext.oPagination, { + /* + * Variable: two_button + * Purpose: Standard two button (forward/back) pagination + * Scope: jQuery.fn.dataTableExt.oPagination + */ + "two_button": { + /* + * Function: oPagination.two_button.fnInit + * Purpose: Initialise dom elements required for pagination with forward/back buttons only + * Returns: - + * Inputs: object:oSettings - dataTables settings object + * node:nPaging - the DIV which contains this pagination control + * function:fnCallbackDraw - draw function which must be called on update + */ + "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) + { + var oLang = oSettings.oLanguage.oPaginate; + var oClasses = oSettings.oClasses; + var fnClickHandler = function ( e ) { + if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) ) + { + fnCallbackDraw( oSettings ); + } + }; + + var sAppend = (!oSettings.bJUI) ? + ''+oLang.sPrevious+''+ + ''+oLang.sNext+'' + : + ''+ + ''; + $(nPaging).append( sAppend ); + + var els = $('a', nPaging); + var nPrevious = els[0], + nNext = els[1]; + + oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler ); + oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); + + /* ID the first elements only */ + if ( !oSettings.aanFeatures.p ) + { + nPaging.id = oSettings.sTableId+'_paginate'; + nPrevious.id = oSettings.sTableId+'_previous'; + nNext.id = oSettings.sTableId+'_next'; + + nPrevious.setAttribute('aria-controls', oSettings.sTableId); + nNext.setAttribute('aria-controls', oSettings.sTableId); + } + }, + + /* + * Function: oPagination.two_button.fnUpdate + * Purpose: Update the two button pagination at the end of the draw + * Returns: - + * Inputs: object:oSettings - dataTables settings object + * function:fnCallbackDraw - draw function to call on page change + */ + "fnUpdate": function ( oSettings, fnCallbackDraw ) + { + if ( !oSettings.aanFeatures.p ) + { + return; + } + + var oClasses = oSettings.oClasses; + var an = oSettings.aanFeatures.p; + + /* Loop over each instance of the pager */ + for ( var i=0, iLen=an.length ; i'+oLang.sFirst+''+ + ''+oLang.sPrevious+''+ + ''+ + ''+oLang.sNext+''+ + ''+oLang.sLast+'' + ); + var els = $('a', nPaging); + var nFirst = els[0], + nPrev = els[1], + nNext = els[2], + nLast = els[3]; + + oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler ); + oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler ); + oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); + oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler ); + + /* ID the first elements only */ + if ( !oSettings.aanFeatures.p ) + { + nPaging.id = oSettings.sTableId+'_paginate'; + nFirst.id =oSettings.sTableId+'_first'; + nPrev.id =oSettings.sTableId+'_previous'; + nNext.id =oSettings.sTableId+'_next'; + nLast.id =oSettings.sTableId+'_last'; + } + }, + + /* + * Function: oPagination.full_numbers.fnUpdate + * Purpose: Update the list of page buttons shows + * Returns: - + * Inputs: object:oSettings - dataTables settings object + * function:fnCallbackDraw - draw function to call on page change + */ + "fnUpdate": function ( oSettings, fnCallbackDraw ) + { + if ( !oSettings.aanFeatures.p ) + { + return; + } + + var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages; + var iPageCountHalf = Math.floor(iPageCount / 2); + var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength); + var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; + var sList = ""; + var iStartButton, iEndButton, i, iLen; + var oClasses = oSettings.oClasses; + var anButtons, anStatic, nPaginateList; + var an = oSettings.aanFeatures.p; + var fnBind = function (j) { + oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) { + /* Use the information in the element to jump to the required page */ + oSettings.oApi._fnPageChange( oSettings, e.data.page ); + fnCallbackDraw( oSettings ); + e.preventDefault(); + } ); + }; + + /* Pages calculation */ + if ( oSettings._iDisplayLength === -1 ) + { + iStartButton = 1; + iEndButton = 1; + iCurrentPage = 1; + } + else if (iPages < iPageCount) + { + iStartButton = 1; + iEndButton = iPages; + } + else if (iCurrentPage <= iPageCountHalf) + { + iStartButton = 1; + iEndButton = iPageCount; + } + else if (iCurrentPage >= (iPages - iPageCountHalf)) + { + iStartButton = iPages - iPageCount + 1; + iEndButton = iPages; + } + else + { + iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1; + iEndButton = iStartButton + iPageCount - 1; + } + + + /* Build the dynamic list */ + for ( i=iStartButton ; i<=iEndButton ; i++ ) + { + sList += (iCurrentPage !== i) ? + ''+oSettings.fnFormatNumber(i)+'' : + ''+oSettings.fnFormatNumber(i)+''; + } + + /* Loop over each instance of the pager */ + for ( i=0, iLen=an.length ; i y) ? 1 : 0)); + }, + + "string-desc": function ( x, y ) + { + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }, + + + /* + * html sorting (ignore html tags) + */ + "html-pre": function ( a ) + { + return a.replace( /<.*?>/g, "" ).toLowerCase(); + }, + + "html-asc": function ( x, y ) + { + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + }, + + "html-desc": function ( x, y ) + { + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + }, + + + /* + * date sorting + */ + "date-pre": function ( a ) + { + var x = Date.parse( a ); + + if ( isNaN(x) || x==="" ) + { + x = Date.parse( "01/01/1970 00:00:00" ); + } + return x; + }, + + "date-asc": function ( x, y ) + { + return x - y; + }, + + "date-desc": function ( x, y ) + { + return y - x; + }, + + + /* + * numerical sorting + */ + "numeric-pre": function ( a ) + { + return (a=="-" || a==="") ? 0 : a*1; + }, + + "numeric-asc": function ( x, y ) + { + return x - y; + }, + + "numeric-desc": function ( x, y ) + { + return y - x; + } +} ); diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.types.js b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.types.js new file mode 100644 index 00000000..ffd4e143 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/ext/ext.types.js @@ -0,0 +1,88 @@ + + +$.extend( DataTable.ext.aTypes, [ + /* + * Function: - + * Purpose: Check to see if a string is numeric + * Returns: string:'numeric' or null + * Inputs: mixed:sText - string to check + */ + function ( sData ) + { + /* Allow zero length strings as a number */ + if ( typeof sData === 'number' ) + { + return 'numeric'; + } + else if ( typeof sData !== 'string' ) + { + return null; + } + + var sValidFirstChars = "0123456789-"; + var sValidChars = "0123456789."; + var Char; + var bDecimal = false; + + /* Check for a valid first char (no period and allow negatives) */ + Char = sData.charAt(0); + if (sValidFirstChars.indexOf(Char) == -1) + { + return null; + } + + /* Check all the other characters are valid */ + for ( var i=1 ; i') != -1 ) + { + return 'html'; + } + return null; + } +] ); + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.column.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.column.js new file mode 100644 index 00000000..0f440cf8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.column.js @@ -0,0 +1,248 @@ + + + +/** + * Template object for the column information object in DataTables. This object + * is held in the settings aoColumns array and contains all the information that + * DataTables needs about each individual column. + * + * Note that this object is related to {@link DataTable.defaults.columns} + * but this one is the internal data store for DataTables's cache of columns. + * It should NOT be manipulated outside of DataTables. Any configuration should + * be done through the initialisation options. + * @namespace + */ +DataTable.models.oColumn = { + /** + * A list of the columns that sorting should occur on when this column + * is sorted. That this property is an array allows multi-column sorting + * to be defined for a column (for example first name / last name columns + * would benefit from this). The values are integers pointing to the + * columns to be sorted on (typically it will be a single integer pointing + * at itself, but that doesn't need to be the case). + * @type array + */ + "aDataSort": null, + + /** + * Define the sorting directions that are applied to the column, in sequence + * as the column is repeatedly sorted upon - i.e. the first value is used + * as the sorting direction when the column if first sorted (clicked on). + * Sort it again (click again) and it will move on to the next index. + * Repeat until loop. + * @type array + */ + "asSorting": null, + + /** + * Flag to indicate if the column is searchable, and thus should be included + * in the filtering or not. + * @type boolean + */ + "bSearchable": null, + + /** + * Flag to indicate if the column is sortable or not. + * @type boolean + */ + "bSortable": null, + + /** + * When using fnRender, you have two options for what to do with the data, + * and this property serves as the switch. Firstly, you can have the sorting + * and filtering use the rendered value (true - default), or you can have + * the sorting and filtering us the original value (false). + * + * *NOTE* It is it is advisable now to use mDataProp as a function and make + * use of the 'type' that it gives, allowing (potentially) different data to + * be used for sorting, filtering, display and type detection. + * @type boolean + * @deprecated + */ + "bUseRendered": null, + + /** + * Flag to indicate if the column is currently visible in the table or not + * @type boolean + */ + "bVisible": null, + + /** + * Flag to indicate to the type detection method if the automatic type + * detection should be used, or if a column type (sType) has been specified + * @type boolean + * @default true + * @private + */ + "_bAutoType": true, + + /** + * Developer definable function that is called whenever a cell is created (Ajax source, + * etc) or processed for input (DOM source). This can be used as a compliment to fnRender + * allowing you to modify the DOM element (add background colour for example) when the + * element is available (since it is not when fnRender is called). + * @type function + * @param {element} nTd The TD node that has been created + * @param {*} sData The Data for the cell + * @param {array|object} oData The data for the whole row + * @param {int} iRow The row index for the aoData data store + * @default null + */ + "fnCreatedCell": null, + + /** + * Function to get data from a cell in a column. You should never + * access data directly through _aData internally in DataTables - always use + * the method attached to this property. It allows mDataProp to function as + * required. This function is automatically assigned by the column + * initialisation method + * @type function + * @param {array|object} oData The data array/object for the array + * (i.e. aoData[]._aData) + * @param {string} sSpecific The specific data type you want to get - + * 'display', 'type' 'filter' 'sort' + * @returns {*} The data for the cell from the given row's data + * @default null + */ + "fnGetData": null, + + /** + * Custom display function that will be called for the display of each cell + * in this column. + * @type function + * @param {object} o Object with the following parameters: + * @param {int} o.iDataRow The row in aoData + * @param {int} o.iDataColumn The column in question + * @param {array} o.aData The data for the row in question + * @param {object} o.oSettings The settings object for this DataTables instance + * @returns {string} The string you which to use in the display + * @default null + */ + "fnRender": null, + + /** + * Function to set data for a cell in the column. You should never + * set the data directly to _aData internally in DataTables - always use + * this method. It allows mDataProp to function as required. This function + * is automatically assigned by the column initialisation method + * @type function + * @param {array|object} oData The data array/object for the array + * (i.e. aoData[]._aData) + * @param {*} sValue Value to set + * @default null + */ + "fnSetData": null, + + /** + * Property to read the value for the cells in the column from the data + * source array / object. If null, then the default content is used, if a + * function is given then the return from the function is used. + * @type function|int|string|null + * @default null + */ + "mDataProp": null, + + /** + * Unique header TH/TD element for this column - this is what the sorting + * listener is attached to (if sorting is enabled.) + * @type node + * @default null + */ + "nTh": null, + + /** + * Unique footer TH/TD element for this column (if there is one). Not used + * in DataTables as such, but can be used for plug-ins to reference the + * footer for each column. + * @type node + * @default null + */ + "nTf": null, + + /** + * The class to apply to all TD elements in the table's TBODY for the column + * @type string + * @default null + */ + "sClass": null, + + /** + * When DataTables calculates the column widths to assign to each column, + * it finds the longest string in each column and then constructs a + * temporary table and reads the widths from that. The problem with this + * is that "mmm" is much wider then "iiii", but the latter is a longer + * string - thus the calculation can go wrong (doing it properly and putting + * it into an DOM object and measuring that is horribly(!) slow). Thus as + * a "work around" we provide this option. It will append its value to the + * text that is found to be the longest string for the column - i.e. padding. + * @type string + */ + "sContentPadding": null, + + /** + * Allows a default value to be given for a column's data, and will be used + * whenever a null data source is encountered (this can be because mDataProp + * is set to null, or because the data source itself is null). + * @type string + * @default null + */ + "sDefaultContent": null, + + /** + * Name for the column, allowing reference to the column by name as well as + * by index (needs a lookup to work by name). + * @type string + */ + "sName": null, + + /** + * Custom sorting data type - defines which of the available plug-ins in + * afnSortData the custom sorting will use - if any is defined. + * @type string + * @default std + */ + "sSortDataType": 'std', + + /** + * Class to be applied to the header element when sorting on this column + * @type string + * @default null + */ + "sSortingClass": null, + + /** + * Class to be applied to the header element when sorting on this column - + * when jQuery UI theming is used. + * @type string + * @default null + */ + "sSortingClassJUI": null, + + /** + * Title of the column - what is seen in the TH element (nTh). + * @type string + */ + "sTitle": null, + + /** + * Column sorting and filtering type + * @type string + * @default null + */ + "sType": null, + + /** + * Width of the column + * @type string + * @default null + */ + "sWidth": null, + + /** + * Width of the column when it was first "encountered" + * @type string + * @default null + */ + "sWidthOrig": null +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.columns.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.columns.js new file mode 100644 index 00000000..4828e02a --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.columns.js @@ -0,0 +1,737 @@ + + +/** + * Column options that can be given to DataTables at initialisation time. + * @namespace + */ +DataTable.defaults.columns = { + /** + * Allows a column's sorting to take multiple columns into account when + * doing a sort. For example first name / last name columns make sense to + * do a multi-column sort over the two columns. + * @type array + * @default null Takes the value of the column index automatically + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] }, + * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] }, + * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "aDataSort": [ 0, 1 ] }, + * { "aDataSort": [ 1, 0 ] }, + * { "aDataSort": [ 2, 3, 4 ] }, + * null, + * null + * ] + * } ); + * } ); + */ + "aDataSort": null, + + + /** + * You can control the default sorting direction, and even alter the behaviour + * of the sort handler (i.e. only allow ascending sorting etc) using this + * parameter. + * @type array + * @default [ 'asc', 'desc' ] + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "asSorting": [ "asc" ], "aTargets": [ 1 ] }, + * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] }, + * { "asSorting": [ "desc" ], "aTargets": [ 3 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * null, + * { "asSorting": [ "asc" ] }, + * { "asSorting": [ "desc", "asc", "asc" ] }, + * { "asSorting": [ "desc" ] }, + * null + * ] + * } ); + * } ); + */ + "asSorting": [ 'asc', 'desc' ], + + + /** + * Enable or disable filtering on the data in this column. + * @type boolean + * @default true + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "bSearchable": false, "aTargets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "bSearchable": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bSearchable": true, + + + /** + * Enable or disable sorting on this column. + * @type boolean + * @default true + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "bSortable": false, "aTargets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "bSortable": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bSortable": true, + + + /** + * When using fnRender() for a column, you may wish to use the original data + * (before rendering) for sorting and filtering (the default is to used the + * rendered data that the user can see). This may be useful for dates etc. + * + * *NOTE* It is it is advisable now to use mDataProp as a function and make + * use of the 'type' that it gives, allowing (potentially) different data to + * be used for sorting, filtering, display and type detection. + * @type boolean + * @default true + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { + * "fnRender": function ( oObj ) { + * return oObj.aData[0] +' '+ oObj.aData[3]; + * }, + * "bUseRendered": false, + * "aTargets": [ 0 ] + * } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { + * "fnRender": function ( oObj ) { + * return oObj.aData[0] +' '+ oObj.aData[3]; + * }, + * "bUseRendered": false + * }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "bUseRendered": true, + + + /** + * Enable or disable the display of this column. + * @type boolean + * @default true + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "bVisible": false, "aTargets": [ 0 ] } + * ] } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "bVisible": false }, + * null, + * null, + * null, + * null + * ] } ); + * } ); + */ + "bVisible": true, + + + /** + * Developer definable function that is called whenever a cell is created (Ajax source, + * etc) or processed for input (DOM source). This can be used as a compliment to fnRender + * allowing you to modify the DOM element (add background colour for example) when the + * element is available (since it is not when fnRender is called). + * @type function + * @param {element} nTd The TD node that has been created + * @param {*} sData The Data for the cell + * @param {array|object} oData The data for the whole row + * @param {int} iRow The row index for the aoData data store + * @param {int} iCol The column index for aoColumns + * @dtopt Columns + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ { + * "aTargets": [3], + * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) { + * if ( sData == "1.7" ) { + * $(nTd).css('color', 'blue') + * } + * } + * } ] + * }); + * } ); + */ + "fnCreatedCell": null, + + + /** + * Custom display function that will be called for the display of each cell in + * this column. + * @type function + * @param {object} o Object with the following parameters: + * @param {int} o.iDataRow The row in aoData + * @param {int} o.iDataColumn The column in question + * @param {array} o.aData The data for the row in question + * @param {object} o.oSettings The settings object for this DataTables instance + * @param {object} o.mDataProp The data property used for this column + * @param {*} val The current cell value + * @returns {string} The string you which to use in the display + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { + * "fnRender": function ( o, val ) { + * return o.aData[0] +' '+ o.aData[3]; + * }, + * "aTargets": [ 0 ] + * } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "fnRender": function ( o, val ) { + * return o.aData[0] +' '+ o.aData[3]; + * } }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "fnRender": null, + + + /** + * The column index (starting from 0!) that you wish a sort to be performed + * upon when this column is selected for sorting. This can be used for sorting + * on hidden columns for example. + * @type int + * @default -1 Use automatically calculated column index + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "iDataSort": 1, "aTargets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "iDataSort": 1 }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "iDataSort": -1, + + + /** + * This property can be used to read data from any JSON data source property, + * including deeply nested objects / properties. mDataProp can be given in a + * number of different ways which effect its behaviour: + *
          + *
        • integer - treated as an array index for the data source. This is the + * default that DataTables uses (incrementally increased for each column).
        • + *
        • string - read an object property from the data source. Note that you can + * use Javascript dotted notation to read deep properties/arrays from the + * data source.
        • + *
        • null - the sDefaultContent option will be used for the cell (null + * by default, so you will need to specify the default content you want - + * typically an empty string). This can be useful on generated columns such + * as edit / delete action columns.
        • + *
        • function - the function given will be executed whenever DataTables + * needs to set or get the data for a cell in the column. The function + * takes three parameters: + *
            + *
          • {array|object} The data source for the row
          • + *
          • {string} The type call data requested - this will be 'set' when + * setting data or 'filter', 'display', 'type', 'sort' or undefined when + * gathering data. Note that when undefined is given for the type + * DataTables expects to get the raw data for the object back
          • + *
          • {*} Data to set when the second parameter is 'set'.
          • + *
          + * The return value from the function is not required when 'set' is the type + * of call, but otherwise the return is what will be used for the data + * requested.
        • + *
        + * @type string|int|function|null + * @default null Use automatically calculated column index + * @dtopt Columns + * + * @example + * // Read table data from objects + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sAjaxSource": "sources/deep.txt", + * "aoColumns": [ + * { "mDataProp": "engine" }, + * { "mDataProp": "browser" }, + * { "mDataProp": "platform.inner" }, + * { "mDataProp": "platform.details.0" }, + * { "mDataProp": "platform.details.1" } + * ] + * } ); + * } ); + * + * @example + * // Using mDataProp as a function to provide different information for + * // sorting, filtering and display. In this case, currency (price) + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "aoColumnDefs": [ + * { + * "aTargets": [ 0 ], + * "mDataProp": function ( source, type, val ) { + * if (type === 'set') { + * source.price = val; + * // Store the computed dislay and filter values for efficiency + * source.price_display = val=="" ? "" : "$"+numberFormat(val); + * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; + * return; + * } + * else if (type === 'display') { + * return source.price_display; + * } + * else if (type === 'filter') { + * return source.price_filter; + * } + * // 'sort', 'type' and undefined all just use the integer + * return source.price; + * } + * ] + * } ); + * } ); + */ + "mDataProp": null, + + + /** + * Change the cell type created for the column - either TD cells or TH cells. This + * can be useful as TH cells have semantic meaning in the table body, allowing them + * to act as a header for a row (you may wish to add scope='row' to the TH elements). + * @type string + * @default td + * @dtopt Columns + * + * @example + * // Make the first column use TH cells + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "aoColumnDefs": [ + * { + * "aTargets": [ 0 ], + * "sCellType": "th" + * ] + * } ); + * } ); + */ + "sCellType": "td", + + + /** + * Class to give to each cell in this column. + * @type string + * @default Empty string + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sClass": "my_class", "aTargets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "sClass": "my_class" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sClass": "", + + /** + * When DataTables calculates the column widths to assign to each column, + * it finds the longest string in each column and then constructs a + * temporary table and reads the widths from that. The problem with this + * is that "mmm" is much wider then "iiii", but the latter is a longer + * string - thus the calculation can go wrong (doing it properly and putting + * it into an DOM object and measuring that is horribly(!) slow). Thus as + * a "work around" we provide this option. It will append its value to the + * text that is found to be the longest string for the column - i.e. padding. + * Generally you shouldn't need this, and it is not documented on the + * general DataTables.net documentation + * @type string + * @default Empty string + * @dtopt Columns + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * null, + * null, + * null, + * { + * "sContentPadding": "mmm" + * } + * ] + * } ); + * } ); + */ + "sContentPadding": "", + + + /** + * Allows a default value to be given for a column's data, and will be used + * whenever a null data source is encountered (this can be because mDataProp + * is set to null, or because the data source itself is null). + * @type string + * @default null + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { + * "mDataProp": null, + * "sDefaultContent": "Edit", + * "aTargets": [ -1 ] + * } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * null, + * null, + * null, + * { + * "mDataProp": null, + * "sDefaultContent": "Edit" + * } + * ] + * } ); + * } ); + */ + "sDefaultContent": null, + + + /** + * This parameter is only used in DataTables' server-side processing. It can + * be exceptionally useful to know what columns are being displayed on the + * client side, and to map these to database fields. When defined, the names + * also allow DataTables to reorder information from the server if it comes + * back in an unexpected order (i.e. if you switch your columns around on the + * client-side, your server-side code does not also need updating). + * @type string + * @default Empty string + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sName": "engine", "aTargets": [ 0 ] }, + * { "sName": "browser", "aTargets": [ 1 ] }, + * { "sName": "platform", "aTargets": [ 2 ] }, + * { "sName": "version", "aTargets": [ 3 ] }, + * { "sName": "grade", "aTargets": [ 4 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "sName": "engine" }, + * { "sName": "browser" }, + * { "sName": "platform" }, + * { "sName": "version" }, + * { "sName": "grade" } + * ] + * } ); + * } ); + */ + "sName": "", + + + /** + * Defines a data source type for the sorting which can be used to read + * realtime information from the table (updating the internally cached + * version) prior to sorting. This allows sorting to occur on user editable + * elements such as form inputs. + * @type string + * @default std + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] }, + * { "sType": "numeric", "aTargets": [ 3 ] }, + * { "sSortDataType": "dom-select", "aTargets": [ 4 ] }, + * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * null, + * null, + * { "sSortDataType": "dom-text" }, + * { "sSortDataType": "dom-text", "sType": "numeric" }, + * { "sSortDataType": "dom-select" }, + * { "sSortDataType": "dom-checkbox" } + * ] + * } ); + * } ); + */ + "sSortDataType": "std", + + + /** + * The title of this column. + * @type string + * @default null Derived from the 'TH' value for this column in the + * original HTML table. + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sTitle": "My column title", "aTargets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "sTitle": "My column title" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sTitle": null, + + + /** + * The type allows you to specify how the data for this column will be sorted. + * Four types (string, numeric, date and html (which will strip HTML tags + * before sorting)) are currently available. Note that only date formats + * understood by Javascript's Date() object will be accepted as type date. For + * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric', + * 'date' or 'html' (by default). Further types can be adding through + * plug-ins. + * @type string + * @default null Auto-detected from raw data + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sType": "html", "aTargets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "sType": "html" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sType": null, + + + /** + * Defining the width of the column, this parameter may take any CSS value + * (3em, 20px etc). DataTables applys 'smart' widths to columns which have not + * been given a specific width through this interface ensuring that the table + * remains readable. + * @type string + * @default null Automatic + * @dtopt Columns + * + * @example + * // Using aoColumnDefs + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumnDefs": [ + * { "sWidth": "20%", "aTargets": [ 0 ] } + * ] + * } ); + * } ); + * + * @example + * // Using aoColumns + * $(document).ready(function() { + * $('#example').dataTable( { + * "aoColumns": [ + * { "sWidth": "20%" }, + * null, + * null, + * null, + * null + * ] + * } ); + * } ); + */ + "sWidth": null +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.js new file mode 100644 index 00000000..a2039401 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.defaults.js @@ -0,0 +1,1944 @@ + + +/** + * Initialisation options that can be given to DataTables at initialisation + * time. + * @namespace + */ +DataTable.defaults = { + /** + * An array of data to use for the table, passed in at initialisation which + * will be used in preference to any data which is already in the DOM. This is + * particularly useful for constructing tables purely in Javascript, for + * example with a custom Ajax call. + * @type array + * @default null + * @dtopt Option + * + * @example + * // Using a 2D array data source + * $(document).ready( function () { + * $('#example').dataTable( { + * "aaData": [ + * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], + * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], + * ], + * "aoColumns": [ + * { "sTitle": "Engine" }, + * { "sTitle": "Browser" }, + * { "sTitle": "Platform" }, + * { "sTitle": "Version" }, + * { "sTitle": "Grade" } + * ] + * } ); + * } ); + * + * @example + * // Using an array of objects as a data source (mDataProp) + * $(document).ready( function () { + * $('#example').dataTable( { + * "aaData": [ + * { + * "engine": "Trident", + * "browser": "Internet Explorer 4.0", + * "platform": "Win 95+", + * "version": 4, + * "grade": "X" + * }, + * { + * "engine": "Trident", + * "browser": "Internet Explorer 5.0", + * "platform": "Win 95+", + * "version": 5, + * "grade": "C" + * } + * ], + * "aoColumns": [ + * { "sTitle": "Engine", "mDataProp": "engine" }, + * { "sTitle": "Browser", "mDataProp": "browser" }, + * { "sTitle": "Platform", "mDataProp": "platform" }, + * { "sTitle": "Version", "mDataProp": "version" }, + * { "sTitle": "Grade", "mDataProp": "grade" } + * ] + * } ); + * } ); + */ + "aaData": null, + + + /** + * If sorting is enabled, then DataTables will perform a first pass sort on + * initialisation. You can define which column(s) the sort is performed upon, + * and the sorting direction, with this variable. The aaSorting array should + * contain an array for each column to be sorted initially containing the + * column's index and a direction string ('asc' or 'desc'). + * @type array + * @default [[0,'asc']] + * @dtopt Option + * + * @example + * // Sort by 3rd column first, and then 4th column + * $(document).ready( function() { + * $('#example').dataTable( { + * "aaSorting": [[2,'asc'], [3,'desc']] + * } ); + * } ); + * + * // No initial sorting + * $(document).ready( function() { + * $('#example').dataTable( { + * "aaSorting": [] + * } ); + * } ); + */ + "aaSorting": [[0,'asc']], + + + /** + * This parameter is basically identical to the aaSorting parameter, but + * cannot be overridden by user interaction with the table. What this means + * is that you could have a column (visible or hidden) which the sorting will + * always be forced on first - any sorting after that (from the user) will + * then be performed as required. This can be useful for grouping rows + * together. + * @type array + * @default null + * @dtopt Option + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "aaSortingFixed": [[0,'asc']] + * } ); + * } ) + */ + "aaSortingFixed": null, + + + /** + * This parameter allows you to readily specify the entries in the length drop + * down menu that DataTables shows when pagination is enabled. It can be + * either a 1D array of options which will be used for both the displayed + * option and the value, or a 2D array which will use the array in the first + * position as the value, and the array in the second position as the + * displayed options (useful for language strings such as 'All'). + * @type array + * @default [ 10, 25, 50, 100 ] + * @dtopt Option + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] + * } ); + * } ); + * + * @example + * // Setting the default display length as well as length menu + * // This is likely to be wanted if you remove the '10' option which + * // is the iDisplayLength default. + * $(document).ready(function() { + * $('#example').dataTable( { + * "iDisplayLength": 25, + * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]] + * } ); + * } ); + */ + "aLengthMenu": [ 10, 25, 50, 100 ], + + + /** + * The aoColumns option in the initialisation parameter allows you to define + * details about the way individual columns behave. For a full list of + * column options that can be set, please see + * {@link DataTable.defaults.columns}. Note that if you use aoColumns to + * define your columns, you must have an entry in the array for every single + * column that you have in your table (these can be null if you don't which + * to specify any options). + * @member + */ + "aoColumns": null, + + /** + * Very similar to aoColumns, aoColumnDefs allows you to target a specific + * column, multiple columns, or all columns, using the aTargets property of + * each object in the array. This allows great flexibility when creating + * tables, as the aoColumnDefs arrays can be of any length, targeting the + * columns you specifically want. aoColumnDefs may use any of the column + * options available: {@link DataTable.defaults.columns}, but it _must_ + * have aTargets defined in each object in the array. Values in the aTargets + * array may be: + *
          + *
        • a string - class name will be matched on the TH for the column
        • + *
        • 0 or a positive integer - column index counting from the left
        • + *
        • a negative integer - column index counting from the right
        • + *
        • the string "_all" - all columns (i.e. assign a default)
        • + *
        + * @member + */ + "aoColumnDefs": null, + + + /** + * Basically the same as oSearch, this parameter defines the individual column + * filtering state at initialisation time. The array must be of the same size + * as the number of columns, and each element be an object with the parameters + * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also + * accepted and the default will be used. + * @type array + * @default [] + * @dtopt Option + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "aoSearchCols": [ + * null, + * { "sSearch": "My filter" }, + * null, + * { "sSearch": "^[0-9]", "bEscapeRegex": false } + * ] + * } ); + * } ) + */ + "aoSearchCols": [], + + + /** + * An array of CSS classes that should be applied to displayed rows. This + * array may be of any length, and DataTables will apply each class + * sequentially, looping when required. + * @type array + * @default null Will take the values determinted by the oClasses.sStripe* + * options + * @dtopt Option + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ] + * } ); + * } ) + */ + "asStripeClasses": null, + + + /** + * Enable or disable automatic column width calculation. This can be disabled + * as an optimisation (it takes some time to calculate the widths) if the + * tables widths are passed in using aoColumns. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bAutoWidth": false + * } ); + * } ); + */ + "bAutoWidth": true, + + + /** + * Deferred rendering can provide DataTables with a huge speed boost when you + * are using an Ajax or JS data source for the table. This option, when set to + * true, will cause DataTables to defer the creation of the table elements for + * each row until they are needed for a draw - saving a significant amount of + * time. + * @type boolean + * @default false + * @dtopt Features + * + * @example + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sAjaxSource": "sources/arrays.txt", + * "bDeferRender": true + * } ); + * } ); + */ + "bDeferRender": false, + + + /** + * Replace a DataTable which matches the given selector and replace it with + * one which has the properties of the new initialisation object passed. If no + * table matches the selector, then the new DataTable will be constructed as + * per normal. + * @type boolean + * @default false + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sScrollY": "200px", + * "bPaginate": false + * } ); + * + * // Some time later.... + * $('#example').dataTable( { + * "bFilter": false, + * "bDestroy": true + * } ); + * } ); + */ + "bDestroy": false, + + + /** + * Enable or disable filtering of data. Filtering in DataTables is "smart" in + * that it allows the end user to input multiple words (space separated) and + * will match a row containing those words, even if not in the order that was + * specified (this allow matching across multiple columns). Note that if you + * wish to use filtering in DataTables this must remain 'true' - to remove the + * default filtering input box and retain filtering abilities, please use + * {@link DataTable.defaults.sDom}. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bFilter": false + * } ); + * } ); + */ + "bFilter": true, + + + /** + * Enable or disable the table information display. This shows information + * about the data that is currently visible on the page, including information + * about filtered data if that action is being performed. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bInfo": false + * } ); + * } ); + */ + "bInfo": true, + + + /** + * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some + * slightly different and additional mark-up from what DataTables has + * traditionally used). + * @type boolean + * @default false + * @dtopt Features + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "bJQueryUI": true + * } ); + * } ); + */ + "bJQueryUI": false, + + + /** + * Allows the end user to select the size of a formatted page from a select + * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate). + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bLengthChange": false + * } ); + * } ); + */ + "bLengthChange": true, + + + /** + * Enable or disable pagination. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bPaginate": false + * } ); + * } ); + */ + "bPaginate": true, + + + /** + * Enable or disable the display of a 'processing' indicator when the table is + * being processed (e.g. a sort). This is particularly useful for tables with + * large amounts of data where it can take a noticeable amount of time to sort + * the entries. + * @type boolean + * @default false + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bProcessing": true + * } ); + * } ); + */ + "bProcessing": false, + + + /** + * Retrieve the DataTables object for the given selector. Note that if the + * table has already been initialised, this parameter will cause DataTables + * to simply return the object that has already been set up - it will not take + * account of any changes you might have made to the initialisation object + * passed to DataTables (setting this parameter to true is an acknowledgement + * that you understand this). bDestroy can be used to reinitialise a table if + * you need. + * @type boolean + * @default false + * @dtopt Options + * + * @example + * $(document).ready(function() { + * initTable(); + * tableActions(); + * } ); + * + * function initTable () + * { + * return $('#example').dataTable( { + * "sScrollY": "200px", + * "bPaginate": false, + * "bRetrieve": true + * } ); + * } + * + * function tableActions () + * { + * var oTable = initTable(); + * // perform API operations with oTable + * } + */ + "bRetrieve": false, + + + /** + * Indicate if DataTables should be allowed to set the padding / margin + * etc for the scrolling header elements or not. Typically you will want + * this. + * @type boolean + * @default true + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bScrollAutoCss": false, + * "sScrollY": "200px" + * } ); + * } ); + */ + "bScrollAutoCss": true, + + + /** + * When vertical (y) scrolling is enabled, DataTables will force the height of + * the table's viewport to the given height at all times (useful for layout). + * However, this can look odd when filtering data down to a small data set, + * and the footer is left "floating" further down. This parameter (when + * enabled) will cause DataTables to collapse the table's viewport down when + * the result set will fit within the given Y height. + * @type boolean + * @default false + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sScrollY": "200", + * "bScrollCollapse": true + * } ); + * } ); + */ + "bScrollCollapse": false, + + + /** + * Enable infinite scrolling for DataTables (to be used in combination with + * sScrollY). Infinite scrolling means that DataTables will continually load + * data as a user scrolls through a table, which is very useful for large + * dataset. This cannot be used with pagination, which is automatically + * disabled. Note - the Scroller extra for DataTables is recommended in + * in preference to this option. + * @type boolean + * @default false + * @dtopt Features + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bScrollInfinite": true, + * "bScrollCollapse": true, + * "sScrollY": "200px" + * } ); + * } ); + */ + "bScrollInfinite": false, + + + /** + * Configure DataTables to use server-side processing. Note that the + * sAjaxSource parameter must also be given in order to give DataTables a + * source to obtain the required data for each draw. + * @type boolean + * @default false + * @dtopt Features + * @dtopt Server-side + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bServerSide": true, + * "sAjaxSource": "xhr.php" + * } ); + * } ); + */ + "bServerSide": false, + + + /** + * Enable or disable sorting of columns. Sorting of individual columns can be + * disabled by the "bSortable" option for each column. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bSort": false + * } ); + * } ); + */ + "bSort": true, + + + /** + * Allows control over whether DataTables should use the top (true) unique + * cell that is found for a single column, or the bottom (false - default). + * This is useful when using complex headers. + * @type boolean + * @default false + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bSortCellsTop": true + * } ); + * } ); + */ + "bSortCellsTop": false, + + + /** + * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and + * 'sorting_3' to the columns which are currently being sorted on. This is + * presented as a feature switch as it can increase processing time (while + * classes are removed and added) so for large data sets you might want to + * turn this off. + * @type boolean + * @default true + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bSortClasses": false + * } ); + * } ); + */ + "bSortClasses": true, + + + /** + * Enable or disable state saving. When enabled a cookie will be used to save + * table display information such as pagination information, display length, + * filtering and sorting. As such when the end user reloads the page the + * display display will match what thy had previously set up. + * @type boolean + * @default false + * @dtopt Features + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "bStateSave": true + * } ); + * } ); + */ + "bStateSave": false, + + + /** + * Customise the cookie and / or the parameters being stored when using + * DataTables with state saving enabled. This function is called whenever + * the cookie is modified, and it expects a fully formed cookie string to be + * returned. Note that the data object passed in is a Javascript object which + * must be converted to a string (JSON.stringify for example). + * @type function + * @param {string} sName Name of the cookie defined by DataTables + * @param {object} oData Data to be stored in the cookie + * @param {string} sExpires Cookie expires string + * @param {string} sPath Path of the cookie to set + * @returns {string} Cookie formatted string (which should be encoded by + * using encodeURIComponent()) + * @dtopt Callbacks + * + * @example + * $(document).ready( function () { + * $('#example').dataTable( { + * "fnCookieCallback": function (sName, oData, sExpires, sPath) { + * // Customise oData or sName or whatever else here + * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath; + * } + * } ); + * } ); + */ + "fnCookieCallback": null, + + + /** + * This function is called when a TR element is created (and all TD child + * elements have been inserted), or registered if using a DOM source, allowing + * manipulation of the TR element (adding classes etc). + * @type function + * @param {node} nRow "TR" element for the current row + * @param {array} aData Raw data array for this row + * @param {int} iDataIndex The index of this row in aoData + * @dtopt Callbacks + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "fnCreatedRow": function( nRow, aData, iDataIndex ) { + * // Bold the grade for all 'A' grade browsers + * if ( aData[4] == "A" ) + * { + * $('td:eq(4)', nRow).html( 'A' ); + * } + * } + * } ); + * } ); + */ + "fnCreatedRow": null, + + + /** + * This function is called on every 'draw' event, and allows you to + * dynamically modify any aspect you want about the created DOM. + * @type function + * @param {object} oSettings DataTables settings object + * @dtopt Callbacks + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "fnDrawCallback": function( oSettings ) { + * alert( 'DataTables has redrawn the table' ); + * } + * } ); + * } ); + */ + "fnDrawCallback": null, + + + /** + * Identical to fnHeaderCallback() but for the table footer this function + * allows you to modify the table footer on every 'draw' even. + * @type function + * @param {node} nFoot "TR" element for the footer + * @param {array} aData Full table data (as derived from the original HTML) + * @param {int} iStart Index for the current display starting point in the + * display array + * @param {int} iEnd Index for the current display ending point in the + * display array + * @param {array int} aiDisplay Index array to translate the visual position + * to the full data array + * @dtopt Callbacks + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) { + * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart; + * } + * } ); + * } ) + */ + "fnFooterCallback": null, + + + /** + * When rendering large numbers in the information element for the table + * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers + * to have a comma separator for the 'thousands' units (e.g. 1 million is + * rendered as "1,000,000") to help readability for the end user. This + * function will override the default method DataTables uses. + * @type function + * @member + * @param {int} iIn number to be formatted + * @returns {string} formatted string for DataTables to show the number + * @dtopt Callbacks + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "fnFormatNumber": function ( iIn ) { + * if ( iIn < 1000 ) { + * return iIn; + * } else { + * var + * s=(iIn+""), + * a=s.split(""), out="", + * iLen=s.length; + * + * for ( var i=0 ; i<iLen ; i++ ) { + * if ( i%3 === 0 && i !== 0 ) { + * out = "'"+out; + * } + * out = a[iLen-i-1]+out; + * } + * } + * return out; + * }; + * } ); + * } ); + */ + "fnFormatNumber": function ( iIn ) { + if ( iIn < 1000 ) + { + // A small optimisation for what is likely to be the majority of use cases + return iIn; + } + + var s=(iIn+""), a=s.split(""), out="", iLen=s.length; + + for ( var i=0 ; iA' ); + * } + * } + * } ); + * } ); + */ + "fnRowCallback": null, + + + /** + * This parameter allows you to override the default function which obtains + * the data from the server ($.getJSON) so something more suitable for your + * application. For example you could use POST data, or pull information from + * a Gears or AIR database. + * @type function + * @member + * @param {string} sSource HTTP source to obtain the data from (sAjaxSource) + * @param {array} aoData A key/value pair object containing the data to send + * to the server + * @param {function} fnCallback to be called on completion of the data get + * process that will draw the data on the page. + * @param {object} oSettings DataTables settings object + * @dtopt Callbacks + * @dtopt Server-side + * + * @example + * // POST data to server + * $(document).ready(function() { + * $('#example').dataTable( { + * "bProcessing": true, + * "bServerSide": true, + * "sAjaxSource": "xhr.php", + * "fnServerData": function ( sSource, aoData, fnCallback, oSettings ) { + * oSettings.jqXHR = $.ajax( { + * "dataType": 'json', + * "type": "POST", + * "url": sSource, + * "data": aoData, + * "success": fnCallback + * } ); + * } + * } ); + * } ); + */ + "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) { + oSettings.jqXHR = $.ajax( { + "url": sUrl, + "data": aoData, + "success": function (json) { + $(oSettings.oInstance).trigger('xhr', oSettings); + fnCallback( json ); + }, + "dataType": "json", + "cache": false, + "type": oSettings.sServerMethod, + "error": function (xhr, error, thrown) { + if ( error == "parsererror" ) { + oSettings.oApi._fnLog( oSettings, 0, "DataTables warning: JSON data from "+ + "server could not be parsed. This is caused by a JSON formatting error." ); + } + } + } ); + }, + + + /** + * It is often useful to send extra data to the server when making an Ajax + * request - for example custom filtering information, and this callback + * function makes it trivial to send extra information to the server. The + * passed in parameter is the data set that has been constructed by + * DataTables, and you can add to this or modify it as you require. + * @type function + * @param {array} aoData Data array (array of objects which are name/value + * pairs) that has been constructed by DataTables and will be sent to the + * server. In the case of Ajax sourced data with server-side processing + * this will be an empty array, for server-side processing there will be a + * significant number of parameters! + * @returns {undefined} Ensure that you modify the aoData array passed in, + * as this is passed by reference. + * @dtopt Callbacks + * @dtopt Server-side + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bProcessing": true, + * "bServerSide": true, + * "sAjaxSource": "scripts/server_processing.php", + * "fnServerParams": function ( aoData ) { + * aoData.push( { "name": "more_data", "value": "my_value" } ); + * } + * } ); + * } ); + */ + "fnServerParams": null, + + + /** + * Load the table state. With this function you can define from where, and how, the + * state of a table is loaded. By default DataTables will load from its state saving + * cookie, but you might wish to use local storage (HTML5) or a server-side database. + * @type function + * @member + * @param {object} oSettings DataTables settings object + * @return {object} The DataTables state object to be loaded + * @dtopt Callbacks + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateLoad": function (oSettings) { + * var o; + * + * // Send an Ajax request to the server to get the data. Note that + * // this is a synchronous request. + * $.ajax( { + * "url": "/state_load", + * "async": false, + * "dataType": "json", + * "success": function (json) { + * o = json; + * } + * } ); + * + * return o; + * } + * } ); + * } ); + */ + "fnStateLoad": function ( oSettings ) { + var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance ); + var oData; + + try { + oData = (typeof $.parseJSON === 'function') ? + $.parseJSON(sData) : eval( '('+sData+')' ); + } catch (e) { + oData = null; + } + + return oData; + }, + + + /** + * Callback which allows modification of the saved state prior to loading that state. + * This callback is called when the table is loading state from the stored data, but + * prior to the settings object being modified by the saved state. Note that for + * plug-in authors, you should use the 'stateLoadParams' event to load parameters for + * a plug-in. + * @type function + * @param {object} oSettings DataTables settings object + * @param {object} oData The state object that is to be loaded + * @dtopt Callbacks + * + * @example + * // Remove a saved filter, so filtering is never loaded + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateLoadParams": function (oSettings, oData) { + * oData.oSearch.sSearch = ""; + * } ); + * } ); + * + * @example + * // Disallow state loading by returning false + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateLoadParams": function (oSettings, oData) { + * return false; + * } ); + * } ); + */ + "fnStateLoadParams": null, + + + /** + * Callback that is called when the state has been loaded from the state saving method + * and the DataTables settings object has been modified as a result of the loaded state. + * @type function + * @param {object} oSettings DataTables settings object + * @param {object} oData The state object that was loaded + * @dtopt Callbacks + * + * @example + * // Show an alert with the filtering value that was saved + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateLoaded": function (oSettings, oData) { + * alert( 'Saved filter was: '+oData.oSearch.sSearch ); + * } ); + * } ); + */ + "fnStateLoaded": null, + + + /** + * Save the table state. This function allows you to define where and how the state + * information for the table is stored - by default it will use a cookie, but you + * might want to use local storage (HTML5) or a server-side database. + * @type function + * @member + * @param {object} oSettings DataTables settings object + * @param {object} oData The state object to be saved + * @dtopt Callbacks + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateSave": function (oSettings, oData) { + * // Send an Ajax request to the server with the state object + * $.ajax( { + * "url": "/state_save", + * "data": oData, + * "dataType": "json", + * "method": "POST" + * "success": function () {} + * } ); + * } + * } ); + * } ); + */ + "fnStateSave": function ( oSettings, oData ) { + this.oApi._fnCreateCookie( + oSettings.sCookiePrefix+oSettings.sInstance, + this.oApi._fnJsonString(oData), + oSettings.iCookieDuration, + oSettings.sCookiePrefix, + oSettings.fnCookieCallback + ); + }, + + + /** + * Callback which allows modification of the state to be saved. Called when the table + * has changed state a new state save is required. This method allows modification of + * the state saving object prior to actually doing the save, including addition or + * other state properties or modification. Note that for plug-in authors, you should + * use the 'stateSaveParams' event to save parameters for a plug-in. + * @type function + * @param {object} oSettings DataTables settings object + * @param {object} oData The state object to be saved + * @dtopt Callbacks + * + * @example + * // Remove a saved filter, so filtering is never saved + * $(document).ready(function() { + * $('#example').dataTable( { + * "bStateSave": true, + * "fnStateSaveParams": function (oSettings, oData) { + * oData.oSearch.sSearch = ""; + * } ); + * } ); + */ + "fnStateSaveParams": null, + + + /** + * Duration of the cookie which is used for storing session information. This + * value is given in seconds. + * @type int + * @default 7200 (2 hours) + * @dtopt Options + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "iCookieDuration": 60*60*24 // 1 day + * } ); + * } ) + */ + "iCookieDuration": 7200, + + + /** + * When enabled DataTables will not make a request to the server for the first + * page draw - rather it will use the data already on the page (no sorting etc + * will be applied to it), thus saving on an XHR at load time. iDeferLoading + * is used to indicate that deferred loading is required, but it is also used + * to tell DataTables how many records there are in the full table (allowing + * the information element and pagination to be displayed correctly). In the case + * where a filtering is applied to the table on initial load, this can be + * indicated by giving the parameter as an array, where the first element is + * the number of records available after filtering and the second element is the + * number of records without filtering (allowing the table information element + * to be shown correctly). + * @type int | array + * @default null + * @dtopt Options + * + * @example + * // 57 records available in the table, no filtering applied + * $(document).ready(function() { + * $('#example').dataTable( { + * "bServerSide": true, + * "sAjaxSource": "scripts/server_processing.php", + * "iDeferLoading": 57 + * } ); + * } ); + * + * @example + * // 57 records after filtering, 100 without filtering (an initial filter applied) + * $(document).ready(function() { + * $('#example').dataTable( { + * "bServerSide": true, + * "sAjaxSource": "scripts/server_processing.php", + * "iDeferLoading": [ 57, 100 ], + * "oSearch": { + * "sSearch": "my_filter" + * } + * } ); + * } ); + */ + "iDeferLoading": null, + + + /** + * Number of rows to display on a single page when using pagination. If + * feature enabled (bLengthChange) then the end user will be able to override + * this to a custom setting using a pop-up menu. + * @type int + * @default 10 + * @dtopt Options + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "iDisplayLength": 50 + * } ); + * } ) + */ + "iDisplayLength": 10, + + + /** + * Define the starting point for data display when using DataTables with + * pagination. Note that this parameter is the number of records, rather than + * the page number, so if you have 10 records per page and want to start on + * the third page, it should be "20". + * @type int + * @default 0 + * @dtopt Options + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "iDisplayStart": 20 + * } ); + * } ) + */ + "iDisplayStart": 0, + + + /** + * The scroll gap is the amount of scrolling that is left to go before + * DataTables will load the next 'page' of data automatically. You typically + * want a gap which is big enough that the scrolling will be smooth for the + * user, while not so large that it will load more data than need. + * @type int + * @default 100 + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bScrollInfinite": true, + * "bScrollCollapse": true, + * "sScrollY": "200px", + * "iScrollLoadGap": 50 + * } ); + * } ); + */ + "iScrollLoadGap": 100, + + + /** + * By default DataTables allows keyboard navigation of the table (sorting, paging, + * and filtering) by adding a tabindex attribute to the required elements. This + * allows you to tab through the controls and press the enter key to activate them. + * The tabindex is default 0, meaning that the tab follows the flow of the document. + * You can overrule this using this parameter if you wish. Use a value of -1 to + * disable built-in keyboard navigation. + * @type int + * @default 0 + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "iTabIndex": 1 + * } ); + * } ); + */ + "iTabIndex": 0, + + + /** + * All strings that DataTables uses in the user interface that it creates + * are defined in this object, allowing you to modified them individually or + * completely replace them all as required. + * @namespace + */ + "oLanguage": { + /** + * Strings that are used for WAI-ARIA labels and controls only (these are not + * actually visible on the page, but will be read by screenreaders, and thus + * must be internationalised as well). + * @namespace + */ + "oAria": { + /** + * ARIA label that is added to the table headers when the column may be + * sorted ascending by activing the column (click or return when focused). + * Note that the column header is prefixed to this string. + * @type string + * @default : activate to sort column ascending + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oAria": { + * "sSortAscending": " - click/return to sort ascending" + * } + * } + * } ); + * } ); + */ + "sSortAscending": ": activate to sort column ascending", + + /** + * ARIA label that is added to the table headers when the column may be + * sorted descending by activing the column (click or return when focused). + * Note that the column header is prefixed to this string. + * @type string + * @default : activate to sort column ascending + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oAria": { + * "sSortDescending": " - click/return to sort descending" + * } + * } + * } ); + * } ); + */ + "sSortDescending": ": activate to sort column descending" + }, + + /** + * Pagination string used by DataTables for the two built-in pagination + * control types ("two_button" and "full_numbers") + * @namespace + */ + "oPaginate": { + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the first page. + * @type string + * @default First + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oPaginate": { + * "sFirst": "First page" + * } + * } + * } ); + * } ); + */ + "sFirst": "First", + + + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the last page. + * @type string + * @default Last + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oPaginate": { + * "sLast": "Last page" + * } + * } + * } ); + * } ); + */ + "sLast": "Last", + + + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the next page. + * @type string + * @default Next + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oPaginate": { + * "sNext": "Next page" + * } + * } + * } ); + * } ); + */ + "sNext": "Next", + + + /** + * Text to use when using the 'full_numbers' type of pagination for the + * button to take the user to the previous page. + * @type string + * @default Previous + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "oPaginate": { + * "sPrevious": "Previous page" + * } + * } + * } ); + * } ); + */ + "sPrevious": "Previous" + }, + + /** + * This string is shown in preference to sZeroRecords when the table is + * empty of data (regardless of filtering). Note that this is an optional + * parameter - if it is not given, the value of sZeroRecords will be used + * instead (either the default or given value). + * @type string + * @default No data available in table + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sEmptyTable": "No data available in table" + * } + * } ); + * } ); + */ + "sEmptyTable": "No data available in table", + + + /** + * This string gives information to the end user about the information that + * is current on display on the page. The _START_, _END_ and _TOTAL_ + * variables are all dynamically replaced as the table display updates, and + * can be freely moved or removed as the language requirements change. + * @type string + * @default Showing _START_ to _END_ of _TOTAL_ entries + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)" + * } + * } ); + * } ); + */ + "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + + + /** + * Display information string for when the table is empty. Typically the + * format of this string should match sInfo. + * @type string + * @default Showing 0 to 0 of 0 entries + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sInfoEmpty": "No entries to show" + * } + * } ); + * } ); + */ + "sInfoEmpty": "Showing 0 to 0 of 0 entries", + + + /** + * When a user filters the information in a table, this string is appended + * to the information (sInfo) to give an idea of how strong the filtering + * is. The variable _MAX_ is dynamically updated. + * @type string + * @default (filtered from _MAX_ total entries) + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sInfoFiltered": " - filtering from _MAX_ records" + * } + * } ); + * } ); + */ + "sInfoFiltered": "(filtered from _MAX_ total entries)", + + + /** + * If can be useful to append extra information to the info string at times, + * and this variable does exactly that. This information will be appended to + * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are + * being used) at all times. + * @type string + * @default Empty string + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sInfoPostFix": "All records shown are derived from real information." + * } + * } ); + * } ); + */ + "sInfoPostFix": "", + + + /** + * DataTables has a build in number formatter (fnFormatNumber) which is used + * to format large numbers that are used in the table information. By + * default a comma is used, but this can be trivially changed to any + * character you wish with this parameter. + * @type string + * @default , + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sInfoThousands": "'" + * } + * } ); + * } ); + */ + "sInfoThousands": ",", + + + /** + * Detail the action that will be taken when the drop down menu for the + * pagination length option is changed. The '_MENU_' variable is replaced + * with a default select list of 10, 25, 50 and 100, and can be replaced + * with a custom select box if required. + * @type string + * @default Show _MENU_ entries + * @dtopt Language + * + * @example + * // Language change only + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sLengthMenu": "Display _MENU_ records" + * } + * } ); + * } ); + * + * @example + * // Language and options change + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sLengthMenu": 'Display records' + * } + * } ); + * } ); + */ + "sLengthMenu": "Show _MENU_ entries", + + + /** + * When using Ajax sourced data and during the first draw when DataTables is + * gathering the data, this message is shown in an empty row in the table to + * indicate to the end user the the data is being loaded. Note that this + * parameter is not used when loading data by server-side processing, just + * Ajax sourced data with client-side processing. + * @type string + * @default Loading... + * @dtopt Language + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sLoadingRecords": "Please wait - loading..." + * } + * } ); + * } ); + */ + "sLoadingRecords": "Loading...", + + + /** + * Text which is displayed when the table is processing a user action + * (usually a sort command or similar). + * @type string + * @default Processing... + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sProcessing": "DataTables is currently busy" + * } + * } ); + * } ); + */ + "sProcessing": "Processing...", + + + /** + * Details the actions that will be taken when the user types into the + * filtering input text box. The variable "_INPUT_", if used in the string, + * is replaced with the HTML text box for the filtering input allowing + * control over where it appears in the string. If "_INPUT_" is not given + * then the input box is appended to the string automatically. + * @type string + * @default Search: + * @dtopt Language + * + * @example + * // Input text box will be appended at the end automatically + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sSearch": "Filter records:" + * } + * } ); + * } ); + * + * @example + * // Specify where the filter should appear + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sSearch": "Apply filter _INPUT_ to table" + * } + * } ); + * } ); + */ + "sSearch": "Search:", + + + /** + * All of the language information can be stored in a file on the + * server-side, which DataTables will look up if this parameter is passed. + * It must store the URL of the language file, which is in a JSON format, + * and the object has the same properties as the oLanguage object in the + * initialiser object (i.e. the above parameters). Please refer to one of + * the example language files to see how this works in action. + * @type string + * @default Empty string - i.e. disabled + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt" + * } + * } ); + * } ); + */ + "sUrl": "", + + + /** + * Text shown inside the table records when the is no information to be + * displayed after filtering. sEmptyTable is shown when there is simply no + * information in the table at all (regardless of filtering). + * @type string + * @default No matching records found + * @dtopt Language + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "oLanguage": { + * "sZeroRecords": "No records to display" + * } + * } ); + * } ); + */ + "sZeroRecords": "No matching records found" + }, + + + /** + * This parameter allows you to have define the global filtering state at + * initialisation time. As an object the "sSearch" parameter must be + * defined, but all other parameters are optional. When "bRegex" is true, + * the search string will be treated as a regular expression, when false + * (default) it will be treated as a straight string. When "bSmart" + * DataTables will use it's smart filtering methods (to word match at + * any point in the data), when false this will not be done. + * @namespace + * @extends DataTable.models.oSearch + * @dtopt Options + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "oSearch": {"sSearch": "Initial search"} + * } ); + * } ) + */ + "oSearch": $.extend( {}, DataTable.models.oSearch ), + + + /** + * By default DataTables will look for the property 'aaData' when obtaining + * data from an Ajax source or for server-side processing - this parameter + * allows that property to be changed. You can use Javascript dotted object + * notation to get a data source for multiple levels of nesting. + * @type string + * @default aaData + * @dtopt Options + * @dtopt Server-side + * + * @example + * // Get data from { "data": [...] } + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sAjaxSource": "sources/data.txt", + * "sAjaxDataProp": "data" + * } ); + * } ); + * + * @example + * // Get data from { "data": { "inner": [...] } } + * $(document).ready(function() { + * var oTable = $('#example').dataTable( { + * "sAjaxSource": "sources/data.txt", + * "sAjaxDataProp": "data.inner" + * } ); + * } ); + */ + "sAjaxDataProp": "aaData", + + + /** + * You can instruct DataTables to load data from an external source using this + * parameter (use aData if you want to pass data in you already have). Simply + * provide a url a JSON object can be obtained from. This object must include + * the parameter 'aaData' which is the data source for the table. + * @type string + * @default null + * @dtopt Options + * @dtopt Server-side + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php" + * } ); + * } ) + */ + "sAjaxSource": null, + + + /** + * This parameter can be used to override the default prefix that DataTables + * assigns to a cookie when state saving is enabled. + * @type string + * @default SpryMedia_DataTables_ + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sCookiePrefix": "my_datatable_", + * } ); + * } ); + */ + "sCookiePrefix": "SpryMedia_DataTables_", + + + /** + * This initialisation variable allows you to specify exactly where in the + * DOM you want DataTables to inject the various controls it adds to the page + * (for example you might want the pagination controls at the top of the + * table). DIV elements (with or without a custom class) can also be added to + * aid styling. The follow syntax is used: + *
          + *
        • The following options are allowed: + *
            + *
          • 'l' - Length changing
          • 'f' - Filtering input + *
          • 't' - The table!
          • + *
          • 'i' - Information
          • + *
          • 'p' - Pagination
          • + *
          • 'r' - pRocessing
          • + *
          + *
        • + *
        • The following constants are allowed: + *
            + *
          • 'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')
          • + *
          • 'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')
          • + *
          + *
        • + *
        • The following syntax is expected: + *
            + *
          • '<' and '>' - div elements
          • + *
          • '<"class" and '>' - div with a class
          • + *
          • '<"#id" and '>' - div with an ID
          • + *
          + *
        • + *
        • Examples: + *
            + *
          • '<"wrapper"flipt>'
          • + *
          • '<lf<t>ip>'
          • + *
          + *
        • + *
        + * @type string + * @default lfrtip (when bJQueryUI is false) or + * <"H"lfr>t<"F"ip> (when bJQueryUI is true) + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sDom": '<"top"i>rt<"bottom"flp><"clear">' + * } ); + * } ); + */ + "sDom": "lfrtip", + + + /** + * DataTables features two different built-in pagination interaction methods + * ('two_button' or 'full_numbers') which present different page controls to + * the end user. Further methods can be added using the API (see below). + * @type string + * @default two_button + * @dtopt Options + * + * @example + * $(document).ready( function() { + * $('#example').dataTable( { + * "sPaginationType": "full_numbers" + * } ); + * } ) + */ + "sPaginationType": "two_button", + + + /** + * Enable horizontal scrolling. When a table is too wide to fit into a certain + * layout, or you have a large number of columns in the table, you can enable + * x-scrolling to show the table in a viewport, which can be scrolled. This + * property can be any CSS unit, or a number (in which case it will be treated + * as a pixel measurement). + * @type string + * @default blank string - i.e. disabled + * @dtopt Features + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sScrollX": "100%", + * "bScrollCollapse": true + * } ); + * } ); + */ + "sScrollX": "", + + + /** + * This property can be used to force a DataTable to use more width than it + * might otherwise do when x-scrolling is enabled. For example if you have a + * table which requires to be well spaced, this parameter is useful for + * "over-sizing" the table, and thus forcing scrolling. This property can by + * any CSS unit, or a number (in which case it will be treated as a pixel + * measurement). + * @type string + * @default blank string - i.e. disabled + * @dtopt Options + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sScrollX": "100%", + * "sScrollXInner": "110%" + * } ); + * } ); + */ + "sScrollXInner": "", + + + /** + * Enable vertical scrolling. Vertical scrolling will constrain the DataTable + * to the given height, and enable scrolling for any data which overflows the + * current viewport. This can be used as an alternative to paging to display + * a lot of data in a small area (although paging and scrolling can both be + * enabled at the same time). This property can be any CSS unit, or a number + * (in which case it will be treated as a pixel measurement). + * @type string + * @default blank string - i.e. disabled + * @dtopt Features + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "sScrollY": "200px", + * "bPaginate": false + * } ); + * } ); + */ + "sScrollY": "", + + + /** + * Set the HTTP method that is used to make the Ajax call for server-side + * processing or Ajax sourced data. + * @type string + * @default GET + * @dtopt Options + * @dtopt Server-side + * + * @example + * $(document).ready(function() { + * $('#example').dataTable( { + * "bServerSide": true, + * "sAjaxSource": "scripts/post.php", + * "sServerMethod": "POST" + * } ); + * } ); + */ + "sServerMethod": "GET" +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.ext.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.ext.js new file mode 100644 index 00000000..7483984d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.ext.js @@ -0,0 +1,528 @@ + + +/** + * DataTables extension options and plug-ins. This namespace acts as a collection "area" + * for plug-ins that can be used to extend the default DataTables behaviour - indeed many + * of the build in methods use this method to provide their own capabilities (sorting methods + * for example). + * + * Note that this namespace is aliased to jQuery.fn.dataTableExt so it can be readily accessed + * and modified by plug-ins. + * @namespace + */ +DataTable.models.ext = { + /** + * Plug-in filtering functions - this method of filtering is complimentary to the default + * type based filtering, and a lot more comprehensive as it allows you complete control + * over the filtering logic. Each element in this array is a function (parameters + * described below) that is called for every row in the table, and your logic decides if + * it should be included in the filtered data set or not. + *
          + *
        • + * Function input parameters: + *
            + *
          • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
          • + *
          • {array|object} Data for the row to be processed (same as the original format + * that was passed in as the data source, or an array from a DOM data source
          • + *
          • {int} Row index in aoData ({@link DataTable.models.oSettings.aoData}), which can + * be useful to retrieve the TR element if you need DOM interaction.
          • + *
          + *
        • + *
        • + * Function return: + *
            + *
          • {boolean} Include the row in the filtered result set (true) or not (false)
          • + *
          + * + *
        + * @type array + * @default [] + * + * @example + * // The following example shows custom filtering being applied to the fourth column (i.e. + * // the aData[3] index) based on two input values from the end-user, matching the data in + * // a certain range. + * $.fn.dataTableExt.afnFiltering.push( + * function( oSettings, aData, iDataIndex ) { + * var iMin = document.getElementById('min').value * 1; + * var iMax = document.getElementById('max').value * 1; + * var iVersion = aData[3] == "-" ? 0 : aData[3]*1; + * if ( iMin == "" && iMax == "" ) { + * return true; + * } + * else if ( iMin == "" && iVersion < iMax ) { + * return true; + * } + * else if ( iMin < iVersion && "" == iMax ) { + * return true; + * } + * else if ( iMin < iVersion && iVersion < iMax ) { + * return true; + * } + * return false; + * } + * ); + */ + "afnFiltering": [], + + + /** + * Plug-in sorting functions - this method of sorting is complimentary to the default type + * based sorting that DataTables does automatically, allowing much greater control over the + * the data that is being used to sort a column. This is useful if you want to do sorting + * based on live data (for example the contents of an 'input' element) rather than just the + * static string that DataTables knows of. The way these plug-ins work is that you create + * an array of the values you wish to be sorted for the column in question and then return + * that array. Which pre-sorting function is run here depends on the sSortDataType parameter + * that is used for the column (if any). This is the corollary of ofnSearch for sort + * data. + *
          + *
        • + * Function input parameters: + *
            + *
          • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
          • + *
          • {int} Target column index
          • + *
          + *
        • + *
        • + * Function return: + *
            + *
          • {array} Data for the column to be sorted upon
          • + *
          + * + *
        + * + * Note that as of v1.9, it is typically preferable to use mDataProp to prepare data for + * the different uses that DataTables can put the data to. Specifically mDataProp when + * used as a function will give you a 'type' (sorting, filtering etc) that you can use to + * prepare the data as required for the different types. As such, this method is deprecated. + * @type array + * @default [] + * @deprecated + * + * @example + * // Updating the cached sorting information with user entered values in HTML input elements + * jQuery.fn.dataTableExt.afnSortData['dom-text'] = function ( oSettings, iColumn ) + * { + * var aData = []; + * $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () { + * aData.push( this.value ); + * } ); + * return aData; + * } + */ + "afnSortData": [], + + + /** + * Feature plug-ins - This is an array of objects which describe the feature plug-ins that are + * available to DataTables. These feature plug-ins are accessible through the sDom initialisation + * option. As such, each feature plug-in must describe a function that is used to initialise + * itself (fnInit), a character so the feature can be enabled by sDom (cFeature) and the name + * of the feature (sFeature). Thus the objects attached to this method must provide: + *
          + *
        • {function} fnInit Initialisation of the plug-in + *
            + *
          • + * Function input parameters: + *
              + *
            • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
            • + *
            + *
          • + *
          • + * Function return: + *
              + *
            • {node|null} The element which contains your feature. Note that the return + * may also be void if your plug-in does not require to inject any DOM elements + * into DataTables control (sDom) - for example this might be useful when + * developing a plug-in which allows table control via keyboard entry.
            • + *
            + * + *
          + *
        • + *
        • {character} cFeature Character that will be matched in sDom - case sensitive
        • + *
        • {string} sFeature Feature name
        • + *
        + * @type array + * @default [] + * + * @example + * // How TableTools initialises itself. + * $.fn.dataTableExt.aoFeatures.push( { + * "fnInit": function( oSettings ) { + * return new TableTools( { "oDTSettings": oSettings } ); + * }, + * "cFeature": "T", + * "sFeature": "TableTools" + * } ); + */ + "aoFeatures": [], + + + /** + * Type detection plug-in functions - DataTables utilises types to define how sorting and + * filtering behave, and types can be either be defined by the developer (sType for the + * column) or they can be automatically detected by the methods in this array. The functions + * defined in the array are quite simple, taking a single parameter (the data to analyse) + * and returning the type if it is a known type, or null otherwise. + *
          + *
        • + * Function input parameters: + *
            + *
          • {*} Data from the column cell to be analysed
          • + *
          + *
        • + *
        • + * Function return: + *
            + *
          • {string|null} Data type detected, or null if unknown (and thus pass it + * on to the other type detection functions.
          • + *
          + * + *
        + * @type array + * @default [] + * + * @example + * // Currency type detection plug-in: + * jQuery.fn.dataTableExt.aTypes.push( + * function ( sData ) { + * var sValidChars = "0123456789.-"; + * var Char; + * + * // Check the numeric part + * for ( i=1 ; iafnSortData
        for filtering data. + *
          + *
        • + * Function input parameters: + *
            + *
          • {*} Data from the column cell to be prepared for filtering
          • + *
          + *
        • + *
        • + * Function return: + *
            + *
          • {string|null} Formatted string that will be used for the filtering.
          • + *
          + * + *
        + * + * Note that as of v1.9, it is typically preferable to use mDataProp to prepare data for + * the different uses that DataTables can put the data to. Specifically mDataProp when + * used as a function will give you a 'type' (sorting, filtering etc) that you can use to + * prepare the data as required for the different types. As such, this method is deprecated. + * @type object + * @default {} + * @deprecated + * + * @example + * $.fn.dataTableExt.ofnSearch['title-numeric'] = function ( sData ) { + * return sData.replace(/\n/g," ").replace( /<.*?>/g, "" ); + * } + */ + "ofnSearch": {}, + + + /** + * Container for all private functions in DataTables so they can be exposed externally + * @type object + * @default {} + */ + "oApi": {}, + + + /** + * Storage for the various classes that DataTables uses + * @type object + * @default {} + */ + "oStdClasses": {}, + + + /** + * Storage for the various classes that DataTables uses - jQuery UI suitable + * @type object + * @default {} + */ + "oJUIClasses": {}, + + + /** + * Pagination plug-in methods - The style and controls of the pagination can significantly + * impact on how the end user interacts with the data in your table, and DataTables allows + * the addition of pagination controls by extending this object, which can then be enabled + * through the sPaginationType initialisation parameter. Each pagination type that + * is added is an object (the property name of which is what sPaginationType refers + * to) that has two properties, both methods that are used by DataTables to update the + * control's state. + *
          + *
        • + * fnInit - Initialisation of the paging controls. Called only during initialisation + * of the table. It is expected that this function will add the required DOM elements + * to the page for the paging controls to work. The element pointer + * 'oSettings.aanFeatures.p' array is provided by DataTables to contain the paging + * controls (note that this is a 2D array to allow for multiple instances of each + * DataTables DOM element). It is suggested that you add the controls to this element + * as children + *
            + *
          • + * Function input parameters: + *
              + *
            • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
            • + *
            • {node} Container into which the pagination controls must be inserted
            • + *
            • {function} Draw callback function - whenever the controls cause a page + * change, this method must be called to redraw the table.
            • + *
            + *
          • + *
          • + * Function return: + *
              + *
            • No return required
            • + *
            + * + *
          + * + *
        • + * fnInit - This function is called whenever the paging status of the table changes and is + * typically used to update classes and/or text of the paging controls to reflex the new + * status. + *
            + *
          • + * Function input parameters: + *
              + *
            • {object} DataTables settings object: see {@link DataTable.models.oSettings}.
            • + *
            • {function} Draw callback function - in case you need to redraw the table again + * or attach new event listeners
            • + *
            + *
          • + *
          • + * Function return: + *
              + *
            • No return required
            • + *
            + * + *
          + * + *
        + * @type object + * @default {} + * + * @example + * $.fn.dataTableExt.oPagination.four_button = { + * "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) { + * nFirst = document.createElement( 'span' ); + * nPrevious = document.createElement( 'span' ); + * nNext = document.createElement( 'span' ); + * nLast = document.createElement( 'span' ); + * + * nFirst.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sFirst ) ); + * nPrevious.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sPrevious ) ); + * nNext.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sNext ) ); + * nLast.appendChild( document.createTextNode( oSettings.oLanguage.oPaginate.sLast ) ); + * + * nFirst.className = "paginate_button first"; + * nPrevious.className = "paginate_button previous"; + * nNext.className="paginate_button next"; + * nLast.className = "paginate_button last"; + * + * nPaging.appendChild( nFirst ); + * nPaging.appendChild( nPrevious ); + * nPaging.appendChild( nNext ); + * nPaging.appendChild( nLast ); + * + * $(nFirst).click( function () { + * oSettings.oApi._fnPageChange( oSettings, "first" ); + * fnCallbackDraw( oSettings ); + * } ); + * + * $(nPrevious).click( function() { + * oSettings.oApi._fnPageChange( oSettings, "previous" ); + * fnCallbackDraw( oSettings ); + * } ); + * + * $(nNext).click( function() { + * oSettings.oApi._fnPageChange( oSettings, "next" ); + * fnCallbackDraw( oSettings ); + * } ); + * + * $(nLast).click( function() { + * oSettings.oApi._fnPageChange( oSettings, "last" ); + * fnCallbackDraw( oSettings ); + * } ); + * + * $(nFirst).bind( 'selectstart', function () { return false; } ); + * $(nPrevious).bind( 'selectstart', function () { return false; } ); + * $(nNext).bind( 'selectstart', function () { return false; } ); + * $(nLast).bind( 'selectstart', function () { return false; } ); + * }, + * + * "fnUpdate": function ( oSettings, fnCallbackDraw ) { + * if ( !oSettings.aanFeatures.p ) { + * return; + * } + * + * // Loop over each instance of the pager + * var an = oSettings.aanFeatures.p; + * for ( var i=0, iLen=an.length ; i + *
      • + * Function input parameters: + *
          + *
        • {*} Data to compare to the second parameter
        • + *
        • {*} Data to compare to the first parameter
        • + *
        + *
      • + *
      • + * Function return: + *
          + *
        • {int} Sorting match: <0 if first parameter should be sorted lower than + * the second parameter, ===0 if the two parameters are equal and >0 if + * the first parameter should be sorted height than the second parameter.
        • + *
        + * + * + * @type object + * @default {} + * + * @example + * // Case-sensitive string sorting, with no pre-formatting method + * $.extend( $.fn.dataTableExt.oSort, { + * "string-case-asc": function(x,y) { + * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + * }, + * "string-case-desc": function(x,y) { + * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + * } + * } ); + * + * @example + * // Case-insensitive string sorting, with pre-formatting + * $.extend( $.fn.dataTableExt.oSort, { + * "string-pre": function(x) { + * return x.toLowerCase(); + * }, + * "string-asc": function(x,y) { + * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + * }, + * "string-desc": function(x,y) { + * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + * } + * } ); + */ + "oSort": {}, + + + /** + * Version string for plug-ins to check compatibility. Allowed format is + * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and + * e are optional + * @type string + * @default Version number + */ + "sVersion": DataTable.version, + + + /** + * How should DataTables report an error. Can take the value 'alert' or 'throw' + * @type string + * @default alert + */ + "sErrMode": "alert", + + + /** + * Store information for DataTables to access globally about other instances + * @namespace + * @private + */ + "_oExternConfig": { + /* int:iNextUnique - next unique number for an instance */ + "iNextUnique": 0 + } +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.row.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.row.js new file mode 100644 index 00000000..f88ec698 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.row.js @@ -0,0 +1,64 @@ + + + +/** + * Template object for the way in which DataTables holds information about + * each individual row. This is the object format used for the settings + * aoData array. + * @namespace + */ +DataTable.models.oRow = { + /** + * TR element for the row + * @type node + * @default null + */ + "nTr": null, + + /** + * Data object from the original data source for the row. This is either + * an array if using the traditional form of DataTables, or an object if + * using mDataProp options. The exact type will depend on the passed in + * data from the data source, or will be an array if using DOM a data + * source. + * @type array|object + * @default [] + */ + "_aData": [], + + /** + * Sorting data cache - this array is ostensibly the same length as the + * number of columns (although each index is generated only as it is + * needed), and holds the data that is used for sorting each column in the + * row. We do this cache generation at the start of the sort in order that + * the formatting of the sort data need be done only once for each cell + * per sort. This array should not be read from or written to by anything + * other than the master sorting methods. + * @type array + * @default [] + * @private + */ + "_aSortData": [], + + /** + * Array of TD elements that are cached for hidden rows, so they can be + * reinserted into the table if a column is made visible again (or to act + * as a store if a column is made hidden). Only hidden columns have a + * reference in the array. For non-hidden columns the value is either + * undefined or null. + * @type array nodes + * @default [] + * @private + */ + "_anHidden": [], + + /** + * Cache of the class name that DataTables has applied to the row, so we + * can quickly look at this variable rather than needing to do a DOM check + * on className for the nTr property. + * @type string + * @default Empty string + * @private + */ + "_sRowStripe": "" +}; diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.search.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.search.js new file mode 100644 index 00000000..455fa297 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.search.js @@ -0,0 +1,40 @@ + + + +/** + * Template object for the way in which DataTables holds information about + * search information for the global filter and individual column filters. + * @namespace + */ +DataTable.models.oSearch = { + /** + * Flag to indicate if the filtering should be case insensitive or not + * @type boolean + * @default true + */ + "bCaseInsensitive": true, + + /** + * Applied search term + * @type string + * @default Empty string + */ + "sSearch": "", + + /** + * Flag to indicate if the search term should be interpreted as a + * regular expression (true) or not (false) and therefore and special + * regex characters escaped. + * @type boolean + * @default false + */ + "bRegex": false, + + /** + * Flag to indicate if DataTables is to use its smart filtering or not. + * @type boolean + * @default true + */ + "bSmart": true +}; + diff --git a/wqflask/wqflask/static/new/packages/DataTables/src/model/model.settings.js b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.settings.js new file mode 100644 index 00000000..6d66e9e6 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/src/model/model.settings.js @@ -0,0 +1,868 @@ + + +/** + * DataTables settings object - this holds all the information needed for a + * given table, including configuration, data and current application of the + * table options. DataTables does not have a single instance for each DataTable + * with the settings attached to that instance, but rather instances of the + * DataTable "class" are created on-the-fly as needed (typically by a + * $().dataTable() call) and the settings object is then applied to that + * instance. + * + * Note that this object is related to {@link DataTable.defaults} but this + * one is the internal data store for DataTables's cache of columns. It should + * NOT be manipulated outside of DataTables. Any configuration should be done + * through the initialisation options. + * @namespace + * @todo Really should attach the settings object to individual instances so we + * don't need to create new instances on each $().dataTable() call (if the + * table already exists). It would also save passing oSettings around and + * into every single function. However, this is a very significant + * architecture change for DataTables and will almost certainly break + * backwards compatibility with older installations. This is something that + * will be done in 2.0. + */ +DataTable.models.oSettings = { + /** + * Primary features of DataTables and their enablement state. + * @namespace + */ + "oFeatures": { + + /** + * Flag to say if DataTables should automatically try to calculate the + * optimum table and columns widths (true) or not (false). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bAutoWidth": null, + + /** + * Delay the creation of TR and TD elements until they are actually + * needed by a driven page draw. This can give a significant speed + * increase for Ajax source and Javascript source data, but makes no + * difference at all fro DOM and server-side processing tables. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bDeferRender": null, + + /** + * Enable filtering on the table or not. Note that if this is disabled + * then there is no filtering at all on the table, including fnFilter. + * To just remove the filtering input use sDom and remove the 'f' option. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bFilter": null, + + /** + * Table information element (the 'Showing x of y records' div) enable + * flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bInfo": null, + + /** + * Present a user control allowing the end user to change the page size + * when pagination is enabled. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bLengthChange": null, + + /** + * Pagination enabled or not. Note that if this is disabled then length + * changing must also be disabled. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bPaginate": null, + + /** + * Processing indicator enable flag whenever DataTables is enacting a + * user request - typically an Ajax request for server-side processing. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bProcessing": null, + + /** + * Server-side processing enabled flag - when enabled DataTables will + * get all data from the server for every draw - there is no filtering, + * sorting or paging done on the client-side. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bServerSide": null, + + /** + * Sorting enablement flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSort": null, + + /** + * Apply a class to the columns which are being sorted to provide a + * visual highlight or not. This can slow things down when enabled since + * there is a lot of DOM interaction. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSortClasses": null, + + /** + * State saving enablement flag. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bStateSave": null + }, + + + /** + * Scrolling settings for a table. + * @namespace + */ + "oScroll": { + /** + * Indicate if DataTables should be allowed to set the padding / margin + * etc for the scrolling header elements or not. Typically you will want + * this. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bAutoCss": null, + + /** + * When the table is shorter in height than sScrollY, collapse the + * table container down to the height of the table (when true). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bCollapse": null, + + /** + * Infinite scrolling enablement flag. Now deprecated in favour of + * using the Scroller plug-in. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bInfinite": null, + + /** + * Width of the scrollbar for the web-browser's platform. Calculated + * during table initialisation. + * @type int + * @default 0 + */ + "iBarWidth": 0, + + /** + * Space (in pixels) between the bottom of the scrolling container and + * the bottom of the scrolling viewport before the next page is loaded + * when using infinite scrolling. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type int + */ + "iLoadGap": null, + + /** + * Viewport width for horizontal scrolling. Horizontal scrolling is + * disabled if an empty string. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sX": null, + + /** + * Width to expand the table to when using x-scrolling. Typically you + * should not need to use this. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @deprecated + */ + "sXInner": null, + + /** + * Viewport height for vertical scrolling. Vertical scrolling is disabled + * if an empty string. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sY": null + }, + + /** + * Language information for the table. + * @namespace + * @extends DataTable.defaults.oLanguage + */ + "oLanguage": { + /** + * Information callback function. See + * {@link DataTable.defaults.fnInfoCallback} + * @type function + * @default + */ + "fnInfoCallback": null + }, + + /** + * Array referencing the nodes which are used for the features. The + * parameters of this object match what is allowed by sDom - i.e. + *
          + *
        • 'l' - Length changing
        • + *
        • 'f' - Filtering input
        • + *
        • 't' - The table!
        • + *
        • 'i' - Information
        • + *
        • 'p' - Pagination
        • + *
        • 'r' - pRocessing
        • + *
        + * @type array + * @default [] + */ + "aanFeatures": [], + + /** + * Store data information - see {@link DataTable.models.oRow} for detailed + * information. + * @type array + * @default [] + */ + "aoData": [], + + /** + * Array of indexes which are in the current display (after filtering etc) + * @type array + * @default [] + */ + "aiDisplay": [], + + /** + * Array of indexes for display - no filtering + * @type array + * @default [] + */ + "aiDisplayMaster": [], + + /** + * Store information about each column that is in use + * @type array + * @default [] + */ + "aoColumns": [], + + /** + * Store information about the table's header + * @type array + * @default [] + */ + "aoHeader": [], + + /** + * Store information about the table's footer + * @type array + * @default [] + */ + "aoFooter": [], + + /** + * Search data array for regular expression searching + * @type array + * @default [] + */ + "asDataSearch": [], + + /** + * Store the applied global search information in case we want to force a + * research or compare the old search to a new one. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @namespace + * @extends DataTable.models.oSearch + */ + "oPreviousSearch": {}, + + /** + * Store the applied search for each column - see + * {@link DataTable.models.oSearch} for the format that is used for the + * filtering information for each column. + * @type array + * @default [] + */ + "aoPreSearchCols": [], + + /** + * Sorting that is applied to the table. Note that the inner arrays are + * used in the following manner: + *
          + *
        • Index 0 - column number
        • + *
        • Index 1 - current sorting direction
        • + *
        • Index 2 - index of asSorting for this column
        • + *
        + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @todo These inner arrays should really be objects + */ + "aaSorting": null, + + /** + * Sorting that is always applied to the table (i.e. prefixed in front of + * aaSorting). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array|null + * @default null + */ + "aaSortingFixed": null, + + /** + * Classes to use for the striping of a table. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @default [] + */ + "asStripeClasses": null, + + /** + * If restoring a table - we should restore its striping classes as well + * @type array + * @default [] + */ + "asDestroyStripes": [], + + /** + * If restoring a table - we should restore its width + * @type int + * @default 0 + */ + "sDestroyWidth": 0, + + /** + * Callback functions array for every time a row is inserted (i.e. on a draw). + * @type array + * @default [] + */ + "aoRowCallback": [], + + /** + * Callback functions for the header on each draw. + * @type array + * @default [] + */ + "aoHeaderCallback": [], + + /** + * Callback function for the footer on each draw. + * @type array + * @default [] + */ + "aoFooterCallback": [], + + /** + * Array of callback functions for draw callback functions + * @type array + * @default [] + */ + "aoDrawCallback": [], + + /** + * Array of callback functions for row created function + * @type array + * @default [] + */ + "aoRowCreatedCallback": [], + + /** + * Callback functions for just before the table is redrawn. A return of + * false will be used to cancel the draw. + * @type array + * @default [] + */ + "aoPreDrawCallback": [], + + /** + * Callback functions for when the table has been initialised. + * @type array + * @default [] + */ + "aoInitComplete": [], + + + /** + * Callbacks for modifying the settings to be stored for state saving, prior to + * saving state. + * @type array + * @default [] + */ + "aoStateSaveParams": [], + + /** + * Callbacks for modifying the settings that have been stored for state saving + * prior to using the stored values to restore the state. + * @type array + * @default [] + */ + "aoStateLoadParams": [], + + /** + * Callbacks for operating on the settings object once the saved state has been + * loaded + * @type array + * @default [] + */ + "aoStateLoaded": [], + + /** + * Cache the table ID for quick access + * @type string + * @default Empty string + */ + "sTableId": "", + + /** + * The TABLE node for the main table + * @type node + * @default null + */ + "nTable": null, + + /** + * Permanent ref to the thead element + * @type node + * @default null + */ + "nTHead": null, + + /** + * Permanent ref to the tfoot element - if it exists + * @type node + * @default null + */ + "nTFoot": null, + + /** + * Permanent ref to the tbody element + * @type node + * @default null + */ + "nTBody": null, + + /** + * Cache the wrapper node (contains all DataTables controlled elements) + * @type node + * @default null + */ + "nTableWrapper": null, + + /** + * Indicate if when using server-side processing the loading of data + * should be deferred until the second draw. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + * @default false + */ + "bDeferLoading": false, + + /** + * Indicate if all required information has been read in + * @type boolean + * @default false + */ + "bInitialised": false, + + /** + * Information about open rows. Each object in the array has the parameters + * 'nTr' and 'nParent' + * @type array + * @default [] + */ + "aoOpenRows": [], + + /** + * Dictate the positioning of DataTables' control elements - see + * {@link DataTable.model.oInit.sDom}. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default null + */ + "sDom": null, + + /** + * Which type of pagination should be used. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default two_button + */ + "sPaginationType": "two_button", + + /** + * The cookie duration (for bStateSave) in seconds. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type int + * @default 0 + */ + "iCookieDuration": 0, + + /** + * The cookie name prefix. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default Empty string + */ + "sCookiePrefix": "", + + /** + * Callback function for cookie creation. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type function + * @default null + */ + "fnCookieCallback": null, + + /** + * Array of callback functions for state saving. Each array element is an + * object with the following parameters: + *
          + *
        • function:fn - function to call. Takes two parameters, oSettings + * and the JSON string to save that has been thus far created. Returns + * a JSON string to be inserted into a json object + * (i.e. '"param": [ 0, 1, 2]')
        • + *
        • string:sName - name of callback
        • + *
        + * @type array + * @default [] + */ + "aoStateSave": [], + + /** + * Array of callback functions for state loading. Each array element is an + * object with the following parameters: + *
          + *
        • function:fn - function to call. Takes two parameters, oSettings + * and the object stored. May return false to cancel state loading
        • + *
        • string:sName - name of callback
        • + *
        + * @type array + * @default [] + */ + "aoStateLoad": [], + + /** + * State that was loaded from the cookie. Useful for back reference + * @type object + * @default null + */ + "oLoadedState": null, + + /** + * Source url for AJAX data for the table. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + * @default null + */ + "sAjaxSource": null, + + /** + * Property from a given object from which to read the table data from. This + * can be an empty string (when not server-side processing), in which case + * it is assumed an an array is given directly. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sAjaxDataProp": null, + + /** + * Note if draw should be blocked while getting data + * @type boolean + * @default true + */ + "bAjaxDataGet": true, + + /** + * The last jQuery XHR object that was used for server-side data gathering. + * This can be used for working with the XHR information in one of the + * callbacks + * @type object + * @default null + */ + "jqXHR": null, + + /** + * Function to get the server-side data. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type function + */ + "fnServerData": null, + + /** + * Functions which are called prior to sending an Ajax request so extra + * parameters can easily be sent to the server + * @type array + * @default [] + */ + "aoServerParams": [], + + /** + * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if + * required). + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type string + */ + "sServerMethod": null, + + /** + * Format numbers for display. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type function + */ + "fnFormatNumber": null, + + /** + * List of options that can be used for the user selectable length menu. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type array + * @default [] + */ + "aLengthMenu": null, + + /** + * Counter for the draws that the table does. Also used as a tracker for + * server-side processing + * @type int + * @default 0 + */ + "iDraw": 0, + + /** + * Indicate if a redraw is being done - useful for Ajax + * @type boolean + * @default false + */ + "bDrawing": false, + + /** + * Draw index (iDraw) of the last error when parsing the returned data + * @type int + * @default -1 + */ + "iDrawError": -1, + + /** + * Paging display length + * @type int + * @default 10 + */ + "_iDisplayLength": 10, + + /** + * Paging start point - aiDisplay index + * @type int + * @default 0 + */ + "_iDisplayStart": 0, + + /** + * Paging end point - aiDisplay index. Use fnDisplayEnd rather than + * this property to get the end point + * @type int + * @default 10 + * @private + */ + "_iDisplayEnd": 10, + + /** + * Server-side processing - number of records in the result set + * (i.e. before filtering), Use fnRecordsTotal rather than + * this property to get the value of the number of records, regardless of + * the server-side processing setting. + * @type int + * @default 0 + * @private + */ + "_iRecordsTotal": 0, + + /** + * Server-side processing - number of records in the current display set + * (i.e. after filtering). Use fnRecordsDisplay rather than + * this property to get the value of the number of records, regardless of + * the server-side processing setting. + * @type boolean + * @default 0 + * @private + */ + "_iRecordsDisplay": 0, + + /** + * Flag to indicate if jQuery UI marking and classes should be used. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bJUI": null, + + /** + * The classes to use for the table + * @type object + * @default {} + */ + "oClasses": {}, + + /** + * Flag attached to the settings object so you can check in the draw + * callback if filtering has been done in the draw. Deprecated in favour of + * events. + * @type boolean + * @default false + * @deprecated + */ + "bFiltered": false, + + /** + * Flag attached to the settings object so you can check in the draw + * callback if sorting has been done in the draw. Deprecated in favour of + * events. + * @type boolean + * @default false + * @deprecated + */ + "bSorted": false, + + /** + * Indicate that if multiple rows are in the header and there is more than + * one unique cell per column, if the top one (true) or bottom one (false) + * should be used for sorting / title by DataTables. + * Note that this parameter will be set by the initialisation routine. To + * set a default use {@link DataTable.defaults}. + * @type boolean + */ + "bSortCellsTop": null, + + /** + * Initialisation object that is used for the table + * @type object + * @default null + */ + "oInit": null, + + /** + * Destroy callback functions - for plug-ins to attach themselves to the + * destroy so they can clean up markup and events. + * @type array + * @default [] + */ + "aoDestroyCallback": [], + + + /** + * Get the number of records in the current record set, before filtering + * @type function + */ + "fnRecordsTotal": function () + { + if ( this.oFeatures.bServerSide ) { + return parseInt(this._iRecordsTotal, 10); + } else { + return this.aiDisplayMaster.length; + } + }, + + /** + * Get the number of records in the current record set, after filtering + * @type function + */ + "fnRecordsDisplay": function () + { + if ( this.oFeatures.bServerSide ) { + return parseInt(this._iRecordsDisplay, 10); + } else { + return this.aiDisplay.length; + } + }, + + /** + * Set the display end point - aiDisplay index + * @type function + * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here + */ + "fnDisplayEnd": function () + { + if ( this.oFeatures.bServerSide ) { + if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) { + return this._iDisplayStart+this.aiDisplay.length; + } else { + return Math.min( this._iDisplayStart+this._iDisplayLength, + this._iRecordsDisplay ); + } + } else { + return this._iDisplayEnd; + } + }, + + /** + * The DataTables object for this table + * @type object + * @default null + */ + "oInstance": null, + + /** + * Unique identifier for each instance of the DataTables object. If there + * is an ID on the table node, then it takes that value, otherwise an + * incrementing internal counter is used. + * @type string + * @default null + */ + "sInstance": null, + + /** + * tabindex attribute value that is added to DataTables control elements, allowing + * keyboard navigation of the table and its controls. + */ + "iTabIndex": 0, + + /** + * DIV container for the footer scrolling table if scrolling + */ + "nScrollHead": null, + + /** + * DIV container for the footer scrolling table if scrolling + */ + "nScrollFoot": null +}; diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.js new file mode 100644 index 00000000..590b756a --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.js @@ -0,0 +1,94 @@ +var giTotalTestCount = 0; +var giActiveModule = 0; +var giModuleTests; +var giStartTime; +var giTest; +var gbStop = false; +var gtoTest; + +function fnTestStart ( sTestInfo ) +{ + gaoTest[ giActiveModule ].iTests++; + document.getElementById('test_info').innerHTML += + (giActiveModule+1)+'.'+(giModuleTests+1)+'. '+sTestInfo+'... '; + document.getElementById('test_number').innerHTML = giTotalTestCount+1; + giModuleTests++; + giTotalTestCount++; + + /* Set a timer to catch stalled script */ + gtoTest = setTimeout( function () { + fnMessage( 'WARNING - test script stalled. Likely a JS error' ); + gbStop = true; + }, 3000 ); +} + +function fnTestResult ( bResult ) +{ + clearTimeout( gtoTest ); + if ( bResult ) + { + fnMessage( 'Passed' ); + } + else + { + fnMessage( 'FAILED' ); + gbStop = true; + fnEnd( false ); + } +} + +function fnUnitStart( iTest ) +{ + if ( !gbStop ) + { + giModuleTests = 0; + window.parent.test_arena.location.href = + (iTest==0?"":"../")+'templates/'+gaoTest[iTest].sTemplate+'.php?scripts='+gaoTest[iTest].sTest; + giTest = iTest; + } +} + +function fnStartMessage( sMessage ) +{ + fnMessage( '
        '+gaoTest[giTest].sGroup+' - '+sMessage+'' ); +} + +function fnMessage( sMessage ) +{ + var nInfo = document.getElementById('test_info'); + nInfo.innerHTML += sMessage+'
        '; + nInfo.scrollTop = nInfo.scrollHeight; +} + +function fnUnitComplete() +{ + if ( giActiveModule < gaoTest.length - 1 ) + { + fnUnitStart( ++giActiveModule ); + } + else + { + fnEnd( true ); + } +} + +function fnEnd( bSuccess ) +{ + var iEndTime = new Date().getTime(); + var sTime = '
        This test run took '+parseInt((iEndTime-giStartTime)/1000, 10)+ + ' second(s) to complete.'; + + if ( bSuccess ) + { + $('#test_running').html( 'Tests complete. '+giTotalTestCount+' tests were run.'+sTime ); + } + else + { + $('#test_running').html( 'Unit tests failed at test '+giTotalTestCount+'.'+sTime ); + } +} + +$(document).ready( function () { + giStartTime = new Date().getTime(); + fnUnitStart( giActiveModule ); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.php new file mode 100644 index 00000000..33f751e2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/controller.php @@ -0,0 +1,100 @@ + + + + + DataTables unit test controller + + + + + + + + +

        DataTables unit testing

        +
        Running test:
        +
        + Test information:
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/index.html b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/index.html new file mode 100644 index 00000000..caab383b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/index.html @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/draw.html b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/draw.html new file mode 100644 index 00000000..32af1a91 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/draw.html @@ -0,0 +1,482 @@ + + + + + + + DataTables example + + + + + + +
        +
        + DataTables performance test - draw +
        +
        + +
        +
      • + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        + + + + + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/large.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/large.php new file mode 100644 index 00000000..c4911528 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/large.php @@ -0,0 +1,108 @@ + + + + + + + DataTables example + + + + + + +
        +
        + DataTables performance test - draw +
        +
        + +
        + + + + + + + + + + + + + + + +'; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } +?> + +
        idnamephoneemailcityzipstatecountryzip2
        '.$aRow['id'].''.$aRow['name'].''.$aRow['phone'].''.$aRow['email'].''.$aRow['city'].''.$aRow['zip'].''.$aRow['state'].''.$aRow['country'].''.$aRow['zip2'].'
        +
        +
        + + +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/page.html b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/page.html new file mode 100644 index 00000000..77c6c2a5 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/page.html @@ -0,0 +1,477 @@ + + + + + + + DataTables example + + + + + + +
        +
        + DataTables performance test - draw +
        +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        + + + +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/sort.html b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/sort.html new file mode 100644 index 00000000..d154fb0b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/performance/sort.html @@ -0,0 +1,477 @@ + + + + + + + DataTables example + + + + + + +
        +
        + DataTables performance test - draw +
        +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        + + + +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/-complex_header.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/-complex_header.php new file mode 100644 index 00000000..2cdc4250 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/-complex_header.php @@ -0,0 +1,469 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowser detailsCSS grade
        BrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/2512.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/2512.php new file mode 100644 index 00000000..9ef8e2f0 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/2512.php @@ -0,0 +1,464 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        Tridenttestsearchstring
        html & entity
        Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/6776.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/6776.php new file mode 100644 index 00000000..62defd14 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/6776.php @@ -0,0 +1,116 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        +

        Live example

        + + + + + + + +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        TridentInternet Explorer 4.0Win 95+ 4X
        +
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/complex_header_2.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/complex_header_2.php new file mode 100644 index 00000000..6795dbe3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/complex_header_2.php @@ -0,0 +1,485 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        123
        45
        678
        910
        1112
        123
        45
        6
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/deferred_table.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/deferred_table.php new file mode 100644 index 00000000..d98a4de9 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/deferred_table.php @@ -0,0 +1,132 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data.php new file mode 100644 index 00000000..b5fed473 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data.php @@ -0,0 +1,465 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_th.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_th.php new file mode 100644 index 00000000..1faf9ab3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_th.php @@ -0,0 +1,465 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_two_headers.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_two_headers.php new file mode 100644 index 00000000..09093b99 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dom_data_two_headers.php @@ -0,0 +1,472 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data - with two rows in header +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        TridentInternet + Explorer 4.0Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        GeckoFirefox 1.0Win 98+ / OSX.2+1.7A
        GeckoFirefox 1.5Win 98+ / OSX.2+1.8A
        GeckoFirefox 2.0Win 98+ / OSX.2+1.8A
        GeckoFirefox 3.0Win 2k+ / OSX.3+1.9A
        GeckoCamino 1.0OSX.2+1.8A
        GeckoCamino 1.5OSX.3+1.8A
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.21.7A
        GeckoNetscape Browser 8Win 98SE+1.7A
        GeckoNetscape Navigator 9Win 98+ / OSX.2+1.8A
        GeckoMozilla 1.0Win 95+ / OSX.1+1A
        GeckoMozilla 1.1Win 95+ / OSX.1+1.1A
        GeckoMozilla 1.2Win 95+ / OSX.1+1.2A
        GeckoMozilla 1.3Win 95+ / OSX.1+1.3A
        GeckoMozilla 1.4Win 95+ / OSX.1+1.4A
        GeckoMozilla 1.5Win 95+ / OSX.1+1.5A
        GeckoMozilla 1.6Win 95+ / OSX.1+1.6A
        GeckoMozilla 1.7Win 98+ / OSX.1+1.7A
        GeckoMozilla 1.8Win 98+ / OSX.1+1.8A
        GeckoSeamonkey 1.1Win 98+ / OSX.2+1.8A
        GeckoEpiphany 2.20Gnome1.8A
        WebkitSafari 1.2OSX.3125.5A
        WebkitSafari 1.3OSX.3312.8A
        WebkitSafari 2.0OSX.4+419.3A
        WebkitSafari 3.0OSX.4+522.1A
        WebkitOmniWeb 5.5OSX.4+420A
        WebkitiPod Touch / iPhoneiPod420.1A
        WebkitS60S60413A
        PrestoOpera 7.0Win 95+ / OSX.1+-A
        PrestoOpera 7.5Win 95+ / OSX.2+-A
        PrestoOpera 8.0Win 95+ / OSX.2+-A
        PrestoOpera 8.5Win 95+ / OSX.2+-A
        PrestoOpera 9.0Win 95+ / OSX.3+-A
        PrestoOpera 9.2Win 88+ / OSX.3+-A
        PrestoOpera 9.5Win 88+ / OSX.3+-A
        PrestoOpera for WiiWii-A
        PrestoNokia N800N800-A
        PrestoNintendo DS browserNintendo DS8.5C/A1
        KHTMLKonqureror 3.1KDE 3.13.1C
        KHTMLKonqureror 3.3KDE 3.33.3A
        KHTMLKonqureror 3.5KDE 3.53.5A
        TasmanInternet Explorer 4.5Mac OS 8-9-X
        TasmanInternet Explorer 5.1Mac OS 7.6-91C
        TasmanInternet Explorer 5.2Mac OS 8-X1C
        MiscNetFront 3.1Embedded devices-C
        MiscNetFront 3.4Embedded devices-A
        MiscDillo 0.8Embedded devices-X
        MiscLinksText only-X
        MiscLynxText only-X
        MiscIE MobileWindows Mobile 6-C
        MiscPSP browserPSP-C
        Other browsersAll others--U
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dymanic_table.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dymanic_table.php new file mode 100644 index 00000000..49606c5f --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/dymanic_table.php @@ -0,0 +1,45 @@ + + + + + + + DataTables unit testing + + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables dynamic table template +
        + +

        Live example

        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/empty_table.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/empty_table.php new file mode 100644 index 00000000..0647f308 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/empty_table.php @@ -0,0 +1,55 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables empty table template +
        + +

        Live example

        +
        + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/html_table.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/html_table.php new file mode 100644 index 00000000..123f54b9 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/html_table.php @@ -0,0 +1,66 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables table with HTML elements template +
        + +

        Live example

        +
        + + + + + + + + + + + + + + + + + + + + + + + + +
        ReflectionLink
        1DataTables
        2A link to Integrity
        3Integrity
        4EIntegrity
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data.php new file mode 100644 index 00000000..61f1852b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data.php @@ -0,0 +1,124 @@ + + + + + + + DataTables unit testing + + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data_mixed_types.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data_mixed_types.php new file mode 100644 index 00000000..9cdd0aa4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/js_data_mixed_types.php @@ -0,0 +1,124 @@ + + + + + + + DataTables unit testing + + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for reading DOM data +
        + +
        + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/two_tables.php b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/two_tables.php new file mode 100644 index 00000000..89b2aa03 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/templates/two_tables.php @@ -0,0 +1,227 @@ + + + + + + + DataTables unit testing + + + + + '."\n"; + } + ?> + + +
        +
        + DataTables unit test template for two tables +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        Tridenttestsearchstring
        html & entity
        Win 95+4X
        TridentInternet + Explorer 5.0Win 95+5C
        TridentInternet + Explorer 5.5Win 95+5.5A
        TridentInternet + Explorer 6Win 98+6A
        TridentInternet Explorer 7Win XP SP2+7A
        TridentAOL browser (AOL desktop)Win XP6A
        Rendering engineBrowserPlatform(s)Engine versionCSS grade
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Rendering engineBrowserPlatform(s)
        GeckoFirefox 1.0Win 98+ / OSX.2+
        GeckoFirefox 1.5Win 98+ / OSX.2+
        GeckoFirefox 2.0Win 98+ / OSX.2+
        GeckoFirefox 3.0Win 2k+ / OSX.3+
        GeckoCamino 1.0OSX.2+
        GeckoCamino 1.5OSX.3+
        GeckoNetscape 7.2Win 95+ / Mac OS 8.6-9.2
        GeckoNetscape Browser 8Win 98SE+
        GeckoNetscape Navigator 9Win 98+ / OSX.2+
        GeckoMozilla 1.0Win 95+ / OSX.1+
        GeckoMozilla 1.1Win 95+ / OSX.1+
        GeckoMozilla 1.2Win 95+ / OSX.1+
        GeckoMozilla 1.3Win 95+ / OSX.1+
        GeckoMozilla 1.4Win 95+ / OSX.1+
        GeckoMozilla 1.5Win 95+ / OSX.1+
        GeckoMozilla 1.6Win 95+ / OSX.1+
        GeckoMozilla 1.7Win 98+ / OSX.1+
        GeckoMozilla 1.8Win 98+ / OSX.1+
        GeckoSeamonkey 1.1Win 98+ / OSX.2+
        GeckoEpiphany 2.20Gnome
        Rendering engineBrowserPlatform(s)
        +
        +
        +
        + + \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests/1_dom/_zero_config.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests/1_dom/_zero_config.js new file mode 100755 index 00000000..b3a941f8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests/1_dom/_zero_config.js @@ -0,0 +1,437 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "Sanity checks for DataTables with DOM data" ); + +oTest.fnTest( + "jQuery.dataTable function", + null, + function () { return typeof jQuery().dataTable == "function"; } +); + +oTest.fnTest( + "jQuery.dataTableSettings storage array", + null, + function () { return typeof jQuery().dataTableSettings == "object"; } +); + +oTest.fnTest( + "jQuery.dataTableExt plugin object", + null, + function () { return typeof jQuery().dataTableExt == "object"; } +); + +$(document).ready( function () { + $('#example').dataTable(); + + /* Basic checks */ + oTest.fnTest( + "Length changing div exists", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Filtering div exists", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + oTest.fnTest( + "Information div exists", + null, + function () { return document.getElementById('example_info') != null; } + ); + + oTest.fnTest( + "Pagination div exists", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Processing div is off by default", + null, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Information on last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 51 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back on first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 25 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records - second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 26 to 50 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 100 records - first page", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('100').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back to 10 records", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('10').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 31 to 31 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' back to first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - second time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter increased to 'Win 98'", + function () { $('#example_filter input').val("Win 98").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter decreased to 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - third time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter removed", + function () { $('#example_filter input').val("").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + + /* + * Filtering + */ + oTest.fnTest( + "Filter 'W' - rows", + function () { + /* Reset the table such that the old sorting doesn't mess things up */ + oSession.fnRestore(); + $('#example').dataTable(); + $('#example_filter input').val("W").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Filter 'W' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 42 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Wi'", + function () { $('#example_filter input').val("Wi").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 32 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "AOL browser (AOL desktop)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 reverse", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - maintaing reverse sorting col 1", + function () { $('#example_filter input').val("Win XP").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Internet Explorer 7"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3 - reversed", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "7"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting col 3 - reversed info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 6 of 6 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'nothinghere'", + function () { $('#example_filter input').val("nothinghere").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == + "No matching records found"; } + ); + + oTest.fnTest( + "Filter 'nothinghere' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter back to blank and 1st column sorting", + function () { + $('#example_filter input').val("").keyup(); + $('#example thead th:eq(0)').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Prefixing a filter entry", + function () { + $('#example_filter input').val("Win").keyup(); + $('#example_filter input').val("GeckoWin").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Prefixing a filter entry with space", + function () { + $('#example_filter input').val("Gecko Win").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 17 entries (filtered from 57 total entries)"; } + ); + + + + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-complex_header.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-complex_header.js new file mode 100755 index 00000000..fb173a78 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-complex_header.js @@ -0,0 +1,52 @@ +// DATA_TEMPLATE: -complex_header +oTest.fnStart( "Complex header" ); + + +$(document).ready( function () { + $('#example').dataTable(); + + oTest.fnTest( + "Sorting on colspan has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr td:eq(1)').html() == "Firefox 1.0"; } + ); + + oTest.fnTest( + "Sorting on non-unique TH and first TH has no effect", + function () { $('#example thead th:eq(2)').click(); }, + function () { return $('#example tbody tr td:eq(1)').html() == "Firefox 1.0"; } + ); + + oTest.fnTest( + "Sorting on non-unique TH and second TH will sort", + function () { $('#example thead th:eq(6)').click(); }, + function () { return $('#example tbody tr td:eq(4)').html() == "A"; } + ); + + oTest.fnTest( + "Sorting on non-unique TH and second TH will sort - reserve", + function () { $('#example thead th:eq(6)').click(); }, + function () { return $('#example tbody tr td:eq(4)').html() == "X"; } + ); + + oTest.fnTest( + "Sorting on unique TH will sort", + function () { $('#example thead th:eq(5)').click(); }, + function () { return $('#example tbody tr td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting on unique TH will sort - reserve", + function () { $('#example thead th:eq(5)').click(); }, + function () { return $('#example tbody tr td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting on unique rowspan TH will sort", + function () { $('#example thead th:eq(0)').click(); }, + function () { return $('#example tbody tr td:eq(0)').html() == "Gecko"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-iDraw.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-iDraw.js new file mode 100755 index 00000000..efbf7415 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/-iDraw.js @@ -0,0 +1,41 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "iDraw - check that iDraw increments for each draw" ); + + +$(document).ready( function () { + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "After first draw, iDraw is 1", + null, + function () { return oSettings.iDraw == 1; } + ); + + oTest.fnTest( + "After second draw, iDraw is 2", + function () { oTable.fnDraw() }, + function () { return oSettings.iDraw == 2; } + ); + + oTest.fnTest( + "After sort", + function () { oTable.fnSort([[1,'asc']]) }, + function () { return oSettings.iDraw == 3; } + ); + + oTest.fnTest( + "After filter", + function () { oTable.fnFilter('gecko') }, + function () { return oSettings.iDraw == 4; } + ); + + oTest.fnTest( + "After another filter", + function () { oTable.fnFilter('gec') }, + function () { return oSettings.iDraw == 5; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2512.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2512.js new file mode 100755 index 00000000..e0c91798 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2512.js @@ -0,0 +1,17 @@ +// DATA_TEMPLATE: 2512 +oTest.fnStart( "Check filtering with BR and HTML entity" ); + + +$(document).ready( function () { + $('#example').dataTable(); + + /* Basic checks */ + oTest.fnTest( + "Check filtering", + function () { $('#example').dataTable().fnFilter('testsearchstring'); }, + function () { return $('#example tbody tr').length == 1; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530-2.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530-2.js new file mode 100755 index 00000000..cba8cf81 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530-2.js @@ -0,0 +1,15 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "User given with is left when no scrolling" ); + +$(document).ready( function () { + $('#example')[0].style.width = "80%"; + $('#example').dataTable(); + + oTest.fnTest( + "Check user width is left", + null, + function () { return $('#example').width() == 640; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530.js new file mode 100755 index 00000000..29e642d7 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2530.js @@ -0,0 +1,29 @@ +// DATA_TEMPLATE: dymanic_table +oTest.fnStart( "2530 - Check width's when dealing with empty strings" ); + + +$(document).ready( function () { + $('#example').dataTable( { + "aaData": [ + ['','Internet Explorer 4.0','Win 95+','4','X'], + ['','Internet Explorer 5.0','Win 95+','5','C'] + ], + "aoColumns": [ + { "sTitle": "", "sWidth": "40px" }, + { "sTitle": "Browser" }, + { "sTitle": "Platform" }, + { "sTitle": "Version", "sClass": "center" }, + { "sTitle": "Grade", "sClass": "center" } + ] + } ); + + /* Basic checks */ + oTest.fnTest( + "Check calculated widths", + null, + function () { return $('#example tbody tr td:eq(0)').width() < 100; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2569.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2569.js new file mode 100755 index 00000000..59eae2ef --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2569.js @@ -0,0 +1,36 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "Destroy with hidden columns" ); + +$(document).ready( function () { + $('#example').dataTable( { + "aoColumnDefs": [ + { "bSearchable": false, "bVisible": false, "aTargets": [ 2 ] }, + { "bVisible": false, "aTargets": [ 3 ] } + ] + } ); + $('#example').dataTable().fnDestroy(); + + oTest.fnTest( + "Check that the number of columns in table is correct", + null, + function () { return $('#example tbody tr:eq(0) td').length == 5; } + ); + + + oTest.fnTest( + "And with scrolling", + function () { + $('#example').dataTable( { + "sScrollY": 200, + "aoColumnDefs": [ + { "bSearchable": false, "bVisible": false, "aTargets": [ 2 ] }, + { "bVisible": false, "aTargets": [ 3 ] } + ] + } ); + $('#example').dataTable().fnDestroy(); + }, + function () { return $('#example tbody tr:eq(0) td').length == 5; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2600.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2600.js new file mode 100755 index 00000000..7acda55b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2600.js @@ -0,0 +1,44 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2600 - Display rewind when changing length" ); + +$(document).ready( function () { + $('#example').dataTable(); + + oTest.fnTest( + "Info correct on init", + null, + function () { return $('#example_info').html() == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Page 2", + function () { $('#example_next').click(); }, + function () { return $('#example_info').html() == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Page 3", + function () { $('#example_next').click(); }, + function () { return $('#example_info').html() == "Showing 21 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Page 4", + function () { $('#example_next').click(); }, + function () { return $('#example_info').html() == "Showing 31 to 40 of 57 entries"; } + ); + + oTest.fnTest( + "Page 5", + function () { $('#example_next').click(); }, + function () { return $('#example_info').html() == "Showing 41 to 50 of 57 entries"; } + ); + + oTest.fnTest( + "Rewind", + function () { $('#example_length select').val('100'); $('#example_length select').change(); }, + function () { return $('#example_info').html() == "Showing 1 to 57 of 57 entries"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2608.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2608.js new file mode 100644 index 00000000..e306c4fc --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2608.js @@ -0,0 +1,54 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2608 - State saving escaping filters" ); + +$(document).ready( function () { + $('#example').dataTable( { + "bStateSave": true + } ); + + oTest.fnTest( + "Set the filter", + function () { + $('#example_filter input').val( '\\s*CVM\\s*$' ); + $('#example_filter input').keyup(); + }, + function () { return $('#example_filter input').val() == '\\s*CVM\\s*$'; } + ); + + oTest.fnTest( + "Destroy the table and remake it - checking the filter was saved", + function () { + $('#example').dataTable( { + "bStateSave": true, + "bDestroy": true + } ); + }, + function () { return $('#example_filter input').val() == '\\s*CVM\\s*$'; } + ); + + oTest.fnTest( + "Do it again without state saving and make sure filter is empty", + function () { + $('#example').dataTable( { + "bDestroy": true + } ); + }, + function () { return $('#example_filter input').val() == ''; } + ); + + oTest.fnTest( + "Clean up", + function () { + $('#example').dataTable( { + "bStateSave": true, + "bDestroy": true + } ); + $('#example_filter input').val( '' ); + $('#example_filter input').keyup(); + }, + function () { return $('#example_filter input').val() == ''; } + ); + + oTest.fnCookieDestroy( $('#example').dataTable() ); + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2635.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2635.js new file mode 100755 index 00000000..7226ea4b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2635.js @@ -0,0 +1,40 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2635 - Hiding column and state saving" ); + +$(document).ready( function () { + $('#example').dataTable( { + "bStateSave": true + } ); + + oTest.fnTest( + "Set the hidden column", + function () { + $('#example').dataTable().fnSetColumnVis( 2, false ); + }, + function () { return $('#example thead th').length == 4; } + ); + + oTest.fnTest( + "Destroy the table and remake it - checking one column was removed", + function () { + $('#example').dataTable( { + "bStateSave": true, + "bDestroy": true + } ); + }, + function () { return $('#example thead th').length == 4; } + ); + + oTest.fnTest( + "Do it again without state saving and make sure we are back to 5 columns", + function () { + $('#example').dataTable( { + "bDestroy": true + } ); + }, + function () { return $('#example thead th').length == 5; } + ); + + oTest.fnCookieDestroy( $('#example').dataTable() ); + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2746-stable-sort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2746-stable-sort.js new file mode 100755 index 00000000..fbd3cf7d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2746-stable-sort.js @@ -0,0 +1,199 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2746 - Stable sorting" ); + +$(document).ready( function () { + $('#example').dataTable(); + + oTest.fnTest( + "Initial sort", + null, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Firefox 1.0' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Firefox 1.5' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Firefox 2.0'; + return ret; + } + ); + + oTest.fnTest( + "Reserve initial sort", + function () { + $('#example thead th:eq(0)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Webkit' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Webkit' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Safari 1.2' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Safari 1.3' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Safari 2.0'; + return ret; + } + ); + + oTest.fnTest( + "Reserve to go back to initial sort sort", + function () { + $('#example thead th:eq(0)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Firefox 1.0' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Firefox 1.5' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Firefox 2.0'; + return ret; + } + ); + + oTest.fnTest( + "Reserve initial sort again", + function () { + $('#example thead th:eq(0)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Webkit' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Webkit' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Safari 1.2' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Safari 1.3' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Safari 2.0'; + return ret; + } + ); + + oTest.fnTest( + "And once more back to the initial sort", + function () { + $('#example thead th:eq(0)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Firefox 1.0' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Firefox 1.5' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Firefox 2.0'; + return ret; + } + ); + + oTest.fnTest( + "Sort on second column", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Other browsers' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Trident' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'AOL browser (AOL desktop)' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Camino 1.0'; + return ret; + } + ); + + oTest.fnTest( + "Reserve sort on second column", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Webkit' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Seamonkey 1.1' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Safari 3.0' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Safari 2.0'; + return ret; + } + ); + + oTest.fnTest( + "And back to asc sorting on second column", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Other browsers' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Trident' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'AOL browser (AOL desktop)' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Camino 1.0'; + return ret; + } + ); + + oTest.fnTest( + "Sort on third column, having now sorted on second", + function () { + $('#example thead th:eq(2)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Other browsers' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Misc' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Dillo 0.8' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'NetFront 3.1'; + return ret; + } + ); + + oTest.fnTest( + "Reserve sort on third column", + function () { + $('#example thead th:eq(2)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Misc' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Trident' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'IE Mobile' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Internet Explorer 7' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'AOL browser (AOL desktop)'; + return ret; + } + ); + + oTest.fnTest( + "Return sorting on third column to asc", + function () { + $('#example thead th:eq(2)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Other browsers' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Misc' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Dillo 0.8' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'NetFront 3.1'; + return ret; + } + ); + + oTest.fnTest( + "Sort on first column having sorted on second then third columns", + function () { + $('#example thead th:eq(0)').click(); + }, + function () { + var ret = + $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(1) td:eq(0)').html() == 'Gecko' && + $('#example tbody tr:eq(0) td:eq(1)').html() == 'Epiphany 2.20' && + $('#example tbody tr:eq(1) td:eq(1)').html() == 'Camino 1.0' && + $('#example tbody tr:eq(2) td:eq(1)').html() == 'Camino 1.5'; + return ret; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2799.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2799.js new file mode 100755 index 00000000..fe3a2c6c --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2799.js @@ -0,0 +1,14 @@ +// DATA_TEMPLATE: two_tables +oTest.fnStart( "Initialise two tables" ); + +$(document).ready( function () { + $('table.display').dataTable(); + + oTest.fnTest( + "Check that initialisation was okay", + null, + function () { return true; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2840-restore-table-width.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2840-restore-table-width.js new file mode 100755 index 00000000..435213f2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2840-restore-table-width.js @@ -0,0 +1,19 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2840 - Restore table width on fnDestroy" ); + +$(document).ready( function () { + document.cookie = ""; + $('#example').dataTable( { + "sScrollX": "100%", + "sScrollXInner": "110%" + } ); + $('#example').dataTable().fnDestroy(); + + oTest.fnTest( + "Width after destroy", + null, + function () { return $('#example').width() == "800"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2914-state-save-sort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2914-state-save-sort.js new file mode 100755 index 00000000..0c616b6d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/2914-state-save-sort.js @@ -0,0 +1,39 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "2914 - State saving with an empty array" ); + +$(document).ready( function () { + document.cookie = ""; + $('#example').dataTable( { + "bStateSave": true, + "aaSorting": [] + } ); + + oTest.fnTest( + "No sort", + null, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Next page", + function () { + $('#example').dataTable().fnPageChange( 'next' ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnTest( + "Destroy the table and remake it - checking we are still on the next page", + function () { + $('#example').dataTable( { + "bStateSave": true, + "aaSorting": [], + "bDestroy": true + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnCookieDestroy( $('#example').dataTable() ); + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5396-fnUpdate-arrays.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5396-fnUpdate-arrays.js new file mode 100755 index 00000000..4ab695b2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5396-fnUpdate-arrays.js @@ -0,0 +1,103 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "5396 - fnUpdate with 2D arrays for a single row" ); + +$(document).ready( function () { + $('#example thead tr').append( '6' ); + $('#example thead tr').append( '7' ); + $('#example thead tr').append( '8' ); + $('#example thead tr').append( '9' ); + $('#example thead tr').append( '10' ); + + var aDataSet = [ + [ + "1", + "홍길동", + "1154315", + "etc1", + [ + [ "test1@daum.net", "2011-03-04" ], + [ "test1@naver.com", "2009-07-06" ], + [ "test4@naver.com", ",hide" ], + [ "test5?@naver.com", "" ] + ], + "2011-03-04", + "show" + ], + [ + "2", + "홍길순", + "2154315", + "etc2", + [ + [ "test2@daum.net", "2009-09-26" ], + [ "test2@naver.com", "2009-05-21,hide" ], + [ "lsb@naver.com", "2010-03-05" ], + [ "lsb3@naver.com", ",hide" ], + [ "sooboklee9@daum.net", "2010-03-05" ] + ], + "2010-03-05", + "show" + ] +] + + var oTable = $('#example').dataTable({ + "aaData": aDataSet, + "aoColumns": [ + { "mDataProp": "0"}, + { "mDataProp": "1"}, + { "mDataProp": "2"}, + { "mDataProp": "3"}, + { "mDataProp": "4.0.0"}, + { "mDataProp": "4.0.1"}, + { "mDataProp": "4.1.0"}, + { "mDataProp": "4.1.1"}, + { "mDataProp": "5"}, + { "mDataProp": "6"} + ] + }); + + + oTest.fnTest( + "Initialisation", + null, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').html() == '1'; + } + ); + + oTest.fnTest( + "Update row", + function () { + $('#example').dataTable().fnUpdate( [ + "0", + "홍길순", + "2154315", + "etc2", + [ + [ "test2@daum.net", "2009-09-26" ], + [ "test2@naver.com", "2009-05-21,hide" ], + [ "lsb@naver.com", "2010-03-05" ], + [ "lsb3@naver.com", ",hide" ], + [ "sooboklee9@daum.net", "2010-03-05" ] + ], + "2010-03-05", + "show" + ], 1 ); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').html() == '0'; + } + ); + + oTest.fnTest( + "Original row preserved", + null, + function () { + return $('#example tbody tr:eq(1) td:eq(0)').html() == '1'; + } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5508-xscroll-zero-content.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5508-xscroll-zero-content.js new file mode 100755 index 00000000..f71ae8f4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/5508-xscroll-zero-content.js @@ -0,0 +1,23 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "5508 - Table container width doesn't change when filtering applied to scrolling table" ); + +$(document).ready( function () { + $('#example').dataTable( { + "sScrollY": "300px", + "bPaginate": false + } ); + + oTest.fnTest( + "Width of container 800px on init with scroll", + null, + function () { return $('div.dataTables_scrollBody').width() == 800; } + ); + + oTest.fnTest( + "Unaltered when filter applied", + function () { $('#example').dataTable().fnFilter('123'); }, + function () { return $('div.dataTables_scrollBody').width() == 800; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/6776-scrolling-table-grows.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/6776-scrolling-table-grows.js new file mode 100755 index 00000000..cfc70d5f --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/6776-scrolling-table-grows.js @@ -0,0 +1,64 @@ +// DATA_TEMPLATE: 6776 +oTest.fnStart( "Actions on a scrolling table keep width" ); + + +$(document).ready( function () { + var oTable = $('#example').dataTable( { + "bFilter": true, + "bSort": true, + "sScrollY": "100px", + "bPaginate": false + } ); + + var iWidth = $('div.dataTables_wrapper').width(); + + oTest.fnTest( + "First sort has no effect on width", + function () { $('th:eq(1)').click(); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "Second sort has no effect on width", + function () { $('th:eq(1)').click(); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "Third sort has no effect on width", + function () { $('th:eq(2)').click(); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "Filter has no effect on width", + function () { oTable.fnFilter('i'); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "Filter 2 has no effect on width", + function () { oTable.fnFilter('in'); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "No result filter has header and body at same width", + function () { oTable.fnFilter('xxx'); }, + function () { return $('#example').width() == $('div.dataTables_scrollHeadInner').width(); } + ); + + oTest.fnTest( + "Filter with no results has no effect on width", + function () { oTable.fnFilter('xxx'); }, + function () { return $('div.dataTables_wrapper').width() == iWidth; } + ); + + oTest.fnTest( + "Filter with no results has table equal to wrapper width", + function () { oTable.fnFilter('xxx'); }, + function () { return $('div.dataTables_wrapper').width() == $('#example').width(); } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/_zero_config.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/_zero_config.js new file mode 100755 index 00000000..b3a941f8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/_zero_config.js @@ -0,0 +1,437 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "Sanity checks for DataTables with DOM data" ); + +oTest.fnTest( + "jQuery.dataTable function", + null, + function () { return typeof jQuery().dataTable == "function"; } +); + +oTest.fnTest( + "jQuery.dataTableSettings storage array", + null, + function () { return typeof jQuery().dataTableSettings == "object"; } +); + +oTest.fnTest( + "jQuery.dataTableExt plugin object", + null, + function () { return typeof jQuery().dataTableExt == "object"; } +); + +$(document).ready( function () { + $('#example').dataTable(); + + /* Basic checks */ + oTest.fnTest( + "Length changing div exists", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Filtering div exists", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + oTest.fnTest( + "Information div exists", + null, + function () { return document.getElementById('example_info') != null; } + ); + + oTest.fnTest( + "Pagination div exists", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Processing div is off by default", + null, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Information on last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 51 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back on first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 25 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records - second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 26 to 50 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 100 records - first page", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('100').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back to 10 records", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('10').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 31 to 31 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' back to first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - second time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter increased to 'Win 98'", + function () { $('#example_filter input').val("Win 98").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter decreased to 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - third time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter removed", + function () { $('#example_filter input').val("").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + + /* + * Filtering + */ + oTest.fnTest( + "Filter 'W' - rows", + function () { + /* Reset the table such that the old sorting doesn't mess things up */ + oSession.fnRestore(); + $('#example').dataTable(); + $('#example_filter input').val("W").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Filter 'W' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 42 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Wi'", + function () { $('#example_filter input').val("Wi").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 32 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "AOL browser (AOL desktop)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 reverse", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - maintaing reverse sorting col 1", + function () { $('#example_filter input').val("Win XP").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Internet Explorer 7"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3 - reversed", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "7"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting col 3 - reversed info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 6 of 6 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'nothinghere'", + function () { $('#example_filter input').val("nothinghere").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == + "No matching records found"; } + ); + + oTest.fnTest( + "Filter 'nothinghere' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter back to blank and 1st column sorting", + function () { + $('#example_filter input').val("").keyup(); + $('#example thead th:eq(0)').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Prefixing a filter entry", + function () { + $('#example_filter input').val("Win").keyup(); + $('#example_filter input').val("GeckoWin").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Prefixing a filter entry with space", + function () { + $('#example_filter input').val("Gecko Win").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 17 entries (filtered from 57 total entries)"; } + ); + + + + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSorting.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSorting.js new file mode 100755 index 00000000..848b85e4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSorting.js @@ -0,0 +1,183 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aaSorting" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default sorting is single column", + null, + function () { + return oSettings.aaSorting.length == 1 && typeof oSettings.aaSorting[0] == 'object'; + } + ); + + oTest.fnTest( + "Default sorting is first column asc", + null, + function () { + return oSettings.aaSorting[0].length == 3 && oSettings.aaSorting[0][0] == 0 && + oSettings.aaSorting[0][1] == 'asc'; + } + ); + + oTest.fnTest( + "Sorting is applied", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + + oTest.fnTest( + "Custom sorting on single string column asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + + oTest.fnTest( + "Custom sorting on single string column desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + + oTest.fnTest( + "Custom sorting on single int column asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + + oTest.fnTest( + "Custom sorting on single int column desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','asc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / string desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','asc'], ['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','desc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "iPod Touch / iPhone"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / string desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','desc'], ['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Safari 3.0"; } + ); + + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / int asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','asc'], ['3','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "1"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / int desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','asc'], ['3','desc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "1.9"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / int asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','desc'], ['3','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "125.5"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / int desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','desc'], ['3','desc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Multi-column sorting (3 column) - string asc / int asc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSorting": [['0','asc'], ['3','asc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody tr:eq(7) td:eq(1)').html() == "Firefox 1.0"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSortingFixed.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSortingFixed.js new file mode 100755 index 00000000..bc470e21 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aaSortingFixed.js @@ -0,0 +1,60 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aaSortingFixed" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "No fixed sorting by default", + null, + function () { + return oSettings.aaSortingFixed == null; + } + ); + + + oTest.fnTest( + "Fixed sorting on first column (string/asc) with user sorting on second column (string/asc)", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSortingFixed": [['0','asc']] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnTest( + "Fixed sorting on first column (string/asc) with user sorting on second column (string/desc)", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Fixed sorting on fourth column (int/asc) with user sorting on second column (string/asc)", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaSortingFixed": [['3','asc']] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Fixed sorting on fourth column (int/asc) with user sorting on second column (string/desc)", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "PSP browser"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSearchable.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSearchable.js new file mode 100755 index 00000000..27c211a7 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSearchable.js @@ -0,0 +1,67 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.bSeachable" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Columns are searchable by default", + function () { oTable.fnFilter("Camino"); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html().match(/Camino/); } + ); + + oTest.fnTest( + "Disabling sorting on a column removes it from the global filter", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "bSearchable": false }, + null, + null, + null + ] + } ); + oSettings = oTable.fnSettings(); + oTable.fnFilter("Camino"); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnTest( + "Disabled on one column has no effect on other columns", + function () { oTable.fnFilter("Webkit"); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Disable filtering on multiple columns", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + { "bSearchable": false }, + { "bSearchable": false }, + null, + null, + null + ] + } ); + oSettings = oTable.fnSettings(); + oTable.fnFilter("Webkit"); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnTest( + "Filter on second disabled column", + function () { oTable.fnFilter("Camino"); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSortable.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSortable.js new file mode 100755 index 00000000..bbb41cd6 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bSortable.js @@ -0,0 +1,105 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.bSortable" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "All columns are sortable by default", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Can disable sorting from one column", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "bSortable": false }, + null, + null, + null + ] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() != "All others"; } + ); + + oTest.fnTest( + "Disabled column has no sorting class", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc") == false; } + ); + + oTest.fnTest( + "Other columns can still sort", + function () { + $('#example thead th:eq(4)').click(); + $('#example thead th:eq(4)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == "X"; } + ); + + oTest.fnTest( + "Disable sorting on multiple columns - no sorting classes", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "bSortable": false }, + null, + { "bSortable": false }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example thead th:eq(1)').hasClass("sorting") || + $('#example thead th:eq(3)').hasClass("sorting") + return bReturn == false; + } + ); + + oTest.fnTest( + "Sorting on disabled column 1 has no effect", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() != "All others"; } + ); + + oTest.fnTest( + "Sorting on disabled column 2 has no effect", + function () { + $('#example thead th:eq(3)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() != "-"; } + ); + + oTest.fnTest( + "Second sort on disabled column 2 has no effect", + function () { + $('#example thead th:eq(3)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() != "-"; } + ); + + oTest.fnTest( + "Even with multiple disabled sorting columns other columns can still sort", + function () { + $('#example thead th:eq(4)').click(); + $('#example thead th:eq(4)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == "X"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bUseRendered.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bUseRendered.js new file mode 100755 index 00000000..161c4121 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bUseRendered.js @@ -0,0 +1,145 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.bUseRendered" ); + +/* bUseRendered is used to alter sorting data, if false then the original data is used for + * sorting rather than the rendered data + */ + +$(document).ready( function () { + /* Check the default */ + var mTmp = 0; + + var oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa"; + } else + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default for bUseRendered is true - rendered data is used for sorting", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'aaa'; } + ); + + oTest.fnTest( + "When bUseRendered is false, original data is used for sorting", + function () { + mTmp = 0; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { + "bUseRendered": false, + "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + null, + null, + null + ] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + + oTest.fnTest( + "bUseRendered set to false on one columns and true (default) on two others", + function () { + mTmp = 0; + var mTmp2 = 0; + var mTmp3 = 0; + + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + { + "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa1"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + { + "bUseRendered": false, + "fnRender": function (a) { + if ( mTmp2 == 0 ) { + mTmp2++; + return "aaa2"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + { + "fnRender": function (a) { + if ( mTmp3 == 0 ) { + mTmp3++; + return "zzz3"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'aaa1'; } + ); + + oTest.fnTest( + "Multi-column rendering - 2nd column sorting", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + oTest.fnTest( + "Multi-column rendering - 3rd column sorting", + function () { + $('#example thead th:eq(2)').click(); + $('#example thead th:eq(2)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(2)').html() == 'zzz3'; } + ); + + oTest.fnTest( + "Multi-column rendering - 4th column sorting", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == '-'; } + ); + + oTest.fnTest( + "Multi-column rendering - 5th column sorting", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible.js new file mode 100755 index 00000000..84f1ee60 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible.js @@ -0,0 +1,132 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.bVisible" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "All columns are visible by default", + null, + function () { return $('#example tbody tr:eq(0) td').length == 5; } + ); + + oTest.fnTest( + "Can hide one column and it removes td column from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "bVisible": false }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 4; } + ); + + oTest.fnTest( + "Can hide one column and it removes thead th column from DOM", + null, + function () { return $('#example thead tr:eq(0) th').length == 4; } + ); + + oTest.fnTest( + "Can hide one column and it removes tfoot th column from DOM", + null, + function () { return $('#example tfoot tr:eq(0) th').length == 4; } + ); + + oTest.fnTest( + "The correct thead column has been hidden", + null, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "Platform(s)" && + jqNodes[2].innerHTML == "Engine version" && + jqNodes[3].innerHTML == "CSS grade"; + return bReturn; + } + ); + + oTest.fnTest( + "The correct tbody column has been hidden", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); + }, + function () { + var jqNodes = $('#example tbody tr:eq(0) td'); + var bReturn = + jqNodes[0].innerHTML == "Gecko" && + jqNodes[1].innerHTML == "Gnome" && + jqNodes[2].innerHTML == "1.8" && + jqNodes[3].innerHTML == "A"; + return bReturn; + } + ); + + + oTest.fnTest( + "Can hide multiple columns and it removes td column from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "bVisible": false }, + { "bVisible": false }, + null, + { "bVisible": false } + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - removes thead th column from DOM", + null, + function () { return $('#example thead tr:eq(0) th').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - removes tfoot th column from DOM", + null, + function () { return $('#example tfoot tr:eq(0) th').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - the correct thead columns have been hidden", + null, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "Engine version" + return bReturn; + } + ); + + oTest.fnTest( + "Multiple hide - the correct tbody columns have been hidden", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); + }, + function () { + var jqNodes = $('#example tbody tr:eq(0) td'); + var bReturn = + jqNodes[0].innerHTML == "Gecko" && + jqNodes[1].innerHTML == "1" + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible2.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible2.js new file mode 100755 index 00000000..5dbe214f --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.bVisible2.js @@ -0,0 +1,268 @@ +// DATA_TEMPLATE: complex_header_2 +oTest.fnStart( "aoColumns.bVisible with complex headers" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "All columns are visible by default", + null, + function () { return $('#example tbody tr:eq(0) td').length == 5; } + ); + + oTest.fnTest( + "Hide the first column", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + { "bVisible": false }, + null, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 4; } + ); + + oTest.fnTest( + "First cell is '2' - first column hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)').html() == "2"; } + ); + + oTest.fnTest( + "First cell has colspan of 3", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('colspan') == 3; } + ); + + oTest.fnTest( + "First cell has rowspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('rowspan') == 2; } + ); + + oTest.fnTest( + "First cell in last column is '11'", + null, + function () { return $('#example thead tr:eq(4) th:eq(0)').html() == 11; } + ); + + oTest.fnTest( + "First cell in last column has been truncated to one column", + null, + function () { return $('#example thead tr:eq(4) th:eq(0)')[0].getAttribute('colspan') == 1; } + ); + + + oTest.fnTest( + "Hide the second column", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "bVisible": false }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 4; } + ); + + oTest.fnTest( + "First cell is '1' - second column hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)').html() == "1"; } + ); + + oTest.fnTest( + "Second cell is '2' - second column hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)').html() == "2"; } + ); + + oTest.fnTest( + "First cell in fourth row is '10' (visibly the first) - second column hidden", + null, + function () { return $('#example thead tr:eq(3) th:eq(0)').html() == "10"; } + ); + + oTest.fnTest( + "First cell has colspan of 1", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('colspan') == 1; } + ); + + oTest.fnTest( + "Second cell has colspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)')[0].getAttribute('colspan') == 2; } + ); + + oTest.fnTest( + "First cell has rowspan of 1", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('rowspan') == 1; } + ); + + oTest.fnTest( + "Second cell has rowspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)')[0].getAttribute('rowspan') == 2; } + ); + + oTest.fnTest( + "First cell in last column is '11'", + null, + function () { return $('#example thead tr:eq(4) th:eq(0)').html() == 11; } + ); + + oTest.fnTest( + "First cell in last column has been truncated to one column", + null, + function () { return $('#example thead tr:eq(4) th:eq(0)')[0].getAttribute('colspan') == 1; } + ); + + + oTest.fnTest( + "Hide the first two columns", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + { "bVisible": false }, + { "bVisible": false }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 3; } + ); + + oTest.fnTest( + "First cell is '2' - first two columns hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)').html() == "2"; } + ); + + oTest.fnTest( + "Second cell is '3' - first two columns hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)').html() == "3"; } + ); + + oTest.fnTest( + "First cell in third row is '6' - first two columns hidden", + null, + function () { return $('#example thead tr:eq(2) th:eq(0)').html() == "6"; } + ); + + oTest.fnTest( + "First cell has colspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('colspan') == 2; } + ); + + oTest.fnTest( + "First cell has rowspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)')[0].getAttribute('rowspan') == 2; } + ); + + oTest.fnTest( + "Second cell has rowspan of 1", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)')[0].getAttribute('rowspan') == 1; } + ); + + oTest.fnTest( + "First cell in last column is '12'", + null, + function () { return $('#example thead tr:eq(4) th:eq(0)').html() == 12; } + ); + + + oTest.fnTest( + "Hide the third column", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + null, + { "bVisible": false }, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 4; } + ); + + oTest.fnTest( + "First cell is '1' - third column hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)').html() == "1"; } + ); + + oTest.fnTest( + "Second cell is '2' - third column hidden", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)').html() == "2"; } + ); + + oTest.fnTest( + "First cell (visible second) in third row is '6' - third column hidden", + null, + function () { return $('#example thead tr:eq(2) th:eq(0)').html() == "6"; } + ); + + oTest.fnTest( + "Second cell has colspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)')[0].getAttribute('colspan') == 2; } + ); + + oTest.fnTest( + "Second cell has rowspan of 2", + null, + function () { return $('#example thead tr:eq(0) th:eq(1)')[0].getAttribute('rowspan') == 2; } + ); + + oTest.fnTest( + "Third row first cell (second visible) colspan is 1", + null, + function () { return $('#example thead tr:eq(2) th:eq(0)')[0].getAttribute('colspan') == 1; } + ); + + oTest.fnTest( + "Third row second cell (third visible) value is 7", + null, + function () { return $('#example thead tr:eq(2) th:eq(1)').html() == "7"; } + ); + + oTest.fnTest( + "Third row second cell (third visible) colspan is 1", + null, + function () { return $('#example thead tr:eq(2) th:eq(1)')[0].getAttribute('colspan') == 1; } + ); + + oTest.fnTest( + "Third row second cell (third visible) rowspan is 3", + null, + function () { return $('#example thead tr:eq(2) th:eq(1)')[0].getAttribute('rowspan') == 3; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.fnRender.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.fnRender.js new file mode 100755 index 00000000..8060ddb8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.fnRender.js @@ -0,0 +1,176 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.fnRender" ); + +$(document).ready( function () { + /* Check the default */ + var mTmp = 0; + var oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + mTmp++; + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Single column - fnRender is called once for each row", + null, + function () { return mTmp == 57; } + ); + + oTest.fnTest( + "Confirm that fnRender passes two arguments with four parameters", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a, v) { + if ( arguments.length != 2 || typeof a.iDataRow=='undefined' || + typeof a.iDataColumn=='undefined' || typeof a.aData=='undefined' || + typeof a.mDataProp=='undefined' ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "fnRender iDataColumn is row number", + function () { + var iCount = 0; + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( iCount != a.iDataRow ) + { + mTmp = false; + } + iCount++; + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "fnRender iDataColumn is the column", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( a.iDataColumn != 1 ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "fnRender aData is data array of correct size", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( a.aData.length != 5 ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "Passed back data is put into the DOM", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "fnRender": function (a) { + return 'unittest'; + } }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'unittest'; } + ); + + oTest.fnTest( + "Passed back data is put into the DOM", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + null, + { "fnRender": function (a) { + return 'unittest1'; + } }, + { "fnRender": function (a) { + return 'unittest2'; + } }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example tbody tr:eq(0) td:eq(2)').html() == 'unittest1' && + $('#example tbody tr:eq(0) td:eq(3)').html() == 'unittest2'; + return bReturn; } + ); + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.iDataSort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.iDataSort.js new file mode 100755 index 00000000..e9366ff4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.iDataSort.js @@ -0,0 +1,88 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.iDataSort" ); + +$(document).ready( function () { + /* Should know that sorting already works by default from other tests, so we can jump + * right in here + */ + var oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "iDataSort": 4 }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Sorting on first column is uneffected", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko'; } + ); + + oTest.fnTest( + "Sorting on second column is the order of the fifth", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + oTest.fnTest( + "Reserve sorting on second column uses fifth column as well", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'X'; } + ); + + oTest.fnTest( + "Sorting on 5th column retains it's own sorting", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + + oTest.fnTest( + "Use 2nd col for sorting 5th col and via-versa - no effect on first col sorting", + function () { + mTmp = 0; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + { "iDataSort": 4 }, + null, + null, + { "iDataSort": 1 } + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko'; } + ); + + oTest.fnTest( + "2nd col sorting uses fifth col", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + oTest.fnTest( + "2nd col sorting uses fifth col - reversed", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'X'; } + ); + + oTest.fnTest( + "5th col sorting uses 2nd col", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + oTest.fnTest( + "5th col sorting uses 2nd col - reversed", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'Seamonkey 1.1'; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sClass.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sClass.js new file mode 100755 index 00000000..09149bb0 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sClass.js @@ -0,0 +1,111 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.sClass" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "By default the test class hasn't been applied to the column (sanity!)", + null, + function () { return $('#example tbody tr:eq(0) td:eq(2)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - first row", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + null, + { "sClass": 'unittest' }, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(1) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - third row", + null, + function () { return $('#example tbody tr:eq(3) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - last row", + null, + function () { return $('#example tbody tr:eq(9) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to other columns - 1st", + null, + function () { return $('#example tbody tr:eq(3) td:eq(0)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to other columns - 5th", + null, + function () { return $('#example tbody tr:eq(3) td:eq(4)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - seventh row - second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody tr:eq(6) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to header", + null, + function () { return $('#example thead tr:eq(3) th:eq(4)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to footer", + null, + function () { return $('#example thead tr:eq(3) th:eq(4)').hasClass('unittest') == false; } + ); + + + oTest.fnTest( + "Class defined for multiple columns - first row", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + { "sClass": 'unittest2' }, + null, + null, + { "sClass": 'unittest1' }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example tbody tr:eq(3) td:eq(0)').hasClass('unittest2') && + $('#example tbody tr:eq(8) td:eq(3)').hasClass('unittest1'); + return bReturn; + } + ); + + oTest.fnTest( + "Class defined for multiple columns - has not applied to other columns - 5th 1", + null, + function () { return $('#example tbody tr:eq(0) td:eq(4)').hasClass('unittest1') == false; } + ); + + oTest.fnTest( + "Class defined for multiple columns - has not applied to other columns - 5th 2", + null, + function () { return $('#example tbody tr:eq(6) td:eq(4)').hasClass('unittest2') == false; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sName.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sName.js new file mode 100755 index 00000000..14a4c189 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sName.js @@ -0,0 +1,27 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.sName" ); + +/* This has no effect at all in DOM methods - so we just check that it has applied the name */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aoColumns": [ + null, + null, + null, + { "sName": 'unit test' }, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Names are stored in the columns object", + null, + function () { return oSettings.aoColumns[3].sName =="unit test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sTitle.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sTitle.js new file mode 100755 index 00000000..5ebac2f4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sTitle.js @@ -0,0 +1,78 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.sTitle" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Column names are read from the DOM by default", + null, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "Browser" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "CSS grade"; + return bReturn; + } + ); + + oTest.fnTest( + "Can set a single column title - and others are read from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "sTitle": 'unit test' }, + null, + null, + null + ] + } ); + }, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "unit test" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "CSS grade"; + return bReturn; + } + ); + + oTest.fnTest( + "Can set multiple column titles", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aoColumns": [ + null, + { "sTitle": 'unit test 1' }, + null, + null, + { "sTitle": 'unit test 2' } + ] + } ); + }, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "unit test 1" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "unit test 2"; + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sWidth.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sWidth.js new file mode 100755 index 00000000..e2777f67 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoColumns.sWidth.js @@ -0,0 +1,84 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoColumns.sWidth" ); + +/* NOTE - we need to disable the auto width for the majority of these test in order to preform + * these tests as the auto width will convert the width to a px value. We can do 'non-exact' tests + * with auto width enabled however to ensure it scales columns as required + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "bAutoWidth": false, + "aoColumns": [ + null, + { "sWidth": '40%' }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "With auto width disabled the width for one column is appled", + null, + function () { return $('#example thead th:eq(1)')[0].style.width == "40%"; } + ); + + oTest.fnTest( + "With auto width disabled the width for one column is appled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "bAutoWidth": false, + "aoColumns": [ + null, + null, + { "sWidth": '20%' }, + { "sWidth": '30%' }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example thead th:eq(2)')[0].style.width == "20%" && + $('#example thead th:eq(3)')[0].style.width == "30%"; + return bReturn; + } + ); + + + oTest.fnTest( + "With auto width, it will make the smallest column the largest with percentage width given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoColumns": [ + null, + null, + null, + { "sWidth": '40%' }, + null + ] + } ); + }, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + + if ( a3>a0 && a3>a1 && a3>a2 && a3>a4 ) + return true; + else + return false; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoSearchCols.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoSearchCols.js new file mode 100755 index 00000000..9a1a3ece --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/aoSearchCols.js @@ -0,0 +1,112 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "aoSearchCols" ); + +/* We could be here forever testing this one, so we test a limited subset on a couple of colums */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default should be to have a empty colums array", + null, + function () { + var bReturn = + oSettings.aoPreSearchCols[0].sSearch == 0 && !oSettings.aoPreSearchCols[0].bRegex && + oSettings.aoPreSearchCols[1].sSearch == 0 && !oSettings.aoPreSearchCols[1].bRegex && + oSettings.aoPreSearchCols[2].sSearch == 0 && !oSettings.aoPreSearchCols[2].bRegex && + oSettings.aoPreSearchCols[3].sSearch == 0 && !oSettings.aoPreSearchCols[3].bRegex && + oSettings.aoPreSearchCols[4].sSearch == 0 && !oSettings.aoPreSearchCols[4].bRegex; + return bReturn; + } + ); + + + oTest.fnTest( + "Search on a single column - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1" }, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Search on two columns - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1.5" }, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "1.5"; } + ); + + oTest.fnTest( + "Search on single column - escape regex false", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + null, + null, + null, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 3 of 3 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Search on two columns - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "3.3", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Konqureror 3.3"; } + ); + + oTest.fnTest( + "Search on two columns (no records) - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "Allan", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/asStripClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/asStripClasses.js new file mode 100755 index 00000000..906fc788 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/asStripClasses.js @@ -0,0 +1,106 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "asStripeClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Default row striping is applied", + null, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + oTest.fnTest( + "Row striping does not effect current classes", + null, + function () { + return $('#example tbody tr:eq(0)').hasClass('gradeA') && + $('#example tbody tr:eq(1)').hasClass('gradeA') && + $('#example tbody tr:eq(2)').hasClass('gradeA') && + $('#example tbody tr:eq(3)').hasClass('gradeA'); + } + ); + + oTest.fnTest( + "Row striping on the second page", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + /* No striping */ + oTest.fnTest( + "No row striping", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "asStripeClasses": [] + } ); + }, + function () { + return $('#example tbody tr:eq(0)')[0].className == "gradeA" && + $('#example tbody tr:eq(1)')[0].className == "gradeA" && + $('#example tbody tr:eq(2)')[0].className == "gradeA" && + $('#example tbody tr:eq(3)')[0].className == "gradeA"; + } + ); + + /* Custom striping */ + oTest.fnTest( + "Custom striping [2]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "asStripeClasses": [ 'test1', 'test2' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test1') && + $('#example tbody tr:eq(3)').hasClass('test2'); + } + ); + + + /* long array of striping */ + oTest.fnTest( + "Custom striping [4]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "asStripeClasses": [ 'test1', 'test2', 'test3', 'test4' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + oTest.fnTest( + "Custom striping is restarted on second page [2]", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bAutoWidth.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bAutoWidth.js new file mode 100755 index 00000000..e88930bd --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bAutoWidth.js @@ -0,0 +1,138 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bAutoWidth" ); + +/* It's actually a little tricky to test this. We can't test absolute numbers because + * different browsers and different platforms will render the width of the columns slightly + * differently. However, we certainly can test the principle of what should happen (column + * width doesn't change over pages) + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Auto width is enabled by default", + null, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + oTest.fnTest( + "First column has a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style').match(/width/i); } + ); + + /* + This would seem like a better test - but there appear to be difficulties with tables + which are bigger (calculated) than there is actually room for. I suspect this is actually + a bug in datatables + oTest.fnTest( + "Check column widths on first page match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + console.log( a0, b0, a1, b1, a2, b2, a3, b3 ); + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + + oTest.fnTest( + "Check column widths on second page match thid page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + */ + + /* Check can disable */ + oTest.fnTest( + "Auto width can be disabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "bAutoWidth": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth == false; } + ); + + oTest.fnTest( + "First column does not have a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style') == null; } + ); + + /* + oTest.fnTest( + "Check column widths on first page do not match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return false; + else + return true; + } + ); + */ + + /* Enable makes no difference */ + oTest.fnTest( + "Auto width enabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "bAutoWidth": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bFilter.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bFilter.js new file mode 100755 index 00000000..f4ec3158 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bFilter.js @@ -0,0 +1,40 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bFilter" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Filtering div exists by default", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + /* Check can disable */ + oTest.fnTest( + "Fltering can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bFilter": false + } ); + }, + function () { return document.getElementById('example_filter') == null; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Filtering enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bFilter": true + } ); + }, + function () { return document.getElementById('example_filter') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfiniteScroll.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfiniteScroll.js new file mode 100755 index 00000000..ce73892b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfiniteScroll.js @@ -0,0 +1,130 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bInfiniteScroll" ); + + +$(document).ready( function () { + var oTable = $('#example').dataTable( { + "bScrollInfinite": true, + "sScrollY": "200px" + } ); + + oTest.fnTest( + "10 rows by default", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Info", + null, + function () { return $('#example_info').html() == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Get nodes", + null, + function () { return $('#example tbody>tr').length == 10; } + ); + + oTest.fnWaitTest( + "Scroll on 20px adds 10 rows", + function () { $('div.dataTables_scrollBody').scrollTop(20); }, + function () { return $('#example tbody tr').length == 20; } + ); + + oTest.fnTest( + "Info after 20px scroll", + null, + function () { return $('#example_info').html() == "Showing 1 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Get nodes after 20px scroll", + null, + function () { return $('#example tbody>tr').length == 20; } + ); + + oTest.fnTest( + "Scroll on 10px more results in the same number of rows", + function () { $('div.dataTables_scrollBody').scrollTop(30); }, + function () { return $('#example tbody tr').length == 20; } + ); + + oTest.fnTest( + "Info after 10 more px scroll", + null, + function () { return $('#example_info').html() == "Showing 1 to 20 of 57 entries"; } + ); + + oTest.fnWaitTest( + "Scroll to 240px adds another 10 rows", + function () { $('div.dataTables_scrollBody').scrollTop(240); }, + function () { return $('#example tbody tr').length == 30; } + ); + + oTest.fnTest( + "Info after 240px scroll", + null, + function () { return $('#example_info').html() == "Showing 1 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Get nodes after 240px scroll", + null, + function () { return $('#example tbody>tr').length == 30; } + ); + + oTest.fnTest( + "Filtering will drop back to 10 rows", + function () { + $('div.dataTables_scrollBody').scrollTop(0); + oTable.fnFilter('gec') + }, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Info after filtering", + null, + function () { return $('#example_info').html() == "Showing 1 to 10 of 20 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Get nodes after filtering", + null, + function () { return $('#example tbody>tr').length == 10; } + ); + + oTest.fnWaitTest( + "Scroll after filtering adds 10", + function () { $('div.dataTables_scrollBody').scrollTop(20); }, + function () { return $('#example tbody tr').length == 20; } + ); + + oTest.fnTest( + "Get nodes after filtering", + null, + function () { return $('#example tbody>tr').length == 20; } + ); + + oTest.fnTest( + "Sorting will drop back to 10 rows", + function () { oTable.fnSort([[1,'asc']]) }, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnWaitTest( + "Scroll after sorting adds 10", + function () { $('div.dataTables_scrollBody').scrollTop(20); }, + function () { return $('#example tbody tr').length == 20; } + ); + + oTest.fnTest( + "Get nodes after scrolling", + null, + function () { return $('#example tbody>tr').length == 20; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfo.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfo.js new file mode 100755 index 00000000..54d470f0 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bInfo.js @@ -0,0 +1,40 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bInfo" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Info div exists by default", + null, + function () { return document.getElementById('example_info') != null; } + ); + + /* Check can disable */ + oTest.fnTest( + "Info can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bInfo": false + } ); + }, + function () { return document.getElementById('example_info') == null; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Info enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bInfo": true + } ); + }, + function () { return document.getElementById('example_info') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bJQueryUI.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bJQueryUI.js new file mode 100755 index 00000000..6c685468 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bJQueryUI.js @@ -0,0 +1,40 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bJQueryUI" ); + +$(document).ready( function () { + $('#example').dataTable( { + "bJQueryUI": true + } ); + + oTest.fnTest( + "Header elements are fully wrapped by DIVs", + null, + function () { + var test = true; + $('#example thead th').each( function () { + if ( this.childNodes > 1 ) { + test = false; + } + } ); + return test; + } + ); + + oTest.fnTest( + "One div for each header element", + null, + function () { + return $('#example thead th div').length == 5; + } + ); + + oTest.fnTest( + "One span for each header element, nested as child of div", + null, + function () { + return $('#example thead th div>span').length == 5; + } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bLengthChange.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bLengthChange.js new file mode 100755 index 00000000..1c8ef40b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bLengthChange.js @@ -0,0 +1,71 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bLengthChange" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Length div exists by default", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Four default options", + null, + function () { return $("select[name=example_length] option").length == 4; } + ); + + oTest.fnTest( + "Default options", + null, + function () { + var opts = $("select[name='example_length'] option"); + return opts[0].getAttribute('value') == 10 && opts[1].getAttribute('value') == 25 && + opts[2].getAttribute('value') == 50 && opts[3].getAttribute('value') == 100; + } + ); + + oTest.fnTest( + "Info takes length into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnTest( + "Change length can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bLengthChange": false + } ); + }, + function () { return document.getElementById('example_length') == null; } + ); + + oTest.fnTest( + "Information takes length disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Length change enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bLengthChange": true + } ); + }, + function () { return document.getElementById('example_length') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bPaginate.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bPaginate.js new file mode 100755 index 00000000..560114e3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bPaginate.js @@ -0,0 +1,55 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bPaginate" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Pagiantion div exists by default", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Information div takes paging into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bPaginate": false + } ); + }, + function () { return document.getElementById('example_paginate') == null; } + ); + + oTest.fnTest( + "Information div takes paging disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 57 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Pagiantion enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bPaginate": true + } ); + }, + function () { return document.getElementById('example_paginate') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bProcessing.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bProcessing.js new file mode 100755 index 00000000..e342a40c --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bProcessing.js @@ -0,0 +1,99 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bProcessing" ); + +/* It's actually a bit hard to set this one due to the fact that it will only be shown + * when DataTables is doing some kind of processing. The server-side processing is a bit + * better to test this than here - so we just the interal functions to enable it and check + * that it is available + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Processing is off by default", + null, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "Processing div cannot be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "Processing div cannot be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + /* Check can disable */ + oTest.fnTest( + "Processing can be enabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "bProcessing": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == true; } + ); + + oTest.fnTest( + "Processing div is in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing'); } + ); + + oTest.fnTest( + "Processing div is hidden by default", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + oTest.fnTest( + "Processing div can be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "visible"; } + ); + + oTest.fnTest( + "Processing div can be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Processing disabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "bProcessing": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bServerSide.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bServerSide.js new file mode 100755 index 00000000..c6aacec6 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bServerSide.js @@ -0,0 +1,18 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bServerSide" ); + +/* Not interested in server-side processing here other than to check that it is off */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Server side is off by default", + null, + function () { return oSettings.oFeatures.bServerSide == false; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSort.js new file mode 100755 index 00000000..ecaf168e --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSort.js @@ -0,0 +1,101 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bSort" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Sorting is on by default", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Sorting Asc by default class applied", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc"); } + ); + + oTest.fnTest( + "Click on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting class removed from first column", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc") != true; } + ); + + oTest.fnTest( + "Sorting asc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc"); } + ); + + oTest.fnTest( + "Reverse on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting acs class removed from second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc") != true; } + ); + + oTest.fnTest( + "Sorting desc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_desc"); } + ); + + /* Check can disable */ + oTest.fnTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bSort": false + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Disabled classes applied", + null, + function () { return $('#example thead th:eq(0)').hasClass('sorting_disabled'); } + ); + + oTest.fnTest( + "Click on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Reverse on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Sorting enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bSort": true + } ); + }, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortCellsTop.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortCellsTop.js new file mode 100755 index 00000000..fc550d5d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortCellsTop.js @@ -0,0 +1,77 @@ +// DATA_TEMPLATE: dom_data_two_headers +oTest.fnStart( "bSortCellsTop" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Sorting class is on the bottom cells by default", + null, + function () { return $('#example thead tr:eq(1) th:eq(0)').hasClass('sorting_asc'); } + ); + + oTest.fnTest( + "Sorting is performed on bottom cells", + function () { return $('#example thead tr:eq(1) th:eq(0)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Sorting class is updated on the bottom cells", + null, + function () { return $('#example thead tr:eq(1) th:eq(0)').hasClass('sorting_desc'); } + ); + + oTest.fnTest( + "Clicking on top cells has no effect", + function () { return $('#example thead tr:eq(0) th:eq(0)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Clicking on another top cell has no effect", + function () { return $('#example thead tr:eq(0) th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + + oTest.fnTest( + "Sorting class is on the top cell when bSortCellsTop is true", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bSortCellsTop": true + } ); + }, + function () { return $('#example thead tr:eq(0) th:eq(0)').hasClass('sorting_asc'); } + ); + + oTest.fnTest( + "Sorting is performed on top cells now", + function () { return $('#example thead tr:eq(0) th:eq(0)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Sorting class is updated on the top cells", + null, + function () { return $('#example thead tr:eq(0) th:eq(0)').hasClass('sorting_desc'); } + ); + + oTest.fnTest( + "Clicking on bottom cells has no effect", + function () { return $('#example thead tr:eq(1) th:eq(0)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Clicking on another bottom cell has no effect", + function () { return $('#example thead tr:eq(1) th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortClasses.js new file mode 100755 index 00000000..97f0c1fc --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/bSortClasses.js @@ -0,0 +1,128 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "bSortClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable(); + + oTest.fnTest( + "Sorting classes are applied by default", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnTest( + "Sorting classes are applied to all required cells", + null, + function () { return $('#example tbody tr:eq(7) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnTest( + "Sorting classes are not applied to non-sorting columns", + null, + function () { return $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_1') == false; } + ); + + oTest.fnTest( + "Sorting multi-column - add column 1", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2'); + } + ); + + oTest.fnTest( + "Sorting multi-column - add column 2", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3'); + } + ); + + oTest.fnTest( + "Sorting multi-column - add column 3", + function () { + oDispacher.click( $('#example thead th:eq(3)')[0], { 'shift': true } ); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3'); + } + ); + + oTest.fnTest( + "Remove sorting classes on single column sort", + function () { + $('#example thead th:eq(4)').click(); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3') == false; + } + ); + + oTest.fnTest( + "Sorting class 1 was added", + null, + function () { return $('#example tbody tr:eq(1) td:eq(4)').hasClass('sorting_1'); } + ); + + + /* Check can disable */ + oTest.fnTest( + "Sorting classes can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bSortClasses": false + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false; } + ); + + oTest.fnTest( + "Sorting classes disabled - add column 1 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false; + } + ); + + oTest.fnTest( + "Sorting classes disabled - add column 2 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false; + } + ); + + + /* Enable makes no difference */ + oTest.fnTest( + "Sorting classes enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "bSortClasses": true + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCookieCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCookieCallback.js new file mode 100755 index 00000000..31d03936 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCookieCallback.js @@ -0,0 +1,97 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "Cookie callback" ); + + +$(document).ready( function () { + var mPass; + /* Note that in order to be fully effective here for saving state, there would need to be a + * stringify function to serialise the data array + */ + + oTest.fnTest( + "null by default", + function () { + $('#example').dataTable(); + }, + function () { return $('#example').dataTable().fnSettings().fnCookieCallback == null; } + ); + + oTest.fnTest( + "Number of arguments", + function () { + $('#example').dataTable( { + "bDestroy": true, + "bStateSave": true, + "fnCookieCallback": function (sName, oData, sExpires, sPath) { + mPass = arguments.length; + return sName + "=; expires=" + sExpires +"; path=" + sPath; + } + } ); + }, + function () { return mPass == 4; } + ); + + oTest.fnTest( + "Name", + function () { + $('#example').dataTable( { + "bDestroy": true, + "bStateSave": true, + "fnCookieCallback": function (sName, oData, sExpires, sPath) { + mPass = sName=="SpryMedia_DataTables_example_dom_data.php"; + return sName + "=; expires=" + sExpires +"; path=" + sPath; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Data", + function () { + $('#example').dataTable( { + "bDestroy": true, + "bStateSave": true, + "fnCookieCallback": function (sName, oData, sExpires, sPath) { + mPass = typeof oData.iStart != 'undefined'; + return sName + "=; expires=" + sExpires +"; path=" + sPath; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Expires", + function () { + $('#example').dataTable( { + "bDestroy": true, + "bStateSave": true, + "fnCookieCallback": function (sName, oData, sExpires, sPath) { + mPass = typeof sExpires == 'string'; + return sName + "=; expires=" + sExpires +"; path=" + sPath; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Path", + function () { + $('#example').dataTable( { + "bDestroy": true, + "bStateSave": true, + "fnCookieCallback": function (sName, oData, sExpires, sPath) { + mPass = sPath.match(/media\/unit_testing\/templates/); + return sName + "=; expires=" + sExpires +"; path=" + sPath; + } + } ); + }, + function () { return mPass; } + ); + + + oTest.fnCookieDestroy( $('#example').dataTable() ); + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedCell.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedCell.js new file mode 100755 index 00000000..1de49671 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedCell.js @@ -0,0 +1,151 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnCreatedCell tests" ); + +$(document).ready( function () { + var tmp = 0; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedCell: function () { + tmp++; + }, + "aTargets": ["_all"] + } ] + } ); + + oTest.fnTest( + "Cell created is called once for each cell on init", + null, + function () { return tmp===285; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===285; } + ); + + oTest.fnTest( + "Four arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments.length !== 4 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "First argument is a TD element", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TD" ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Second argument is the HTML value", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td').html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Third argument is the data array", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2].length !== 5 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Fourth argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Fifth argument is the the col index", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td:eq('+arguments[4]+')', arguments[0].parentNode).html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedRow.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedRow.js new file mode 100755 index 00000000..e408f709 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnCreatedRow.js @@ -0,0 +1,115 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnCreatedRow tests" ); + +$(document).ready( function () { + var tmp = 0; + + $('#example').dataTable( { + fnCreatedRow: function () { + tmp++; + } + } ); + + oTest.fnTest( + "Row created is called once for each row on init", + null, + function () { return tmp===57; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===57; } + ); + + oTest.fnTest( + "Three arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + fnCreatedRow: function () { + if ( arguments.length !== 3 ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "First argument is a TR element", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TR" ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Second argument is an array with 5 elements", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + fnCreatedRow: function () { + if ( arguments[1].length !== 5 ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Third argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + fnCreatedRow: function () { + if ( arguments[1] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "TR element is tied to the correct data", + function () { + oSession.fnRestore(); + tmp = false; + + $('#example').dataTable( { + fnCreatedRow: function (tr, data, index) { + if ( data[1] === "Firefox 1.0" ) { + if ( $('td:eq(3)', tr).html() == "1.7" ) { + tmp = true; + } + } + } + } ); + }, + function () { return tmp; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDeleteRow.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDeleteRow.js new file mode 100755 index 00000000..29a0b3fd --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDeleteRow.js @@ -0,0 +1,30 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnDeleteRow" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Check that the default data is sane", + null, + function () { return oSettings.asDataSearch.join(' ').match(/4.0/g).length == 3; } + ); + + oTest.fnTest( + "Remove the first data row, and check that hte search data has been updated", + function () { oTable.fnDeleteRow( 0 ); }, + function () { return oSettings.asDataSearch.join(' ').match(/4.0/g).length == 2; } + ); + + oTest.fnTest( + "Check that the info element has been updated", + null, + function () { return $('#example_info').html() == "Showing 1 to 10 of 56 entries"; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDrawCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDrawCallback.js new file mode 100755 index 00000000..ffa5f814 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnDrawCallback.js @@ -0,0 +1,80 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnDrawCallback" ); + +/* Fairly boring function compared to the others! */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnTest( + "Default should be null", + null, + function () { return oSettings.fnDrawCallback == null; } + ); + + + oTest.fnTest( + "One argument passed", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "fnDrawCallback": function ( ) { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 1; } + ); + + + oTest.fnTest( + "That one argument is the settings object", + function () { + oSession.fnRestore(); + + oTable = $('#example').dataTable( { + "fnDrawCallback": function ( oSettings ) { + mPass = oSettings; + } + } ); + }, + function () { return oTable.fnSettings() == mPass; } + ); + + + oTest.fnTest( + "fnRowCallback called once on first draw", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "fnDrawCallback": function ( ) { + mPass++; + } + } ); + }, + function () { return mPass == 1; } + ); + + oTest.fnTest( + "fnRowCallback called once on each draw there after as well", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return mPass == 4; } + ); + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFilter.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFilter.js new file mode 100755 index 00000000..1e18b22d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFilter.js @@ -0,0 +1,16 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnFilter" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + oTable.fnFilter(1); + + oTest.fnTest( + "Filtering with a non-string input is valid", + null, + function () { return $('#example_info').html() == "Showing 1 to 10 of 32 entries (filtered from 57 total entries)"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFooterCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFooterCallback.js new file mode 100755 index 00000000..a02f8de2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/fnFooterCallback.js @@ -0,0 +1,227 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "fnFooterCallback" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnTest( + "Default should be null", + null, + function () { return oSettings.fnFooterCallback == null; } + ); + + + oTest.fnTest( + "Five arguments passed", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "fnFooterCallback": function ( ) { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 5; } + ); + + + oTest.fnTest( + "fnRowCallback called once per draw", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + mPass++; + } + } ); + }, + function () { return mPass == 1; } + ); + + oTest.fnTest( + "fnRowCallback called on paging (i.e. another draw)", + function () { $('#example_next').click(); }, + function () { return mPass == 2; } + ); + + + oTest.fnTest( + "fnRowCallback allows us to alter row information", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + nFoot.getElementsByTagName('th')[0].innerHTML = "Displaying "+(iEnd-iStart)+" records"; + } + } ); + }, + function () { return $('#example tfoot th:eq(0)').html() == "Displaying 10 records"; } + ); + + + oTest.fnTest( + "Data array has length matching original data", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + if ( aasData.length != 57 ) + { + mPass = false; + } + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Data array's column lengths match original data", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + for ( var i=0, iLen=aasData.length ; i' + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.sDom == '<"wrapper"flipt>'; } + ); + + oTest.fnTest( + "Check example 1 in DOM", + null, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; iip>' + } ); + }, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + var nCustomWrappers = [] + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; irti' + } ); + }, + function () { + return $('#test').length == 1; + } + ); + + oTest.fnTest( + "Element with an id and a class", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sDom": '<"#test.classTest"lf>rti' + } ); + }, + function () { + return ($('#test').length == 1 && $('#test')[0].className == "classTest"); + } + ); + + oTest.fnTest( + "Element with just a class", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sDom": '<"classTest"lf>rti' + } ); + }, + function () { + return ($('div.classTest').length == 1 ); + } + ); + + oTest.fnTest( + "Two elements with an id", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sDom": '<"#test1"lf>rti<"#test2"lf>' + } ); + }, + function () { + return ($('#test1').length == 1 && $('#test2').length == 1); + } + ); + + oTest.fnTest( + "Two elements with an id and one with a class", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sDom": '<"#test1"lf>rti<"#test2.classTest"lf>' + } ); + }, + function () { + return ($('#test1').length == 1 && $('#test2').length == 1 && $('div.classTest').length == 1); + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sPaginationType.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sPaginationType.js new file mode 100755 index 00000000..8d975f55 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sPaginationType.js @@ -0,0 +1,122 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "sPaginationType" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable(); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Check two button paging is the default", + null, + function () { return oSettings.sPaginationType == "two_button"; } + ); + + oTest.fnTest( + "Check class is applied", + null, + function () { return $('#example_paginate').hasClass('paging_two_button'); } + ); + + oTest.fnTest( + "Two A elements are in the wrapper", + null, + function () { return $('#example_paginate a').length == 2; } + ); + + oTest.fnTest( + "We have the previous button", + null, + function () { return document.getElementById('example_previous'); } + ); + + oTest.fnTest( + "We have the next button", + null, + function () { return document.getElementById('example_next'); } + ); + + oTest.fnTest( + "Previous button is disabled", + null, + function () { return $('#example_previous').hasClass('paginate_disabled_previous'); } + ); + + oTest.fnTest( + "Next button is enabled", + null, + function () { return $('#example_next').hasClass('paginate_enabled_next'); } + ); + + /* Don't test paging - that's done by the zero config test script. */ + + + /* Two buttons paging */ + oTest.fnTest( + "Can enabled full numbers paging", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sPaginationType": "full_numbers" + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.sPaginationType == "full_numbers"; } + ); + + oTest.fnTest( + "Check full numbers class is applied", + null, + function () { return $('#example_paginate').hasClass('paging_full_numbers'); } + ); + + + var nFirst, nPrevious, nNext, nLast; + oTest.fnTest( + "Jump to last page", + function () { + nFirst = $('div.dataTables_paginate a.first'); + nPrevious = $('div.dataTables_paginate a.previous'); + nNext = $('div.dataTables_paginate a.next'); + nLast = $('div.dataTables_paginate a.last'); + nLast.click(); + }, + function () { + return document.getElementById('example_info').innerHTML == "Showing 51 to 57 of 57 entries"; + } + ); + + oTest.fnTest( + "Go to two pages previous", + function () { + nPrevious.click(); + nPrevious.click(); + }, + function () { + return document.getElementById('example_info').innerHTML == "Showing 31 to 40 of 57 entries"; + } + ); + + oTest.fnTest( + "Next (second last) page", + function () { + nNext.click(); + }, + function () { + return document.getElementById('example_info').innerHTML == "Showing 41 to 50 of 57 entries"; + } + ); + + oTest.fnTest( + "Jump to first page", + function () { + nFirst.click(); + }, + function () { + return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sScrollXY.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sScrollXY.js new file mode 100755 index 00000000..d9a61195 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/sScrollXY.js @@ -0,0 +1,63 @@ +// DATA_TEMPLATE: dom_data +oTest.fnStart( "sScrollX / Y" ); + + +$(document).ready( function () { + // Force some x scrolling + $('body').css('white-space', 'nowrap'); + $('#container').css('width', '400px'); + + var oTable = $('#example').dataTable( { + "sScrollX": "100%", + "sScrollY": "200px", + "bPaginate": false + } ); + + oTest.fnWaitTest( + "Header follows x-scrolling", + function () { $('div.dataTables_scrollBody').scrollLeft(20); }, + function () { return $('div.dataTables_scrollHead').scrollLeft() == 20; } + ); + + oTest.fnWaitTest( + "Footer follows x-scrolling", + null, + function () { return $('div.dataTables_scrollFoot').scrollLeft() == 20; } + ); + + oTest.fnWaitTest( + "y-scrolling has no effect on header", + function () { $('div.dataTables_scrollBody').scrollTop(20); }, + function () { return $('div.dataTables_scrollHead').scrollLeft() == 20; } + ); + + oTest.fnWaitTest( + "Filtering results in sets y-scroll back to 0", + function () { oTable.fnFilter('1') }, + function () { return $('div.dataTables_scrollBody').scrollTop() == 0; } + ); + + oTest.fnWaitTest( + "Filtering has no effect on x-scroll", + null, + function () { return $('div.dataTables_scrollBody').scrollLeft() == 20; } + ); + + oTest.fnWaitTest( + "Full x-scroll has header track all the way with it", + function () { + $('div.dataTables_scrollBody').scrollLeft( + $('#example').width() - $('div.dataTables_scrollBody')[0].clientWidth + ); + }, + function () { return $('div.dataTables_scrollBody').scrollLeft() == $('div.dataTables_scrollHead').scrollLeft(); } + ); + + oTest.fnTest( + "Footer also tracked all the way", + null, + function () { return $('div.dataTables_scrollBody').scrollLeft() == $('div.dataTables_scrollFoot').scrollLeft(); } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/th_in_body.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/th_in_body.js new file mode 100755 index 00000000..bbf5ee3a --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/1_dom/th_in_body.js @@ -0,0 +1,437 @@ +// DATA_TEMPLATE: dom_data_th +oTest.fnStart( "Sanity checks for DataTables with DOM data and a TH in the body" ); + +oTest.fnTest( + "jQuery.dataTable function", + null, + function () { return typeof jQuery().dataTable == "function"; } +); + +oTest.fnTest( + "jQuery.dataTableSettings storage array", + null, + function () { return typeof jQuery().dataTableSettings == "object"; } +); + +oTest.fnTest( + "jQuery.dataTableExt plugin object", + null, + function () { return typeof jQuery().dataTableExt == "object"; } +); + +$(document).ready( function () { + $('#example').dataTable(); + + /* Basic checks */ + oTest.fnTest( + "Length changing div exists", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Filtering div exists", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + oTest.fnTest( + "Information div exists", + null, + function () { return document.getElementById('example_info') != null; } + ); + + oTest.fnTest( + "Pagination div exists", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Processing div is off by default", + null, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Information on last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 51 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back on first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 25 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records - second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 26 to 50 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 100 records - first page", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('100').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back to 10 records", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('10').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 31 to 31 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' back to first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - second time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter increased to 'Win 98'", + function () { $('#example_filter input').val("Win 98").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter decreased to 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - third time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter removed", + function () { $('#example_filter input').val("").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + + /* + * Filtering + */ + oTest.fnTest( + "Filter 'W' - rows", + function () { + /* Reset the table such that the old sorting doesn't mess things up */ + oSession.fnRestore(); + $('#example').dataTable(); + $('#example_filter input').val("W").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Filter 'W' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 42 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Wi'", + function () { $('#example_filter input').val("Wi").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 32 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "AOL browser (AOL desktop)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 reverse", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - maintaing reverse sorting col 1", + function () { $('#example_filter input').val("Win XP").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Internet Explorer 7"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3 - reversed", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "7"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting col 3 - reversed info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 6 of 6 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'nothinghere'", + function () { $('#example_filter input').val("nothinghere").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == + "No matching records found"; } + ); + + oTest.fnTest( + "Filter 'nothinghere' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter back to blank and 1st column sorting", + function () { + $('#example_filter input').val("").keyup(); + $('#example thead th:eq(0)').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Prefixing a filter entry", + function () { + $('#example_filter input').val("Win").keyup(); + $('#example_filter input').val("GeckoWin").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Prefixing a filter entry with space", + function () { + $('#example_filter input').val("Gecko Win").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 17 entries (filtered from 57 total entries)"; } + ); + + + + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/6872-default-content-missing-props.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/6872-default-content-missing-props.js new file mode 100644 index 00000000..5ae4126b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/6872-default-content-missing-props.js @@ -0,0 +1,285 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "6872 - mDataProp and sDefaultContent for deep objects" ); + +$(document).ready( function () { + var test = false; + + $.fn.dataTable.ext.sErrMode = "throw"; + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Shallow properties + */ + + $('#example').dataTable( { + "aaData": [ + { + "a": "a", + "b": "b", + "c": "c", + "d": "d", + "e": "e" + } + ], + "aoColumns": [ + { "mDataProp": "a" }, + { "mDataProp": "b" }, + { "mDataProp": "c" }, + { "mDataProp": "d" }, + { "mDataProp": "e" } + ] + } ); + + oTest.fnTest( + "Basic initialisation of objects works", + null, + function () { return $('#example tbody td:eq(0)').html() === "a"; } + ); + + oTest.fnTest( + "Error when property missing (no default content)", + function () { + oSession.fnRestore(); + test = false; + + try { + $('#example').dataTable( { + "aaData": [ + { + "a": "a", + "b": "b", + "d": "d", + "e": "e" + } + ], + "aoColumns": [ + { "mDataProp": "a" }, + { "mDataProp": "b" }, + { "mDataProp": "c" }, + { "mDataProp": "d" }, + { "mDataProp": "e" } + ] + } ); + } catch (e) { + test = true; + } + }, + function () { return test; } + ); + + oTest.fnTest( + "Default content used for missing prop and no error", + function () { + oSession.fnRestore(); + + $('#example').dataTable( { + "aaData": [ + { + "a": "a", + "b": "b", + "d": "d", + "e": "e" + } + ], + "aoColumns": [ + { "mDataProp": "a" }, + { "mDataProp": "b" }, + { "mDataProp": "c", "sDefaultContent": "test" }, + { "mDataProp": "d" }, + { "mDataProp": "e" } + ] + } ); + }, + function () { return $('#example tbody td:eq(2)').html() === "test"; } + ); + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Deep properties with a single object + */ + + oTest.fnTest( + "Basic test with deep properties", + function () { + oSession.fnRestore(); + + $('#example').dataTable( { + "aaData": [ + { + "z": { + "a": "a", + "b": "b", + "c": "c", + "d": "d", + "e": "e" + } + } + ], + "aoColumns": [ + { "mDataProp": "z.a" }, + { "mDataProp": "z.b" }, + { "mDataProp": "z.c" }, + { "mDataProp": "z.d" }, + { "mDataProp": "z.e" } + ] + } ); + }, + function () { return $('#example tbody td:eq(0)').html() === "a"; } + ); + + oTest.fnTest( + "Error when property missing on deep get (no default content)", + function () { + oSession.fnRestore(); + test = false; + + try { + $('#example').dataTable( { + "aaData": [ + { + "z": { + "a": "a", + "b": "b", + "c": "c", + "e": "e" + } + } + ], + "aoColumns": [ + { "mDataProp": "z.a" }, + { "mDataProp": "z.b" }, + { "mDataProp": "z.c" }, + { "mDataProp": "z.d" }, + { "mDataProp": "z.e" } + ] + } ); + } catch (e) { + test = true; + } + }, + function () { return test; } + ); + + oTest.fnTest( + "Default content used for missing prop on deep get and no error", + function () { + oSession.fnRestore(); + + $('#example').dataTable( { + "aaData": [ + { + "z": { + "a": "a", + "b": "b", + "c": "c", + "e": "e" + } + } + ], + "aoColumns": [ + { "mDataProp": "z.a" }, + { "mDataProp": "z.b" }, + { "mDataProp": "z.c" }, + { "mDataProp": "z.d", "sDefaultContent": "test" }, + { "mDataProp": "z.e" } + ] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() === "test"; } + ); + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Deep properties with individual objects + */ + + oTest.fnTest( + "Basic test with deep individual properties", + function () { + oSession.fnRestore(); + + $('#example').dataTable( { + "aaData": [ + { + "m": { "a": "a" }, + "n": { "b": "b" }, + "o": { "c": "c" }, + "p": { "d": "d" }, + "q": { "e": "e" } + } + ], + "aoColumns": [ + { "mDataProp": "m.a" }, + { "mDataProp": "n.b" }, + { "mDataProp": "o.c" }, + { "mDataProp": "p.d" }, + { "mDataProp": "q.e" } + ] + } ); + }, + function () { return $('#example tbody td:eq(0)').html() === "a"; } + ); + + oTest.fnTest( + "Error when property missing on deep individual get (no default content)", + function () { + oSession.fnRestore(); + test = false; + + try { + $('#example').dataTable( { + "aaData": [ + { + "m": { "a": "a" }, + "n": { "b": "b" }, + "p": { "d": "d" }, + "q": { "e": "e" } + } + ], + "aoColumns": [ + { "mDataProp": "m.a" }, + { "mDataProp": "n.b" }, + { "mDataProp": "o.c" }, + { "mDataProp": "p.d" }, + { "mDataProp": "q.e" } + ] + } ); + } catch (e) { + test = true; + } + }, + function () { return test; } + ); + + oTest.fnTest( + "Default content used for missing prop on deep individual get and no error", + function () { + oSession.fnRestore(); + + $('#example').dataTable( { + "aaData": [ + { + "m": { "a": "a" }, + "n": { "b": "b" }, + "p": { "d": "d" }, + "q": { "e": "e" } + } + ], + "aoColumns": [ + { "mDataProp": "m.a" }, + { "mDataProp": "n.b" }, + { "mDataProp": "o.c", "sDefaultContent": "test" }, + { "mDataProp": "p.d" }, + { "mDataProp": "q.e" } + ] + } ); + }, + function () { return $('#example tbody td:eq(2)').html() === "test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/8549--string-sorting-nonstrings.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/8549--string-sorting-nonstrings.js new file mode 100644 index 00000000..57ffebc0 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/8549--string-sorting-nonstrings.js @@ -0,0 +1,47 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "8549 - string sorting non-string types" ); + +$(document).ready( function () { + var test = false; + + $.fn.dataTable.ext.sErrMode = "throw"; + + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Shallow properties + */ + + $('#example').dataTable( { + "aaData": [ + [ null ], + [ 5 ], + [ "1a" ], + [ new Date(0) ] + ], + "aoColumns": [ + { "sTitle": "Test" } + ] + } ); + + oTest.fnTest( + "Sorting works - first cell is empty", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() === ""; } + ); + + oTest.fnTest( + "Second cell is 1a", + null, + function () { return $('#example tbody tr:eq(1) td:eq(0)').html() === "1a"; } + ); + + oTest.fnTest( + "Third cell is 5", + null, + function () { return $('#example tbody tr:eq(2) td:eq(0)').html() === "5"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/_zero_config.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/_zero_config.js new file mode 100644 index 00000000..51abbad2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/_zero_config.js @@ -0,0 +1,440 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "Sanity checks for DataTables with data from JS" ); + +oTest.fnTest( + "jQuery.dataTable function", + null, + function () { return typeof jQuery().dataTable == "function"; } +); + +oTest.fnTest( + "jQuery.dataTableSettings storage array", + null, + function () { return typeof jQuery().dataTableSettings == "object"; } +); + +oTest.fnTest( + "jQuery.dataTableExt plugin object", + null, + function () { return typeof jQuery().dataTableExt == "object"; } +); + +$(document).ready( function () { + var oInit = { + "aaData": gaaData + }; + $('#example').dataTable( oInit ); + + /* Basic checks */ + oTest.fnTest( + "Length changing div exists", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Filtering div exists", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + oTest.fnTest( + "Information div exists", + null, + function () { return document.getElementById('example_info') != null; } + ); + + oTest.fnTest( + "Pagination div exists", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Processing div is off by default", + null, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + oTest.fnTest( + "Information on last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 51 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back on first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 25 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 25 records - second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 26 to 50 of 57 entries"; } + ); + + oTest.fnTest( + "Information with 100 records - first page", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('100').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 57 of 57 entries"; } + ); + + oTest.fnTest( + "Information back to 10 records", + function () { + $('#example_previous').click(); + $("select[name=example_length]").val('10').change(); + }, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information with filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' last page", + function () { + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 31 to 31 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' back to first page", + function () { + $('#example_previous').click(); + $('#example_previous').click(); + $('#example_previous').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - second time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter increased to 'Win 98'", + function () { $('#example_filter input').val("Win 98").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter decreased to 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter 'Win' second page - third time", + function () { + $('#example_next').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 11 to 20 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Information with filter removed", + function () { $('#example_filter input').val("").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + + /* + * Filtering + */ + oTest.fnTest( + "Filter 'W' - rows", + function () { + /* Reset the table such that the old sorting doesn't mess things up */ + oSession.fnRestore(); + $('#example').dataTable( oInit ); + $('#example_filter input').val("W").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Filter 'W' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 42 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Wi'", + function () { $('#example_filter input').val("Wi").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 32 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win'", + function () { $('#example_filter input').val("Win").keyup(); }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "AOL browser (AOL desktop)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 31 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting column 1 reverse", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - maintaing reverse sorting col 1", + function () { $('#example_filter input').val("Win XP").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Internet Explorer 7"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Filter 'Win XP' - sorting col 3 - reversed", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "7"; } + ); + + oTest.fnTest( + "Filter 'Win' - sorting col 3 - reversed info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 6 of 6 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter 'nothinghere'", + function () { $('#example_filter input').val("nothinghere").keyup(); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == + "No matching records found"; } + ); + + oTest.fnTest( + "Filter 'nothinghere' - info", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Filter back to blank and 1st column sorting", + function () { + $('#example_filter input').val("").keyup(); + $('#example thead th:eq(0)').click(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Prefixing a filter entry", + function () { + $('#example_filter input').val("Win").keyup(); + $('#example_filter input').val("GeckoWin").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 0 to 0 of 0 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Prefixing a filter entry with space", + function () { + $('#example_filter input').val("Gecko Win").keyup(); + }, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 17 entries (filtered from 57 total entries)"; } + ); + + + + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSorting.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSorting.js new file mode 100644 index 00000000..3b16828e --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSorting.js @@ -0,0 +1,198 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aaSorting" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default sorting is single column", + null, + function () { + return oSettings.aaSorting.length == 1 && typeof oSettings.aaSorting[0] == 'object'; + } + ); + + oTest.fnTest( + "Default sorting is first column asc", + null, + function () { + return oSettings.aaSorting[0].length == 3 && oSettings.aaSorting[0][0] == 0 && + oSettings.aaSorting[0][1] == 'asc'; + } + ); + + oTest.fnTest( + "Sorting is applied", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + + oTest.fnTest( + "Custom sorting on single string column asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + + oTest.fnTest( + "Custom sorting on single string column desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + + oTest.fnTest( + "Custom sorting on single int column asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + + oTest.fnTest( + "Custom sorting on single int column desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','asc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / string desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','asc'], ['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','desc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "iPod Touch / iPhone"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / string desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','desc'], ['1','desc']] + } ); + }, + function () { return $('#example tbody td:eq(1)').html() == "Safari 3.0"; } + ); + + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / int asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','asc'], ['3','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "1"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string asc / int desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','asc'], ['3','desc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "1.9"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / int asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','desc'], ['3','asc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "125.5"; } + ); + + oTest.fnTest( + "Multi-column sorting (2 column) - string desc / int desc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','desc'], ['3','desc']] + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Multi-column sorting (3 column) - string asc / int asc / string asc", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSorting": [['0','asc'], ['3','asc'], ['1','asc']] + } ); + }, + function () { return $('#example tbody tr:eq(7) td:eq(1)').html() == "Firefox 1.0"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSortingFixed.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSortingFixed.js new file mode 100644 index 00000000..a28e6101 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aaSortingFixed.js @@ -0,0 +1,64 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aaSortingFixed" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "No fixed sorting by default", + null, + function () { + return oSettings.aaSortingFixed == null; + } + ); + + + oTest.fnTest( + "Fixed sorting on first column (string/asc) with user sorting on second column (string/asc)", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSortingFixed": [['0','asc']] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "Camino 1.0"; } + ); + + oTest.fnTest( + "Fixed sorting on first column (string/asc) with user sorting on second column (string/desc)", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Fixed sorting on fourth column (int/asc) with user sorting on second column (string/asc)", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aaSortingFixed": [['3','asc']] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Fixed sorting on fourth column (int/asc) with user sorting on second column (string/desc)", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody td:eq(1)').html() == "PSP browser"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSearchable.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSearchable.js new file mode 100755 index 00000000..4ce91588 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSearchable.js @@ -0,0 +1,71 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.bSeachable" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Columns are searchable by default", + function () { oTable.fnFilter("Camino"); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html().match(/Camino/); } + ); + + oTest.fnTest( + "Disabling sorting on a column removes it from the global filter", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "bSearchable": false }, + null, + null, + null + ] + } ); + oSettings = oTable.fnSettings(); + oTable.fnFilter("Camino"); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnTest( + "Disabled on one column has no effect on other columns", + function () { oTable.fnFilter("Webkit"); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Webkit"; } + ); + + oTest.fnTest( + "Disable filtering on multiple columns", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + { "bSearchable": false }, + { "bSearchable": false }, + null, + null, + null + ] + } ); + oSettings = oTable.fnSettings(); + oTable.fnFilter("Webkit"); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnTest( + "Filter on second disabled column", + function () { oTable.fnFilter("Camino"); }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSortable.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSortable.js new file mode 100755 index 00000000..4e4548d1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bSortable.js @@ -0,0 +1,109 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.bSortable" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "All columns are sortable by default", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Can disable sorting from one column", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "bSortable": false }, + null, + null, + null + ] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() != "All others"; } + ); + + oTest.fnTest( + "Disabled column has no sorting class", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc") == false; } + ); + + oTest.fnTest( + "Other columns can still sort", + function () { + $('#example thead th:eq(4)').click(); + $('#example thead th:eq(4)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == "X"; } + ); + + oTest.fnTest( + "Disable sorting on multiple columns - no sorting classes", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "bSortable": false }, + null, + { "bSortable": false }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example thead th:eq(1)').hasClass("sorting") || + $('#example thead th:eq(3)').hasClass("sorting") + return bReturn == false; + } + ); + + oTest.fnTest( + "Sorting on disabled column 1 has no effect", + function () { + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() != "All others"; } + ); + + oTest.fnTest( + "Sorting on disabled column 2 has no effect", + function () { + $('#example thead th:eq(3)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() != "-"; } + ); + + oTest.fnTest( + "Second sort on disabled column 2 has no effect", + function () { + $('#example thead th:eq(3)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() != "-"; } + ); + + oTest.fnTest( + "Even with multiple disabled sorting columns other columns can still sort", + function () { + $('#example thead th:eq(4)').click(); + $('#example thead th:eq(4)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == "X"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bUseRendered.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bUseRendered.js new file mode 100755 index 00000000..2e3a9489 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bUseRendered.js @@ -0,0 +1,148 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.bUseRendered" ); + +/* bUseRendered is used to alter sorting data, if false then the original data is used for + * sorting rather than the rendered data + */ + +$(document).ready( function () { + /* Check the default */ + var mTmp = 0; + + var oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa"; + } else + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default for bUseRendered is true - rendered data is used for sorting", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'aaa'; } + ); + + oTest.fnTest( + "When bUseRendered is false, original data is used for sorting", + function () { + mTmp = 0; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { + "bUseRendered": false, + "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + null, + null, + null + ] + } ); + $('#example thead th:eq(1)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + + oTest.fnTest( + "bUseRendered set to false on one columns and true (default) on two others", + function () { + mTmp = 0; + var mTmp2 = 0; + var mTmp3 = 0; + + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + { + "fnRender": function (a) { + if ( mTmp == 0 ) { + mTmp++; + return "aaa1"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + { + "bUseRendered": false, + "fnRender": function (a) { + if ( mTmp2 == 0 ) { + mTmp2++; + return "aaa2"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + { + "fnRender": function (a) { + if ( mTmp3 == 0 ) { + mTmp3++; + return "zzz3"; + } else { + return a.aData[a.iDataColumn]; + } + } + }, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'aaa1'; } + ); + + oTest.fnTest( + "Multi-column rendering - 2nd column sorting", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + oTest.fnTest( + "Multi-column rendering - 3rd column sorting", + function () { + $('#example thead th:eq(2)').click(); + $('#example thead th:eq(2)').click(); + }, + function () { return $('#example tbody tr:eq(0) td:eq(2)').html() == 'zzz3'; } + ); + + oTest.fnTest( + "Multi-column rendering - 4th column sorting", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == '-'; } + ); + + oTest.fnTest( + "Multi-column rendering - 5th column sorting", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bVisible.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bVisible.js new file mode 100755 index 00000000..e38948ce --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.bVisible.js @@ -0,0 +1,110 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.bVisible" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "All columns are visible by default", + null, + function () { return $('#example tbody tr:eq(0) td').length == 5; } + ); + + oTest.fnTest( + "Can hide one column and it removes td column from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "bVisible": false }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 4; } + ); + + oTest.fnTest( + "Can hide one column and it removes thead th column from DOM", + null, + function () { return $('#example thead tr:eq(0) th').length == 4; } + ); + + oTest.fnTest( + "Can hide one column and it removes tfoot th column from DOM", + null, + function () { return $('#example tfoot tr:eq(0) th').length == 4; } + ); + + oTest.fnTest( + "The correct tbody column has been hidden", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); + }, + function () { + var jqNodes = $('#example tbody tr:eq(0) td'); + var bReturn = + jqNodes[0].innerHTML == "Gecko" && + jqNodes[1].innerHTML == "Gnome" && + jqNodes[2].innerHTML == "1.8" && + jqNodes[3].innerHTML == "A"; + return bReturn; + } + ); + + + oTest.fnTest( + "Can hide multiple columns and it removes td column from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "bVisible": false }, + { "bVisible": false }, + null, + { "bVisible": false } + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - removes thead th column from DOM", + null, + function () { return $('#example thead tr:eq(0) th').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - removes tfoot th column from DOM", + null, + function () { return $('#example tfoot tr:eq(0) th').length == 2; } + ); + + oTest.fnTest( + "Multiple hide - the correct tbody columns have been hidden", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); + }, + function () { + var jqNodes = $('#example tbody tr:eq(0) td'); + var bReturn = + jqNodes[0].innerHTML == "Gecko" && + jqNodes[1].innerHTML == "1" + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.fnRender.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.fnRender.js new file mode 100755 index 00000000..cb89aeb9 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.fnRender.js @@ -0,0 +1,156 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.fnRender" ); + +$(document).ready( function () { + /* Check the default */ + var mTmp = 0; + var oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + mTmp++; + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Single column - fnRender is called once for each row", + null, + function () { return mTmp == 57; } + ); + + oTest.fnTest( + "Confirm that fnRender passes two arguments with four parameters", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( arguments.length != 2 || typeof a.iDataRow=='undefined' || + typeof a.iDataColumn=='undefined' || typeof a.aData=='undefined' || + typeof a.mDataProp=='undefined' ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "fnRender iDataColumn is the column", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( a.iDataColumn != 1 ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "fnRender aData is data array of correct size", + function () { + mTmp = true; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + if ( a.aData.length != 5 ) + { + mTmp = false; + } + return a.aData[a.iDataColumn]; + } }, + null, + null, + null + ] + } ); + }, + function () { return mTmp; } + ); + + oTest.fnTest( + "Passed back data is put into the DOM", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "fnRender": function (a) { + return 'unittest'; + } }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'unittest'; } + ); + + oTest.fnTest( + "Passed back data is put into the DOM", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + null, + { "fnRender": function (a) { + return 'unittest1'; + } }, + { "fnRender": function (a) { + return 'unittest2'; + } }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example tbody tr:eq(0) td:eq(2)').html() == 'unittest1' && + $('#example tbody tr:eq(0) td:eq(3)').html() == 'unittest2'; + return bReturn; } + ); + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.iDataSort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.iDataSort.js new file mode 100755 index 00000000..6c0c7057 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.iDataSort.js @@ -0,0 +1,90 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.iDataSort" ); + +$(document).ready( function () { + /* Should know that sorting already works by default from other tests, so we can jump + * right in here + */ + var oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "iDataSort": 4 }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Sorting on first column is uneffected", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko'; } + ); + + oTest.fnTest( + "Sorting on second column is the order of the fifth", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + oTest.fnTest( + "Reserve sorting on second column uses fifth column as well", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'X'; } + ); + + oTest.fnTest( + "Sorting on 5th column retains it's own sorting", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + + oTest.fnTest( + "Use 2nd col for sorting 5th col and via-versa - no effect on first col sorting", + function () { + mTmp = 0; + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "iDataSort": 4 }, + null, + null, + { "iDataSort": 1 } + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == 'Gecko'; } + ); + + oTest.fnTest( + "2nd col sorting uses fifth col", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'A'; } + ); + + oTest.fnTest( + "2nd col sorting uses fifth col - reversed", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(4)').html() == 'X'; } + ); + + oTest.fnTest( + "5th col sorting uses 2nd col", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'All others'; } + ); + + oTest.fnTest( + "5th col sorting uses 2nd col - reversed", + function () { $('#example thead th:eq(4)').click(); }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == 'Seamonkey 1.1'; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sClass.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sClass.js new file mode 100755 index 00000000..b99cf181 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sClass.js @@ -0,0 +1,115 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.sClass" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "By default the test class hasn't been applied to the column (sanity!)", + null, + function () { return $('#example tbody tr:eq(0) td:eq(2)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - first row", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + null, + { "sClass": 'unittest' }, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(1) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - third row", + null, + function () { return $('#example tbody tr:eq(3) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - last row", + null, + function () { return $('#example tbody tr:eq(9) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to other columns - 1st", + null, + function () { return $('#example tbody tr:eq(3) td:eq(0)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to other columns - 5th", + null, + function () { return $('#example tbody tr:eq(3) td:eq(4)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - seventh row - second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody tr:eq(6) td:eq(2)').hasClass('unittest'); } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to header", + null, + function () { return $('#example thead tr:eq(3) th:eq(4)').hasClass('unittest') == false; } + ); + + oTest.fnTest( + "Add a class to a single column - has not applied to footer", + null, + function () { return $('#example thead tr:eq(3) th:eq(4)').hasClass('unittest') == false; } + ); + + + oTest.fnTest( + "Class defined for multiple columns - first row", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + { "sClass": 'unittest2' }, + null, + null, + { "sClass": 'unittest1' }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example tbody tr:eq(3) td:eq(0)').hasClass('unittest2') && + $('#example tbody tr:eq(8) td:eq(3)').hasClass('unittest1'); + return bReturn; + } + ); + + oTest.fnTest( + "Class defined for multiple columns - has not applied to other columns - 5th 1", + null, + function () { return $('#example tbody tr:eq(0) td:eq(4)').hasClass('unittest1') == false; } + ); + + oTest.fnTest( + "Class defined for multiple columns - has not applied to other columns - 5th 2", + null, + function () { return $('#example tbody tr:eq(6) td:eq(4)').hasClass('unittest2') == false; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sName.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sName.js new file mode 100755 index 00000000..b11f58cb --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sName.js @@ -0,0 +1,28 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.sName" ); + +/* This has no effect at all in DOM methods - so we just check that it has applied the name */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + null, + null, + { "sName": 'unit test' }, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Names are stored in the columns object", + null, + function () { return oSettings.aoColumns[3].sName =="unit test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sTitle.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sTitle.js new file mode 100755 index 00000000..da13f1c2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sTitle.js @@ -0,0 +1,82 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.sTitle" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "If not given, then the columns titles are empty", + null, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "Browser" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "CSS grade"; + return bReturn; + } + ); + + oTest.fnTest( + "Can set a single column title - and others are read from DOM", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "sTitle": 'unit test' }, + null, + null, + null + ] + } ); + }, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "unit test" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "CSS grade"; + return bReturn; + } + ); + + oTest.fnTest( + "Can set multiple column titles", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + { "sTitle": 'unit test 1' }, + null, + null, + { "sTitle": 'unit test 2' } + ] + } ); + }, + function () { + var jqNodes = $('#example thead tr:eq(0) th'); + var bReturn = + jqNodes[0].innerHTML == "Rendering engine" && + jqNodes[1].innerHTML == "unit test 1" && + jqNodes[2].innerHTML == "Platform(s)" && + jqNodes[3].innerHTML == "Engine version" && + jqNodes[4].innerHTML == "unit test 2"; + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sWidth.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sWidth.js new file mode 100755 index 00000000..960c0561 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoColumns.sWidth.js @@ -0,0 +1,87 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoColumns.sWidth" ); + +/* NOTE - we need to disable the auto width for the majority of these test in order to preform + * these tests as the auto width will convert the width to a px value. We can do 'non-exact' tests + * with auto width enabled however to ensure it scales columns as required + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData, + "bAutoWidth": false, + "aoColumns": [ + null, + { "sWidth": '40%' }, + null, + null, + null + ] + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "With auto width disabled the width for one column is appled", + null, + function () { return $('#example thead th:eq(1)')[0].style.width == "40%"; } + ); + + oTest.fnTest( + "With auto width disabled the width for one column is appled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "bAutoWidth": false, + "aoColumns": [ + null, + null, + { "sWidth": '20%' }, + { "sWidth": '30%' }, + null + ] + } ); + }, + function () { + var bReturn = + $('#example thead th:eq(2)')[0].style.width == "20%" && + $('#example thead th:eq(3)')[0].style.width == "30%"; + return bReturn; + } + ); + + + oTest.fnTest( + "With auto width, it will make the smallest column the largest with percentage width given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoColumns": [ + null, + null, + null, + { "sWidth": '40%' }, + null + ] + } ); + }, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + + if ( a3>a0 && a3>a1 && a3>a2 && a3>a4 ) + return true; + else + return false; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoSearchCols.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoSearchCols.js new file mode 100644 index 00000000..ac70b387 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/aoSearchCols.js @@ -0,0 +1,119 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "aoSearchCols" ); + +/* We could be here forever testing this one, so we test a limited subset on a couple of colums */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Default should be to have a empty colums array", + null, + function () { + var bReturn = + oSettings.aoPreSearchCols[0].sSearch == 0 && !oSettings.aoPreSearchCols[0].bRegex && + oSettings.aoPreSearchCols[1].sSearch == 0 && !oSettings.aoPreSearchCols[1].bRegex && + oSettings.aoPreSearchCols[2].sSearch == 0 && !oSettings.aoPreSearchCols[2].bRegex && + oSettings.aoPreSearchCols[3].sSearch == 0 && !oSettings.aoPreSearchCols[3].bRegex && + oSettings.aoPreSearchCols[4].sSearch == 0 && !oSettings.aoPreSearchCols[4].bRegex; + return bReturn; + } + ); + + + oTest.fnTest( + "Search on a single column - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1" }, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Search on two columns - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1.5" }, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "1.5"; } + ); + + oTest.fnTest( + "Search on single column - escape regex false", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + null, + null, + null, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 3 of 3 entries (filtered from 57 total entries)"; } + ); + + oTest.fnTest( + "Search on two columns - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "3.3", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Konqureror 3.3"; } + ); + + oTest.fnTest( + "Search on two columns (no records) - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "Allan", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/asStripClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/asStripClasses.js new file mode 100644 index 00000000..fa3af827 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/asStripClasses.js @@ -0,0 +1,100 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "asStripeClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Default row striping is applied", + null, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + oTest.fnTest( + "Row striping on the second page", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + /* No striping */ + oTest.fnTest( + "No row striping", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "asStripeClasses": [] + } ); + }, + function () { + return $('#example tbody tr:eq(0)')[0].className == "" && + $('#example tbody tr:eq(1)')[0].className == "" && + $('#example tbody tr:eq(2)')[0].className == "" && + $('#example tbody tr:eq(3)')[0].className == ""; + } + ); + + /* Custom striping */ + oTest.fnTest( + "Custom striping [2]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "asStripeClasses": [ 'test1', 'test2' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test1') && + $('#example tbody tr:eq(3)').hasClass('test2'); + } + ); + + + /* long array of striping */ + oTest.fnTest( + "Custom striping [4]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "asStripeClasses": [ 'test1', 'test2', 'test3', 'test4' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + oTest.fnTest( + "Custom striping is restarted on second page [2]", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bAutoWidth.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bAutoWidth.js new file mode 100644 index 00000000..094fe15b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bAutoWidth.js @@ -0,0 +1,142 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bAutoWidth" ); + +/* It's actually a little tricky to test this. We can't test absolute numbers because + * different browsers and different platforms will render the width of the columns slightly + * differently. However, we certainly can test the principle of what should happen (column + * width doesn't change over pages) + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Auto width is enabled by default", + null, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + oTest.fnTest( + "First column has a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style').match(/width/i); } + ); + + /* + This would seem like a better test - but there appear to be difficulties with tables + which are bigger (calculated) than there is actually room for. I suspect this is actually + a bug in datatables + oTest.fnTest( + "Check column widths on first page match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + console.log( a0, b0, a1, b1, a2, b2, a3, b3 ); + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + + oTest.fnTest( + "Check column widths on second page match thid page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + */ + + /* Check can disable */ + oTest.fnTest( + "Auto width can be disabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "bAutoWidth": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth == false; } + ); + + oTest.fnTest( + "First column does not have a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style') == null; } + ); + + /* + oTest.fnTest( + "Check column widths on first page do not match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return false; + else + return true; + } + ); + */ + + /* Enable makes no difference */ + oTest.fnTest( + "Auto width enabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "bAutoWidth": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bFilter.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bFilter.js new file mode 100644 index 00000000..d838e4ad --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bFilter.js @@ -0,0 +1,44 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bFilter" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Filtering div exists by default", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + /* Check can disable */ + oTest.fnTest( + "Fltering can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bFilter": false + } ); + }, + function () { return document.getElementById('example_filter') == null; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Filtering enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bFilter": true + } ); + }, + function () { return document.getElementById('example_filter') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bInfo.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bInfo.js new file mode 100644 index 00000000..60a42734 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bInfo.js @@ -0,0 +1,44 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bInfo" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Info div exists by default", + null, + function () { return document.getElementById('example_info') != null; } + ); + + /* Check can disable */ + oTest.fnTest( + "Info can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bInfo": false + } ); + }, + function () { return document.getElementById('example_info') == null; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Info enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bInfo": true + } ); + }, + function () { return document.getElementById('example_info') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bLengthChange.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bLengthChange.js new file mode 100644 index 00000000..d67b4d2d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bLengthChange.js @@ -0,0 +1,75 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bLengthChange" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Length div exists by default", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnTest( + "Four default options", + null, + function () { return $("select[name=example_length] option").length == 4; } + ); + + oTest.fnTest( + "Default options", + null, + function () { + var opts = $("select[name='example_length'] option"); + return opts[0].getAttribute('value') == 10 && opts[1].getAttribute('value') == 25 && + opts[2].getAttribute('value') == 50 && opts[3].getAttribute('value') == 100; + } + ); + + oTest.fnTest( + "Info takes length into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnTest( + "Change length can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bLengthChange": false + } ); + }, + function () { return document.getElementById('example_length') == null; } + ); + + oTest.fnTest( + "Information takes length disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Length change enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bLengthChange": true + } ); + }, + function () { return document.getElementById('example_length') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bPaginate.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bPaginate.js new file mode 100644 index 00000000..d386bbf0 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bPaginate.js @@ -0,0 +1,59 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bPaginate" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Pagiantion div exists by default", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnTest( + "Information div takes paging into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bPaginate": false + } ); + }, + function () { return document.getElementById('example_paginate') == null; } + ); + + oTest.fnTest( + "Information div takes paging disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 57 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Pagiantion enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bPaginate": true + } ); + }, + function () { return document.getElementById('example_paginate') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bProcessing.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bProcessing.js new file mode 100644 index 00000000..1408656f --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bProcessing.js @@ -0,0 +1,103 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bProcessing" ); + +/* It's actually a bit hard to set this one due to the fact that it will only be shown + * when DataTables is doing some kind of processing. The server-side processing is a bit + * better to test this than here - so we just the interal functions to enable it and check + * that it is available + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Processing is off by default", + null, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "Processing div cannot be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnTest( + "Processing div cannot be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + /* Check can disable */ + oTest.fnTest( + "Processing can be enabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "bProcessing": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == true; } + ); + + oTest.fnTest( + "Processing div is in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing'); } + ); + + oTest.fnTest( + "Processing div is hidden by default", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + oTest.fnTest( + "Processing div can be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "visible"; } + ); + + oTest.fnTest( + "Processing div can be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Processing disabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "aaData": gaaData, + "bProcessing": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bServerSide.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bServerSide.js new file mode 100644 index 00000000..65c75b1a --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bServerSide.js @@ -0,0 +1,20 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bServerSide" ); + +/* Not interested in server-side processing here other than to check that it is off */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "Server side is off by default", + null, + function () { return oSettings.oFeatures.bServerSide == false; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSort.js new file mode 100644 index 00000000..9107937b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSort.js @@ -0,0 +1,99 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bSort" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Sorting is on by default", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnTest( + "Sorting Asc by default class applied", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc"); } + ); + + oTest.fnTest( + "Click on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting class removed from first column", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc") != true; } + ); + + oTest.fnTest( + "Sorting asc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc"); } + ); + + oTest.fnTest( + "Reverse on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting acs class removed from second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc") != true; } + ); + + oTest.fnTest( + "Sorting desc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_desc"); } + ); + + /* Check can disable */ + oTest.fnTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bSort": false + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Click on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnTest( + "Reverse on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + /* Enable makes no difference */ + oTest.fnTest( + "Sorting enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bSort": true + } ); + }, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSortClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSortClasses.js new file mode 100644 index 00000000..5726561f --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/bSortClasses.js @@ -0,0 +1,132 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "bSortClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "aaData": gaaData + } ); + + oTest.fnTest( + "Sorting classes are applied by default", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnTest( + "Sorting classes are applied to all required cells", + null, + function () { return $('#example tbody tr:eq(7) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnTest( + "Sorting classes are not applied to non-sorting columns", + null, + function () { return $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_1') == false; } + ); + + oTest.fnTest( + "Sorting multi-column - add column 1", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2'); + } + ); + + oTest.fnTest( + "Sorting multi-column - add column 2", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3'); + } + ); + + oTest.fnTest( + "Sorting multi-column - add column 3", + function () { + oDispacher.click( $('#example thead th:eq(3)')[0], { 'shift': true } ); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3'); + } + ); + + oTest.fnTest( + "Remove sorting classes on single column sort", + function () { + $('#example thead th:eq(4)').click(); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3') == false; + } + ); + + oTest.fnTest( + "Sorting class 1 was added", + null, + function () { return $('#example tbody tr:eq(1) td:eq(4)').hasClass('sorting_1'); } + ); + + + /* Check can disable */ + oTest.fnTest( + "Sorting classes can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bSortClasses": false + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false; } + ); + + oTest.fnTest( + "Sorting classes disabled - add column 1 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false; + } + ); + + oTest.fnTest( + "Sorting classes disabled - add column 2 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false; + } + ); + + + /* Enable makes no difference */ + oTest.fnTest( + "Sorting classes enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "bSortClasses": true + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedCell.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedCell.js new file mode 100755 index 00000000..59fe717d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedCell.js @@ -0,0 +1,158 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "fnCreatedCell tests" ); + +$(document).ready( function () { + var tmp = 0; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedCell: function () { + tmp++; + }, + "aTargets": ["_all"] + } ] + } ); + + oTest.fnTest( + "Cell created is called once for each cell on init", + null, + function () { return tmp===285; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===285; } + ); + + oTest.fnTest( + "Four arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments.length !== 4 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "First argument is a TD element", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TD" ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Second argument is the HTML value", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td').html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Third argument is the data array", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2].length !== 5 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Fourth argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Fifth argument is the the col index", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td:eq('+arguments[4]+')', arguments[0].parentNode).html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ] + } ); + }, + function () { return tmp; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedRow.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedRow.js new file mode 100755 index 00000000..72b2ddde --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnCreatedRow.js @@ -0,0 +1,121 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "fnCreatedRow tests" ); + +$(document).ready( function () { + var tmp = 0; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function () { + tmp++; + } + } ); + + oTest.fnTest( + "Row created is called once for each row on init", + null, + function () { return tmp===57; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===57; } + ); + + oTest.fnTest( + "Three arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function () { + if ( arguments.length !== 3 ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "First argument is a TR element", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TR" ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Second argument is an array with 5 elements", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function () { + if ( arguments[1].length !== 5 ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Third argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function () { + if ( arguments[1] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + } + } ); + }, + function () { return tmp; } + ); + + oTest.fnTest( + "TR element is tied to the correct data", + function () { + oSession.fnRestore(); + tmp = false; + + $('#example').dataTable( { + "aaData": gaaData, + fnCreatedRow: function (tr, data, index) { + if ( data[1] === "Firefox 1.0" ) { + if ( $('td:eq(3)', tr).html() == "1.7" ) { + tmp = true; + } + } + } + } ); + }, + function () { return tmp; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnDrawCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnDrawCallback.js new file mode 100644 index 00000000..28d5871d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnDrawCallback.js @@ -0,0 +1,85 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "fnDrawCallback" ); + +/* Fairly boring function compared to the others! */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnTest( + "Default should be null", + null, + function () { return oSettings.fnDrawCallback == null; } + ); + + + oTest.fnTest( + "One argument passed", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "aaData": gaaData, + "fnDrawCallback": function ( ) { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 1; } + ); + + + oTest.fnTest( + "That one argument is the settings object", + function () { + oSession.fnRestore(); + + oTable = $('#example').dataTable( { + "aaData": gaaData, + "fnDrawCallback": function ( oSettings ) { + mPass = oSettings; + } + } ); + }, + function () { return oTable.fnSettings() == mPass; } + ); + + + oTest.fnTest( + "fnRowCallback called once on first draw", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "aaData": gaaData, + "fnDrawCallback": function ( ) { + mPass++; + } + } ); + }, + function () { return mPass == 1; } + ); + + oTest.fnTest( + "fnRowCallback called once on each draw there after as well", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return mPass == 4; } + ); + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnFooterCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnFooterCallback.js new file mode 100644 index 00000000..f16b921c --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/2_js/fnFooterCallback.js @@ -0,0 +1,240 @@ +// DATA_TEMPLATE: js_data +oTest.fnStart( "fnFooterCallback" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "aaData": gaaData + } ); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnTest( + "Default should be null", + null, + function () { return oSettings.fnFooterCallback == null; } + ); + + + oTest.fnTest( + "Five arguments passed", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "aaData": gaaData, + "fnFooterCallback": function ( ) { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 5; } + ); + + + oTest.fnTest( + "fnRowCallback called once per draw", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "aaData": gaaData, + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + mPass++; + } + } ); + }, + function () { return mPass == 1; } + ); + + oTest.fnTest( + "fnRowCallback called on paging (i.e. another draw)", + function () { $('#example_next').click(); }, + function () { return mPass == 2; } + ); + + + oTest.fnTest( + "fnRowCallback allows us to alter row information", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "aaData": gaaData, + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + nFoot.getElementsByTagName('th')[0].innerHTML = "Displaying "+(iEnd-iStart)+" records"; + } + } ); + }, + function () { return $('#example tfoot th:eq(0)').html() == "Displaying 10 records"; } + ); + + + oTest.fnTest( + "Data array has length matching original data", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "aaData": gaaData, + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + if ( aasData.length != 57 ) + { + mPass = false; + } + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Data array's column lengths match original data", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "aaData": gaaData, + "fnFooterCallback": function ( nFoot, aasData, iStart, iEnd, aiDisplay ) { + for ( var i=0, iLen=aasData.length ; i' + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.sDom == '<"wrapper"flipt>'; } + ); + + oTest.fnTest( + "Check example 1 in DOM", + null, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; iip>' + } ); + }, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + var nCustomWrappers = [] + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; ia0 && a3>a1 && a3>a2 && a3>a4 ) + return true; + else + return false; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoSearchCols.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoSearchCols.js new file mode 100644 index 00000000..d0a9a6be --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/aoSearchCols.js @@ -0,0 +1,119 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "aoSearchCols" ); + +/* We could be here forever testing this one, so we test a limited subset on a couple of colums */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Default should be to have a empty colums array", + null, + function () { + var bReturn = + oSettings.aoPreSearchCols[0].sSearch == 0 && !oSettings.aoPreSearchCols[0].bRegex && + oSettings.aoPreSearchCols[1].sSearch == 0 && !oSettings.aoPreSearchCols[1].bRegex && + oSettings.aoPreSearchCols[2].sSearch == 0 && !oSettings.aoPreSearchCols[2].bRegex && + oSettings.aoPreSearchCols[3].sSearch == 0 && !oSettings.aoPreSearchCols[3].bRegex && + oSettings.aoPreSearchCols[4].sSearch == 0 && !oSettings.aoPreSearchCols[4].bRegex; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "Search on a single column - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1" }, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 9 of 9 entries (filtered from 57 total entries)"; } + ); + + oTest.fnWaitTest( + "Search on two columns - no regex statement given", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoSearchCols": [ + null, + { "sSearch": "Mozilla" }, + null, + { "sSearch": "1.5" }, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(3)').html() == "1.5"; } + ); + + oTest.fnWaitTest( + "Search on single column - escape regex false", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + null, + null, + null, + null + ] + } ); + }, + function () { return $('#example_info').html() == "Showing 1 to 3 of 3 entries (filtered from 57 total entries)"; } + ); + + oTest.fnWaitTest( + "Search on two columns - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "3.3", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Konqureror 3.3"; } + ); + + oTest.fnWaitTest( + "Search on two columns (no records) - escape regex false on first, true on second", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoSearchCols": [ + { "sSearch": ".*ML", "bEscapeRegex": false }, + { "sSearch": "Allan", "bEscapeRegex": true }, + null, + null, + null + ] + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/asStripClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/asStripClasses.js new file mode 100644 index 00000000..b195c405 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/asStripClasses.js @@ -0,0 +1,105 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "asStripeClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Default row striping is applied", + null, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + oTest.fnWaitTest( + "Row striping on the second page", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('odd') && + $('#example tbody tr:eq(1)').hasClass('even') && + $('#example tbody tr:eq(2)').hasClass('odd') && + $('#example tbody tr:eq(3)').hasClass('even'); + } + ); + + /* No striping */ + oTest.fnWaitTest( + "No row striping", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "asStripeClasses": [] + } ); + }, + function () { + if ( typeof $('#example tbody tr:eq(1)')[0] == 'undefined' ) + { + /* Use the 'wait for' to allow this to become true */ + return false; + } + return $('#example tbody tr:eq(0)')[0].className == "" && + $('#example tbody tr:eq(1)')[0].className == "" && + $('#example tbody tr:eq(2)')[0].className == "" && + $('#example tbody tr:eq(3)')[0].className == ""; + } + ); + + /* Custom striping */ + oTest.fnWaitTest( + "Custom striping [2]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "asStripeClasses": [ 'test1', 'test2' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test1') && + $('#example tbody tr:eq(3)').hasClass('test2'); + } + ); + + + /* long array of striping */ + oTest.fnWaitTest( + "Custom striping [4]", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "asStripeClasses": [ 'test1', 'test2', 'test3', 'test4' ] + } ); + }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + oTest.fnWaitTest( + "Custom striping is restarted on second page [2]", + function () { $('#example_next').click(); }, + function () { + return $('#example tbody tr:eq(0)').hasClass('test1') && + $('#example tbody tr:eq(1)').hasClass('test2') && + $('#example tbody tr:eq(2)').hasClass('test3') && + $('#example tbody tr:eq(3)').hasClass('test4'); + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bAutoWidth.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bAutoWidth.js new file mode 100644 index 00000000..ee49f7c1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bAutoWidth.js @@ -0,0 +1,142 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bAutoWidth" ); + +/* It's actually a little tricky to test this. We can't test absolute numbers because + * different browsers and different platforms will render the width of the columns slightly + * differently. However, we certainly can test the principle of what should happen (column + * width doesn't change over pages) + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Auto width is enabled by default", + null, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + oTest.fnWaitTest( + "First column has a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style').match(/width/i); } + ); + + /* + This would seem like a better test - but there appear to be difficulties with tables + which are bigger (calculated) than there is actually room for. I suspect this is actually + a bug in datatables + oTest.fnWaitTest( + "Check column widths on first page match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + console.log( a0, b0, a1, b1, a2, b2, a3, b3 ); + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + + oTest.fnWaitTest( + "Check column widths on second page match thid page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return true; + else + return false; + } + ); + */ + + /* Check can disable */ + oTest.fnWaitTest( + "Auto width can be disabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bAutoWidth": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth == false; } + ); + + oTest.fnWaitTest( + "First column does not have a width assigned to it", + null, + function () { return $('#example thead th:eq(0)').attr('style') == null; } + ); + + /* + oTest.fnWaitTest( + "Check column widths on first page do not match second page", + null, + function () { + var anThs = $('#example thead th'); + var a0 = anThs[0].offsetWidth; + var a1 = anThs[1].offsetWidth; + var a2 = anThs[2].offsetWidth; + var a3 = anThs[3].offsetWidth; + var a4 = anThs[4].offsetWidth; + $('#example_next').click(); + var b0 = anThs[0].offsetWidth; + var b1 = anThs[1].offsetWidth; + var b2 = anThs[2].offsetWidth; + var b3 = anThs[3].offsetWidth; + var b4 = anThs[4].offsetWidth; + if ( a0==b0 && a1==b1 && a2==b2 && a3==b3 ) + return false; + else + return true; + } + ); + */ + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Auto width enabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bAutoWidth": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bAutoWidth; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bFilter.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bFilter.js new file mode 100644 index 00000000..8c322293 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bFilter.js @@ -0,0 +1,44 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bFilter" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Filtering div exists by default", + null, + function () { return document.getElementById('example_filter') != null; } + ); + + /* Check can disable */ + oTest.fnWaitTest( + "Fltering can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bFilter": false + } ); + }, + function () { return document.getElementById('example_filter') == null; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Filtering enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bFilter": true + } ); + }, + function () { return document.getElementById('example_filter') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bInfo.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bInfo.js new file mode 100644 index 00000000..24eeedfa --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bInfo.js @@ -0,0 +1,44 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bInfo" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Info div exists by default", + null, + function () { return document.getElementById('example_info') != null; } + ); + + /* Check can disable */ + oTest.fnWaitTest( + "Info can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bInfo": false + } ); + }, + function () { return document.getElementById('example_info') == null; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Info enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bInfo": true + } ); + }, + function () { return document.getElementById('example_info') != null; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bLengthChange.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bLengthChange.js new file mode 100644 index 00000000..551878c5 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bLengthChange.js @@ -0,0 +1,75 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bLengthChange" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Length div exists by default", + null, + function () { return document.getElementById('example_length') != null; } + ); + + oTest.fnWaitTest( + "Four default options", + null, + function () { return $("select[name=example_length] option").length == 4; } + ); + + oTest.fnWaitTest( + "Default options", + null, + function () { + var opts = $("select[name='example_length'] option"); + return opts[0].getAttribute('value') == 10 && opts[1].getAttribute('value') == 25 && + opts[2].getAttribute('value') == 50 && opts[3].getAttribute('value') == 100; + } + ); + + oTest.fnWaitTest( + "Info takes length into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnWaitTest( + "Change length can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bLengthChange": false + } ); + }, + function () { return document.getElementById('example_length') == null; } + ); + + oTest.fnWaitTest( + "Information takes length disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Length change enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bLengthChange": true + } ); + }, + function () { return document.getElementById('example_length') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bPaginate.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bPaginate.js new file mode 100644 index 00000000..6e3ec5e4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bPaginate.js @@ -0,0 +1,59 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bPaginate" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Pagiantion div exists by default", + null, + function () { return document.getElementById('example_paginate') != null; } + ); + + oTest.fnWaitTest( + "Information div takes paging into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 10 of 57 entries"; } + ); + + /* Check can disable */ + oTest.fnWaitTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bPaginate": false + } ); + }, + function () { return document.getElementById('example_paginate') == null; } + ); + + oTest.fnWaitTest( + "Information div takes paging disabled into account", + null, + function () { return document.getElementById('example_info').innerHTML == + "Showing 1 to 57 of 57 entries"; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Pagiantion enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bPaginate": true + } ); + }, + function () { return document.getElementById('example_paginate') != null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bProcessing.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bProcessing.js new file mode 100644 index 00000000..100db867 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bProcessing.js @@ -0,0 +1,103 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bProcessing" ); + +/* It's actually a bit hard to set this one due to the fact that it will only be shown + * when DataTables is doing some kind of processing. The server-side processing is a bit + * better to test this than here - so we just the interal functions to enable it and check + * that it is available + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Processing is off by default", + null, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnWaitTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnWaitTest( + "Processing div cannot be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + oTest.fnWaitTest( + "Processing div cannot be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + /* Check can disable */ + oTest.fnWaitTest( + "Processing can be enabled", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bProcessing": true + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == true; } + ); + + oTest.fnWaitTest( + "Processing div is in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing'); } + ); + + oTest.fnWaitTest( + "Processing div is hidden by default", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + oTest.fnWaitTest( + "Processing div can be shown", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing').style.visibility = "visible"; } + ); + + oTest.fnWaitTest( + "Processing div can be hidden", + function () { oTable.oApi._fnProcessingDisplay( oSettings, false ); }, + function () { return document.getElementById('example_processing').style.visibility = "hidden"; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Processing disabled override", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bProcessing": false + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oFeatures.bProcessing == false; } + ); + + oTest.fnWaitTest( + "Processing div is not in the DOM", + function () { oTable.oApi._fnProcessingDisplay( oSettings, true ); }, + function () { return document.getElementById('example_processing') == null; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bServerSide.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bServerSide.js new file mode 100644 index 00000000..61fdce4b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bServerSide.js @@ -0,0 +1,20 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bServerSide" ); + +/* Not interested in server-side processing here other than to check that it is off */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Server side is off by default", + null, + function () { return oSettings.oFeatures.bServerSide == false; } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSort.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSort.js new file mode 100644 index 00000000..066afee8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSort.js @@ -0,0 +1,99 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bSort" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Sorting is on by default", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnWaitTest( + "Sorting Asc by default class applied", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc"); } + ); + + oTest.fnWaitTest( + "Click on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnWaitTest( + "Sorting class removed from first column", + null, + function () { return $('#example thead th:eq(0)').hasClass("sorting_asc") != true; } + ); + + oTest.fnWaitTest( + "Sorting asc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc"); } + ); + + oTest.fnWaitTest( + "Reverse on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnWaitTest( + "Sorting acs class removed from second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_asc") != true; } + ); + + oTest.fnWaitTest( + "Sorting desc class applied to second column", + null, + function () { return $('#example thead th:eq(1)').hasClass("sorting_desc"); } + ); + + /* Check can disable */ + oTest.fnWaitTest( + "Pagiantion can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bSort": false + } ); + }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnWaitTest( + "Click on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + oTest.fnWaitTest( + "Reverse on second column has no effect", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "4"; } + ); + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Sorting enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bSort": true + } ); + }, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSortClasses.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSortClasses.js new file mode 100644 index 00000000..b957c805 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/bSortClasses.js @@ -0,0 +1,132 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "bSortClasses" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Sorting classes are applied by default", + null, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnWaitTest( + "Sorting classes are applied to all required cells", + null, + function () { return $('#example tbody tr:eq(7) td:eq(0)').hasClass('sorting_1'); } + ); + + oTest.fnWaitTest( + "Sorting classes are not applied to non-sorting columns", + null, + function () { return $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_1') == false; } + ); + + oTest.fnWaitTest( + "Sorting multi-column - add column 1", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2'); + } + ); + + oTest.fnWaitTest( + "Sorting multi-column - add column 2", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3'); + } + ); + + oTest.fnWaitTest( + "Sorting multi-column - add column 3", + function () { + oDispacher.click( $('#example thead th:eq(3)')[0], { 'shift': true } ); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3'); + } + ); + + oTest.fnWaitTest( + "Remove sorting classes on single column sort", + function () { + $('#example thead th:eq(4)').click(); + }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false && + $('#example tbody tr:eq(0) td:eq(3)').hasClass('sorting_3') == false; + } + ); + + oTest.fnWaitTest( + "Sorting class 1 was added", + null, + function () { return $('#example tbody tr:eq(1) td:eq(4)').hasClass('sorting_1'); } + ); + + + /* Check can disable */ + oTest.fnWaitTest( + "Sorting classes can be disabled", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bSortClasses": false + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false; } + ); + + oTest.fnWaitTest( + "Sorting classes disabled - add column 1 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false; + } + ); + + oTest.fnWaitTest( + "Sorting classes disabled - add column 2 - no effect", + function () { + oDispacher.click( $('#example thead th:eq(2)')[0], { 'shift': true } ); }, + function () { + return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1') == false && + $('#example tbody tr:eq(0) td:eq(1)').hasClass('sorting_2') == false && + $('#example tbody tr:eq(0) td:eq(2)').hasClass('sorting_3') == false; + } + ); + + + /* Enable makes no difference */ + oTest.fnWaitTest( + "Sorting classes enabled override", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bSortClasses": true + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').hasClass('sorting_1'); } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedCell.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedCell.js new file mode 100755 index 00000000..e930d052 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedCell.js @@ -0,0 +1,183 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnCreatedCell tests" ); + +$(document).ready( function () { + var tmp = 0; + var complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedCell: function () { + tmp++; + }, + "aTargets": ["_all"] + } ] + } ); + + oTest.fnWaitTest( + "Cell created is called once for each cell on init", + null, + function () { return tmp===285; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===285; } + ); + + oTest.fnWaitTest( + "Four arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments.length !== 4 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "First argument is a TD element", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TD" ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Second argument is the HTML value", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td').html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Third argument is the data array", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2].length !== 5 ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Fourth argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[2] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Fifth argument is the the col index", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "aoColumnDefs": [ { + fnCreatedRow: function () { + if ( arguments[1] != $('td:eq('+arguments[4]+')', arguments[0].parentNode).html() ) { + tmp = false; + } + }, + "aTargets": ["_all"] + } ], + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedRow.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedRow.js new file mode 100755 index 00000000..66fc3287 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnCreatedRow.js @@ -0,0 +1,142 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnCreatedRow tests" ); + +$(document).ready( function () { + var tmp = 0; + var complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function () { + tmp++; + } + } ); + + oTest.fnWaitTest( + "Row created is called once for each row on init", + null, + function () { return tmp===57; } + ); + + oTest.fnTest( + "Created isn't called back on other draws", + function () { $('#example th:eq(1)').click(); }, + function () { return tmp===57; } + ); + + oTest.fnWaitTest( + "Three arguments for the function", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function () { + if ( arguments.length !== 3 ) { + tmp = false; + } + }, + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "First argument is a TR element", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function () { + if ( arguments[0].nodeName !== "TR" ) { + tmp = false; + } + }, + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Second argument is an array with 5 elements", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function () { + if ( arguments[1].length !== 5 ) { + tmp = false; + } + }, + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "Third argument is the data source for the row", + function () { + oSession.fnRestore(); + tmp = true; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function () { + if ( arguments[1] !== this.fnSettings().aoData[ arguments[2] ]._aData ) { + tmp = false; + } + }, + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + oTest.fnWaitTest( + "TR element is tied to the correct data", + function () { + oSession.fnRestore(); + tmp = false; + complete = false; + + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + fnCreatedRow: function (tr, data, index) { + if ( data[1] === "Firefox 1.0" ) { + if ( $('td:eq(3)', tr).html() == "1.7" ) { + tmp = true; + } + } + }, + fnInitComplete: function () { + complete = true; + } + } ); + }, + function () { return (tmp && complete); } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnDrawCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnDrawCallback.js new file mode 100644 index 00000000..14c5ff19 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnDrawCallback.js @@ -0,0 +1,98 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnDrawCallback" ); + +/* Fairly boring function compared to the others! */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + var mPass, bInit; + + oTest.fnWaitTest( + "Default should be null", + null, + function () { return oSettings.fnDrawCallback == null; } + ); + + + oTest.fnWaitTest( + "One argument passed", + function () { + oSession.fnRestore(); + + mPass = -1; + bInit = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnDrawCallback": function ( ) { + mPass = arguments.length; + }, + "fnInitComplete": function () { + bInit = true; + } + } ); + }, + function () { return mPass == 1 && bInit; } + ); + + + oTest.fnWaitTest( + "That one argument is the settings object", + function () { + oSession.fnRestore(); + + bInit = false; + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnDrawCallback": function ( oSettings ) { + mPass = oSettings; + }, + "fnInitComplete": function () { + bInit = true; + } + } ); + }, + function () { return oTable.fnSettings() == mPass && bInit; } + ); + + + /* The draw callback is called once for the init and then when the data is added */ + oTest.fnWaitTest( + "fnRowCallback called once on first draw", + function () { + oSession.fnRestore(); + + mPass = 0; + bInit = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnDrawCallback": function ( ) { + mPass++; + }, + "fnInitComplete": function () { + bInit = true; + } + } ); + }, + function () { return mPass == 2 && bInit; } + ); + + oTest.fnWaitTest( + "fnRowCallback called once on each draw there after as well", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return mPass == 5; } + ); + + + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnHeaderCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnHeaderCallback.js new file mode 100644 index 00000000..dd161287 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnHeaderCallback.js @@ -0,0 +1,191 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnHeaderCallback" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + var mPass, bInit; + + oTest.fnWaitTest( + "Default should be null", + null, + function () { return oSettings.fnHeaderCallback == null; } + ); + + + oTest.fnWaitTest( + "Five arguments passed", + function () { + oSession.fnRestore(); + + mPass = -1; + bInit = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( ) { + mPass = arguments.length; + }, + "fnInitComplete": function () { + bInit = true; + } + } ); + }, + function () { return mPass == 5 && bInit; } + ); + + + /* The header callback is called once for the init and then when the data is added */ + oTest.fnWaitTest( + "fnHeaderCallback called once per draw", + function () { + oSession.fnRestore(); + + mPass = 0; + bInit = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + mPass++; + }, + "fnInitComplete": function () { + bInit = true; + } + } ); + }, + function () { return mPass == 2 && bInit; } + ); + + oTest.fnWaitTest( + "fnRowCallback called on paging (i.e. another draw)", + function () { $('#example_next').click(); }, + function () { return mPass == 3; } + ); + + + oTest.fnWaitTest( + "fnRowCallback allows us to alter row information", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + nHead.getElementsByTagName('th')[0].innerHTML = "Displaying "+(iEnd-iStart)+" records"; + } + } ); + }, + function () { return $('#example thead th:eq(0)').html() == "Displaying 10 records"; } + ); + + + oTest.fnWaitTest( + "iStart correct on first page", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + if ( iStart != 0 ) + { + mPass = false; + } + } + } ); + }, + function () { return mPass; } + ); + + + oTest.fnWaitTest( + "iStart correct on second page", + function () { + oSession.fnRestore(); + + mPass = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + if ( iStart == 10 ) + { + mPass = true; + } + }, + "fnInitComplete": function () { + $('#example_next').click(); + } + } ); + }, + function () { return mPass; } + ); + + + oTest.fnWaitTest( + "iEnd correct on second page", + function () { + oSession.fnRestore(); + + mPass = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + if ( iEnd == 20 ) + { + mPass = true; + } + }, + "fnInitComplete": function () { + $('#example_next').click(); + } + } ); + }, + function () { return mPass; } + ); + + + oTest.fnWaitTest( + "aiDisplay length is full data when not filtered", + function () { + oSession.fnRestore(); + + mPass = false; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + if ( aiDisplay.length == 57 ) + { + mPass = true; + } + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnWaitTest( + "aiDisplay length is 9 when filtering on 'Mozilla'", + function () { + oSession.fnRestore(); + + mPass = false; + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnHeaderCallback": function ( nHead, aasData, iStart, iEnd, aiDisplay ) { + if ( aiDisplay.length == 9 ) + { + mPass = true; + } + } + } ); + oTable.fnFilter( "Mozilla" ); + }, + function () { return mPass; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnInitComplete.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnInitComplete.js new file mode 100644 index 00000000..fe2c65e4 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnInitComplete.js @@ -0,0 +1,100 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnInitComplete" ); + +/* Fairly boring function compared to the others! */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnWaitTest( + "Default should be null", + null, + function () { return oSettings.fnInitComplete == null; } + ); + + + oTest.fnWaitTest( + "Two arguments passed (for Ajax!)", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnInitComplete": function ( ) { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 2; } + ); + + + oTest.fnWaitTest( + "That one argument is the settings object", + function () { + oSession.fnRestore(); + + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnInitComplete": function ( oSettings ) { + mPass = oSettings; + } + } ); + }, + function () { return oTable.fnSettings() == mPass; } + ); + + + oTest.fnWaitTest( + "fnInitComplete called once on first draw", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnInitComplete": function ( ) { + mPass++; + } + } ); + }, + function () { return mPass == 1; } + ); + + oTest.fnWaitTest( + "fnInitComplete never called there after", + function () { + $('#example_next').click(); + $('#example_next').click(); + $('#example_next').click(); + }, + function () { return mPass == 1; } + ); + + + oTest.fnWaitTest( + "10 rows in the table on complete", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnInitComplete": function ( ) { + mPass = $('#example tbody tr').length; + } + } ); + }, + function () { return mPass == 10; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnRowCallback.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnRowCallback.js new file mode 100644 index 00000000..766f09a2 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnRowCallback.js @@ -0,0 +1,112 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnRowCallback" ); + +/* Note - fnRowCallback MUST return the first arguments (modified or not) */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + var mPass; + + oTest.fnWaitTest( + "Default should be null", + null, + function () { return oSettings.fnRowCallback == null; } + ); + + + oTest.fnWaitTest( + "Four arguments passed", + function () { + oSession.fnRestore(); + + mPass = -1; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnRowCallback": function ( nTr ) { + mPass = arguments.length; + return nTr; + } + } ); + }, + function () { return mPass == 4; } + ); + + + oTest.fnWaitTest( + "fnRowCallback called once for each drawn row", + function () { + oSession.fnRestore(); + + mPass = 0; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnRowCallback": function ( nTr, asData, iDrawIndex, iDataIndex ) { + mPass++; + return nTr; + } + } ); + }, + function () { return mPass == 10; } + ); + + oTest.fnWaitTest( + "fnRowCallback allows us to alter row information", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnRowCallback": function ( nTr, asData, iDrawIndex, iDataIndex ) { + $(nTr).addClass('unit_test'); + return nTr; + } + } ); + }, + function () { return $('#example tbody tr:eq(1)').hasClass('unit_test'); } + ); + + oTest.fnWaitTest( + "Data array has length matching columns", + function () { + oSession.fnRestore(); + + mPass = true; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnRowCallback": function ( nTr, asData, iDrawIndex, iDataIndex ) { + if ( asData.length != 5 ) + mPass = false; + return nTr; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnWaitTest( + "Data array has length matching columns", + function () { + oSession.fnRestore(); + + mPass = true; + var iCount = 0; + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnRowCallback": function ( nTr, asData, iDrawIndex, iDataIndex ) { + if ( iCount != iDrawIndex ) + mPass = false; + iCount++; + return nTr; + } + } ); + }, + function () { return mPass; } + ); + + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnServerData.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnServerData.js new file mode 100644 index 00000000..ab20ba3d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/fnServerData.js @@ -0,0 +1,64 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "fnServerData for Ajax sourced data" ); + +$(document).ready( function () { + var mPass; + + oTest.fnTest( + "Argument length", + function () { + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnServerData": function () { + mPass = arguments.length; + } + } ); + }, + function () { return mPass == 4; } + ); + + oTest.fnTest( + "Url", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnServerData": function (sUrl, aoData, fnCallback, oSettings) { + mPass = sUrl == "../../../examples/ajax/sources/arrays.txt"; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Data array", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnServerData": function (sUrl, aoData, fnCallback, oSettings) { + mPass = aoData.length==0; + } + } ); + }, + function () { return mPass; } + ); + + oTest.fnTest( + "Callback function", + function () { + $('#example').dataTable( { + "bDestroy": true, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "fnServerData": function (sUrl, aoData, fnCallback, oSettings) { + mPass = typeof fnCallback == 'function'; + } + } ); + }, + function () { return mPass; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/iDisplayLength.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/iDisplayLength.js new file mode 100644 index 00000000..69e7abed --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/iDisplayLength.js @@ -0,0 +1,81 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "iDisplayLength" ); + +$(document).ready( function () { + /* Check the default */ + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + + oTest.fnWaitTest( + "Default length is ten", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnWaitTest( + "Select menu shows 10", + null, + function () { return $('#example_length select').val() == 10; } + ); + + + oTest.fnWaitTest( + "Set initial length to 25", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "iDisplayLength": 25 + } ); + }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnWaitTest( + "Select menu shows 25", + null, + function () { return $('#example_length select').val() == 25; } + ); + + + oTest.fnWaitTest( + "Set initial length to 100", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "iDisplayLength": 100 + } ); + }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnWaitTest( + "Select menu shows 25", + null, + function () { return $('#example_length select').val() == 100; } + ); + + + oTest.fnWaitTest( + "Set initial length to 23 (unknown select menu length)", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "iDisplayLength": 23 + } ); + }, + function () { return $('#example tbody tr').length == 23; } + ); + + oTest.fnWaitTest( + "Select menu shows 10 (since 23 is unknow)", + null, + function () { return $('#example_length select').val() == 10; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.oPaginate.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.oPaginate.js new file mode 100644 index 00000000..0dc5812b --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.oPaginate.js @@ -0,0 +1,84 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.oPaginate" ); + +/* Note that the paging language information only has relevence in full numbers */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "sPaginationType": "full_numbers" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "oLanguage.oPaginate defaults", + null, + function () { + var bReturn = + oSettings.oLanguage.oPaginate.sFirst == "First" && + oSettings.oLanguage.oPaginate.sPrevious == "Previous" && + oSettings.oLanguage.oPaginate.sNext == "Next" && + oSettings.oLanguage.oPaginate.sLast == "Last"; + return bReturn; + } + ); + + oTest.fnTest( + "oLanguage.oPaginate defaults are in the DOM", + null, + function () { + var bReturn = + $('#example_paginate .first').html() == "First" && + $('#example_paginate .previous').html() == "Previous" && + $('#example_paginate .next').html() == "Next" && + $('#example_paginate .last').html() == "Last"; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "oLanguage.oPaginate can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "sPaginationType": "full_numbers", + "oLanguage": { + "oPaginate": { + "sFirst": "unit1", + "sPrevious": "test2", + "sNext": "unit3", + "sLast": "test4" + } + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { + var bReturn = + oSettings.oLanguage.oPaginate.sFirst == "unit1" && + oSettings.oLanguage.oPaginate.sPrevious == "test2" && + oSettings.oLanguage.oPaginate.sNext == "unit3" && + oSettings.oLanguage.oPaginate.sLast == "test4"; + return bReturn; + } + ); + + oTest.fnTest( + "oLanguage.oPaginate definitions are in the DOM", + null, + function () { + var bReturn = + $('#example_paginate .first').html() == "unit1" && + $('#example_paginate .previous').html() == "test2" && + $('#example_paginate .next').html() == "unit3" && + $('#example_paginate .last').html() == "test4"; + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfo.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfo.js new file mode 100644 index 00000000..1a72a0a8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfo.js @@ -0,0 +1,117 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sInfo" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Info language is 'Showing _START_ to _END_ of _TOTAL_ entries' by default", + null, + function () { return oSettings.oLanguage.sInfo == "Showing _START_ to _END_ of _TOTAL_ entries"; } + ); + + oTest.fnTest( + "Info language default is in the DOM", + null, + function () { return document.getElementById('example_info').innerHTML = "Showing 1 to 10 of 57 entries"; } + ); + + + oTest.fnWaitTest( + "Info language can be defined - without any macros", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sInfo == "unit test"; } + ); + + oTest.fnTest( + "Info language definition is in the DOM", + null, + function () { return document.getElementById('example_info').innerHTML = "unit test"; } + ); + + oTest.fnWaitTest( + "Info language can be defined - with macro _START_ only", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit _START_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "unit 1 test"; } + ); + + oTest.fnWaitTest( + "Info language can be defined - with macro _END_ only", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit _END_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "unit 10 test"; } + ); + + oTest.fnWaitTest( + "Info language can be defined - with macro _TOTAL_ only", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit _END_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "unit 57 test"; } + ); + + oTest.fnWaitTest( + "Info language can be defined - with macros _START_ and _END_", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit _START_ _END_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "unit 1 10 test"; } + ); + + oTest.fnWaitTest( + "Info language can be defined - with macros _START_, _END_ and _TOTAL_", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfo": "unit _START_ _END_ _TOTAL_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "unit 1 10 57 test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoEmpty.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoEmpty.js new file mode 100644 index 00000000..a5066cf8 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoEmpty.js @@ -0,0 +1,79 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sInfoEmpty" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Info empty language is 'Showing 0 to 0 of 0 entries' by default", + function () { oTable.fnFilter("nothinghere"); }, + function () { return oSettings.oLanguage.sInfoEmpty == "Showing 0 to 0 of 0 entries"; } + ); + + oTest.fnTest( + "Info empty language default is in the DOM", + null, + function () { + var bReturn = document.getElementById('example_info').innerHTML.replace( + ' '+oSettings.oLanguage.sInfoFiltered.replace( '_MAX_', '57' ), "" ) == + "Showing 0 to 0 of 0 entries"; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "Info empty language can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfoEmpty": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + oTable.fnFilter("nothinghere"); + }, + function () { return oSettings.oLanguage.sInfoEmpty == "unit test"; } + ); + + oTest.fnTest( + "Info empty language default is in the DOM", + null, + function () { + var bReturn = document.getElementById('example_info').innerHTML.replace( + ' '+oSettings.oLanguage.sInfoFiltered.replace( '_MAX_', '57' ), "" ) == + "unit test"; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "Macro's replaced", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfoEmpty": "unit _START_ _END_ _TOTAL_ test" + } + } ); + oTable.fnFilter("nothinghere"); + }, + function () { + var bReturn = document.getElementById('example_info').innerHTML.replace( + ' '+oSettings.oLanguage.sInfoFiltered.replace( '_MAX_', '57' ), "" ) == + "unit 1 0 0 test"; + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoPostFix.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoPostFix.js new file mode 100644 index 00000000..f91e5daf --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sInfoPostFix.js @@ -0,0 +1,78 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sInfoPostFix" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Info post fix language is '' (blank) by default", + null, + function () { return oSettings.oLanguage.sInfoPostFix == ""; } + ); + + oTest.fnTest( + "Width no post fix, the basic info shows", + null, + function () { return document.getElementById('example_info').innerHTML = "Showing 1 to 10 of 57 entries"; } + ); + + + oTest.fnWaitTest( + "Info post fix language can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfoPostFix": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sInfoPostFix == "unit test"; } + ); + + oTest.fnTest( + "Info empty language default is in the DOM", + null, + function () { return document.getElementById('example_info').innerHTML = "Showing 1 to 10 of 57 entries unit test"; } + ); + + + oTest.fnWaitTest( + "Macros have no effect in the post fix", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfoPostFix": "unit _START_ _END_ _TOTAL_ test" + } + } ); + }, + function () { return document.getElementById('example_info').innerHTML = "Showing 1 to 10 of 57 entries unit _START_ _END_ _TOTAL_ test"; } + ); + + + oTest.fnWaitTest( + "Post fix is applied after fintering info", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sInfoPostFix": "unit test" + } + } ); + oTable.fnFilter("nothinghere"); + }, + function () { return document.getElementById('example_info').innerHTML = "Showing 0 to 0 of 0 entries unit (filtered from 57 total entries) test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLengthMenu.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLengthMenu.js new file mode 100644 index 00000000..6fae9483 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLengthMenu.js @@ -0,0 +1,111 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sLengthMenu" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Menu language is 'Show _MENU_ entries' by default", + null, + function () { return oSettings.oLanguage.sLengthMenu == "Show _MENU_ entries"; } + ); + + oTest.fnTest( + "_MENU_ macro is replaced by select menu in DOM", + null, + function () { return $('select', oSettings.aanFeatures.l[0]).length == 1 } + ); + + oTest.fnTest( + "A label input is used", + null, + function () { return $('label', oSettings.aanFeatures.l[0]).length == 1 } + ); + + oTest.fnTest( + "Default is put into DOM", + null, + function () { + var anChildren = $('label',oSettings.aanFeatures.l[0])[0].childNodes; + var bReturn = + anChildren[0].nodeValue == "Show " && + anChildren[2].nodeValue == " entries"; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "Menu length language can be defined - no _MENU_ macro", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sLengthMenu": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sLengthMenu == "unit test"; } + ); + + oTest.fnTest( + "Menu length language definition is in the DOM", + null, + function () { + return $('label', oSettings.aanFeatures.l[0]).text() == "unit test"; + } + ); + + + oTest.fnWaitTest( + "Menu length language can be defined - with _MENU_ macro", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sLengthMenu": "unit _MENU_ test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { + var anChildren = $('label',oSettings.aanFeatures.l[0])[0].childNodes; + var bReturn = + anChildren[0].nodeValue == "unit " && + anChildren[2].nodeValue == " test"; + return bReturn; + } + ); + + + oTest.fnWaitTest( + "Only the _MENU_ macro", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sLengthMenu": "_MENU_" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { + var anChildren = oSettings.aanFeatures.l[0].childNodes; + var bReturn = + anChildren.length == 1 && + $('select', oSettings.aanFeatures.l[0]).length == 1; + return bReturn; + } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLoadingRecords.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLoadingRecords.js new file mode 100644 index 00000000..616b0ef3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sLoadingRecords.js @@ -0,0 +1,65 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sLoadingRecords" ); + +$(document).ready( function () { + var tmp = false; + oTest.fnTest( + "Default loading text is 'Loading...'", + function () { + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + tmp = $('#example tbody tr td')[0].innerHTML == "Loading..."; + }, + function () { return tmp; } + ); + + oTest.fnTest( + "Text can be overriden", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "oLanguage": { + "sLoadingRecords": "unitest" + }, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + tmp = $('#example tbody tr td')[0].innerHTML == "unitest"; + }, + function () { return tmp; } + ); + + oTest.fnTest( + "When sZeroRecords is given but sLoadingRecords is not, sZeroRecords is used", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "oLanguage": { + "sZeroRecords": "unitest_sZeroRecords" + }, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + tmp = $('#example tbody tr td')[0].innerHTML == "unitest_sZeroRecords"; + }, + function () { return tmp; } + ); + + oTest.fnTest( + "sLoadingRecords and sZeroRecords both given", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "oLanguage": { + "sZeroRecords": "unitest_sZeroRecords2", + "sLoadingRecords": "unitest2" + }, + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + tmp = $('#example tbody tr td')[0].innerHTML == "unitest2"; + }, + function () { return tmp; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sProcessing.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sProcessing.js new file mode 100644 index 00000000..39886194 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sProcessing.js @@ -0,0 +1,49 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sProcessing" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bProcessing": true + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Processing language is 'Processing...' by default", + null, + function () { return oSettings.oLanguage.sProcessing == "Processing..."; } + ); + + oTest.fnTest( + "Processing language default is in the DOM", + null, + function () { return document.getElementById('example_processing').innerHTML = "Processing..."; } + ); + + + oTest.fnWaitTest( + "Processing language can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "bProcessing": true, + "oLanguage": { + "sProcessing": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sProcessing == "unit test"; } + ); + + oTest.fnTest( + "Processing language definition is in the DOM", + null, + function () { return document.getElementById('example_processing').innerHTML = "unit test"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sSearch.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sSearch.js new file mode 100644 index 00000000..5a1584d1 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sSearch.js @@ -0,0 +1,70 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sSearch" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Search language is 'Search:' by default", + null, + function () { return oSettings.oLanguage.sSearch == "Search:"; } + ); + + oTest.fnTest( + "A label input is used", + null, + function () { return $('label', oSettings.aanFeatures.f[0]).length == 1 } + ); + + oTest.fnTest( + "Search language default is in the DOM", + null, + function () { return $('label', oSettings.aanFeatures.f[0]).text() + == "Search: "; } + ); + + + oTest.fnWaitTest( + "Search language can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sSearch": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sSearch == "unit test"; } + ); + + oTest.fnTest( + "Info language definition is in the DOM", + null, + function () { return $('label', oSettings.aanFeatures.f[0]).text().indexOf('unit test') !== -1; } + ); + + + oTest.fnWaitTest( + "Blank search has a no space (separator) inserted", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sSearch": "" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return document.getElementById('example_filter').childNodes.length == 1; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sUrl.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sUrl.js new file mode 100644 index 00000000..5ebfe5dd --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sUrl.js @@ -0,0 +1,62 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sUrl" ); + +/* Note that we only test the internal storage of language information pulled form a file here + * as the other language tests will check it goes into the DOM correctly + */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnTest( + "sUrl is blank by default", + null, + function () { return oSettings.oLanguage.sUrl == ""; } + ); + + + oTest.fnWaitTest( + "Loading of German file loads language information", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sUrl": "../../../examples/examples_support/de_DE.txt" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { + var bReturn = + oSettings.oLanguage.sProcessing == "Bitte warten..." && + oSettings.oLanguage.sLengthMenu == "_MENU_ Einträge anzeigen" && + oSettings.oLanguage.sZeroRecords == "Keine Einträge vorhanden." && + oSettings.oLanguage.sInfo == "_START_ bis _END_ von _TOTAL_ Einträgen" && + oSettings.oLanguage.sInfoEmpty == "0 bis 0 von 0 Einträgen" && + oSettings.oLanguage.sInfoFiltered == "(gefiltert von _MAX_ Einträgen)" && + oSettings.oLanguage.sInfoPostFix == "" && + oSettings.oLanguage.sSearch == "Suchen" && + oSettings.oLanguage.oPaginate.sFirst == "Erster" && + oSettings.oLanguage.oPaginate.sPrevious == "Zurück" && + oSettings.oLanguage.oPaginate.sNext == "Nächster" && + oSettings.oLanguage.oPaginate.sLast == "Letzter"; + + return bReturn; + } + ); + + /* One DOM check just to ensure that they go into the DOM */ + oTest.fnTest( + "Loaded language goes into the DOM", + null, + function () { return document.getElementById('example_info').innerHTML = "1 bis 10 von 57 Einträgen"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sZeroRecords.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sZeroRecords.js new file mode 100644 index 00000000..7dffc151 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oLanguage.sZeroRecords.js @@ -0,0 +1,48 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oLanguage.sZeroRecords" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Zero records language is 'No matching records found' by default", + null, + function () { return oSettings.oLanguage.sZeroRecords == "No matching records found"; } + ); + + oTest.fnWaitTest( + "Text is shown when empty table (after filtering)", + function () { oTable.fnFilter('nothinghere'); }, + function () { return $('#example tbody tr td')[0].innerHTML == "No matching records found" } + ); + + + + oTest.fnWaitTest( + "Zero records language can be defined", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oLanguage": { + "sZeroRecords": "unit test" + } + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.oLanguage.sZeroRecords == "unit test"; } + ); + + oTest.fnWaitTest( + "Text is shown when empty table (after filtering)", + function () { oTable.fnFilter('nothinghere2'); }, + function () { return $('#example tbody tr td')[0].innerHTML == "unit test" } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oSearch.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oSearch.js new file mode 100644 index 00000000..42f1b948 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/oSearch.js @@ -0,0 +1,108 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "oSearch" ); + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Default values should be blank", + null, + function () { + var bReturn = oSettings.oPreviousSearch.sSearch == "" && + !oSettings.oPreviousSearch.bRegex; + return bReturn; + } + ); + + /* This test might be considered iffy since the full object isn't given, but it's reasonable to + * expect DataTables to cope with this. It should just assumine regex false + */ + oTest.fnWaitTest( + "Search term only in object", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oSearch": { + "sSearch": "Mozilla" + } + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + oTest.fnWaitTest( + "New search will kill old one", + function () { + oTable.fnFilter("Opera"); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Presto"; } + ); + + oTest.fnWaitTest( + "Search plain text term and escape regex true", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oSearch": { + "sSearch": "DS", + "bRegex": false + } + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(1)').html() == "Nintendo DS browser"; } + ); + + oTest.fnWaitTest( + "Search plain text term and escape regex false", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oSearch": { + "sSearch": "Opera", + "bRegex": true + } + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Presto"; } + ); + + oTest.fnWaitTest( + "Search regex text term and escape regex true", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oSearch": { + "sSearch": "1.*", + "bRegex": false + } + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "No matching records found"; } + ); + + oTest.fnWaitTest( + "Search regex text term and escape regex false", + function () { + oSession.fnRestore(); + $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "oSearch": { + "sSearch": "1.*", + "bRegex": true + } + } ); + }, + function () { return $('#example tbody tr:eq(0) td:eq(0)').html() == "Gecko"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp.js new file mode 100644 index 00000000..5759c47d --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp.js @@ -0,0 +1,139 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "Custom data source property - property given" ); + + +$(document).ready( function () { + var oInit = { + "sAjaxSource": "../../../examples/ajax/sources/custom_prop.txt", + "sAjaxDataProp": "demo" + }; + $('#example').dataTable( oInit ); + + oTest.fnWaitTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp2.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp2.js new file mode 100644 index 00000000..646657e3 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxDataProp2.js @@ -0,0 +1,139 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "Custom data source property - array only" ); + + +$(document).ready( function () { + var oInit = { + "sAjaxSource": "../../../examples/ajax/sources/array_only.txt", + "sAjaxDataProp": "" + }; + $('#example').dataTable( oInit ); + + oTest.fnWaitTest( + "10 rows shown on the first page", + null, + function () { return $('#example tbody tr').length == 10; } + ); + + oTest.fnTest( + "Initial sort occured", + null, + function () { return $('#example tbody td:eq(0)').html() == "Gecko"; } + ); + + /* Need to use the WaitTest for sorting due to the setTimeout datatables uses */ + oTest.fnTest( + "Sorting (first click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (second click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "Seamonkey 1.1"; } + ); + + oTest.fnTest( + "Sorting (third click) on second column", + function () { $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Sorting (first click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "-"; } + ); + + oTest.fnTest( + "Sorting (second click) on numeric column", + function () { $('#example thead th:eq(3)').click(); }, + function () { return $('#example tbody td:eq(3)').html() == "522.1"; } + ); + + oTest.fnTest( + "Sorting multi-column (first click)", + function () { + $('#example thead th:eq(0)').click(); + oDispacher.click( $('#example thead th:eq(1)')[0], { 'shift': true } ); }, + function () { var b = + $('#example tbody td:eq(0)').html() == "Gecko" && + $('#example tbody td:eq(1)').html() == "Camino 1.0"; return b; } + ); + + oTest.fnTest( + "Sorting multi-column - sorting second column only", + function () { + $('#example thead th:eq(1)').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Basic paging */ + oTest.fnTest( + "Paging to second page", + function () { $('#example_next').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "IE Mobile"; } + ); + + oTest.fnTest( + "Paging to first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + oTest.fnTest( + "Attempting to page back beyond the first page", + function () { $('#example_previous').click(); }, + function () { return $('#example tbody td:eq(1)').html() == "All others"; } + ); + + /* Changing length */ + oTest.fnTest( + "Changing table length to 25 records", + function () { $("select[name=example_length]").val('25').change(); }, + function () { return $('#example tbody tr').length == 25; } + ); + + oTest.fnTest( + "Changing table length to 50 records", + function () { $("select[name=example_length]").val('50').change(); }, + function () { return $('#example tbody tr').length == 50; } + ); + + oTest.fnTest( + "Changing table length to 100 records", + function () { $("select[name=example_length]").val('100').change(); }, + function () { return $('#example tbody tr').length == 57; } + ); + + oTest.fnTest( + "Changing table length to 10 records", + function () { $("select[name=example_length]").val('10').change(); }, + function () { return $('#example tbody tr').length == 10; } + ); + + /* + * Information element + */ + oTest.fnTest( + "Information on zero config", + null, + function () { return document.getElementById('example_info').innerHTML == "Showing 1 to 10 of 57 entries"; } + ); + + oTest.fnTest( + "Information on second page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 11 to 20 of 57 entries"; } + ); + + oTest.fnTest( + "Information on third page", + function () { $('#example_next').click(); }, + function () { return document.getElementById('example_info').innerHTML == "Showing 21 to 30 of 57 entries"; } + ); + + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxSource.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxSource.js new file mode 100644 index 00000000..b633d097 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sAjaxSource.js @@ -0,0 +1,22 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "sAjaxSource" ); + +/* Sanitfy check really - all the other tests blast this */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Server side is off by default", + null, + function () { + return oSettings.sAjaxSource == "../../../examples/ajax/sources/arrays.txt"; + } + ); + + oTest.fnComplete(); +} ); \ No newline at end of file diff --git a/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sDom.js b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sDom.js new file mode 100644 index 00000000..0af1f599 --- /dev/null +++ b/wqflask/wqflask/static/new/packages/DataTables/unit_testing/tests_onhold/3_ajax/sDom.js @@ -0,0 +1,262 @@ +// DATA_TEMPLATE: empty_table +oTest.fnStart( "sDom" ); + +/* This is going to be brutal on the browser! There is a lot that can be tested here... */ + +$(document).ready( function () { + /* Check the default */ + var oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt" + } ); + var oSettings = oTable.fnSettings(); + + oTest.fnWaitTest( + "Default DOM varaible", + null, + function () { return oSettings.sDom == "lfrtip"; } + ); + + oTest.fnWaitTest( + "Default DOM in document", + null, + function () { + var nNodes = $('#demo div, #demo table'); + var nWrapper = document.getElementById('example_wrapper'); + var nLength = document.getElementById('example_length'); + var nFilter = document.getElementById('example_filter'); + var nInfo = document.getElementById('example_info'); + var nPaging = document.getElementById('example_paginate'); + var nTable = document.getElementById('example'); + + var bReturn = + nNodes[0] == nWrapper && + nNodes[1] == nLength && + nNodes[2] == nFilter && + nNodes[3] == nTable && + nNodes[4] == nInfo && + nNodes[5] == nPaging; + return bReturn; + } + ); + + oTest.fnWaitTest( + "Check example 1 in code propagates", + function () { + oSession.fnRestore(); + oTable = $('#example').dataTable( { + "sAjaxSource": "../../../examples/ajax/sources/arrays.txt", + "sDom": '<"wrapper"flipt>' + } ); + oSettings = oTable.fnSettings(); + }, + function () { return oSettings.sDom == '<"wrapper"flipt>'; } + ); + + oTest.fnWaitTest( + "Check example 1 in DOM", + null, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; iip>' + } ); + }, + function () { + var jqNodes = $('#demo div, #demo table'); + var nNodes = []; + var nCustomWrappers = [] + + /* Strip the paging nodes */ + for ( var i=0, iLen=jqNodes.length ; i
      • ' + , minLength: 1 + } + + $.fn.typeahead.Constructor = Typeahead + + + /* TYPEAHEAD DATA-API + * ================== */ + + $(function () { + $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { + var $this = $(this) + if ($this.data('typeahead')) return + e.preventDefault() + $this.typeahead($this.data()) + }) + }) + +}(window.jQuery); +/* ========================================================== + * bootstrap-affix.js v2.1.1 + * http://twitter.github.com/bootstrap/javascript.html#affix + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* AFFIX CLASS DEFINITION + * ====================== */ + + var Affix = function (element, options) { + this.options = $.extend({}, $.fn.affix.defaults, options) + this.$window = $(window).on('scroll.affix.data-api', $.proxy(this.checkPosition, this)) + this.$element = $(element) + this.checkPosition() + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var scrollHeight = $(document).height() + , scrollTop = this.$window.scrollTop() + , position = this.$element.offset() + , offset = this.options.offset + , offsetBottom = offset.bottom + , offsetTop = offset.top + , reset = 'affix affix-top affix-bottom' + , affix + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top() + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom() + + affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? + false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? + 'bottom' : offsetTop != null && scrollTop <= offsetTop ? + 'top' : false + + if (this.affixed === affix) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? position.top - scrollTop : null + + this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : '')) + } + + + /* AFFIX PLUGIN DEFINITION + * ======================= */ + + $.fn.affix = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('affix') + , options = typeof option == 'object' && option + if (!data) $this.data('affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.affix.Constructor = Affix + + $.fn.affix.defaults = { + offset: 0 + } + + + /* AFFIX DATA-API + * ============== */ + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + , data = $spy.data() + + data.offset = data.offset || {} + + data.offsetBottom && (data.offset.bottom = data.offsetBottom) + data.offsetTop && (data.offset.top = data.offsetTop) + + $spy.affix(data) + }) + }) + + +}(window.jQuery); \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/bootstrap/js/bootstrap.min.js b/wqflask/wqflask/static/packages/bootstrap/js/bootstrap.min.js new file mode 100644 index 00000000..0e33fb16 --- /dev/null +++ b/wqflask/wqflask/static/packages/bootstrap/js/bootstrap.min.js @@ -0,0 +1,6 @@ +/*! +* Bootstrap.js by @fat & @mdo +* Copyright 2012 Twitter, Inc. +* http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +!function(e){e(function(){"use strict";e.support.transition=function(){var e=function(){var e=document.createElement("bootstrap"),t={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"},n;for(n in t)if(e.style[n]!==undefined)return t[n]}();return e&&{end:e}}()})}(window.jQuery),!function(e){"use strict";var t='[data-dismiss="alert"]',n=function(n){e(n).on("click",t,this.close)};n.prototype.close=function(t){function s(){i.trigger("closed").remove()}var n=e(this),r=n.attr("data-target"),i;r||(r=n.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,"")),i=e(r),t&&t.preventDefault(),i.length||(i=n.hasClass("alert")?n:n.parent()),i.trigger(t=e.Event("close"));if(t.isDefaultPrevented())return;i.removeClass("in"),e.support.transition&&i.hasClass("fade")?i.on(e.support.transition.end,s):s()},e.fn.alert=function(t){return this.each(function(){var r=e(this),i=r.data("alert");i||r.data("alert",i=new n(this)),typeof t=="string"&&i[t].call(r)})},e.fn.alert.Constructor=n,e(function(){e("body").on("click.alert.data-api",t,n.prototype.close)})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.button.defaults,n)};t.prototype.setState=function(e){var t="disabled",n=this.$element,r=n.data(),i=n.is("input")?"val":"html";e+="Text",r.resetText||n.data("resetText",n[i]()),n[i](r[e]||this.options[e]),setTimeout(function(){e=="loadingText"?n.addClass(t).attr(t,t):n.removeClass(t).removeAttr(t)},0)},t.prototype.toggle=function(){var e=this.$element.closest('[data-toggle="buttons-radio"]');e&&e.find(".active").removeClass("active"),this.$element.toggleClass("active")},e.fn.button=function(n){return this.each(function(){var r=e(this),i=r.data("button"),s=typeof n=="object"&&n;i||r.data("button",i=new t(this,s)),n=="toggle"?i.toggle():n&&i.setState(n)})},e.fn.button.defaults={loadingText:"loading..."},e.fn.button.Constructor=t,e(function(){e("body").on("click.button.data-api","[data-toggle^=button]",function(t){var n=e(t.target);n.hasClass("btn")||(n=n.closest(".btn")),n.button("toggle")})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=n,this.options.slide&&this.slide(this.options.slide),this.options.pause=="hover"&&this.$element.on("mouseenter",e.proxy(this.pause,this)).on("mouseleave",e.proxy(this.cycle,this))};t.prototype={cycle:function(t){return t||(this.paused=!1),this.options.interval&&!this.paused&&(this.interval=setInterval(e.proxy(this.next,this),this.options.interval)),this},to:function(t){var n=this.$element.find(".item.active"),r=n.parent().children(),i=r.index(n),s=this;if(t>r.length-1||t<0)return;return this.sliding?this.$element.one("slid",function(){s.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",e(r[t]))},pause:function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&e.support.transition.end&&(this.$element.trigger(e.support.transition.end),this.cycle()),clearInterval(this.interval),this.interval=null,this},next:function(){if(this.sliding)return;return this.slide("next")},prev:function(){if(this.sliding)return;return this.slide("prev")},slide:function(t,n){var r=this.$element.find(".item.active"),i=n||r[t](),s=this.interval,o=t=="next"?"left":"right",u=t=="next"?"first":"last",a=this,f=e.Event("slide",{relatedTarget:i[0]});this.sliding=!0,s&&this.pause(),i=i.length?i:this.$element.find(".item")[u]();if(i.hasClass("active"))return;if(e.support.transition&&this.$element.hasClass("slide")){this.$element.trigger(f);if(f.isDefaultPrevented())return;i.addClass(t),i[0].offsetWidth,r.addClass(o),i.addClass(o),this.$element.one(e.support.transition.end,function(){i.removeClass([t,o].join(" ")).addClass("active"),r.removeClass(["active",o].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger("slid")},0)})}else{this.$element.trigger(f);if(f.isDefaultPrevented())return;r.removeClass("active"),i.addClass("active"),this.sliding=!1,this.$element.trigger("slid")}return s&&this.cycle(),this}},e.fn.carousel=function(n){return this.each(function(){var r=e(this),i=r.data("carousel"),s=e.extend({},e.fn.carousel.defaults,typeof n=="object"&&n),o=typeof n=="string"?n:s.slide;i||r.data("carousel",i=new t(this,s)),typeof n=="number"?i.to(n):o?i[o]():s.interval&&i.cycle()})},e.fn.carousel.defaults={interval:5e3,pause:"hover"},e.fn.carousel.Constructor=t,e(function(){e("body").on("click.carousel.data-api","[data-slide]",function(t){var n=e(this),r,i=e(n.attr("data-target")||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,"")),s=!i.data("modal")&&e.extend({},i.data(),n.data());i.carousel(s),t.preventDefault()})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.collapse.defaults,n),this.options.parent&&(this.$parent=e(this.options.parent)),this.options.toggle&&this.toggle()};t.prototype={constructor:t,dimension:function(){var e=this.$element.hasClass("width");return e?"width":"height"},show:function(){var t,n,r,i;if(this.transitioning)return;t=this.dimension(),n=e.camelCase(["scroll",t].join("-")),r=this.$parent&&this.$parent.find("> .accordion-group > .in");if(r&&r.length){i=r.data("collapse");if(i&&i.transitioning)return;r.collapse("hide"),i||r.data("collapse",null)}this.$element[t](0),this.transition("addClass",e.Event("show"),"shown"),e.support.transition&&this.$element[t](this.$element[0][n])},hide:function(){var t;if(this.transitioning)return;t=this.dimension(),this.reset(this.$element[t]()),this.transition("removeClass",e.Event("hide"),"hidden"),this.$element[t](0)},reset:function(e){var t=this.dimension();return this.$element.removeClass("collapse")[t](e||"auto")[0].offsetWidth,this.$element[e!==null?"addClass":"removeClass"]("collapse"),this},transition:function(t,n,r){var i=this,s=function(){n.type=="show"&&i.reset(),i.transitioning=0,i.$element.trigger(r)};this.$element.trigger(n);if(n.isDefaultPrevented())return;this.transitioning=1,this.$element[t]("in"),e.support.transition&&this.$element.hasClass("collapse")?this.$element.one(e.support.transition.end,s):s()},toggle:function(){this[this.$element.hasClass("in")?"hide":"show"]()}},e.fn.collapse=function(n){return this.each(function(){var r=e(this),i=r.data("collapse"),s=typeof n=="object"&&n;i||r.data("collapse",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.collapse.defaults={toggle:!0},e.fn.collapse.Constructor=t,e(function(){e("body").on("click.collapse.data-api","[data-toggle=collapse]",function(t){var n=e(this),r,i=n.attr("data-target")||t.preventDefault()||(r=n.attr("href"))&&r.replace(/.*(?=#[^\s]+$)/,""),s=e(i).data("collapse")?"toggle":n.data();n[e(i).hasClass("in")?"addClass":"removeClass"]("collapsed"),e(i).collapse(s)})})}(window.jQuery),!function(e){"use strict";function r(){i(e(t)).removeClass("open")}function i(t){var n=t.attr("data-target"),r;return n||(n=t.attr("href"),n=n&&/#/.test(n)&&n.replace(/.*(?=#[^\s]*$)/,"")),r=e(n),r.length||(r=t.parent()),r}var t="[data-toggle=dropdown]",n=function(t){var n=e(t).on("click.dropdown.data-api",this.toggle);e("html").on("click.dropdown.data-api",function(){n.parent().removeClass("open")})};n.prototype={constructor:n,toggle:function(t){var n=e(this),s,o;if(n.is(".disabled, :disabled"))return;return s=i(n),o=s.hasClass("open"),r(),o||(s.toggleClass("open"),n.focus()),!1},keydown:function(t){var n,r,s,o,u,a;if(!/(38|40|27)/.test(t.keyCode))return;n=e(this),t.preventDefault(),t.stopPropagation();if(n.is(".disabled, :disabled"))return;o=i(n),u=o.hasClass("open");if(!u||u&&t.keyCode==27)return n.click();r=e("[role=menu] li:not(.divider) a",o);if(!r.length)return;a=r.index(r.filter(":focus")),t.keyCode==38&&a>0&&a--,t.keyCode==40&&a').appendTo(document.body),this.options.backdrop!="static"&&this.$backdrop.click(e.proxy(this.hide,this)),i&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),i?this.$backdrop.one(e.support.transition.end,t):t()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),e.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(e.support.transition.end,e.proxy(this.removeBackdrop,this)):this.removeBackdrop()):t&&t()}},e.fn.modal=function(n){return this.each(function(){var r=e(this),i=r.data("modal"),s=e.extend({},e.fn.modal.defaults,r.data(),typeof n=="object"&&n);i||r.data("modal",i=new t(this,s)),typeof n=="string"?i[n]():s.show&&i.show()})},e.fn.modal.defaults={backdrop:!0,keyboard:!0,show:!0},e.fn.modal.Constructor=t,e(function(){e("body").on("click.modal.data-api",'[data-toggle="modal"]',function(t){var n=e(this),r=n.attr("href"),i=e(n.attr("data-target")||r&&r.replace(/.*(?=#[^\s]+$)/,"")),s=i.data("modal")?"toggle":e.extend({remote:!/#/.test(r)&&r},i.data(),n.data());t.preventDefault(),i.modal(s).one("hide",function(){n.focus()})})})}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,n,r){var i,s;this.type=t,this.$element=e(n),this.options=this.getOptions(r),this.enabled=!0,this.options.trigger=="click"?this.$element.on("click."+this.type,this.options.selector,e.proxy(this.toggle,this)):this.options.trigger!="manual"&&(i=this.options.trigger=="hover"?"mouseenter":"focus",s=this.options.trigger=="hover"?"mouseleave":"blur",this.$element.on(i+"."+this.type,this.options.selector,e.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,e.proxy(this.leave,this))),this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,t,this.$element.data()),t.delay&&typeof t.delay=="number"&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);if(!n.options.delay||!n.options.delay.show)return n.show();clearTimeout(this.timeout),n.hoverState="in",this.timeout=setTimeout(function(){n.hoverState=="in"&&n.show()},n.options.delay.show)},leave:function(t){var n=e(t.currentTarget)[this.type](this._options).data(this.type);this.timeout&&clearTimeout(this.timeout);if(!n.options.delay||!n.options.delay.hide)return n.hide();n.hoverState="out",this.timeout=setTimeout(function(){n.hoverState=="out"&&n.hide()},n.options.delay.hide)},show:function(){var e,t,n,r,i,s,o;if(this.hasContent()&&this.enabled){e=this.tip(),this.setContent(),this.options.animation&&e.addClass("fade"),s=typeof this.options.placement=="function"?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,t=/in/.test(s),e.remove().css({top:0,left:0,display:"block"}).appendTo(t?this.$element:document.body),n=this.getPosition(t),r=e[0].offsetWidth,i=e[0].offsetHeight;switch(t?s.split(" ")[1]:s){case"bottom":o={top:n.top+n.height,left:n.left+n.width/2-r/2};break;case"top":o={top:n.top-i,left:n.left+n.width/2-r/2};break;case"left":o={top:n.top+n.height/2-i/2,left:n.left-r};break;case"right":o={top:n.top+n.height/2-i/2,left:n.left+n.width}}e.css(o).addClass(s).addClass("in")}},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.options.html?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function r(){var t=setTimeout(function(){n.off(e.support.transition.end).remove()},500);n.one(e.support.transition.end,function(){clearTimeout(t),n.remove()})}var t=this,n=this.tip();return n.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?r():n.remove(),this},fixTitle:function(){var e=this.$element;(e.attr("title")||typeof e.attr("data-original-title")!="string")&&e.attr("data-original-title",e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(t){return e.extend({},t?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-original-title")||(typeof n.title=="function"?n.title.call(t[0]):n.title),e},tip:function(){return this.$tip=this.$tip||e(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}},e.fn.tooltip=function(n){return this.each(function(){var r=e(this),i=r.data("tooltip"),s=typeof n=="object"&&n;i||r.data("tooltip",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'
        ',trigger:"hover",title:"",delay:0,html:!0}}(window.jQuery),!function(e){"use strict";var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),n=this.getContent();e.find(".popover-title")[this.options.html?"html":"text"](t),e.find(".popover-content > *")[this.options.html?"html":"text"](n),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,n=this.options;return e=t.attr("data-content")||(typeof n.content=="function"?n.content.call(t[0]):n.content),e},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip},destroy:function(){this.hide().$element.off("."+this.type).removeData(this.type)}}),e.fn.popover=function(n){return this.each(function(){var r=e(this),i=r.data("popover"),s=typeof n=="object"&&n;i||r.data("popover",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",trigger:"click",content:"",template:'

        '})}(window.jQuery),!function(e){"use strict";function t(t,n){var r=e.proxy(this.process,this),i=e(t).is("body")?e(window):e(t),s;this.options=e.extend({},e.fn.scrollspy.defaults,n),this.$scrollElement=i.on("scroll.scroll-spy.data-api",r),this.selector=(this.options.target||(s=e(t).attr("href"))&&s.replace(/.*(?=#[^\s]+$)/,"")||"")+" .nav li > a",this.$body=e("body"),this.refresh(),this.process()}t.prototype={constructor:t,refresh:function(){var t=this,n;this.offsets=e([]),this.targets=e([]),n=this.$body.find(this.selector).map(function(){var t=e(this),n=t.data("target")||t.attr("href"),r=/^#\w/.test(n)&&e(n);return r&&r.length&&[[r.position().top,n]]||null}).sort(function(e,t){return e[0]-t[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},process:function(){var e=this.$scrollElement.scrollTop()+this.options.offset,t=this.$scrollElement[0].scrollHeight||this.$body[0].scrollHeight,n=t-this.$scrollElement.height(),r=this.offsets,i=this.targets,s=this.activeTarget,o;if(e>=n)return s!=(o=i.last()[0])&&this.activate(o);for(o=r.length;o--;)s!=i[o]&&e>=r[o]&&(!r[o+1]||e<=r[o+1])&&this.activate(i[o])},activate:function(t){var n,r;this.activeTarget=t,e(this.selector).parent(".active").removeClass("active"),r=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',n=e(r).parent("li").addClass("active"),n.parent(".dropdown-menu").length&&(n=n.closest("li.dropdown").addClass("active")),n.trigger("activate")}},e.fn.scrollspy=function(n){return this.each(function(){var r=e(this),i=r.data("scrollspy"),s=typeof n=="object"&&n;i||r.data("scrollspy",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.scrollspy.Constructor=t,e.fn.scrollspy.defaults={offset:10},e(window).on("load",function(){e('[data-spy="scroll"]').each(function(){var t=e(this);t.scrollspy(t.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t){this.element=e(t)};t.prototype={constructor:t,show:function(){var t=this.element,n=t.closest("ul:not(.dropdown-menu)"),r=t.attr("data-target"),i,s,o;r||(r=t.attr("href"),r=r&&r.replace(/.*(?=#[^\s]*$)/,""));if(t.parent("li").hasClass("active"))return;i=n.find(".active a").last()[0],o=e.Event("show",{relatedTarget:i}),t.trigger(o);if(o.isDefaultPrevented())return;s=e(r),this.activate(t.parent("li"),n),this.activate(s,s.parent(),function(){t.trigger({type:"shown",relatedTarget:i})})},activate:function(t,n,r){function o(){i.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),t.addClass("active"),s?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu")&&t.closest("li.dropdown").addClass("active"),r&&r()}var i=n.find("> .active"),s=r&&e.support.transition&&i.hasClass("fade");s?i.one(e.support.transition.end,o):o(),i.removeClass("in")}},e.fn.tab=function(n){return this.each(function(){var r=e(this),i=r.data("tab");i||r.data("tab",i=new t(this)),typeof n=="string"&&i[n]()})},e.fn.tab.Constructor=t,e(function(){e("body").on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(t){t.preventDefault(),e(this).tab("show")})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.$element=e(t),this.options=e.extend({},e.fn.typeahead.defaults,n),this.matcher=this.options.matcher||this.matcher,this.sorter=this.options.sorter||this.sorter,this.highlighter=this.options.highlighter||this.highlighter,this.updater=this.options.updater||this.updater,this.$menu=e(this.options.menu).appendTo("body"),this.source=this.options.source,this.shown=!1,this.listen()};t.prototype={constructor:t,select:function(){var e=this.$menu.find(".active").attr("data-value");return this.$element.val(this.updater(e)).change(),this.hide()},updater:function(e){return e},show:function(){var t=e.extend({},this.$element.offset(),{height:this.$element[0].offsetHeight});return this.$menu.css({top:t.top+t.height,left:t.left}),this.$menu.show(),this.shown=!0,this},hide:function(){return this.$menu.hide(),this.shown=!1,this},lookup:function(t){var n;return this.query=this.$element.val(),!this.query||this.query.length"+t+""})},render:function(t){var n=this;return t=e(t).map(function(t,r){return t=e(n.options.item).attr("data-value",r),t.find("a").html(n.highlighter(r)),t[0]}),t.first().addClass("active"),this.$menu.html(t),this},next:function(t){var n=this.$menu.find(".active").removeClass("active"),r=n.next();r.length||(r=e(this.$menu.find("li")[0])),r.addClass("active")},prev:function(e){var t=this.$menu.find(".active").removeClass("active"),n=t.prev();n.length||(n=this.$menu.find("li").last()),n.addClass("active")},listen:function(){this.$element.on("blur",e.proxy(this.blur,this)).on("keypress",e.proxy(this.keypress,this)).on("keyup",e.proxy(this.keyup,this)),(e.browser.chrome||e.browser.webkit||e.browser.msie)&&this.$element.on("keydown",e.proxy(this.keydown,this)),this.$menu.on("click",e.proxy(this.click,this)).on("mouseenter","li",e.proxy(this.mouseenter,this))},move:function(e){if(!this.shown)return;switch(e.keyCode){case 9:case 13:case 27:e.preventDefault();break;case 38:e.preventDefault(),this.prev();break;case 40:e.preventDefault(),this.next()}e.stopPropagation()},keydown:function(t){this.suppressKeyPressRepeat=!~e.inArray(t.keyCode,[40,38,9,13,27]),this.move(t)},keypress:function(e){if(this.suppressKeyPressRepeat)return;this.move(e)},keyup:function(e){switch(e.keyCode){case 40:case 38:break;case 9:case 13:if(!this.shown)return;this.select();break;case 27:if(!this.shown)return;this.hide();break;default:this.lookup()}e.stopPropagation(),e.preventDefault()},blur:function(e){var t=this;setTimeout(function(){t.hide()},150)},click:function(e){e.stopPropagation(),e.preventDefault(),this.select()},mouseenter:function(t){this.$menu.find(".active").removeClass("active"),e(t.currentTarget).addClass("active")}},e.fn.typeahead=function(n){return this.each(function(){var r=e(this),i=r.data("typeahead"),s=typeof n=="object"&&n;i||r.data("typeahead",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.typeahead.defaults={source:[],items:8,menu:'',item:'
      • ',minLength:1},e.fn.typeahead.Constructor=t,e(function(){e("body").on("focus.typeahead.data-api",'[data-provide="typeahead"]',function(t){var n=e(this);if(n.data("typeahead"))return;t.preventDefault(),n.typeahead(n.data())})})}(window.jQuery),!function(e){"use strict";var t=function(t,n){this.options=e.extend({},e.fn.affix.defaults,n),this.$window=e(window).on("scroll.affix.data-api",e.proxy(this.checkPosition,this)),this.$element=e(t),this.checkPosition()};t.prototype.checkPosition=function(){if(!this.$element.is(":visible"))return;var t=e(document).height(),n=this.$window.scrollTop(),r=this.$element.offset(),i=this.options.offset,s=i.bottom,o=i.top,u="affix affix-top affix-bottom",a;typeof i!="object"&&(s=o=i),typeof o=="function"&&(o=i.top()),typeof s=="function"&&(s=i.bottom()),a=this.unpin!=null&&n+this.unpin<=r.top?!1:s!=null&&r.top+this.$element.height()>=t-s?"bottom":o!=null&&n<=o?"top":!1;if(this.affixed===a)return;this.affixed=a,this.unpin=a=="bottom"?r.top-n:null,this.$element.removeClass(u).addClass("affix"+(a?"-"+a:""))},e.fn.affix=function(n){return this.each(function(){var r=e(this),i=r.data("affix"),s=typeof n=="object"&&n;i||r.data("affix",i=new t(this,s)),typeof n=="string"&&i[n]()})},e.fn.affix.Constructor=t,e.fn.affix.defaults={offset:0},e(window).on("load",function(){e('[data-spy="affix"]').each(function(){var t=e(this),n=t.data();n.offset=n.offset||{},n.offsetBottom&&(n.offset.bottom=n.offsetBottom),n.offsetTop&&(n.offset.top=n.offsetTop),t.affix(n)})})}(window.jQuery); \ No newline at end of file diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 7d9218ed..1d721673 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -1,4 +1,4 @@ - + @@ -18,8 +18,10 @@ - - + + + + -- cgit v1.2.3 From 2ab2856ef6f06c45108483deb8730d42abb65422 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 9 Oct 2012 17:10:08 -0500 Subject: Changed button and text field/dropdown appearance --- wqflask/wqflask/templates/base.html | 2 +- wqflask/wqflask/templates/index_page.html | 38 ++++++++++++------------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 1d721673..2e30b1b2 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -11,7 +11,7 @@ - + diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index 8c6c016d..a1c9c8ce 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -9,7 +9,9 @@

        Select and Search -

        + @@ -46,7 +48,7 @@ - + @@ -85,7 +87,7 @@ @@ -107,7 +109,7 @@ @@ -129,30 +133,16 @@ - - - - - - - - @@ -164,9 +154,9 @@ -- cgit v1.2.3 From 5d92e3bce336095ac746a9cd9384bf96361f8244 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 9 Oct 2012 17:40:54 -0500 Subject: Removed error related to LEFT in the html of index_page.html --- wqflask/wqflask/templates/index_page.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index a1c9c8ce..d3839c09 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -9,7 +9,7 @@ - + + + + {% endblock %} + -- cgit v1.2.3 From 8c91843b58e7534ea0070357ca53e28d6beb84d2 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 10 Oct 2012 14:50:23 -0500 Subject: Committing before removing some attempted validation code for the trait data page --- .../static/new/javascript/show_trait.coffee | 26 +++++++++++++++++++--- .../wqflask/static/new/javascript/show_trait.js | 8 +++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 5e47dedc..9498a1bb 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -237,14 +237,34 @@ $ -> else if $('#block_group').val() == "other" $('#Other_'+index.toString()).find('.trait_value_input').val("x") - $('#remove_samples_field').validate( + $('#block_by_index').click(block_by_index) + + #validate_block_index = -> + # $('#remove_samples_field').valid( + # rules: + # field: + # required: true + # number: true + # messages: + # field: + # "Please check that your input is valid." + # ) + + $('#trait_data_form').validate() + + $('#remove_samples_field').valid( rules: field: required: true number: true - ) + messages: + field: + "Please check that your input is valid." + ) + + #$('#remove_samples_field').change(validate_block_index) + - $('#block_by_index').click(block_by_index) ##End Block Samples By Index Code diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 7af60fae..5704e183 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -280,15 +280,19 @@ } return _results; }; - $('#remove_samples_field').validate({ + $('#block_by_index').click(block_by_index); + $('#trait_data_form').validate(); + $('#remove_samples_field').valid({ rules: { field: { required: true, number: true } + }, + messages: { + field: "Please check that your input is valid." } }); - $('#block_by_index').click(block_by_index); hide_no_value = function() { var _this = this; return $('.value_se').each(function(index, element) { -- cgit v1.2.3 From 1c6fd4dea9a4650966ae1b902897fb75a67d287c Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 10 Oct 2012 15:50:16 -0500 Subject: Got a rudimentary version of the validation code for block samples by index completed --- .../static/new/javascript/show_trait.coffee | 31 ++-------------------- .../wqflask/static/new/javascript/show_trait.js | 14 ---------- .../static/new/javascript/validation.coffee | 19 +++++++++++++ wqflask/wqflask/templates/base.html | 6 ++--- wqflask/wqflask/templates/show_trait.html | 13 ++++++--- 5 files changed, 33 insertions(+), 50 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/validation.coffee diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 9498a1bb..a22a3beb 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -9,7 +9,7 @@ $ -> for x in [start..10] $("#stats_tabs" + x).hide() - hide_tabs(1) + #hide_tabs(1) # Changes stats table between all, bxd only and non-bxd, etc. stats_mdp_change = -> @@ -17,7 +17,7 @@ $ -> hide_tabs(0) $("#stats_tabs" + selected).show() - $(".stats_mdp").change(stats_mdp_change) + #$(".stats_mdp").change(stats_mdp_change) change_stats_value = (sample_sets, category, value_type, decimal_places)-> id = "#" + process_id(category, value_type) @@ -238,33 +238,6 @@ $ -> $('#Other_'+index.toString()).find('.trait_value_input').val("x") $('#block_by_index').click(block_by_index) - - #validate_block_index = -> - # $('#remove_samples_field').valid( - # rules: - # field: - # required: true - # number: true - # messages: - # field: - # "Please check that your input is valid." - # ) - - $('#trait_data_form').validate() - - $('#remove_samples_field').valid( - rules: - field: - required: true - number: true - messages: - field: - "Please check that your input is valid." - ) - - #$('#remove_samples_field').change(validate_block_index) - - ##End Block Samples By Index Code diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 5704e183..d6c5226f 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -20,14 +20,12 @@ } return _results; }; - hide_tabs(1); stats_mdp_change = function() { var selected; selected = $(this).val(); hide_tabs(0); return $("#stats_tabs" + selected).show(); }; - $(".stats_mdp").change(stats_mdp_change); change_stats_value = function(sample_sets, category, value_type, decimal_places) { var current_value, id, in_box, the_value; id = "#" + process_id(category, value_type); @@ -281,18 +279,6 @@ return _results; }; $('#block_by_index').click(block_by_index); - $('#trait_data_form').validate(); - $('#remove_samples_field').valid({ - rules: { - field: { - required: true, - number: true - } - }, - messages: { - field: "Please check that your input is valid." - } - }); hide_no_value = function() { var _this = this; return $('.value_se').each(function(index, element) { diff --git a/wqflask/wqflask/static/new/javascript/validation.coffee b/wqflask/wqflask/static/new/javascript/validation.coffee new file mode 100644 index 00000000..f389254e --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/validation.coffee @@ -0,0 +1,19 @@ +$ -> + + remove_samples_is_valid = (input)-> + return $.isNumeric(input) + + #invalidate_block_by_index = -> + # $('#remove_samples_invalid').show() + + validate_remove_samples = -> + input = $('#remove_samples_field').val() + console.log("input is:", input) + $('#remove_samples_invalid').hide() + if remove_samples_is_valid(input) + console.log("input is valid") + else + console.log("input isn't valid") + $('#remove_samples_invalid').show() + + $('#remove_samples_field').change(validate_remove_samples) \ No newline at end of file diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 2e30b1b2..f52041b1 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -12,22 +12,22 @@ + - + - + - @@ -817,7 +817,7 @@

        @@ -1214,8 +1214,12 @@
          Block samples by index:     -     + + +    

        -
        +

        + + + + + +
        +

        Select and Search

        + + +
        + + + + + + + + + + + + + + + + +

        Databases marked with ** + suffix are not public yet.
        + Access requires user login.

        + + + + + + + + + + Enter terms, genes, ID numbers in the + Search field.
        + Use * or ? wildcards (Cyp*a?, + synap*).
        + Use quotes for terms such as "tyrosine + kinase".

        + + + + + + + + + + + +
        + +
        + + diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index a20017da..1e1d8b8f 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -1378,6 +1378,7 @@ + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 82a08c71..7210a1de 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -11,6 +11,7 @@ from flask import render_template, request from wqflask import search_results from wqflask.show_trait import show_trait +from wqflask.show_trait import export_trait_data from wqflask.correlation import CorrelationPage from wqflask.dataSharing import SharingInfo, SharingInfoPage @@ -26,6 +27,11 @@ def index_page(): return render_template("index_page.html") +@app.route("/new") +def new_index_page(): + print("Sending index_page") + return render_template("new_index_page.html") + @app.route("/data_sharing") def data_sharing_page(): print("In data_sharing") @@ -81,6 +87,14 @@ def show_trait_page(): print("show_trait template_vars:", pf(template_vars.__dict__)) return render_template("show_trait.html", **template_vars.__dict__) +@app.route("/export_trait_data", methods=('POST',)) +def export_sample_table(): + """CSV file consisting of the sample data from the trait data and analysis page""" + print("In export_sample_table") + print("request.args:", request.args) + print("request.form:", request.form) + template_vars = export_trait_data.export_sample_table(request.form) + @app.route("/corr_compute", methods=('POST',)) def corr_compute_page(): -- cgit v1.2.3 From f44e0255f19fc581d4ae9f2ad253f01068508d90 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 11 Oct 2012 18:04:27 -0500 Subject: Worked with the export code and Sam worked on a redesigned index page --- wqflask/wqflask/show_trait/export_trait_data.py | 10 +- wqflask/wqflask/templates/new_index_page.html | 122 +++++++++++++----------- 2 files changed, 73 insertions(+), 59 deletions(-) diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index 7c77f1c1..b1444440 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -8,8 +8,16 @@ from pprint import pformat as pf def export_sample_table(targs): #print("* keys0 args is:", targs[0].keys()) + + test_export_file = open("/home/zas1024/gene/wqflask/wqflask/show_trait/export_test.txt", "w") + for key, item in targs.iteritems(): print("[arrow] key is:", key) sample_data = json.loads(targs['json_data']) - print("sample_data is:", pf(sample_data)) \ No newline at end of file + + print("primary_samples is:", pf(sample_data['primary_samples'])) + + for key in sample_data['primary_samples'][0]: + test_export_file.write(key + ",") + test_export_file.write("\n") \ No newline at end of file diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index 46839690..85c63b3f 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -1,85 +1,91 @@ GeneNetwork - - -
        -

        Select and Search

        - - + +
        +

        Gene Network

        +
        +
        +
        + Select and Search - - - - - + +
        + + + + + +
        + + - - - - + "fillOptions('tissue');"> + + +
        + + +
        - - -

        Databases marked with ** - suffix are not public yet.
        - Access requires user login.

        - + + + + + + + - + - - - - - - Enter terms, genes, ID numbers in the - Search field.
        - Use * or ? wildcards (Cyp*a?, - synap*).
        - Use quotes for terms such as "tyrosine - kinase".

        - - - - - - - - + + + + + +

        Enter terms, genes, ID numbers in the + Search field.
        + Use * or ? wildcards (Cyp*a?, + synap*).
        + Use quotes for terms such as "tyrosine + kinase".

        + + + + + + + + - +
        +
        - - + + + + -- cgit v1.2.3 From 5d8b5c7481429267b418bc27a41dcf58701e1959 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 12 Oct 2012 17:09:02 -0500 Subject: Finished getting trait data to export as a download prompt Sam worked on the new index page model that uses bootstrap --- wqflask/wqflask/show_trait/export_trait_data.py | 29 +- wqflask/wqflask/show_trait/show_trait.py | 3 +- .../static/new/javascript/show_trait.coffee | 20 +- .../wqflask/static/new/javascript/show_trait.js | 10 +- .../wqflask/static/packages/bootstrap/css/docs.css | 1001 ++++++++++++++++++++ wqflask/wqflask/templates/new_index_page.html | 226 +++-- wqflask/wqflask/views.py | 30 +- 7 files changed, 1237 insertions(+), 82 deletions(-) create mode 100644 wqflask/wqflask/static/packages/bootstrap/css/docs.css diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index b1444440..e5f2035d 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -1,5 +1,7 @@ from __future__ import print_function, division +import operator + import simplejson as json #import xlwt @@ -9,15 +11,24 @@ def export_sample_table(targs): #print("* keys0 args is:", targs[0].keys()) - test_export_file = open("/home/zas1024/gene/wqflask/wqflask/show_trait/export_test.txt", "w") - - for key, item in targs.iteritems(): - print("[arrow] key is:", key) + #test_export_file = open("/home/zas1024/gene/wqflask/wqflask/show_trait/export_test.txt", "w") + # + #for key, item in targs.iteritems(): + # print("[arrow] key is:", key) - sample_data = json.loads(targs['json_data']) + sample_data = json.loads(targs['export_data']) + final_sample_data = [] - print("primary_samples is:", pf(sample_data['primary_samples'])) + for sample_group in ['primary_samples', 'other_samples']: + for row in sample_data[sample_group]: + sorted_row = dict_to_sorted_list(row) + print("sorted_row is:", pf(sorted_row)) + final_sample_data.append(sorted_row) + + return final_sample_data - for key in sample_data['primary_samples'][0]: - test_export_file.write(key + ",") - test_export_file.write("\n") \ No newline at end of file +def dict_to_sorted_list(dictionary): + sorted_list = [item for item in dictionary.iteritems()] + sorted_list = sorted(sorted_list, key=operator.itemgetter(0)) + sorted_values = [item[1] for item in sorted_list] + return sorted_values \ No newline at end of file diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 942ce336..86a0a992 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -89,7 +89,8 @@ class ShowTrait(templatePage): otherStrainVals = '_', otherStrainVars = '_', extra_attributes = '_', - other_extra_attributes = '_' + other_extra_attributes = '_', + export_data = None ) if fd.enablevariance: diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index a89b29af..c7dc7c88 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -295,17 +295,25 @@ $ -> samples.other_samples = other_samples return samples - export_sample_table_data = -> sample_data = get_sample_table_data() console.log("sample_data is:", sample_data) json_sample_data = JSON.stringify(sample_data) console.log("json_sample_data is:", json_sample_data) - $.ajax( - url: '/export_trait_data' - type: 'POST' - data: "json_data=" + json_sample_data - ) + + $('input[name=export_data]').val(json_sample_data) + + console.log("export_data is", $('input[name=export_data]').val()) + + $('#trait_data_form').attr('action', '/export_trait_csv') + console.log("action is:", $('#trait_data_form').attr('action')) + $('#trait_data_form').submit() + + #$.ajax( + # url: '/export_trait_csv' + # type: 'POST' + # data: "json_data=" + json_sample_data + #) $('#export').click(export_sample_table_data) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index e4f477f3..5729eb22 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -339,11 +339,11 @@ console.log("sample_data is:", sample_data); json_sample_data = JSON.stringify(sample_data); console.log("json_sample_data is:", json_sample_data); - return $.ajax({ - url: '/export_trait_data', - type: 'POST', - data: "json_data=" + json_sample_data - }); + $('input[name=export_data]').val(json_sample_data); + console.log("export_data is", $('input[name=export_data]').val()); + $('#trait_data_form').attr('action', '/export_trait_csv'); + console.log("action is:", $('#trait_data_form').attr('action')); + return $('#trait_data_form').submit(); }; $('#export').click(export_sample_table_data); console.log("before registering block_outliers"); diff --git a/wqflask/wqflask/static/packages/bootstrap/css/docs.css b/wqflask/wqflask/static/packages/bootstrap/css/docs.css new file mode 100644 index 00000000..a6fff3c3 --- /dev/null +++ b/wqflask/wqflask/static/packages/bootstrap/css/docs.css @@ -0,0 +1,1001 @@ +/* Add additional stylesheets below +-------------------------------------------------- */ +/* + Bootstrap's documentation styles + Special styles for presenting Bootstrap's documentation and examples +*/ + + + +/* Body and structure +-------------------------------------------------- */ + +body { + position: relative; + padding-top: 40px; +} + +/* Code in headings */ +h3 code { + font-size: 14px; + font-weight: normal; +} + + + +/* Tweak navbar brand link to be super sleek +-------------------------------------------------- */ + +body > .navbar { + font-size: 13px; +} + +/* Change the docs' brand */ +body > .navbar .brand { + padding-right: 0; + padding-left: 0; + margin-left: 20px; + float: right; + font-weight: bold; + color: #000; + text-shadow: 0 1px 0 rgba(255,255,255,.1), 0 0 30px rgba(255,255,255,.125); + -webkit-transition: all .2s linear; + -moz-transition: all .2s linear; + transition: all .2s linear; +} +body > .navbar .brand:hover { + text-decoration: none; + text-shadow: 0 1px 0 rgba(255,255,255,.1), 0 0 30px rgba(255,255,255,.4); +} + + +/* Sections +-------------------------------------------------- */ + +/* padding for in-page bookmarks and fixed navbar */ +section { + padding-top: 30px; +} +section > .page-header, +section > .lead { + color: #5a5a5a; +} +section > ul li { + margin-bottom: 5px; +} + +/* Separators (hr) */ +.bs-docs-separator { + margin: 40px 0 39px; +} + +/* Faded out hr */ +hr.soften { + height: 1px; + margin: 70px 0; + background-image: -webkit-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); + background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); + background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); + background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,.1), rgba(0,0,0,0)); + border: 0; +} + + + +/* Jumbotrons +-------------------------------------------------- */ + +/* Base class +------------------------- */ +.jumbotron { + position: relative; + padding: 40px 0; + color: #fff; + text-align: center; + text-shadow: 0 1px 3px rgba(0,0,0,.4), 0 0 30px rgba(0,0,0,.075); + background: #020031; /* Old browsers */ + background: -moz-linear-gradient(45deg, #020031 0%, #6d3353 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left bottom, right top, color-stop(0%,#020031), color-stop(100%,#6d3353)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(45deg, #020031 0%,#6d3353 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(45deg, #020031 0%,#6d3353 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(45deg, #020031 0%,#6d3353 100%); /* IE10+ */ + background: linear-gradient(45deg, #020031 0%,#6d3353 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#020031', endColorstr='#6d3353',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */ + -webkit-box-shadow: inset 0 3px 7px rgba(0,0,0,.2), inset 0 -3px 7px rgba(0,0,0,.2); + -moz-box-shadow: inset 0 3px 7px rgba(0,0,0,.2), inset 0 -3px 7px rgba(0,0,0,.2); + box-shadow: inset 0 3px 7px rgba(0,0,0,.2), inset 0 -3px 7px rgba(0,0,0,.2); +} +.jumbotron h1 { + font-size: 80px; + font-weight: bold; + letter-spacing: -1px; + line-height: 1; +} +.jumbotron p { + font-size: 24px; + font-weight: 300; + line-height: 30px; + margin-bottom: 30px; +} + +/* Link styles (used on .masthead-links as well) */ +.jumbotron a { + color: #fff; + color: rgba(255,255,255,.5); + -webkit-transition: all .2s ease-in-out; + -moz-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.jumbotron a:hover { + color: #fff; + text-shadow: 0 0 10px rgba(255,255,255,.25); +} + +/* Download button */ +.masthead .btn { + padding: 14px 24px; + font-size: 24px; + font-weight: 200; + color: #fff; /* redeclare to override the `.jumbotron a` */ + border: 0; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + -webkit-transition: none; + -moz-transition: none; + transition: none; +} +.masthead .btn:hover { + -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); + box-shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 5px rgba(0,0,0,.25); +} +.masthead .btn:active { + -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.1); + -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.1); + box-shadow: inset 0 2px 4px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.1); +} + + +/* Pattern overlay +------------------------- */ +.jumbotron .container { + position: relative; + z-index: 2; +} +.jumbotron:after { + content: ''; + display: block; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: url(../img/bs-docs-masthead-pattern.png) repeat center center; + opacity: .4; +} + +/* Masthead (docs home) +------------------------- */ +.masthead { + padding: 70px 0 80px; + margin-bottom: 0; + color: #fff; +} +.masthead h1 { + font-size: 120px; + line-height: 1; + letter-spacing: -2px; +} +.masthead p { + font-size: 40px; + font-weight: 200; + line-height: 1.25; +} + +/* Textual links in masthead */ +.masthead-links { + margin: 0; + list-style: none; +} +.masthead-links li { + display: inline; + padding: 0 10px; + color: rgba(255,255,255,.25); +} + +/* Social proof buttons from GitHub & Twitter */ +.bs-docs-social { + padding: 15px 0; + text-align: center; + background-color: #f5f5f5; + border-top: 1px solid #fff; + border-bottom: 1px solid #ddd; +} + +/* Quick links on Home */ +.bs-docs-social-buttons { + margin-left: 0; + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.bs-docs-social-buttons li { + display: inline-block; + padding: 5px 8px; + line-height: 1; + *display: inline; + *zoom: 1; +} + +/* Subhead (other pages) +------------------------- */ +.subhead { + text-align: left; + border-bottom: 1px solid #ddd; +} +.subhead h1 { + font-size: 60px; +} +.subhead p { + margin-bottom: 20px; +} +.subhead .navbar { + display: none; +} + + + +/* Marketing section of Overview +-------------------------------------------------- */ + +.marketing { + text-align: center; + color: #5a5a5a; +} +.marketing h1 { + margin: 60px 0 10px; + font-size: 60px; + font-weight: 200; + line-height: 1; + letter-spacing: -1px; +} +.marketing h2 { + font-weight: 200; + margin-bottom: 5px; +} +.marketing p { + font-size: 16px; + line-height: 1.5; +} +.marketing .marketing-byline { + margin-bottom: 40px; + font-size: 20px; + font-weight: 300; + line-height: 25px; + color: #999; +} +.marketing img { + display: block; + margin: 0 auto 30px; +} + + + +/* Footer +-------------------------------------------------- */ + +.footer { + padding: 70px 0; + margin-top: 70px; + border-top: 1px solid #e5e5e5; + background-color: #f5f5f5; +} +.footer p { + margin-bottom: 0; + color: #777; +} +.footer-links { + margin: 10px 0; +} +.footer-links li { + display: inline; + margin-right: 10px; +} + + + +/* Special grid styles +-------------------------------------------------- */ + +.show-grid { + margin-top: 10px; + margin-bottom: 20px; +} +.show-grid [class*="span"] { + background-color: #eee; + text-align: center; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + min-height: 40px; + line-height: 40px; +} +.show-grid:hover [class*="span"] { + background: #ddd; +} +.show-grid .show-grid { + margin-top: 0; + margin-bottom: 0; +} +.show-grid .show-grid [class*="span"] { + background-color: #ccc; +} + + + +/* Mini layout previews +-------------------------------------------------- */ +.mini-layout { + border: 1px solid #ddd; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.075); + -moz-box-shadow: 0 1px 2px rgba(0,0,0,.075); + box-shadow: 0 1px 2px rgba(0,0,0,.075); +} +.mini-layout, +.mini-layout .mini-layout-body, +.mini-layout.fluid .mini-layout-sidebar { + height: 300px; +} +.mini-layout { + margin-bottom: 20px; + padding: 9px; +} +.mini-layout div { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.mini-layout .mini-layout-body { + background-color: #dceaf4; + margin: 0 auto; + width: 70%; +} +.mini-layout.fluid .mini-layout-sidebar, +.mini-layout.fluid .mini-layout-header, +.mini-layout.fluid .mini-layout-body { + float: left; +} +.mini-layout.fluid .mini-layout-sidebar { + background-color: #bbd8e9; + width: 20%; +} +.mini-layout.fluid .mini-layout-body { + width: 77.5%; + margin-left: 2.5%; +} + + + +/* Download page +-------------------------------------------------- */ + +.download .page-header { + margin-top: 36px; +} +.page-header .toggle-all { + margin-top: 5px; +} + +/* Space out h3s when following a section */ +.download h3 { + margin-bottom: 5px; +} +.download-builder input + h3, +.download-builder .checkbox + h3 { + margin-top: 9px; +} + +/* Fields for variables */ +.download-builder input[type=text] { + margin-bottom: 9px; + font-family: Menlo, Monaco, "Courier New", monospace; + font-size: 12px; + color: #d14; +} +.download-builder input[type=text]:focus { + background-color: #fff; +} + +/* Custom, larger checkbox labels */ +.download .checkbox { + padding: 6px 10px 6px 25px; + font-size: 13px; + line-height: 18px; + color: #555; + background-color: #f9f9f9; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + cursor: pointer; +} +.download .checkbox:hover { + color: #333; + background-color: #f5f5f5; +} +.download .checkbox small { + font-size: 12px; + color: #777; +} + +/* Variables section */ +#variables label { + margin-bottom: 0; +} + +/* Giant download button */ +.download-btn { + margin: 36px 0 108px; +} +#download p, +#download h4 { + max-width: 50%; + margin: 0 auto; + color: #999; + text-align: center; +} +#download h4 { + margin-bottom: 0; +} +#download p { + margin-bottom: 18px; +} +.download-btn .btn { + display: block; + width: auto; + padding: 19px 24px; + margin-bottom: 27px; + font-size: 30px; + line-height: 1; + text-align: center; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + + + +/* Misc +-------------------------------------------------- */ + +/* Make tables spaced out a bit more */ +h2 + table, +h3 + table, +h4 + table, +h2 + .row { + margin-top: 5px; +} + +/* Example sites showcase */ +.example-sites { + xmargin-left: 20px; +} +.example-sites img { + max-width: 100%; + margin: 0 auto; +} + +.scrollspy-example { + height: 200px; + overflow: auto; + position: relative; +} + + +/* Fake the :focus state to demo it */ +.focused { + border-color: rgba(82,168,236,.8); + -webkit-box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); + -moz-box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); + box-shadow: inset 0 1px 3px rgba(0,0,0,.1), 0 0 8px rgba(82,168,236,.6); + outline: 0; +} + +/* For input sizes, make them display block */ +.docs-input-sizes select, +.docs-input-sizes input[type=text] { + display: block; + margin-bottom: 9px; +} + +/* Icons +------------------------- */ +.the-icons { + margin-left: 0; + list-style: none; +} +.the-icons li { + float: left; + width: 25%; + line-height: 25px; +} +.the-icons i:hover { + background-color: rgba(255,0,0,.25); +} + +/* Example page +------------------------- */ +.bootstrap-examples p { + font-size: 13px; + line-height: 18px; +} +.bootstrap-examples .thumbnail { + margin-bottom: 9px; + background-color: #fff; +} + + + +/* Bootstrap code examples +-------------------------------------------------- */ + +/* Base class */ +.bs-docs-example { + position: relative; + margin: 15px 0; + padding: 39px 19px 14px; + *padding-top: 19px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +/* Echo out a label for the example */ +.bs-docs-example:after { + content: "Example"; + position: absolute; + top: -1px; + left: -1px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + background-color: #f5f5f5; + border: 1px solid #ddd; + color: #9da0a4; + -webkit-border-radius: 4px 0 4px 0; + -moz-border-radius: 4px 0 4px 0; + border-radius: 4px 0 4px 0; +} + +/* Remove spacing between an example and it's code */ +.bs-docs-example + .prettyprint { + margin-top: -20px; + padding-top: 15px; +} + +/* Tweak examples +------------------------- */ +.bs-docs-example > p:last-child { + margin-bottom: 0; +} +.bs-docs-example .table, +.bs-docs-example .progress, +.bs-docs-example .well, +.bs-docs-example .alert, +.bs-docs-example .hero-unit, +.bs-docs-example .pagination, +.bs-docs-example .navbar, +.bs-docs-example > .nav, +.bs-docs-example blockquote { + margin-bottom: 5px; +} +.bs-docs-example .pagination { + margin-top: 0; +} +.bs-navbar-top-example, +.bs-navbar-bottom-example { + z-index: 1; + padding: 0; + height: 90px; + overflow: hidden; /* cut the drop shadows off */ +} +.bs-navbar-top-example .navbar-fixed-top, +.bs-navbar-bottom-example .navbar-fixed-bottom { + margin-left: 0; + margin-right: 0; +} +.bs-navbar-top-example { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} +.bs-navbar-top-example:after { + top: auto; + bottom: -1px; + -webkit-border-radius: 0 4px 0 4px; + -moz-border-radius: 0 4px 0 4px; + border-radius: 0 4px 0 4px; +} +.bs-navbar-bottom-example { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} +.bs-navbar-bottom-example .navbar { + margin-bottom: 0; +} +form.bs-docs-example { + padding-bottom: 19px; +} + +/* Images */ +.bs-docs-example-images img { + margin: 10px; + display: inline-block; +} + +/* Tooltips */ +.bs-docs-tooltip-examples { + text-align: center; + margin: 0 0 10px; + list-style: none; +} +.bs-docs-tooltip-examples li { + display: inline; + padding: 0 10px; +} + +/* Popovers */ +.bs-docs-example-popover { + padding-bottom: 24px; + background-color: #f9f9f9; +} +.bs-docs-example-popover .popover { + position: relative; + display: block; + float: left; + width: 260px; + margin: 20px; +} + + + +/* Responsive docs +-------------------------------------------------- */ + +/* Utility classes table +------------------------- */ +.responsive-utilities th small { + display: block; + font-weight: normal; + color: #999; +} +.responsive-utilities tbody th { + font-weight: normal; +} +.responsive-utilities td { + text-align: center; +} +.responsive-utilities td.is-visible { + color: #468847; + background-color: #dff0d8 !important; +} +.responsive-utilities td.is-hidden { + color: #ccc; + background-color: #f9f9f9 !important; +} + +/* Responsive tests +------------------------- */ +.responsive-utilities-test { + margin-top: 5px; + margin-left: 0; + list-style: none; + overflow: hidden; /* clear floats */ +} +.responsive-utilities-test li { + position: relative; + float: left; + width: 25%; + height: 43px; + font-size: 14px; + font-weight: bold; + line-height: 43px; + color: #999; + text-align: center; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.responsive-utilities-test li + li { + margin-left: 10px; +} +.responsive-utilities-test span { + position: absolute; + top: -1px; + left: -1px; + right: -1px; + bottom: -1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.responsive-utilities-test span { + color: #468847; + background-color: #dff0d8; + border: 1px solid #d6e9c6; +} + + + +/* Sidenav for Docs +-------------------------------------------------- */ + +.bs-docs-sidenav { + width: 228px; + margin: 30px 0 0; + padding: 0; + background-color: #fff; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 1px 4px rgba(0,0,0,.065); + -moz-box-shadow: 0 1px 4px rgba(0,0,0,.065); + box-shadow: 0 1px 4px rgba(0,0,0,.065); +} +.bs-docs-sidenav > li > a { + display: block; + *width: 190px; + margin: 0 0 -1px; + padding: 8px 14px; + border: 1px solid #e5e5e5; +} +.bs-docs-sidenav > li:first-child > a { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} +.bs-docs-sidenav > li:last-child > a { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} +.bs-docs-sidenav > .active > a { + position: relative; + z-index: 2; + padding: 9px 15px; + border: 0; + text-shadow: 0 1px 0 rgba(0,0,0,.15); + -webkit-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); + -moz-box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); + box-shadow: inset 1px 0 0 rgba(0,0,0,.1), inset -1px 0 0 rgba(0,0,0,.1); +} +/* Chevrons */ +.bs-docs-sidenav .icon-chevron-right { + float: right; + margin-top: 2px; + margin-right: -6px; + opacity: .25; +} +.bs-docs-sidenav > li > a:hover { + background-color: #f5f5f5; +} +.bs-docs-sidenav a:hover .icon-chevron-right { + opacity: .5; +} +.bs-docs-sidenav .active .icon-chevron-right, +.bs-docs-sidenav .active a:hover .icon-chevron-right { + background-image: url(../img/glyphicons-halflings-white.png); + opacity: 1; +} +.bs-docs-sidenav.affix { + top: 40px; +} +.bs-docs-sidenav.affix-bottom { + position: absolute; + top: auto; + bottom: 270px; +} + + + + +/* Responsive +-------------------------------------------------- */ + +/* Desktop large +------------------------- */ +@media (min-width: 1200px) { + .bs-docs-container { + max-width: 970px; + } + .bs-docs-sidenav { + width: 258px; + } +} + +/* Desktop +------------------------- */ +@media (max-width: 980px) { + /* Unfloat brand */ + body > .navbar-fixed-top .brand { + float: left; + margin-left: 0; + padding-left: 10px; + padding-right: 10px; + } + + /* Inline-block quick links for more spacing */ + .quick-links li { + display: inline-block; + margin: 5px; + } + + /* When affixed, space properly */ + .bs-docs-sidenav { + top: 0; + margin-top: 30px; + margin-right: 0; + } +} + +/* Tablet to desktop +------------------------- */ +@media (min-width: 768px) and (max-width: 980px) { + /* Remove any padding from the body */ + body { + padding-top: 0; + } + /* Widen masthead and social buttons to fill body padding */ + .jumbotron { + margin-top: -20px; /* Offset bottom margin on .navbar */ + } + /* Adjust sidenav width */ + .bs-docs-sidenav { + width: 166px; + margin-top: 20px; + } + .bs-docs-sidenav.affix { + top: 0; + } +} + +/* Tablet +------------------------- */ +@media (max-width: 767px) { + /* Remove any padding from the body */ + body { + padding-top: 0; + } + + /* Widen masthead and social buttons to fill body padding */ + .jumbotron { + padding: 40px 20px; + margin-top: -20px; /* Offset bottom margin on .navbar */ + margin-right: -20px; + margin-left: -20px; + } + .masthead h1 { + font-size: 90px; + } + .masthead p, + .masthead .btn { + font-size: 24px; + } + .marketing .span4 { + margin-bottom: 40px; + } + .bs-docs-social { + margin: 0 -20px; + } + + /* Space out the show-grid examples */ + .show-grid [class*="span"] { + margin-bottom: 5px; + } + + /* Sidenav */ + .bs-docs-sidenav { + width: auto; + margin-bottom: 20px; + } + .bs-docs-sidenav.affix { + position: static; + width: auto; + top: 0; + } + + /* Unfloat the back to top link in footer */ + .footer { + margin-left: -20px; + margin-right: -20px; + padding-left: 20px; + padding-right: 20px; + } + .footer p { + margin-bottom: 9px; + } +} + +/* Landscape phones +------------------------- */ +@media (max-width: 480px) { + /* Remove padding above jumbotron */ + body { + padding-top: 0; + } + + /* Change up some type stuff */ + h2 small { + display: block; + } + + /* Downsize the jumbotrons */ + .jumbotron h1 { + font-size: 60px; + } + .jumbotron p, + .jumbotron .btn { + font-size: 20px; + } + .jumbotron .btn { + display: block; + margin: 0 auto; + } + + /* center align subhead text like the masthead */ + .subhead h1, + .subhead p { + text-align: center; + } + + /* Marketing on home */ + .marketing h1 { + font-size: 40px; + } + + /* center example sites */ + .example-sites { + margin-left: 0; + } + .example-sites > li { + float: none; + display: block; + max-width: 280px; + margin: 0 auto 18px; + text-align: center; + } + .example-sites .thumbnail > img { + max-width: 270px; + } + + /* Do our best to make tables work in narrow viewports */ + table code { + white-space: normal; + word-wrap: break-word; + word-break: break-all; + } + + /* Modal example */ + .modal-example .modal { + position: relative; + top: auto; + right: auto; + bottom: auto; + left: auto; + } + + /* Unfloat the back to top in footer to prevent odd text wrapping */ + .footer .pull-right { + float: none; + } +} diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index 85c63b3f..b415daee 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -1,91 +1,199 @@ + + GeneNetwork + + -
        +
        +

        Gene Network

        +

        Open Source Bioinformatics Website For Systems Genetics

        +
        -
        -

        Gene Network

        -
        -
        -
        -
        - Select and Search - - - -
        - - - - - + +
        +
        + + +
        +
        + + +
        + + + + +
        + + + + +
        + + + + + + +
        + + +
        + + + + + + + + - - + + -
        - - + + +

        Enter terms, genes, ID numbers in the + Search field.
        + Use * or ? wildcards (Cyp*a?, + synap*).
        + Use quotes for terms such as "tyrosine + kinase".

        + + + + + + + + + + + +
        + +
        + +
        + - +
          +
        1. Select Species (or select All)
        2. + +
        3. Select Group (a specific sample)
        4. - - - - +
        5. Select Type of data: - +
            +
          • Phenotype (traits)
          • - +
          • Genotype (markers)
          • - +
          • Expression (mRNAs)
          • +
          +
        6. - +
        7. Select a Database
        8. -

          Enter terms, genes, ID numbers in the - Search field.
          - Use * or ? wildcards (Cyp*a?, - synap*).
          - Use quotes for terms such as "tyrosine - kinase".

          +
        9. Enter terms in the search field: words, + genes, ID numbers, probes, advanced search commands
        10. - +
        11. Click on the Search button
        12. +
        13. Optional: Use the Make Default button to save your preferences
        14. +
        - +

        For more information, read our User's Guide.

        - +
        - - -
        - +
        + + +

        You can also do more advanced + searches. Copy these examples + into the search field:

        + +
          +
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on + chromosome 1 between 25 and 30 Mb.
        • + +
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds + highly expressed genes (15 to 16 log2 units) AND with peak LRS + linkage between 23 and 46.
        • + +
        • RIF=mitochondrial searches RNA databases for + GeneRIF links.
        • + +
        • WIKI=nicotine searches + GeneWiki for genes that you or other users have annotated + with the word nicotine.
        • + +
        • GO:0045202 searches for synapse-associated genes listed in the + + Gene Ontology + .
        • + +
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10) + finds synapse-associated genes with + cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores + between 9 and 999.
        • + +
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10) + finds diabetes-associated transcripts with peak + trans eQTLs on Chr 2 between 100 and 105 Mb with LRS + scores between 9 and 999.
        • +
        +
        + +
        - - - + + + + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 7210a1de..94768c9f 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -7,7 +7,7 @@ import flask from wqflask import app -from flask import render_template, request +from flask import render_template, request, make_response, Response from wqflask import search_results from wqflask.show_trait import show_trait @@ -87,11 +87,37 @@ def show_trait_page(): print("show_trait template_vars:", pf(template_vars.__dict__)) return render_template("show_trait.html", **template_vars.__dict__) + +@app.route('/export_trait_csv', methods=('POST',)) +def export_trait_csv(): + """CSV file consisting of the sample data from the trait data and analysis page""" + print("In export_trait_csv") + print("request.form:", request.form) + sample_data = export_trait_data.export_sample_table(request.form) + + print("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) + + def generate(sample_data): + for row in sample_data: + print(','.join(row) + '\n') + yield ','.join(row) + '\n' + + print("generated data:", pf(generate(sample_data))) + + #print(pf(Response(generate(sample_data), + # mimetype='text/plain', + # headers={"Content-Disposition": + # "attachment;filename=test.csv"}))) + + return Response(generate(sample_data), + mimetype='text/csv', + headers={"Content-Disposition":"attachment;filename=test.csv"}) + + @app.route("/export_trait_data", methods=('POST',)) def export_sample_table(): """CSV file consisting of the sample data from the trait data and analysis page""" print("In export_sample_table") - print("request.args:", request.args) print("request.form:", request.form) template_vars = export_trait_data.export_sample_table(request.form) -- cgit v1.2.3 From d78728ce6c5290be5905066e674679d5997f2dcc Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 12 Oct 2012 17:29:54 -0500 Subject: Changed export code to use csv module --- wqflask/wqflask/views.py | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 94768c9f..693b863a 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -1,5 +1,8 @@ from __future__ import absolute_import, division, print_function +import csv +import StringIO # Todo: Use cStringIO? + import simplejson as json import yaml @@ -97,29 +100,24 @@ def export_trait_csv(): print("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) - def generate(sample_data): - for row in sample_data: - print(','.join(row) + '\n') - yield ','.join(row) + '\n' - - print("generated data:", pf(generate(sample_data))) - - #print(pf(Response(generate(sample_data), - # mimetype='text/plain', - # headers={"Content-Disposition": - # "attachment;filename=test.csv"}))) + buff = StringIO.StringIO() + writer = csv.writer(buff) + for row in sample_data: + writer.writerow(row) + csv_data = buff.getvalue() + buff.close() - return Response(generate(sample_data), + return Response(csv_data, mimetype='text/csv', headers={"Content-Disposition":"attachment;filename=test.csv"}) -@app.route("/export_trait_data", methods=('POST',)) -def export_sample_table(): - """CSV file consisting of the sample data from the trait data and analysis page""" - print("In export_sample_table") - print("request.form:", request.form) - template_vars = export_trait_data.export_sample_table(request.form) +#@app.route("/export_trait_data", methods=('POST',)) +#def export_sample_table(): +# """CSV file consisting of the sample data from the trait data and analysis page""" +# print("In export_sample_table") +# print("request.form:", request.form) +# template_vars = export_trait_data.export_sample_table(request.form) @app.route("/corr_compute", methods=('POST',)) -- cgit v1.2.3 From 3edf991dbb54472f5b594c79f54b7c8e86c84829 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 12 Oct 2012 19:10:43 -0500 Subject: Continued work on new_index_page --- wqflask/wqflask/templates/new_index_page.html | 174 +++++++++++++++++++++++--- 1 file changed, 156 insertions(+), 18 deletions(-) diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index b415daee..ab9e188b 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -13,7 +13,8 @@

        Gene Network

        -

        Open Source Bioinformatics Website For Systems Genetics

        +

        Open source bioinformatics for systems genetics
        + Brought to you by the University of Tennessee

        @@ -22,18 +23,17 @@
        @@ -81,11 +81,11 @@

        Enter terms, genes, ID numbers in the - Search field.
        + Search field
        Use * or ? wildcards (Cyp*a?, - synap*).
        + synap*)
        Use quotes for terms such as "tyrosine - kinase".

        + kinase"

        @@ -109,7 +109,7 @@
          @@ -138,19 +138,21 @@
        1. Optional: Use the Make Default button to save your preferences
        -

        For more information, read our User's Guide.

        +

        For more information, read our + + user guide.

        -

        You can also do more advanced - searches. Copy these examples - into the search field:

        +

        GeneNetwork supports a variety of advanced searches.

        + +

        To try them out copy these examples into the search field:

        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on @@ -172,8 +174,7 @@
        • GO:0045202 searches for synapse-associated genes listed in the - Gene Ontology - .
        • + Gene Ontology.
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10) finds synapse-associated genes with
        +
        + + +

        Thirty minute tour

        +

        + Take the 30 minute + GeneNetwork tour that includes screen shots and + typical steps in the analysis. +

        + +

        Even more info

        +

        + For information about + resources and methods, select the Info buttons next to the Group + and Database fields above. +

        + +

        The conditions + and contact + pages have information on the status of data sets + and advice on their use and citation.

        + +
        + +
        + +

        Websites affiliated with GeneNetwork

        + +

        Mirror and development sites

        + +

        History and archive

        + +

        The + + time machine + has earlier versions that correspond to specific publication dates. +

        + +

        The next generation

        +

        Try the + development site to explore exerimental data and features.

        +
        + + + -- cgit v1.2.3 From dc191dfac1c198610e3991c66516643a158a5d31 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 12 Oct 2012 20:47:06 -0500 Subject: New home page beginning to look good --- wqflask/wqflask/templates/new_index_page.html | 143 ++++++++++++++++++++------ 1 file changed, 111 insertions(+), 32 deletions(-) diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index ab9e188b..3d6d3f3f 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -1,37 +1,87 @@ - + GeneNetwork + + + - - + + + + + - -
        -

        Gene Network

        -

        Open source bioinformatics for systems genetics
        - Brought to you by the University of Tennessee

        + + + +
        +
        +

        GeneNetwork

        +

        Open source bioinformatics for systems genetics
        + Brought to you by the University of Tennessee

        +
        +
        +
        -
        +
        - + @@ -80,7 +130,7 @@ -

        Enter terms, genes, ID numbers in the +

        Enter terms, genes, ID numbers in the Search field
        Use * or ? wildcards (Cyp*a?, synap*)
        @@ -107,13 +157,13 @@ -

        +
          -
        1. Select Species (or select All)
        2. +
        3. Select Species (or All)
        4. Select Group (a specific sample)
        5. @@ -133,19 +183,20 @@
        6. Enter terms in the search field: words, genes, ID numbers, probes, advanced search commands
        7. -
        8. Click on the Search button
        9. +
        10. Click the Search button
        11. Optional: Use the Make Default button to save your preferences
        -

        For more information, read our +

        User Guide

        +
        Read the - user guide.
        + user guide.
        -
        +
        @@ -190,9 +241,9 @@
        -
        +

        Thirty minute tour

        @@ -218,7 +269,7 @@
        -
        +
        @@ -277,7 +328,7 @@

        The next generation

        Try the - development site to explore exerimental data and features.

        + development site to explore experimental data and features.

        @@ -289,7 +340,10 @@

        Back to top

        -

        Launched in 1994 as The Portable Dictionary of the Mouse Genome and 2001 as WebQTL.

        +

        Launched in 1994 as + + The Portable Dictionary of the Mouse Genome and in 2001 as WebQTL. +

        Operated by Rob Williams, Lei Yan, @@ -310,18 +364,30 @@

        Special thanks to CYP1A2 and AHR.


        -

        GeneNetwork support from: +

        GeneNetwork is supported by:

        -

        +
        + + + + -- cgit v1.2.3 From 79105a574b68c837ca3ab0343250da3da600a544 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 17 Oct 2012 17:05:51 -0500 Subject: Fixed bug in an SQL query, changed search field id from "ORkeyword" to "search_terms" --- wqflask/wqflask/parser.py | 15 +++++----- wqflask/wqflask/search_results.py | 33 ++++++++++++++-------- wqflask/wqflask/show_trait/export_trait_data.py | 12 ++------ .../static/new/javascript/show_trait.coffee | 24 +++++++--------- .../wqflask/static/new/javascript/show_trait.js | 9 ++++-- wqflask/wqflask/templates/index_page.html | 2 +- wqflask/wqflask/templates/new_index_page.html | 2 +- wqflask/wqflask/templates/show_trait.html | 25 ++++++++++------ wqflask/wqflask/views.py | 31 +++++++++++++------- 9 files changed, 87 insertions(+), 66 deletions(-) diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 67325b56..e34992a0 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -36,10 +36,11 @@ def parse(pstring): print(pf(items)) return(items) -parse("foo=(3 2 1)") -parse("shh") -parse("shh grep") -parse("LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)") -parse("sal1 LRS=(9 99 Chr4 122 155) sal2 cisLRS=(9 999 10)") -parse("sal1 sal3 LRS=(9 99 Chr4 122 155) wiki=bar sal2 go:foobar cisLRS=(9 999 10)") -parse("sal1 LRS=(9 99 Chr4 122 155) wiki=bar sal2 go:foobar cisLRS=(9, 999, 10)") \ No newline at end of file +if __name__ == '__main__': + parse("foo=(3 2 1)") + parse("shh") + parse("shh grep") + parse("LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)") + parse("sal1 LRS=(9 99 Chr4 122 155) sal2 cisLRS=(9 999 10)") + parse("sal1 sal3 LRS=(9 99 Chr4 122 155) wiki=bar sal2 go:foobar cisLRS=(9 999 10)") + parse("sal1 LRS=(9 99 Chr4 122 155) wiki=bar sal2 go:foobar cisLRS=(9, 999, 10)") \ No newline at end of file diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 4cca6492..585deb8f 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -60,6 +60,7 @@ class SearchResultPage(templatePage): nkeywords = 0 def __init__(self, fd): + self.fd = fd if not self.openMysql(): return @@ -98,9 +99,15 @@ class SearchResultPage(templatePage): #userExist = None for individualDB in self.database: - self.cursor.execute('''SELECT Id, Name, FullName, confidentiality, - AuthorisedUsers FROM %sFreeze WHERE Name = %s''', ( - self.database[0].type, individualDB)) + # Can't use paramater substitution for table names apparently + db_type = self.database[0].type + "Freeze" + print("db_type [%s]: %s" % (type(db_type), db_type)) + + query = '''SELECT Id, Name, FullName, confidentiality, + AuthorisedUsers FROM %s WHERE Name = %%s''' % (db_type) + + self.cursor.execute(query, (individualDB,)) + (indId, indName, indFullName, @@ -175,6 +182,8 @@ class SearchResultPage(templatePage): 'RefSeq_TranscriptId'] elif self.dbType == "Geno": self.searchField = ['Name','Chr'] + + self.do_search() ########################################### # Search Options @@ -545,7 +554,6 @@ class SearchResultPage(templatePage): _log.info("Done executing queries") - #searchCountQuery retrieve all the results, for counting use only if searchCountQuery != searchQuery: for item in searchQuery: @@ -558,7 +566,6 @@ class SearchResultPage(templatePage): return nresults - def assembleQuery(self): self.query = [] if self.ANDQuery or self.ORQuery: @@ -635,13 +642,15 @@ class SearchResultPage(templatePage): return 0 + def do_search(self): + print("fd.search_terms:", self.fd['search_terms']) + self.search_terms = parser.parse(self.fd['search_terms']) + print("After parsing:", self.search_terms) + #print("ORkeyword is:", pf(self.ORkeyword)) + #self.ANDkeyword2 = parser.parse(self.ANDkeyword) + #self.ORkeyword2 = parser.parse(self.ORkeyword) + #print("ORkeyword2 is:", pf(parser.parse(self.ORkeyword))) - def normalSearch(self): - print("ORkeyword is:", pf(self.ORkeyword)) - self.ANDkeyword2 = parser.parse(self.ANDkeyword) - self.ORkeyword2 = parser.parse(self.ORkeyword) - print("ORkeyword2 is:", pf(parser.parse(self.ORkeyword))) - #self.ANDkeyword2 = re.sub(self._1mPattern, '', self.ANDkeyword) #self.ANDkeyword2 = re.sub(self._2mPattern, '', self.ANDkeyword2) #self.ANDkeyword2 = re.sub(self._3mPattern, '', self.ANDkeyword2) @@ -649,7 +658,7 @@ class SearchResultPage(templatePage): ###remove remain parethesis, could be input with syntax error #self.ANDkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ANDkeyword2) #self.ANDkeyword2 = self.encregexp(self.ANDkeyword2) - # + #self.ORkeyword2 = re.sub(self._1mPattern, '', self.ORkeyword) #self.ORkeyword2 = re.sub(self._2mPattern, '', self.ORkeyword2) #self.ORkeyword2 = re.sub(self._3mPattern, '', self.ORkeyword2) diff --git a/wqflask/wqflask/show_trait/export_trait_data.py b/wqflask/wqflask/show_trait/export_trait_data.py index e5f2035d..f7f2d6d4 100644 --- a/wqflask/wqflask/show_trait/export_trait_data.py +++ b/wqflask/wqflask/show_trait/export_trait_data.py @@ -4,21 +4,13 @@ import operator import simplejson as json -#import xlwt from pprint import pformat as pf def export_sample_table(targs): - #print("* keys0 args is:", targs[0].keys()) - - - #test_export_file = open("/home/zas1024/gene/wqflask/wqflask/show_trait/export_test.txt", "w") - # - #for key, item in targs.iteritems(): - # print("[arrow] key is:", key) - + sample_data = json.loads(targs['export_data']) final_sample_data = [] - + for sample_group in ['primary_samples', 'other_samples']: for row in sample_data[sample_group]: sorted_row = dict_to_sorted_list(row) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index c7dc7c88..b1cca461 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -295,6 +295,10 @@ $ -> samples.other_samples = other_samples return samples + ##End Get Sample Data from Table Code + + ##Export Sample Table Data Code + export_sample_table_data = -> sample_data = get_sample_table_data() console.log("sample_data is:", sample_data) @@ -302,27 +306,19 @@ $ -> console.log("json_sample_data is:", json_sample_data) $('input[name=export_data]').val(json_sample_data) - console.log("export_data is", $('input[name=export_data]').val()) - $('#trait_data_form').attr('action', '/export_trait_csv') + format = $('#export_format').val() + if format == "excel" + $('#trait_data_form').attr('action', '/export_trait_excel') + else + $('#trait_data_form').attr('action', '/export_trait_csv') console.log("action is:", $('#trait_data_form').attr('action')) + $('#trait_data_form').submit() - - #$.ajax( - # url: '/export_trait_csv' - # type: 'POST' - # data: "json_data=" + json_sample_data - #) $('#export').click(export_sample_table_data) - - - ##End Get Sample Data from Table Code - - ##Export Sample Table Data Code - ##End Export Sample Table Data Code diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 5729eb22..5aadedef 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -334,14 +334,19 @@ return samples; }; export_sample_table_data = function() { - var json_sample_data, sample_data; + var format, json_sample_data, sample_data; sample_data = get_sample_table_data(); console.log("sample_data is:", sample_data); json_sample_data = JSON.stringify(sample_data); console.log("json_sample_data is:", json_sample_data); $('input[name=export_data]').val(json_sample_data); console.log("export_data is", $('input[name=export_data]').val()); - $('#trait_data_form').attr('action', '/export_trait_csv'); + format = $('#export_format').val(); + if (format === "excel") { + $('#trait_data_form').attr('action', '/export_trait_excel'); + } else { + $('#trait_data_form').attr('action', '/export_trait_csv'); + } console.log("action is:", $('#trait_data_form').attr('action')); return $('#trait_data_form').submit(); }; diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index a209f302..db0b2d9e 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -96,7 +96,7 @@
        diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index 3d6d3f3f..f2178f3c 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -125,7 +125,7 @@ diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 1e1d8b8f..d48f9487 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -1253,10 +1253,18 @@ {% endif %}
        - - - - +
        + + + + + + + +

        @@ -1272,17 +1280,16 @@

        - - - - + + +
        {% for sample_type in sample_groups %}

        {{ sample_type.header }}

        -
        - Get Any: + Search: @@ -115,7 +117,9 @@ - +
        -

            Enter terms, genes, ID numbers in the Get Any field. +

            Enter terms, genes, ID numbers in the Search field.
            Use * or ? wildcards (Cyp*a?, synap*). -
            Use Combined for terms such as tyrosine kinase.

        +
            Use quotes for terms such as "tyrosine kinase".

        - Combined: - - - - -
        -      -      - +      +      +

        Select and Search - @@ -173,7 +173,7 @@ -

         ______________________________________________________ +

         ______________________________________________________

          -- cgit v1.2.3 From 2b3aaf9b9da45d6a4c4bb461edb4a2d4247ed8ea Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 9 Oct 2012 17:49:46 -0500 Subject: Used tidyp to improve/beautify index_page.html --- misc/notes.txt | 5 + wqflask/wqflask/templates/index_page.html | 548 +++++++++++++++--------------- 2 files changed, 288 insertions(+), 265 deletions(-) diff --git a/misc/notes.txt b/misc/notes.txt index 76962804..fab9fac6 100644 --- a/misc/notes.txt +++ b/misc/notes.txt @@ -55,5 +55,10 @@ htop: Gives information on processes, cpu/memory load, etc dstat: Also gives various system information, resource usage, etc df: Reports file system disk space usage +=========================================== + +tidyp - Improves/beautifies html code +tidyp -m -i -w 100 index_page.html + diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index d3839c09..a209f302 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -1,302 +1,320 @@ {% extends "base.html" %} {% block title %}GeneNetwork{% endblock %} -{% block content %} - -

        - - - - + - +
      • Switzerland at the EPFL
      • + - - - +

        History and + Archive

        +
        +

        GeneNetwork's Time + Machine links to earlier versions that correspond to specific + publication dates.

        +
        + + +
        -

        Select and Search - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - Species: - - - -
        - Group: - - - -
        - Type: - - - -
        - Database: - - - -
        - - -

            Databases marked with ** suffix are not public yet. -
            Access requires user login.

        -
        - Search: - - - - -
        - - - -

            Enter terms, genes, ID numbers in the Search field. -
            Use * or ? wildcards (Cyp*a?, synap*). -
            Use quotes for terms such as "tyrosine kinase".

        - -
        - - -      -      - - -
        - - - - - - - - - - - - -

         ______________________________________________________ - -

          - -Quick HELP Examples and - - User's Guide

        - - -  You can also use advanced commands. Copy these simple examples -
          into the Get Any or Combined search fields: -
          - -
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on chromosome 1 between 25 and 30 Mb. - -
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46. - +{% block content %} + +
        + + + - +
      • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)
        + in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores + between 9 and 999.
      • - +
      • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
        + in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS + scores between 9 and 999.
      • + + + - +
      • Singapore at the NUS
      • - -
        +

        Select and + Search

        + + -
      • RIF=mitochondrial searches RNA databases for GeneRIF links. +

         ______________________________________________________

        -
      • WIKI=nicotine searches GeneWiki for genes that you or other users have annotated with the word nicotine. +

          Quick HELP + Examples and User's Guide

          You can also use advanced + commands. Copy these simple examples
        +   into the Get Any or Combined search fields: -
      • GO:0045202 searches for synapse-associated genes listed in the Gene Ontology. +
          +
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on + chromosome 1 between 25 and 30 Mb.
        • +
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds + highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46.
        • -
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)
          in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores between 9 and 999. +
        • RIF=mitochondrial searches RNA databases for GeneRIF links.
        • -
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
          in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS scores between 9 and 999. +
        • WIKI=nicotine searches GeneWiki for genes that you or other users have annotated + with the word nicotine.
        • +
        • GO:0045202 searches for synapse-associated genes listed in the + Gene Ontology.
        • -
        - -
      • -

        Websites Affiliated with GeneNetwork

        -

        -

        -

        -

        ____________________________ +

        +

        Websites Affiliated with + GeneNetwork

        -

        Getting Started   

        -
          -
        1. Select Species (or select All) -
        2. Select Group (a specific sample) -
        3. Select Type of data: -
            -
          • Phenotype (traits) -
          • Genotype (markers) -
          • Expression (mRNAs) -
          -
        4. Select a Database -
        5. Enter search terms in the Get Any or Combined field: words, genes, ID numbers, probes, advanced search commands -
        6. Click on the Search button -
        7. Optional: Use the Make Default button to save your preferences -
        +

        -

        ____________________________ +

          +
        • Genome + Browser at UTHSC
        • -

          How to Use GeneNetwork +

        • Galaxy at + UTHSC
        • -
          -

          Take a 20-40 minute GeneNetwork Tour that includes screen shots and typical steps in the analysis.

          -
          -
          -

          For information about resources and methods, select the INFO buttons.

          +
        • GeneNetwork at Amazon + Cloud (EC2)
        • +
        • GeneNetwork Source Codes at SourceForge
        • +
        • GeneNetwork Source Codes at GitHub
        • +
        -

        Try the Workstation site to explore data and features that are being implemented.

        +

        ____________________________

        +

        Getting Started +   

        -

        Review the Conditions and Contacts pages for information on the status of data sets and advice on their use and citation.

        +
          +
        1. Select Species (or select All)
        2. +
        3. Select Group (a specific sample)
        4. - +
        5. Select Type of data: +
            +
          • Phenotype (traits)
          • + +
          • Genotype (markers)
          • + +
          • Expression (mRNAs)
          • +
          +
        6. + +
        7. Select a Database
        8. + +
        9. Enter search terms in the Get Any or Combined field: words, + genes, ID numbers, probes, advanced search commands
        10. + +
        11. Click on the Search button
        12. + +
        13. Optional: Use the Make Default button to save your preferences
        14. +
        + +

        ____________________________

        + +

        How to Use + GeneNetwork

        + +
        +

        Take a 20-40 minute + GeneNetwork Tour that includes screen shots and + typical steps in the analysis.

        +
        + +
        +

        For information about + resources and methods, select the INFO buttons.

        +

        Try the Workstation site to explore data and features that are + being implemented.

        + +

        Review the Conditions + and Contacts pages for information on the status of data sets + and advice on their use and citation.

        +
        -

        Mirror and Development Sites

        +

        Mirror and Development + Sites

        - +
        -
        +
        diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 693b863a..2933b428 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -90,6 +90,25 @@ def show_trait_page(): print("show_trait template_vars:", pf(template_vars.__dict__)) return render_template("show_trait.html", **template_vars.__dict__) +@app.route('/export_trait_csv', methods=('POST',)) +def export_trait_excel(): + """Excel file consisting of the sample data from the trait data and analysis page""" + print("In export_trait_excel") + print("request.form:", request.form) + sample_data = export_trait_data.export_sample_table(request.form) + + print("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) + + buff = StringIO.StringIO() + writer = csv.writer(buff) + for row in sample_data: + writer.writerow(row) + csv_data = buff.getvalue() + buff.close() + + return Response(csv_data, + mimetype='text/csv', + headers={"Content-Disposition":"attachment;filename=test.csv"}) @app.route('/export_trait_csv', methods=('POST',)) def export_trait_csv(): @@ -97,7 +116,7 @@ def export_trait_csv(): print("In export_trait_csv") print("request.form:", request.form) sample_data = export_trait_data.export_sample_table(request.form) - + print("sample_data - type: %s -- size: %s" % (type(sample_data), len(sample_data))) buff = StringIO.StringIO() @@ -106,20 +125,12 @@ def export_trait_csv(): writer.writerow(row) csv_data = buff.getvalue() buff.close() - + return Response(csv_data, mimetype='text/csv', headers={"Content-Disposition":"attachment;filename=test.csv"}) -#@app.route("/export_trait_data", methods=('POST',)) -#def export_sample_table(): -# """CSV file consisting of the sample data from the trait data and analysis page""" -# print("In export_sample_table") -# print("request.form:", request.form) -# template_vars = export_trait_data.export_sample_table(request.form) - - @app.route("/corr_compute", methods=('POST',)) def corr_compute_page(): #print("In corr_compute, request.args is:", pf(request.form)) -- cgit v1.2.3 From c3169069206124ec79c70c18f97290a6672428a3 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 18 Oct 2012 16:16:41 -0500 Subject: Converted selectDatasetMenu.js code to coffeescript as dataset_select_menu.coffee Copied the menu variables from selectDatasetMenu.js as dataset_select_items.js --- web/javascript/selectDatasetMenu.js | 0 .../static/new/javascript/dataset_select_items.js | 773 +++++++++++++++++++++ .../new/javascript/dataset_select_menu.coffee | 370 ++++++++++ .../static/new/javascript/dataset_select_menu.js | 363 ++++++++++ .../wqflask/static/new/javascript/validation.js | 51 ++ wqflask/wqflask/templates/new_index_page.html | 4 +- 6 files changed, 1559 insertions(+), 2 deletions(-) mode change 100755 => 100644 web/javascript/selectDatasetMenu.js create mode 100755 wqflask/wqflask/static/new/javascript/dataset_select_items.js create mode 100644 wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee create mode 100644 wqflask/wqflask/static/new/javascript/dataset_select_menu.js create mode 100644 wqflask/wqflask/static/new/javascript/validation.js diff --git a/web/javascript/selectDatasetMenu.js b/web/javascript/selectDatasetMenu.js old mode 100755 new mode 100644 diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_items.js b/wqflask/wqflask/static/new/javascript/dataset_select_items.js new file mode 100755 index 00000000..11be18cc --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/dataset_select_items.js @@ -0,0 +1,773 @@ +var sArr = [ +{txt:'',val:''}, +{txt:'Human',val:'human'}, +{txt:'Macaque monkey',val:'macaque monkey'}, +{txt:'Mouse',val:'mouse'}, +{txt:'Rat',val:'rat'}, +{txt:'Drosophila',val:'drosophila'}, +{txt:'Arabidopsis thaliana',val:'arabidopsis'}, +{txt:'Barley',val:'barley'}, +{txt:'Soybean',val:'soybean'}, +{txt:'Tomato',val:'tomato'}, +{txt:'All Species',val:'All Species'}]; + +var gArr = [ +{txt:'',val:''}, +{txt:'AD Cases & Controls (Liang)',val:'AD-cases-controls'}, +{txt:'AD Cases & Controls (Myers)',val:'AD-cases-controls-Myers'}, +{txt:'AKXD',val:'AKXD'}, +{txt:'AXB/BXA',val:'AXBXA'}, +{txt:'B6BTBRF2',val:'B6BTBRF2'}, +{txt:'B6D2F2',val:'B6D2F2'}, +{txt:'BayXSha',val:'BayXSha'}, +{txt:'BDF2 UCLA',val:'BDF2-1999'}, +{txt:'BDF2-2005',val:'BDF2-2005'}, +{txt:'BHF2 (Apoe Null) UCLA',val:'BHF2'}, +{txt:'BH/HB F2 UCLA',val:'BHHBF2'}, +{txt:'BXD',val:'BXD'}, +{txt:'BXH',val:'BXH'}, +{txt:'CANDLE',val:'CANDLE'}, +{txt:'CEPH Families',val:'CEPH-2004'}, +{txt:'ColXBur',val:'ColXBur'}, +{txt:'ColXCvi',val:'ColXCvi'}, +{txt:'CastB6/B6Cast F2 UCLA',val:'CTB6F2'}, +{txt:'CXB',val:'CXB'}, +{txt:'Drosophila Genetic Reference Panel',val:'DGRP'}, +{txt:'Harvard Brain Tissue Resource Center',val:'HB'}, +{txt:'Human Liver Cohort',val:'HLC'}, +{txt:'Heterogeneous Stock',val:'HS'}, +{txt:'Heterogeneous Stock Collaborative Cross',val:'HS-CC'}, +{txt:'KIN/YSM',val:'HSB'}, +{txt:'HXB/BXH',val:'HXBBXH'}, +{txt:'J12XJ58F2',val:'J12XJ58F2'}, +{txt:'LXP',val:'LXP'}, +{txt:'LXS',val:'LXS'}, +{txt:'Macaca fasicularis (Cynomolgus monkey)',val:'Macaca-fasicularis'}, +{txt:'Mouse Diversity Panel',val:'MDP'}, +{txt:'NZB/FVB N2 NCI',val:'NZBXFVB-N2'}, +{txt:'Oregon-R x 2b3',val:'Oregon-R_x_2b3'}, +{txt:'QSM',val:'QSM'}, +{txt:'UIOWA SRxSHRSP F2',val:'SRxSHRSPF2'}, +{txt:'SXM',val:'SXM'}, +{txt:'All Groups',val:'all groups'}]; + +var tArr = [ +{txt:'',val:''}, +{txt:'Adipose mRNA',val:'Adipose'}, +{txt:'Adrenal Gland mRNA',val:'Adrenal Gland'}, +{txt:'Amygdala mRNA',val:'Amygdala'}, +{txt:'Brain mRNA',val:'Brain'}, +{txt:'Cartilage mRNA',val:'Cartilage'}, +{txt:'Caudal Ganglionic Eminence mRNA',val:'Caudal Ganglionic Eminence'}, +{txt:'Cerebellar Cortex mRNA',val:'Cerebellar Cortex'}, +{txt:'Cerebellum mRNA',val:'Cerebellum'}, +{txt:'Diencephalon mRNA',val:'Diencephalon'}, +{txt:'Dorsal Thalamus mRNA',val:'Dorsal Thalamus'}, +{txt:'Dorsolateral Prefrontal Cortex mRNA',val:'Dorsolateral Prefrontal Cortex'}, +{txt:'Embryo mRNA',val:'Embryo'}, +{txt:'Eye mRNA',val:'Eye'}, +{txt:'Frontal Cerebral Wall mRNA',val:'Frontal Cerebral Wall'}, +{txt:'Heart mRNA',val:'Heart'}, +{txt:'Hematopoietic Cells mRNA',val:'Hematopoietic Cells'}, +{txt:'Hippocampus mRNA',val:'Hippocampus'}, +{txt:'Hypothalamus mRNA',val:'Hypothalamus'}, +{txt:'Inferior Temporal Cortex mRNA',val:'Inferior Temporal Cortex'}, +{txt:'Kidney mRNA',val:'Kidney'}, +{txt:'Lateral Ganglionic Eminence mRNA',val:'Lateral Ganglionic Eminence'}, +{txt:'Leaf mRNA',val:'Leaf'}, +{txt:'Leucocytes mRNA',val:'Leucocytes'}, +{txt:'Liver mRNA',val:'Liver'}, +{txt:'Lung mRNA',val:'Lung'}, +{txt:'Lymphoblast B-cell mRNA',val:'Lymphoblast B-cell'}, +{txt:'Mammary Tumors mRNA',val:'Mammary Tumors'}, +{txt:'Medial Ganglionic Eminence mRNA',val:'Medial Ganglionic Eminence'}, +{txt:'Medial Prefrontal Cortex mRNA',val:'Medial Prefrontal Cortex'}, +{txt:'Mediodorsal Nucleus of Thalamus mRNA',val:'Mediodorsal Nucleus of Thalamus'}, +{txt:'Midbrain mRNA',val:'Midbrain'}, +{txt:'Muscle mRNA',val:'Muscle'}, +{txt:'Neocortex mRNA',val:'Neocortex'}, +{txt:'Newborn Cord Blood mRNA',val:'Newborn Cord Blood'}, +{txt:'Nucleus Accumbens mRNA',val:'Nucleus Accumbens'}, +{txt:'Occipital Cerebral Wall mRNA',val:'Occipital Cerebral Wall'}, +{txt:'Orbital Prefrontal Cortex mRNA',val:'Orbital Prefrontal Cortex'}, +{txt:'Parietal Cerebral Wall mRNA',val:'Parietal Cerebral Wall'}, +{txt:'Peritoneal Fat mRNA',val:'Peritoneal Fat'}, +{txt:'Posterior Inferior Parietal Cortex mRNA',val:'Posterior Inferior Parietal Cortex'}, +{txt:'Posterior Superior Temporal Cortex mRNA',val:'Posterior Superior Temporal Cortex'}, +{txt:'Prefrontal Cortex mRNA',val:'Prefrontal Cortex'}, +{txt:'Primary Auditory (A1) Cortex mRNA',val:'Primary Auditory (A1) Cortex'}, +{txt:'Primary Motor (M1) Cortex mRNA',val:'Primary Motor (M1) Cortex'}, +{txt:'Primary Somatosensory (S1) Cortex mRNA',val:'Primary Somatosensory (S1) Cortex'}, +{txt:'Primary Visual Cortex mRNA',val:'Primary Visual Cortex'}, +{txt:'Retina mRNA',val:'Retina'}, +{txt:'Spleen mRNA',val:'Spleen'}, +{txt:'Striatum mRNA',val:'Striatum'}, +{txt:'T Cell (helper) mRNA',val:'T Cell (helper)'}, +{txt:'T Cell (regulatory) mRNA',val:'T Cell (regulatory)'}, +{txt:'Temporal Cerebral Wall mRNA',val:'Temporal Cerebral Wall'}, +{txt:'Thymus mRNA',val:'Thymus'}, +{txt:'Upper (Rostral) Rhombic Lip mRNA',val:'Upper (Rostral) Rhombic Lip'}, +{txt:'Ventral Forebrain mRNA',val:'Ventral Forebrain'}, +{txt:'Ventral Tegmental Area mRNA',val:'Ventral Tegmental Area'}, +{txt:'Ventrolateral Prefrontal Cortex mRNA',val:'Ventrolateral Prefrontal Cortex'}, +{txt:'Whole Body mRNA',val:'Whole Body'}, +{txt:'Phenotypes',val:'Phenotypes'}, +{txt:'Genotypes',val:'Genotypes'}]; + +var dArr = [ +{txt:'',val:''}, +{txt:'GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv',val:'GSE15222_F_A_RI_0409'}, +{txt:'GSE15222 Human Brain Normal Myers (Apr09) RankInv',val:'GSE15222_F_N_RI_0409'}, +{txt:'Normal HEI Retina (April 2010) RankInv',val:'G2NEI_ILM_Retina_BXD_RI0410'}, +{txt:'Full HEI Retina (April 2010) RankInv',val:'Illum_Retina_BXD_RankInv0410'}, +{txt:'ONC HEI Retina (April 2012) RankInv',val:'ONCRetILM6_0412'}, +{txt:'B6D2 ONC Retina (April 2012) RankInv **',val:'B6D2ONCILM_0412'}, +{txt:'INIA Macaca fasicularis Nucleus Accumbens (Jan10) RMA **',val:'INIA_MacFas_Ac_RMA_0110'}, +{txt:'UCLA CTB6/B6CTF2 Liver (2005) mlratio',val:'UCLA_CTB6B6CTF2_LIVER_2005'}, +{txt:'UCLA CTB6/B6CTF2 Adipose (2005) mlratio',val:'UCLA_CTB6B6CTF2_ADIPOSE_2005'}, +{txt:'UCLA CTB6/B6CTF2 Brain (2005) mlratio',val:'UCLA_CTB6B6CTF2_BRAIN_2005'}, +{txt:'UCLA CTB6/B6CTF2 Muscle (2005) mlratio',val:'UCLA_CTB6B6CTF2_MUSCLE_2005'}, +{txt:'INIA Macaca fasicularis Hippocampus (Jan10) RMA **',val:'INIA_MacFas_Hc_RMA_0110'}, +{txt:'UCLA CTB6B6CTF2 Muscle Female mlratio **',val:'UCLA_CTB6B6CTF2_MUSCLE_FEMALE'}, +{txt:'INIA Macaca fasicularis Amygdala (Jan10) RMA **',val:'INIA_MacFas_AMG_RMA_0110'}, +{txt:'UCLA CTB6B6CTF2 Adipose Female mlratio **',val:'UCLA_CTB6B6CTF2_ADIPOSE_FEMALE'}, +{txt:'UCLA CTB6B6CTF2 Brain Female mlratio **',val:'UCLA_CTB6B6CTF2_BRAIN_FEMALE'}, +{txt:'UCLA CTB6B6CTF2 Liver Female mlratio **',val:'UCLA_CTB6B6CTF2_LIVER_FEMALE'}, +{txt:'VU BXD Midbrain Agilent SurePrint G3 Mouse GE (May12) Quantile **',val:'VUBXDMouseMidBrainQ0512'}, +{txt:'GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA',val:'GSE16780_UCLA_ML0911'}, +{txt:'EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleRMA1211'}, +{txt:'EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleHFDRMA1211'}, +{txt:'EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleCDRMA1211'}, +{txt:'BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **',val:'DevStriatum_ILM6.2P14RInv_1111'}, +{txt:'BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **',val:'DevStriatum_ILM6.2P3RInv_1111'}, +{txt:'BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv',val:'DevNeocortex_ILM6.2P14RInv_1111'}, +{txt:'BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv',val:'DevNeocortex_ILM6.2P3RInv_1111'}, +{txt:'G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **',val:'G2HEIONCRetILM6_0911'}, +{txt:'HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **',val:'HEIONCvsCRetILM6_0911'}, +{txt:'JAX Liver Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_0711'}, +{txt:'JAX Liver HF Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_HF_0711'}, +{txt:'JAX Liver 6C Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_6C_0711'}, +{txt:'CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **',val:'CANDLE_NB_0711'}, +{txt:'KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_AMY_0711'}, +{txt:'KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_A1C_0711'}, +{txt:'KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_TC_0711'}, +{txt:'KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_CBC_0711'}, +{txt:'KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_CGE_0711'}, +{txt:'KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_FC_0711'}, +{txt:'KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_S1C_0711'}, +{txt:'KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_STR_0711'}, +{txt:'KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_URL_0711'}, +{txt:'KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_V1C_0711'}, +{txt:'KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_VF_0711'}, +{txt:'KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_VFC_0711'}, +{txt:'KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_STC_0711'}, +{txt:'KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_ITC_0711'}, +{txt:'KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_LGE_0711'}, +{txt:'KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_M1C_0711'}, +{txt:'KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MD_0711'}, +{txt:'KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_IPC_0711'}, +{txt:'KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_HIP_0711'}, +{txt:'KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MFC_0711'}, +{txt:'KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DFC_0711'}, +{txt:'KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DIE_0711'}, +{txt:'KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MGE_0711'}, +{txt:'KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DTH_0711'}, +{txt:'KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_PC_0711'}, +{txt:'KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_OC_0711'}, +{txt:'KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_OFC_0711'}, +{txt:'HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio',val:'HBTRC-MLC_0611'}, +{txt:'HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio',val:'HBTRC-MLC_N_0611'}, +{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio',val:'HBTRC-MLPFC_0611'}, +{txt:'HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio',val:'HBTRC-MLC_AD_0611'}, +{txt:'HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio',val:'HBTRC-MLVC_0611'}, +{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio',val:'HBTRC-MLPFC_N_0611'}, +{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio',val:'HBTRC-MLPFC_AD_0611'}, +{txt:'HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio',val:'HBTRC-MLC_HD_0611'}, +{txt:'HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio',val:'HBTRC-MLVC_N_0611'}, +{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio',val:'HBTRC-MLPFC_HD_0611'}, +{txt:'HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio',val:'HBTRC-MLVC_AD_0611'}, +{txt:'HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio',val:'HBTRC-MLVC_HD_0611'}, +{txt:'INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA',val:'INIA_AmgCoh_0311'}, +{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA',val:'INIA_Amg_BLA_RMA_1110'}, +{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male',val:'INIA_Amg_BLA_RMA_M_1110'}, +{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female',val:'INIA_Amg_BLA_RMA_F_1110'}, +{txt:'GSE9588 Human Liver Normal (Mar11) Both Sexes',val:'HLC_0311'}, +{txt:'GSE9588 Human Liver Normal (Mar11) Males',val:'HLCM_0311'}, +{txt:'HZI Thelp M430v2 (Feb11) RMA',val:'RTHC_0211_R'}, +{txt:'GSE5281 Human Brain Normal Full Liang (Jul09) RMA',val:'GSE5281_F_RMA_N_0709'}, +{txt:'GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA',val:'GSE5281_F_RMA_Alzh_0709'}, +{txt:'OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv',val:'OHSU_HS-CC_ILMStr_0211'}, +{txt:'NCSU Drosophila Whole Body (Jan11) RMA',val:'NCSU_DrosWB_LC_RMA_0111'}, +{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females',val:'LV_G_0106_F'}, +{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males',val:'LV_G_0106_M'}, +{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes',val:'LV_G_0106_B'}, +{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **',val:'GenEx_BXD_liverSal_RMA_F_0211'}, +{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **',val:'GenEx_BXD_liverSal_RMA_M_0211'}, +{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **',val:'GenEx_BXD_liverSal_RMA_0211'}, +{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **',val:'GenEx_BXD_liverEt_RMA_F_0211'}, +{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **',val:'GenEx_BXD_liverEt_RMA_M_0211'}, +{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **',val:'GenEx_BXD_liverEt_RMA_0211'}, +{txt:'SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **',val:'SUH_Liv_RMA_0611'}, +{txt:'HQF BXD Striatum ILM6.1 (Dec10v2) RankInv',val:'UTHSC_Striatum_RankInv_1210'}, +{txt:'HQF BXD Striatum ILM6.1 (Dec10) RankInv',val:'UTHSC_Str_RankInv_1210'}, +{txt:'HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv',val:'HQFNeoc_1210v2_RankInv'}, +{txt:'UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA',val:'UTHSC_SPL_RMA_1210'}, +{txt:'HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv',val:'HQFNeoc_1210_RankInv'}, +{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)',val:'INIA_Hyp_RMA_1110'}, +{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male',val:'INIA_Hyp_M_RMA_1110'}, +{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female',val:'INIA_Hyp_F_RMA_1110'}, +{txt:'UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA',val:'UTHSC_SPL_RMA_1010'}, +{txt:'Hippocampus Consortium M430v2 (Jun06) RMA MDP',val:'HC_M2_0606_MDP'}, +{txt:'UMUTAffy Hippocampus Exon (Feb09) RMA MDP',val:'UMUTAffyExon_0209_RMA_MDP'}, +{txt:'OX UK HS ILM6v1.1 Lung (May 2010) RankInv',val:'OXUKHS_ILMLung_RI0510'}, +{txt:'OX UK HS ILM6v1.1 Liver (May 2010) RankInv',val:'OXUKHS_ILMLiver_RI0510'}, +{txt:'OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv',val:'OXUKHS_ILMHipp_RI0510'}, +{txt:'INIA Macaca fasicularis Prefrontal Cortex (Jan10) RMA **',val:'INIA_MacFas_Pf_RMA_0110'}, +{txt:'INIA Macaca fasicularis Brain (Jan10) RMA **',val:'INIA_MacFas_brain_RMA_0110'}, +{txt:'UAB Whole body D.m. mRNA control (Oct09) RMA',val:'UAB_DrosWB_LC_RMA_1009'}, +{txt:'UAB Whole body D.m. mRNA lead (pbAc) (Oct09) RMA',val:'UAB_DrosWB_LE_RMA_1009'}, +{txt:'UMCG Stem Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_HemaStem_ori'}, +{txt:'UMCG Stem Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_HemaStem'}, +{txt:'UMCG Progenitor Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Pro_ori'}, +{txt:'UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Pro'}, +{txt:'UMCG Erythroid Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Eryth_ori'}, +{txt:'UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Eryth'}, +{txt:'UMCG Myeloid Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Myeloid_ori'}, +{txt:'UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Myeloid'}, +{txt:'UTHSC CEPH B-cells Illumina (Sep09) RankInv',val:'UT_CEPH_RankInv0909'}, +{txt:'Mouse kidney M430v2 Female (Aug06) RMA',val:'MA_M2F_0706_R'}, +{txt:'Mouse kidney M430v2 Male (Aug06) RMA',val:'MA_M2M_0706_R'}, +{txt:'Barley1 Leaf INOC TTKS (Aug09) RMA',val:'B1LI0809R'}, +{txt:'Barley1 Leaf INOC TTKS (Aug09) MAS5',val:'B1LI0809M5'}, +{txt:'Barley1 Leaf MOCK TTKS (Aug09) MAS5',val:'B1MI0809M5'}, +{txt:'Barley1 Leaf MOCK TTKS (Aug09) RMA',val:'B1MI0809R'}, +{txt:'GSE15222 Human Brain Myers (Apr09) RankInv',val:'GSE15222_F_RI_0409'}, +{txt:'GSE5281 Human Brain Full Liang (Jul09) RMA',val:'GSE5281_F_RMA0709'}, +{txt:'GSE5281 Human Brain Best 102 Liang (Jul09) RMA',val:'GSE5281_RMA0709'}, +{txt:'UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA',val:'UT_HippRatEx_RMA_0709'}, +{txt:'VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **',val:'VCUEtOH_0609_R'}, +{txt:'VCU BXD VTA Sal M430 2.0 (Jun09) RMA **',val:'VCUSal_0609_R'}, +{txt:'VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **',val:'VCUEtvsSal_0609_R'}, +{txt:'IoP Affy MOE 430v2 Spleen (May09) RMA',val:'IoP_SPL_RMA_0509'}, +{txt:'NCI Mammary M430v2 (Apr09) RMA',val:'NCI_Mam_Tum_RMA_0409'}, +{txt:'NCI Mammary LMT miRNA v2 (Apr09) RMA',val:'NCI_Agil_Mam_Tum_RMA_0409'}, +{txt:'MDC/CAS/UCL Liver 230v2 (Dec08) RMA',val:'HXB_Liver_1208'}, +{txt:'MDC/CAS/UCL Heart 230_V2 (Dec08) RMA',val:'HXB_Heart_1208'}, +{txt:'MDC/CAS/UCL Adrenal 230A (Dec08) RMA',val:'HXB_Adrenal_1208'}, +{txt:'UWA Illumina PBL (Nov08) RSN **',val:'Illum_BXD_PBL_1108'}, +{txt:'UWA Illumina Thymus (Nov08) RSN **',val:'Illum_BXD_Thy_1108'}, +{txt:'UWA Illumina Spleen (Nov08) RSN **',val:'Illum_BXD_Spl_1108'}, +{txt:'Monks CEPH B-cells Agilent (Dec04) Log10Ratio',val:'Human_1008'}, +{txt:'UTK Spleen ILM6.1 (Jan10) VST',val:'UTK_BXDSpl_VST_0110'}, +{txt:'Eye AXBXA Illumina V6.2(Oct08) RankInv Beta',val:'Eye_AXBXA_1008_RankInv'}, +{txt:'Eye M430v2 (Sep08) RMA',val:'Eye_M2_0908_R'}, +{txt:'Eye M430v2 Mutant Gpnmb (Sep08) RMA **',val:'Eye_M2_0908_R_NB'}, +{txt:'Eye M430v2 WT Gpnmb (Sep08) RMA **',val:'Eye_M2_0908_R_ND'}, +{txt:'Eye M430v2 Mutant Tyrp1 (Sep08) RMA **',val:'Eye_M2_0908_R_MT'}, +{txt:'Eye M430v2 WT WT (Sep08) RMA **',val:'Eye_M2_0908_WTWT'}, +{txt:'Eye M430v2 WT Tyrp1 (Sep08) RMA **',val:'Eye_M2_0908_R_WT'}, +{txt:'BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **',val:'BXD_GLA_0911'}, +{txt:'UCLA BXH and BXD Cartilage v2',val:'UCLA_BXHBXD_CARTILAGE_V2'}, +{txt:'UCLA BXD and BXH Cartilage v2',val:'UCLA_BXDBXH_CARTILAGE_V2'}, +{txt:'UCLA BXD and BXH Cartilage',val:'UCLA_BXDBXH_CARTILAGE'}, +{txt:'UCLA BXH and BXD Cartilage',val:'UCLA_BXHBXD_CARTILAGE'}, +{txt:'UCLA BHF2 Brain Male mlratio',val:'UCLA_BHF2_BRAIN_MALE'}, +{txt:'UCLA BHF2 Brain Female mlratio',val:'UCLA_BHF2_BRAIN_FEMALE'}, +{txt:'UCLA BHF2 Adipose Female mlratio',val:'UCLA_BHF2_ADIPOSE_FEMALE'}, +{txt:'UCLA BHF2 Adipose Male mlratio',val:'UCLA_BHF2_ADIPOSE_MALE'}, +{txt:'UCLA CTB6B6CTF2 Muscle Male mlratio **',val:'UCLA_CTB6B6CTF2_MUSCLE_MALE'}, +{txt:'UCLA CTB6B6CTF2 Liver Male mlratio **',val:'UCLA_CTB6B6CTF2_LIVER_MALE'}, +{txt:'UCLA CTB6B6CTF2 Brain Male mlratio **',val:'UCLA_CTB6B6CTF2_BRAIN_MALE'}, +{txt:'UCLA CTB6B6CTF2 Adipose Male mlratio **',val:'UCLA_CTB6B6CTF2_ADIPOSE_MALE'}, +{txt:'UCLA BHF2 Liver Male mlratio',val:'UCLA_BHF2_LIVER_MALE'}, +{txt:'UCLA BHF2 Liver Female mlratio',val:'UCLA_BHF2_LIVER_FEMALE'}, +{txt:'UCLA BHHBF2 Brain Female Only',val:'UCLA_BHHBF2_BRAIN_FEMALE'}, +{txt:'UCLA BHHBF2 Liver Female Only',val:'UCLA_BHHBF2_LIVER_FEMALE'}, +{txt:'UCLA BHHBF2 Muscle Male Only',val:'UCLA_BHHBF2_MUSCLE_MALE'}, +{txt:'UCLA BHHBF2 Muscle Female Only',val:'UCLA_BHHBF2_MUSCLE_FEMALE'}, +{txt:'UCLA BHHBF2 Liver Male Only',val:'UCLA_BHHBF2_LIVER_MALE'}, +{txt:'UCLA BHHBF2 Brain Male Only',val:'UCLA_BHHBF2_BRAIN_MALE'}, +{txt:'UCLA BHHBF2 Adipose Female Only',val:'UCLA_BHHBF2_ADIPOSE_FEMALE'}, +{txt:'UCLA BHHBF2 Adipose Male Only',val:'UCLA_BHHBF2_ADIPOSE_MALE'}, +{txt:'UCLA BHF2 Muscle Female mlratio **',val:'UCLA_BHF2_MUSCLE_FEMALE'}, +{txt:'UCLA BHF2 Muscle Male mlratio **',val:'UCLA_BHF2_MUSCLE_MALE'}, +{txt:'UCLA BXH Cartilage',val:'UCLA_BXH_CARTILAGE'}, +{txt:'UCLA BXD Cartilage',val:'UCLA_BXD_CARTILAGE'}, +{txt:'UCLA BHHBF2 Adipose (2005) mlratio **',val:'UCLA_BHHBF2_ADIPOSE_2005'}, +{txt:'UCLA BHHBF2 Brain (2005) mlratio **',val:'UCLA_BHHBF2_BRAIN_2005'}, +{txt:'UCLA BHHBF2 Liver (2005) mlratio **',val:'UCLA_BHHBF2_LIVER_2005'}, +{txt:'UCLA BHHBF2 Muscle (2005) mlratio **',val:'UCLA_BHHBF2_MUSCLE_2005'}, +{txt:'UCLA BHF2 Adipose (June05) mlratio',val:'UCLA_BHF2_ADIPOSE_0605'}, +{txt:'UCLA BDF2 Liver (1999) mlratio',val:'UCLA_BDF2_LIVER_1999'}, +{txt:'UCLA BHF2 Muscle (June05) mlratio **',val:'UCLA_BHF2_MUSCLE_0605'}, +{txt:'UCLA BHF2 Brain (June05) mlratio',val:'UCLA_BHF2_BRAIN_0605'}, +{txt:'UCLA BHF2 Liver (June05) mlratio',val:'UCLA_BHF2_LIVER_0605'}, +{txt:'HZI Lung M430v2 (Apr08) RMA',val:'HZI_0408_R'}, +{txt:'HZI Lung M430v2 (Apr08) MAS5',val:'HZI_0408_M'}, +{txt:'HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv',val:'HQFNeoc_0208_RankInv'}, +{txt:'VCU BXD NA Sal M430 2.0 (Oct07) RMA',val:'VCUSalo_1007_R'}, +{txt:'VCU BXD NA EtOH M430 2.0 (Oct07) RMA **',val:'VCUEtOH_1007_R'}, +{txt:'VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **',val:'VCUSal_1007_R'}, +{txt:'Stuart Spleen M430v2 (Nov07) RMA',val:'STSPL_1107_R'}, +{txt:'HQF BXD Striatum ILM6.1 (Nov07) RankInv',val:'UTHSC_1107_RankInv'}, +{txt:'Hippocampus Illumina (Aug07) LOESS',val:'Illum_LXS_Hipp_loess0807'}, +{txt:'Hippocampus Illumina (Aug07) LOESS_NB',val:'Illum_LXS_Hipp_loess_nb0807'}, +{txt:'Hippocampus Illumina (Aug07) QUANT',val:'Illum_LXS_Hipp_quant0807'}, +{txt:'Hippocampus Illumina (Aug07) QUANT_NB',val:'Illum_LXS_Hipp_quant_nb0807'}, +{txt:'Hippocampus Illumina (Aug07) RSN',val:'Illum_LXS_Hipp_rsn0807'}, +{txt:'Hippocampus Illumina (Aug07) RSN_NB',val:'Illum_LXS_Hipp_rsn_nb0807'}, +{txt:'VCU BXD PFC EtOH M430 2.0 (Dec06) RMA',val:'VCUEtOH_1206_R'}, +{txt:'VCU BXD PFC Sal M430 2.0 (Dec06) RMA',val:'VCUSal_1206_R'}, +{txt:'VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore',val:'VCUSal_1006_R'}, +{txt:'VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **',val:'VCU_PF_Air_0111_R'}, +{txt:'VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **',val:'VCU_PF_Et_0111_R'}, +{txt:'VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **',val:'VCU_PF_AvE_0111_Ss'}, +{txt:'Hippocampus Illumina (May07) RankInv',val:'Hipp_Illumina_RankInv_0507'}, +{txt:'VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **',val:'VCUEtOH_0806_R'}, +{txt:'VCU LXS PFC Sal M430A 2.0 (Aug06) RMA',val:'VCUSal_0806_R'}, +{txt:'VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **',val:'VCUEt_vs_Sal_0806_R'}, +{txt:'Barley1 Embryo gcRMA SCRI (Dec06)',val:'B139_K_1206_R'}, +{txt:'Barley1 Leaf MAS 5.0 SCRI (Dec06)',val:'B30_K_1206_M'}, +{txt:'Barley1 Leaf gcRMAn SCRI (Dec06)',val:'B30_K_1206_Rn'}, +{txt:'Barley1 Leaf gcRMA SCRI (Dec06)',val:'B30_K_1206_R'}, +{txt:'Barley1 Embryo MAS 5.0 SCRI (Dec06)',val:'B139_K_1206_M'}, +{txt:'UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA',val:'BR_M2_1106_R'}, +{txt:'HZI Treg M430v2 (Feb11) RMA',val:'RTC_1106_R'}, +{txt:'UIOWA Eye mRNA RAE230v2 (Sep06) RMA',val:'UIOWA_Eye_RMA_0906'}, +{txt:'Mouse kidney M430v2 Sex Balanced (Aug06) RMA',val:'MA_M2_0806_R'}, +{txt:'Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN',val:'MA_M2_0806_P'}, +{txt:'Mouse Kidney M430v2 (Jul06) PDNN',val:'MA_M2_0706_P'}, +{txt:'Mouse Kidney M430v2 (Jul06) RMA',val:'MA_M2_0706_R'}, +{txt:'Barley1 Embryo0 gcRMA SCRI (Apr06)',val:'B150_K_0406_R'}, +{txt:'INIA Brain mRNA M430 (Jun06) RMA',val:'IBR_M_0606_R'}, +{txt:'Hippocampus Consortium M430v2 (Jun06) PDNN',val:'HC_M2_0606_P'}, +{txt:'Hippocampus Consortium M430v2 (Jun06) MAS5',val:'HC_M2_0606_M'}, +{txt:'Hippocampus Consortium M430v2 (Jun06) RMA',val:'HC_M2_0606_R'}, +{txt:'INIA Brain mRNA M430 (Jan06) RMA',val:'IBR_M_0106_R'}, +{txt:'INIA Brain mRNA M430 (Jan06) PDNN',val:'IBR_M_0106_P'}, +{txt:'Hippocampus Consortium M430v2 CXB (Dec05) RMA',val:'HC_M2CB_1205_R'}, +{txt:'Hippocampus Consortium M430v2 CXB (Dec05) PDNN',val:'HC_M2CB_1205_P'}, +{txt:'UTHSC Brain mRNA U74Av2 (Nov05) PDNN',val:'BR_U_1105_P'}, +{txt:'UMUTAffy Hippocampus Exon (Feb09) RMA',val:'UMUTAffyExon_0209_RMA'}, +{txt:'UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NON_0909'}, +{txt:'UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NOS_0909'}, +{txt:'UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NOE_0909'}, +{txt:'UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv',val:'UT_ILM_BXD_hipp_RSS_0909'}, +{txt:'UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv',val:'UT_ILM_BXD_hipp_RSE_0909'}, +{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN',val:'SA_M2_0905_P'}, +{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA',val:'SA_M2_0905_R'}, +{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5',val:'SA_M2_0905_M'}, +{txt:'UTHSC Brain mRNA U74Av2 (Aug05) RMA',val:'BR_U_0805_R'}, +{txt:'UTHSC Brain mRNA U74Av2 (Aug05) PDNN',val:'BR_U_0805_P'}, +{txt:'UTHSC Brain mRNA U74Av2 (Aug05) MAS5',val:'BR_U_0805_M'}, +{txt:'MDC/CAS/ICL Peritoneal Fat 230A (Aug05) MAS5',val:'FT_2A_0805_M'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA',val:'BRF2_M_0805_R'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN',val:'BRF2_M_0805_P'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5',val:'BRF2_M_0805_M'}, +{txt:'MDC/CAS/ICL Peritoneal Fat 230A (Jun05) RMA 2z+8',val:'FT_2A_0605_Rz'}, +{txt:'HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean',val:'SA_M2_0405_MC'}, +{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) PDNN',val:'GCB_M2_0505_P'}, +{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) RMA',val:'GCB_M2_0505_R'}, +{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) MAS5',val:'GCB_M2_0505_M'}, +{txt:'MDC/CAS/ICL Kidney 230A (Apr05) MAS5',val:'KI_2A_0405_M'}, +{txt:'HBP Rosen Striatum M430V2 (Apr05) RMA Clean',val:'SA_M2_0405_RC'}, +{txt:'HBP Rosen Striatum M430V2 (Apr05) PDNN Clean',val:'SA_M2_0405_PC'}, +{txt:'HBP Rosen Striatum M430V2 (Apr05) SScore',val:'SA_M2_0405_SS'}, +{txt:'HBP Rosen Striatum M430V2 (Apr05) RMA Orig',val:'SA_M2_0405_RR'}, +{txt:'MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8',val:'KI_2A_0405_Rz'}, +{txt:'MDC/CAS/ICL Kidney 230A (Apr05) RMA',val:'KI_2A_0405_R'}, +{txt:'SJUT Cerebellum mRNA M430 (Mar05) PDNN',val:'CB_M_0305_P'}, +{txt:'SJUT Cerebellum mRNA M430 (Mar05) MAS5',val:'CB_M_0305_M'}, +{txt:'SJUT Cerebellum mRNA M430 (Mar05) RMA',val:'CB_M_0305_R'}, +{txt:'HQF Striatum Exon (Feb09) RMA',val:'Striatum_Exon_0209'}, +{txt:'BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv',val:'DevNeocortex_ILM6.2P14RInv_1110'}, +{txt:'BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **',val:'DevStriatum_ILM6.2P14RInv_1110'}, +{txt:'BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **',val:'DevStriatum_ILM6.2P3RInv_1110'}, +{txt:'BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv',val:'DevNeocortex_ILM6.2P3RInv_1110'}, +{txt:'SJUT Cerebellum mRNA M430 (Oct04) MAS5',val:'CB_M_1004_M'}, +{txt:'SJUT Cerebellum mRNA M430 (Oct04) PDNN',val:'CB_M_1004_P'}, +{txt:'SJUT Cerebellum mRNA M430 (Oct04) RMA',val:'CB_M_1004_R'}, +{txt:'(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5',val:'LVF2_M_0704_M'}, +{txt:'(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA',val:'LVF2_M_0704_R'}, +{txt:'NCI Mammary mRNA M430 (July04) MAS5',val:'MA_M_0704_M'}, +{txt:'NCI Mammary mRNA M430 (July04) RMA',val:'MA_M_0704_R'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN',val:'BRF2_M_0304_P'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA',val:'BRF2_M_0304_R'}, +{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5',val:'BRF2_M_0304_M'}, +{txt:'GNF Stem Cells U74Av2 (Mar04) RMA',val:'HC_U_0304_R'}, +{txt:'INIA Brain mRNA M430 (Feb04) PDNN',val:'CB_M_0204_P'}, +{txt:'SJUT Cerebellum mRNA M430 (Oct03) MAS5',val:'CB_M_1003_M'}, +{txt:'Hippocampus Illumina NOS (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NOS_1008'}, +{txt:'Hippocampus Illumina RSE (Oct08) RankInv beta',val:'Illum_LXS_Hipp_RSE_1008'}, +{txt:'GSE9588 Human Liver Normal (Mar11) Females',val:'HLCF_0311'}, +{txt:'Hippocampus Illumina RSS (Oct08) RankInv beta',val:'Illum_LXS_Hipp_RSS_1008'}, +{txt:'Hippocampus Illumina NOE (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NOE_1008'}, +{txt:'Hippocampus Illumina NON (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NON_1008'}, +{txt:'CANDLE Published Phenotypes',val:'CANDLEPublish'}, +{txt:'HLC Published Phenotypes',val:'HLCPublish'}, +{txt:'AKXD Genotypes',val:'AKXDGeno'}, +{txt:'AXBXA Published Phenotypes',val:'AXBXAPublish'}, +{txt:'AXBXA Genotypes',val:'AXBXAGeno'}, +{txt:'B6BTBRF2 Published Phenotypes',val:'B6BTBRF2Publish'}, +{txt:'B6BTBRF2 Genotypes',val:'B6BTBRF2Geno'}, +{txt:'B6D2F2 Genotypes',val:'B6D2F2Geno'}, +{txt:'BDF2-1999 Genotypes',val:'BDF2-1999Geno'}, +{txt:'BDF2-2005 Genotypes',val:'BDF2-2005Geno'}, +{txt:'BHF2 Genotypes',val:'BHF2Geno'}, +{txt:'BHHBF2 Genotypes',val:'BHHBF2Geno'}, +{txt:'BXD Published Phenotypes',val:'BXDPublish'}, +{txt:'BXD Genotypes',val:'BXDGeno'}, +{txt:'BXH Published Phenotypes',val:'BXHPublish'}, +{txt:'BXH Genotypes',val:'BXHGeno'}, +{txt:'CTB6F2 Published Phenotypes',val:'CTB6F2Publish'}, +{txt:'CTB6F2 Genotypes',val:'CTB6F2Geno'}, +{txt:'CXB Published Phenotypes',val:'CXBPublish'}, +{txt:'CXB Genotypes',val:'CXBGeno'}, +{txt:'LXS Published Phenotypes',val:'LXSPublish'}, +{txt:'LXS Genotypes',val:'LXSGeno'}, +{txt:'Mouse Phenome Database',val:'MDPPublish'}, +{txt:'MDP Genotypes',val:'MDPGeno'}, +{txt:'NZBXFVB-N2 Published Phenotypes',val:'NZBXFVB-N2Publish'}, +{txt:'HXBBXH Published Phenotypes',val:'HXBBXHPublish'}, +{txt:'HXBBXH Genotypes',val:'HXBBXHGeno'}, +{txt:'BayXSha Published Phenotypes',val:'BayXShaPublish'}, +{txt:'BayXSha Genotypes',val:'BayXShaGeno'}, +{txt:'ColXBur Published Phenotypes',val:'ColXBurPublish'}, +{txt:'ColXBur Genotypes',val:'ColXBurGeno'}, +{txt:'ColXCvi Published Phenotypes',val:'ColXCviPublish'}, +{txt:'ColXCvi Genotypes',val:'ColXCviGeno'}, +{txt:'SXM Published Phenotypes',val:'SXMPublish'}, +{txt:'SXM Genotypes',val:'SXMGeno'}, +{txt:'J12XJ58F2 Published Phenotypes',val:'J12XJ58F2Publish'}, +{txt:'LXP Published Phenotypes',val:'LXPPublish'}, +{txt:'All Phenotypes',val:'_allPublish'}]; + +var lArr = [ + null, +[1,1,4,79], +[1,1,4,80], +[1,1,4,127], +[1,1,4,128], +[1,2,4,1], +[1,2,4,2], +[1,2,4,126], +[1,14,59,288], +[1,14,34,32], +[1,15,26,119], +[1,15,26,142], +[1,21,8,60], +[1,21,8,61], +[1,21,8,63], +[1,21,8,67], +[1,21,42,62], +[1,21,42,65], +[1,21,42,66], +[1,21,42,69], +[1,21,46,64], +[1,21,46,68], +[1,21,46,70], +[1,21,46,71], +[1,22,59,289], +[1,22,24,76], +[1,22,24,77], +[1,22,24,284], +[1,25,3,33], +[1,25,6,37], +[1,25,7,36], +[1,25,9,54], +[1,25,10,56], +[1,25,11,53], +[1,25,14,38], +[1,25,17,51], +[1,25,19,46], +[1,25,21,47], +[1,25,28,55], +[1,25,29,52], +[1,25,30,49], +[1,25,36,58], +[1,25,37,59], +[1,25,38,57], +[1,25,40,50], +[1,25,41,45], +[1,25,43,34], +[1,25,44,48], +[1,25,45,39], +[1,25,46,42], +[1,25,49,40], +[1,25,52,35], +[1,25,54,41], +[1,25,55,43], +[1,25,57,44], +[2,30,3,14], +[2,30,4,108], +[2,30,17,12], +[2,30,35,7], +[2,30,42,107], +[3,3,60,290], +[3,3,27,135], +[3,3,27,274], +[3,3,27,275], +[3,4,59,291], +[3,4,60,292], +[3,4,13,144], +[3,5,59,293], +[3,5,60,294], +[3,5,24,272], +[3,5,24,273], +[3,6,60,295], +[3,6,4,246], +[3,6,4,247], +[3,6,4,248], +[3,6,4,276], +[3,6,4,277], +[3,6,4,278], +[3,8,60,296], +[3,8,24,183], +[3,9,60,297], +[3,9,49,239], +[3,9,49,240], +[3,9,49,241], +[3,10,60,298], +[3,10,1,158], +[3,10,1,159], +[3,10,1,182], +[3,10,4,156], +[3,10,4,157], +[3,10,4,185], +[3,10,24,164], +[3,10,24,165], +[3,10,24,186], +[3,10,32,174], +[3,10,32,175], +[3,10,32,184], +[3,11,60,299], +[3,11,1,172], +[3,11,1,173], +[3,11,1,178], +[3,11,4,166], +[3,11,4,171], +[3,11,4,179], +[3,11,24,167], +[3,11,24,170], +[3,11,24,180], +[3,11,32,168], +[3,11,32,169], +[3,11,32,181], +[3,12,59,300], +[3,12,60,301], +[3,12,3,72], +[3,12,3,73], +[3,12,3,74], +[3,12,3,75], +[3,12,4,216], +[3,12,4,224], +[3,12,4,228], +[3,12,4,229], +[3,12,4,232], +[3,12,4,242], +[3,12,4,243], +[3,12,4,244], +[3,12,4,280], +[3,12,5,153], +[3,12,5,154], +[3,12,5,177], +[3,12,8,251], +[3,12,8,252], +[3,12,8,253], +[3,12,8,261], +[3,12,8,262], +[3,12,8,263], +[3,12,8,269], +[3,12,8,270], +[3,12,8,271], +[3,12,8,281], +[3,12,13,145], +[3,12,13,146], +[3,12,13,147], +[3,12,13,148], +[3,12,13,149], +[3,12,13,150], +[3,12,13,151], +[3,12,16,111], +[3,12,16,112], +[3,12,16,113], +[3,12,16,114], +[3,12,16,115], +[3,12,16,116], +[3,12,16,117], +[3,12,16,118], +[3,12,16,279], +[3,12,17,225], +[3,12,17,226], +[3,12,17,227], +[3,12,17,233], +[3,12,17,234], +[3,12,17,235], +[3,12,17,236], +[3,12,17,237], +[3,12,17,238], +[3,12,18,98], +[3,12,18,99], +[3,12,18,100], +[3,12,20,120], +[3,12,20,121], +[3,12,20,219], +[3,12,20,220], +[3,12,20,221], +[3,12,20,222], +[3,12,23,139], +[3,12,24,19], +[3,12,24,83], +[3,12,24,84], +[3,12,24,85], +[3,12,24,86], +[3,12,24,87], +[3,12,24,88], +[3,12,24,89], +[3,12,24,90], +[3,12,24,91], +[3,12,24,92], +[3,12,25,187], +[3,12,25,188], +[3,12,31,18], +[3,12,32,20], +[3,12,32,21], +[3,12,32,22], +[3,12,33,25], +[3,12,33,26], +[3,12,33,95], +[3,12,33,97], +[3,12,33,189], +[3,12,33,265], +[3,12,33,268], +[3,12,35,190], +[3,12,35,191], +[3,12,35,192], +[3,12,42,201], +[3,12,42,202], +[3,12,42,203], +[3,12,42,204], +[3,12,42,205], +[3,12,42,206], +[3,12,47,3], +[3,12,47,4], +[3,12,47,5], +[3,12,47,6], +[3,12,47,27], +[3,12,47,28], +[3,12,48,96], +[3,12,48,101], +[3,12,48,133], +[3,12,48,141], +[3,12,48,143], +[3,12,49,23], +[3,12,49,24], +[3,12,49,93], +[3,12,49,94], +[3,12,49,194], +[3,12,49,250], +[3,12,49,255], +[3,12,49,256], +[3,12,49,257], +[3,12,49,258], +[3,12,49,264], +[3,12,49,266], +[3,12,49,267], +[3,12,50,78], +[3,12,51,217], +[3,12,53,140], +[3,12,56,130], +[3,12,56,131], +[3,12,56,132], +[3,13,59,302], +[3,13,60,303], +[3,13,5,152], +[3,13,5,155], +[3,13,5,176], +[3,18,59,304], +[3,18,60,305], +[3,18,1,9], +[3,18,1,15], +[3,18,1,163], +[3,18,4,10], +[3,18,4,16], +[3,18,4,162], +[3,18,24,8], +[3,18,24,17], +[3,18,24,161], +[3,18,32,11], +[3,18,32,13], +[3,18,32,160], +[3,19,59,306], +[3,19,60,307], +[3,19,17,230], +[3,19,17,231], +[3,19,48,193], +[3,23,17,106], +[3,23,24,105], +[3,23,25,104], +[3,24,49,81], +[3,29,59,308], +[3,29,60,309], +[3,29,17,195], +[3,29,17,196], +[3,29,17,197], +[3,29,17,198], +[3,29,17,199], +[3,29,17,200], +[3,29,17,207], +[3,29,17,282], +[3,29,17,283], +[3,29,17,285], +[3,29,17,286], +[3,29,17,287], +[3,29,42,208], +[3,29,42,209], +[3,29,42,210], +[3,31,59,310], +[3,31,60,311], +[3,31,17,102], +[3,31,17,103], +[3,31,24,29], +[3,31,24,30], +[3,31,24,31], +[3,32,59,312], +[3,32,27,134], +[4,26,59,313], +[4,26,60,314], +[4,26,2,138], +[4,26,15,137], +[4,26,17,129], +[4,26,20,254], +[4,26,20,259], +[4,26,20,260], +[4,26,24,136], +[4,26,39,245], +[4,26,39,249], +[4,35,13,218], +[5,20,58,82], +[5,33,58,109], +[5,33,58,110], +[6,7,59,315], +[6,7,60,316], +[6,16,59,317], +[6,16,60,318], +[6,17,59,319], +[6,17,60,320], +[7,34,22,122], +[7,34,22,123], +[7,34,22,124], +[7,34,22,125], +[7,36,59,321], +[7,36,60,322], +[7,36,12,211], +[7,36,12,215], +[7,36,12,223], +[7,36,22,212], +[7,36,22,213], +[7,36,22,214], +[8,27,59,323], +[9,28,59,324], +[10,37,59,325]]; + + diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee new file mode 100644 index 00000000..c9bd91f1 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee @@ -0,0 +1,370 @@ +# +#* function: based on different browser use, will have different initial actions; +#* Once the index.html page is loaded, this function will be called +# +initialDatasetSelection = -> + defaultSpecies = getDefaultValue("species") + defaultSet = getDefaultValue("cross") + defaultType = getDefaultValue("tissue") + defaultDB = getDefaultValue("database") + if navigator.userAgent.indexOf("MSIE") >= 0 + sOptions = fillOptionsForIE(null, defaultSpecies) + menu0 = "" + document.getElementById("menu0").innerHTML = menu0 + gOptions = fillOptionsForIE("species", defaultSet) + menu1 = "" + document.getElementById("menu1").innerHTML = menu1 + tOptions = fillOptionsForIE("cross", defaultType) + menu2 = "" + document.getElementById("menu2").innerHTML = menu2 + dOptions = fillOptionsForIE("tissue", defaultDB) + menu3 = "" + document.getElementById("menu3").innerHTML = menu3 + else + fillOptions null + searchtip() + +# +#* input: selectObjId (designated select menu, such as species, cross, etc... ) +#* defaultValue (default Value of species, cross,tissue or database) +#* function: special for IE browser,setting options value for select menu dynamically based on linkage array(lArr), +#* output: options string +# +fillOptionsForIE = (selectObjId, defaultValue) -> + options = "" + unless selectObjId? + len = sArr.length + i = 1 + + while i < len + + # setting Species' option + if sArr[i].val is defaultValue + options = options + "" + else + options = options + "" + i++ + else if selectObjId is "species" + speciesObj = document.getElementById("species") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get group(cross) info from lArr + arr[idx++] = lArr[i][1] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and not Contains(arr, lArr[i][1]) + i++ + idx = 0 + len = arr.length + removeOptions "cross" + i = 0 + + while i < len + + # setting Group's option + if gArr[arr[i]].val is defaultValue + options = options + "" + else + options = options + "" + i++ + else if selectObjId is "cross" + speciesObj = document.getElementById("species") + groupObj = document.getElementById("cross") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get type(tissue) info from lArr + arr[idx++] = lArr[i][2] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and not Contains(arr, lArr[i][2]) + i++ + idx = 0 + len = arr.length + removeOptions "tissue" + i = 0 + + while i < len + + # setting Type's option + if tArr[arr[i]].val is defaultValue + options = options + "" + else + options = options + "" + i++ + else if selectObjId is "tissue" + speciesObj = document.getElementById("species") + groupObj = document.getElementById("cross") + typeObj = document.getElementById("tissue") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get dataset(database) info from lArr + arr[idx++] = lArr[i][3] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and lArr[i][2] is (getIndexByValue("tissue", typeObj.value)).toString() and not Contains(arr, lArr[i][3]) + i++ + idx = 0 + len = arr.length + removeOptions "database" + i = 0 + + while i < len + + # setting Database's option + if dArr[arr[i]].val is defaultValue + options = options + "" + else + options = options + "" + i++ + options + +# +#* input: selectObjId (designated select menu, such as species, cross, etc... ) +#* function: setting options value for select menu dynamically based on linkage array(lArr) +#* output: null +# +fillOptions = (selectObjId) -> + unless selectObjId? + speciesObj = document.getElementById("species") + len = sArr.length + i = 1 + + while i < len + + # setting Species' option + speciesObj.options[i - 1] = new Option(sArr[i].txt, sArr[i].val) + i++ + updateChocie "species" + else if selectObjId is "species" + speciesObj = document.getElementById("species") + groupObj = document.getElementById("cross") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get group(cross) info from lArr + arr[idx++] = lArr[i][1] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and not Contains(arr, lArr[i][1]) + i++ + idx = 0 + len = arr.length + removeOptions "cross" + i = 0 + + while i < len + + # setting Group's option + groupObj.options[idx++] = new Option(gArr[arr[i]].txt, gArr[arr[i]].val) + i++ + updateChocie "cross" + else if selectObjId is "cross" + speciesObj = document.getElementById("species") + groupObj = document.getElementById("cross") + typeObj = document.getElementById("tissue") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get type(tissue) info from lArr + arr[idx++] = lArr[i][2] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and not Contains(arr, lArr[i][2]) + i++ + idx = 0 + len = arr.length + removeOptions "tissue" + i = 0 + + while i < len + + # setting Type's option + typeObj.options[idx++] = new Option(tArr[arr[i]].txt, tArr[arr[i]].val) + i++ + updateChocie "tissue" + else if selectObjId is "tissue" + speciesObj = document.getElementById("species") + groupObj = document.getElementById("cross") + typeObj = document.getElementById("tissue") + databaseObj = document.getElementById("database") + len = lArr.length + arr = [] + idx = 0 + i = 1 + + while i < len + + #get dataset(database) info from lArr + arr[idx++] = lArr[i][3] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and lArr[i][2] is (getIndexByValue("tissue", typeObj.value)).toString() and not Contains(arr, lArr[i][3]) + i++ + idx = 0 + len = arr.length + removeOptions "database" + i = 0 + + while i < len + + # setting Database's option + databaseObj.options[idx++] = new Option(dArr[arr[i]].txt, dArr[arr[i]].val) + i++ + updateChocie "database" + +# +#* input: arr (targeted array); obj (targeted value) +#* function: check whether targeted array contains targeted value or not +#* output: return true, if array contains targeted value, otherwise return false +# +Contains = (arr, obj) -> + i = arr.length + return true if arr[i] is obj while i-- + false + +# +#* input: selectObj (designated select menu, such as species, cross, etc... ) +#* function: clear designated select menu's option +#* output: null +# +removeOptions = (selectObj) -> + selectObj = document.getElementById(selectObj) unless typeof selectObj is "object" + len = selectObj.options.length + i = 0 + + while i < len + + # clear current selection + selectObj.options[0] = null + i++ + +# +#* input: selectObjId (designated select menu, such as species, cross, etc... ) +#* Value: target value +#* function: retrieve Index info of target value in designated array +#* output: index info +# +getIndexByValue = (selectObjId, val) -> + if selectObjId is "species" + i = 1 + + while i < sArr.length + return i if sArr[i].val is val + i++ + else if selectObjId is "cross" + i = 1 + + while i < gArr.length + return i if gArr[i].val is val + i++ + else if selectObjId is "tissue" + i = 1 + + while i < tArr.length + return i if tArr[i].val is val + i++ + else + return + +# +#* input: objId (designated select menu, such as species, cross, etc... ) +#* val(targeted value) +#* function: setting option's selected status for designated select menu based on target value, also update the following select menu in the main search page +#* output: return true if selected status has been set, otherwise return false. +# +setChoice = (objId, val) -> + Obj = document.getElementById(objId) + idx = -1 + i = 0 + while i < Obj.options.length + if Obj.options[i].value is val + idx = i + break + i++ + if idx >= 0 + + #setting option's selected status + Obj.options[idx].selected = true + + #update the following select menu + fillOptions objId + else + Obj.options[0].selected = true + fillOptions objId + +# setting option's selected status based on default setting or cookie setting for Species, Group, Type and Database select menu in the main search page http://www.genenetwork.org/ +updateChocie = (selectObjId) -> + if selectObjId is "species" + defaultSpecies = getDefaultValue("species") + + #setting option's selected status + setChoice "species", defaultSpecies + else if selectObjId is "cross" + defaultSet = getDefaultValue("cross") + + #setting option's selected status + setChoice "cross", defaultSet + else if selectObjId is "tissue" + defaultType = getDefaultValue("tissue") + + #setting option's selected status + setChoice "tissue", defaultType + else if selectObjId is "database" + defaultDB = getDefaultValue("database") + + #setting option's selected status + setChoice "database", defaultDB + +#get default value;if cookie exists, then use cookie value, otherwise use default value +getDefaultValue = (selectObjId) -> + + #define default value + defaultSpecies = "mouse" + defaultSet = "BXD" + defaultType = "Hippocampus" + defaultDB = "HC_M2_0606_P" + if selectObjId is "species" + + #if cookie exists, then use cookie value, otherwise use default value + cookieSpecies = getCookie("defaultSpecies") + defaultSpecies = cookieSpecies if cookieSpecies + defaultSpecies + else if selectObjId is "cross" + cookieSet = getCookie("defaultSet") + defaultSet = cookieSet if cookieSet + defaultSet + else if selectObjId is "tissue" + cookieType = getCookie("defaultType") + defaultType = cookieType if cookieType + defaultType + else if selectObjId is "database" + cookieDB = getCookie("defaultDB") + defaultDB = cookieDB if cookieDB + defaultDB + +#setting default value into cookies for the dropdown menus: Species,Group, Type, and Database +setDefault = (thisform) -> + setCookie "cookieTest", "cookieTest", 1 + cookieTest = getCookie("cookieTest") + delCookie "cookieTest" + if cookieTest + defaultSpecies = thisform.species.value + setCookie "defaultSpecies", defaultSpecies, 10 + defaultSet = thisform.cross.value + setCookie "defaultSet", defaultSet, 10 + defaultType = thisform.tissue.value + setCookie "defaultType", defaultType, 10 + defaultDB = thisform.database.value + setCookie "defaultDB", defaultDB, 10 + updateChocie "species" + updateChocie "cross" + updateChocie "tissue" + updateChocie "database" + alert "The current settings are now your default" + else + alert "You need to enable Cookies in your browser." \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js new file mode 100644 index 00000000..d96d7b44 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js @@ -0,0 +1,363 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + var Contains, fillOptions, fillOptionsForIE, getDefaultValue, getIndexByValue, initialDatasetSelection, removeOptions, setChoice, setDefault, updateChocie; + + initialDatasetSelection = function() { + var dOptions, defaultDB, defaultSet, defaultSpecies, defaultType, gOptions, menu0, menu1, menu2, menu3, sOptions, tOptions; + defaultSpecies = getDefaultValue("species"); + defaultSet = getDefaultValue("cross"); + defaultType = getDefaultValue("tissue"); + defaultDB = getDefaultValue("database"); + if (navigator.userAgent.indexOf("MSIE") >= 0) { + sOptions = fillOptionsForIE(null, defaultSpecies); + menu0 = ""; + document.getElementById("menu0").innerHTML = menu0; + gOptions = fillOptionsForIE("species", defaultSet); + menu1 = ""; + document.getElementById("menu1").innerHTML = menu1; + tOptions = fillOptionsForIE("cross", defaultType); + menu2 = ""; + document.getElementById("menu2").innerHTML = menu2; + dOptions = fillOptionsForIE("tissue", defaultDB); + menu3 = ""; + document.getElementById("menu3").innerHTML = menu3; + } else { + fillOptions(null); + } + return searchtip(); + }; + + fillOptionsForIE = function(selectObjId, defaultValue) { + var arr, groupObj, i, idx, len, options, speciesObj, typeObj; + options = ""; + if (selectObjId == null) { + len = sArr.length; + i = 1; + while (i < len) { + if (sArr[i].val === defaultValue) { + options = options + ""; + } else { + options = options + ""; + } + i++; + } + } else if (selectObjId === "species") { + speciesObj = document.getElementById("species"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && !Contains(arr, lArr[i][1])) { + arr[idx++] = lArr[i][1]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("cross"); + i = 0; + while (i < len) { + if (gArr[arr[i]].val === defaultValue) { + options = options + ""; + } else { + options = options + ""; + } + i++; + } + } else if (selectObjId === "cross") { + speciesObj = document.getElementById("species"); + groupObj = document.getElementById("cross"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && lArr[i][1] === (getIndexByValue("cross", groupObj.value)).toString() && !Contains(arr, lArr[i][2])) { + arr[idx++] = lArr[i][2]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("tissue"); + i = 0; + while (i < len) { + if (tArr[arr[i]].val === defaultValue) { + options = options + ""; + } else { + options = options + ""; + } + i++; + } + } else if (selectObjId === "tissue") { + speciesObj = document.getElementById("species"); + groupObj = document.getElementById("cross"); + typeObj = document.getElementById("tissue"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && lArr[i][1] === (getIndexByValue("cross", groupObj.value)).toString() && lArr[i][2] === (getIndexByValue("tissue", typeObj.value)).toString() && !Contains(arr, lArr[i][3])) { + arr[idx++] = lArr[i][3]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("database"); + i = 0; + while (i < len) { + if (dArr[arr[i]].val === defaultValue) { + options = options + ""; + } else { + options = options + ""; + } + i++; + } + } + return options; + }; + + fillOptions = function(selectObjId) { + var arr, databaseObj, groupObj, i, idx, len, speciesObj, typeObj; + if (selectObjId == null) { + speciesObj = document.getElementById("species"); + len = sArr.length; + i = 1; + while (i < len) { + speciesObj.options[i - 1] = new Option(sArr[i].txt, sArr[i].val); + i++; + } + return updateChocie("species"); + } else if (selectObjId === "species") { + speciesObj = document.getElementById("species"); + groupObj = document.getElementById("cross"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && !Contains(arr, lArr[i][1])) { + arr[idx++] = lArr[i][1]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("cross"); + i = 0; + while (i < len) { + groupObj.options[idx++] = new Option(gArr[arr[i]].txt, gArr[arr[i]].val); + i++; + } + return updateChocie("cross"); + } else if (selectObjId === "cross") { + speciesObj = document.getElementById("species"); + groupObj = document.getElementById("cross"); + typeObj = document.getElementById("tissue"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && lArr[i][1] === (getIndexByValue("cross", groupObj.value)).toString() && !Contains(arr, lArr[i][2])) { + arr[idx++] = lArr[i][2]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("tissue"); + i = 0; + while (i < len) { + typeObj.options[idx++] = new Option(tArr[arr[i]].txt, tArr[arr[i]].val); + i++; + } + return updateChocie("tissue"); + } else if (selectObjId === "tissue") { + speciesObj = document.getElementById("species"); + groupObj = document.getElementById("cross"); + typeObj = document.getElementById("tissue"); + databaseObj = document.getElementById("database"); + len = lArr.length; + arr = []; + idx = 0; + i = 1; + while (i < len) { + if (lArr[i][0] === (getIndexByValue("species", speciesObj.value)).toString() && lArr[i][1] === (getIndexByValue("cross", groupObj.value)).toString() && lArr[i][2] === (getIndexByValue("tissue", typeObj.value)).toString() && !Contains(arr, lArr[i][3])) { + arr[idx++] = lArr[i][3]; + } + i++; + } + idx = 0; + len = arr.length; + removeOptions("database"); + i = 0; + while (i < len) { + databaseObj.options[idx++] = new Option(dArr[arr[i]].txt, dArr[arr[i]].val); + i++; + } + return updateChocie("database"); + } + }; + + Contains = function(arr, obj) { + var i; + i = arr.length; + if ((function() { + var _results; + _results = []; + while (i--) { + _results.push(arr[i] === obj); + } + return _results; + })()) { + return true; + } + return false; + }; + + removeOptions = function(selectObj) { + var i, len, _results; + if (typeof selectObj !== "object") { + selectObj = document.getElementById(selectObj); + } + len = selectObj.options.length; + i = 0; + _results = []; + while (i < len) { + selectObj.options[0] = null; + _results.push(i++); + } + return _results; + }; + + getIndexByValue = function(selectObjId, val) { + var i; + if (selectObjId === "species") { + i = 1; + while (i < sArr.length) { + if (sArr[i].val === val) { + return i; + } + i++; + } + } else if (selectObjId === "cross") { + i = 1; + while (i < gArr.length) { + if (gArr[i].val === val) { + return i; + } + i++; + } + } else if (selectObjId === "tissue") { + i = 1; + while (i < tArr.length) { + if (tArr[i].val === val) { + return i; + } + i++; + } + } else { + + } + }; + + setChoice = function(objId, val) { + var Obj, i, idx; + Obj = document.getElementById(objId); + idx = -1; + i = 0; + while (i < Obj.options.length) { + if (Obj.options[i].value === val) { + idx = i; + break; + } + i++; + } + if (idx >= 0) { + Obj.options[idx].selected = true; + return fillOptions(objId); + } else { + Obj.options[0].selected = true; + return fillOptions(objId); + } + }; + + updateChocie = function(selectObjId) { + var defaultDB, defaultSet, defaultSpecies, defaultType; + if (selectObjId === "species") { + defaultSpecies = getDefaultValue("species"); + return setChoice("species", defaultSpecies); + } else if (selectObjId === "cross") { + defaultSet = getDefaultValue("cross"); + return setChoice("cross", defaultSet); + } else if (selectObjId === "tissue") { + defaultType = getDefaultValue("tissue"); + return setChoice("tissue", defaultType); + } else if (selectObjId === "database") { + defaultDB = getDefaultValue("database"); + return setChoice("database", defaultDB); + } + }; + + getDefaultValue = function(selectObjId) { + var cookieDB, cookieSet, cookieSpecies, cookieType, defaultDB, defaultSet, defaultSpecies, defaultType; + defaultSpecies = "mouse"; + defaultSet = "BXD"; + defaultType = "Hippocampus"; + defaultDB = "HC_M2_0606_P"; + if (selectObjId === "species") { + cookieSpecies = getCookie("defaultSpecies"); + if (cookieSpecies) { + defaultSpecies = cookieSpecies; + } + return defaultSpecies; + } else if (selectObjId === "cross") { + cookieSet = getCookie("defaultSet"); + if (cookieSet) { + defaultSet = cookieSet; + } + return defaultSet; + } else if (selectObjId === "tissue") { + cookieType = getCookie("defaultType"); + if (cookieType) { + defaultType = cookieType; + } + return defaultType; + } else if (selectObjId === "database") { + cookieDB = getCookie("defaultDB"); + if (cookieDB) { + defaultDB = cookieDB; + } + return defaultDB; + } + }; + + setDefault = function(thisform) { + var cookieTest, defaultDB, defaultSet, defaultSpecies, defaultType; + setCookie("cookieTest", "cookieTest", 1); + cookieTest = getCookie("cookieTest"); + delCookie("cookieTest"); + if (cookieTest) { + defaultSpecies = thisform.species.value; + setCookie("defaultSpecies", defaultSpecies, 10); + defaultSet = thisform.cross.value; + setCookie("defaultSet", defaultSet, 10); + defaultType = thisform.tissue.value; + setCookie("defaultType", defaultType, 10); + defaultDB = thisform.database.value; + setCookie("defaultDB", defaultDB, 10); + updateChocie("species"); + updateChocie("cross"); + updateChocie("tissue"); + updateChocie("database"); + return alert("The current settings are now your default"); + } else { + return alert("You need to enable Cookies in your browser."); + } + }; + +}).call(this); diff --git a/wqflask/wqflask/static/new/javascript/validation.js b/wqflask/wqflask/static/new/javascript/validation.js new file mode 100644 index 00000000..06ed196d --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/validation.js @@ -0,0 +1,51 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + + $(function() { + var remove_samples_is_valid, validate_remove_samples; + remove_samples_is_valid = function(input) { + var new_splats, pattern, splat, splats, _i, _len; + if (_.trim(input).length === 0) { + return true; + } + splats = input.split(","); + new_splats = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = splats.length; _i < _len; _i++) { + input = splats[_i]; + _results.push(_.trim(input)); + } + return _results; + })(); + console.log("new_splats:", new_splats); + pattern = /^\d+\s*(?:-\s*\d+)?\s*$/; + for (_i = 0, _len = new_splats.length; _i < _len; _i++) { + splat = new_splats[_i]; + console.log("splat is:", splat); + if (!splat.match(pattern)) { + return false; + } + } + return true; + }; + validate_remove_samples = function() { + /* + Check if input for the remove samples function is valid and notify the user if not + */ + + var input; + input = $('#remove_samples_field').val(); + console.log("input is:", input); + if (remove_samples_is_valid(input)) { + console.log("input is valid"); + return $('#remove_samples_invalid').hide(); + } else { + console.log("input isn't valid"); + return $('#remove_samples_invalid').show(); + } + }; + return $('#remove_samples_field').change(validate_remove_samples); + }); + +}).call(this); diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index f2178f3c..1610c521 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -365,7 +365,7 @@

        Special thanks to CYP1A2 and AHR.


        GeneNetwork is supported by:

        -
        - - - - - - -
         name
        - - - - - -
        - - - - - - -
        - -
        - - branch: master - - -
        - -
        Switch branches/tags
        -
        -
        - - -
        - -
        -
        Nothing to show
        -
        - -

        - master -

        -
        -
        - - -
        -
        -
        -
        - - - -
        - - - - - - - - - - -
        - - - - - - - - -
        - - - - -
        - - douglascrockford - - - - - -
        - - -
        -
        - -
        -
        -
        -
        - - file - 487 lines (369 sloc) - 17.53 kb -
        - -
        -
        - - - - - -
        -
        1
        -2
        -3
        -4
        -5
        -6
        -7
        -8
        -9
        -10
        -11
        -12
        -13
        -14
        -15
        -16
        -17
        -18
        -19
        -20
        -21
        -22
        -23
        -24
        -25
        -26
        -27
        -28
        -29
        -30
        -31
        -32
        -33
        -34
        -35
        -36
        -37
        -38
        -39
        -40
        -41
        -42
        -43
        -44
        -45
        -46
        -47
        -48
        -49
        -50
        -51
        -52
        -53
        -54
        -55
        -56
        -57
        -58
        -59
        -60
        -61
        -62
        -63
        -64
        -65
        -66
        -67
        -68
        -69
        -70
        -71
        -72
        -73
        -74
        -75
        -76
        -77
        -78
        -79
        -80
        -81
        -82
        -83
        -84
        -85
        -86
        -87
        -88
        -89
        -90
        -91
        -92
        -93
        -94
        -95
        -96
        -97
        -98
        -99
        -100
        -101
        -102
        -103
        -104
        -105
        -106
        -107
        -108
        -109
        -110
        -111
        -112
        -113
        -114
        -115
        -116
        -117
        -118
        -119
        -120
        -121
        -122
        -123
        -124
        -125
        -126
        -127
        -128
        -129
        -130
        -131
        -132
        -133
        -134
        -135
        -136
        -137
        -138
        -139
        -140
        -141
        -142
        -143
        -144
        -145
        -146
        -147
        -148
        -149
        -150
        -151
        -152
        -153
        -154
        -155
        -156
        -157
        -158
        -159
        -160
        -161
        -162
        -163
        -164
        -165
        -166
        -167
        -168
        -169
        -170
        -171
        -172
        -173
        -174
        -175
        -176
        -177
        -178
        -179
        -180
        -181
        -182
        -183
        -184
        -185
        -186
        -187
        -188
        -189
        -190
        -191
        -192
        -193
        -194
        -195
        -196
        -197
        -198
        -199
        -200
        -201
        -202
        -203
        -204
        -205
        -206
        -207
        -208
        -209
        -210
        -211
        -212
        -213
        -214
        -215
        -216
        -217
        -218
        -219
        -220
        -221
        -222
        -223
        -224
        -225
        -226
        -227
        -228
        -229
        -230
        -231
        -232
        -233
        -234
        -235
        -236
        -237
        -238
        -239
        -240
        -241
        -242
        -243
        -244
        -245
        -246
        -247
        -248
        -249
        -250
        -251
        -252
        -253
        -254
        -255
        -256
        -257
        -258
        -259
        -260
        -261
        -262
        -263
        -264
        -265
        -266
        -267
        -268
        -269
        -270
        -271
        -272
        -273
        -274
        -275
        -276
        -277
        -278
        -279
        -280
        -281
        -282
        -283
        -284
        -285
        -286
        -287
        -288
        -289
        -290
        -291
        -292
        -293
        -294
        -295
        -296
        -297
        -298
        -299
        -300
        -301
        -302
        -303
        -304
        -305
        -306
        -307
        -308
        -309
        -310
        -311
        -312
        -313
        -314
        -315
        -316
        -317
        -318
        -319
        -320
        -321
        -322
        -323
        -324
        -325
        -326
        -327
        -328
        -329
        -330
        -331
        -332
        -333
        -334
        -335
        -336
        -337
        -338
        -339
        -340
        -341
        -342
        -343
        -344
        -345
        -346
        -347
        -348
        -349
        -350
        -351
        -352
        -353
        -354
        -355
        -356
        -357
        -358
        -359
        -360
        -361
        -362
        -363
        -364
        -365
        -366
        -367
        -368
        -369
        -370
        -371
        -372
        -373
        -374
        -375
        -376
        -377
        -378
        -379
        -380
        -381
        -382
        -383
        -384
        -385
        -386
        -387
        -388
        -389
        -390
        -391
        -392
        -393
        -394
        -395
        -396
        -397
        -398
        -399
        -400
        -401
        -402
        -403
        -404
        -405
        -406
        -407
        -408
        -409
        -410
        -411
        -412
        -413
        -414
        -415
        -416
        -417
        -418
        -419
        -420
        -421
        -422
        -423
        -424
        -425
        -426
        -427
        -428
        -429
        -430
        -431
        -432
        -433
        -434
        -435
        -436
        -437
        -438
        -439
        -440
        -441
        -442
        -443
        -444
        -445
        -446
        -447
        -448
        -449
        -450
        -451
        -452
        -453
        -454
        -455
        -456
        -457
        -458
        -459
        -460
        -461
        -462
        -463
        -464
        -465
        -466
        -467
        -468
        -469
        -470
        -471
        -472
        -473
        -474
        -475
        -476
        -477
        -478
        -479
        -480
        -481
        -482
        -483
        -484
        -485
        -486
        -
        -
        -
        /*
        json2.js
        2012-10-08

        Public Domain.

        NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

        See http://www.JSON.org/js.html


        This code should be minified before deployment.
        See http://javascript.crockford.com/jsmin.html

        USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
        NOT CONTROL.


        This file creates a global JSON object containing two methods: stringify
        and parse.

        JSON.stringify(value, replacer, space)
        value any JavaScript value, usually an object or array.

        replacer an optional parameter that determines how object
        values are stringified for objects. It can be a
        function or an array of strings.

        space an optional parameter that specifies the indentation
        of nested structures. If it is omitted, the text will
        be packed without extra whitespace. If it is a number,
        it will specify the number of spaces to indent at each
        level. If it is a string (such as '\t' or '&nbsp;'),
        it contains the characters used to indent at each level.

        This method produces a JSON text from a JavaScript value.

        When an object value is found, if the object contains a toJSON
        method, its toJSON method will be called and the result will be
        stringified. A toJSON method does not serialize: it returns the
        value represented by the name/value pair that should be serialized,
        or undefined if nothing should be serialized. The toJSON method
        will be passed the key associated with the value, and this will be
        bound to the value

        For example, this would serialize Dates as ISO strings.

        Date.prototype.toJSON = function (key) {
        function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
        }

        return this.getUTCFullYear() + '-' +
        f(this.getUTCMonth() + 1) + '-' +
        f(this.getUTCDate()) + 'T' +
        f(this.getUTCHours()) + ':' +
        f(this.getUTCMinutes()) + ':' +
        f(this.getUTCSeconds()) + 'Z';
        };

        You can provide an optional replacer method. It will be passed the
        key and value of each member, with this bound to the containing
        object. The value that is returned from your method will be
        serialized. If your method returns undefined, then the member will
        be excluded from the serialization.

        If the replacer parameter is an array of strings, then it will be
        used to select the members to be serialized. It filters the results
        such that only members with keys listed in the replacer array are
        stringified.

        Values that do not have JSON representations, such as undefined or
        functions, will not be serialized. Such values in objects will be
        dropped; in arrays they will be replaced with null. You can use
        a replacer function to replace those with JSON values.
        JSON.stringify(undefined) returns undefined.

        The optional space parameter produces a stringification of the
        value that is filled with line breaks and indentation to make it
        easier to read.

        If the space parameter is a non-empty string, then that string will
        be used for indentation. If the space parameter is a number, then
        the indentation will be that many spaces.

        Example:

        text = JSON.stringify(['e', {pluribus: 'unum'}]);
        // text is '["e",{"pluribus":"unum"}]'


        text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
        // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'

        text = JSON.stringify([new Date()], function (key, value) {
        return this[key] instanceof Date ?
        'Date(' + this[key] + ')' : value;
        });
        // text is '["Date(---current time---)"]'


        JSON.parse(text, reviver)
        This method parses a JSON text to produce an object or array.
        It can throw a SyntaxError exception.

        The optional reviver parameter is a function that can filter and
        transform the results. It receives each of the keys and values,
        and its return value is used instead of the original value.
        If it returns what it received, then the structure is not modified.
        If it returns undefined then the member is deleted.

        Example:

        // Parse the text. Values that look like ISO date strings will
        // be converted to Date objects.

        myData = JSON.parse(text, function (key, value) {
        var a;
        if (typeof value === 'string') {
        a =
        /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
        if (a) {
        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
        +a[5], +a[6]));
        }
        }
        return value;
        });

        myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
        var d;
        if (typeof value === 'string' &&
        value.slice(0, 5) === 'Date(' &&
        value.slice(-1) === ')') {
        d = new Date(value.slice(5, -1));
        if (d) {
        return d;
        }
        }
        return value;
        });


        This is a reference implementation. You are free to copy, modify, or
        redistribute.
        */

        /*jslint evil: true, regexp: true */

        /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
        call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
        getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
        lastIndex, length, parse, prototype, push, replace, slice, stringify,
        test, toJSON, toString, valueOf
        */


        // Create a JSON object only if one does not already exist. We create the
        // methods in a closure to avoid creating global variables.

        if (typeof JSON !== 'object') {
            JSON = {};
        }

        (function () {
            'use strict';

            function f(n) {
                // Format integers to have at least two digits.
                return n < 10 ? '0' + n : n;
            }

            if (typeof Date.prototype.toJSON !== 'function') {

                Date.prototype.toJSON = function (key) {

                    return isFinite(this.valueOf())
                        ? this.getUTCFullYear() + '-' +
                            f(this.getUTCMonth() + 1) + '-' +
                            f(this.getUTCDate()) + 'T' +
                            f(this.getUTCHours()) + ':' +
                            f(this.getUTCMinutes()) + ':' +
                            f(this.getUTCSeconds()) + 'Z'
                        : null;
                };

                String.prototype.toJSON =
                    Number.prototype.toJSON =
                    Boolean.prototype.toJSON = function (key) {
                        return this.valueOf();
                    };
            }

            var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
                escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
                gap,
                indent,
                meta = { // table of character substitutions
                    '\b': '\\b',
                    '\t': '\\t',
                    '\n': '\\n',
                    '\f': '\\f',
                    '\r': '\\r',
                    '"' : '\\"',
                    '\\': '\\\\'
                },
                rep;


            function quote(string) {

        // If the string contains no control characters, no quote characters, and no
        // backslash characters, then we can safely slap some quotes around it.
        // Otherwise we must also replace the offending characters with safe escape
        // sequences.

                escapable.lastIndex = 0;
                return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
                    var c = meta[a];
                    return typeof c === 'string'
                        ? c
                        : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                }) + '"' : '"' + string + '"';
            }


            function str(key, holder) {

        // Produce a string from holder[key].

                var i, // The loop counter.
                    k, // The member key.
                    v, // The member value.
                    length,
                    mind = gap,
                    partial,
                    value = holder[key];

        // If the value has a toJSON method, call it to obtain a replacement value.

                if (value && typeof value === 'object' &&
                        typeof value.toJSON === 'function') {
                    value = value.toJSON(key);
                }

        // If we were called with a replacer function, then call the replacer to
        // obtain a replacement value.

                if (typeof rep === 'function') {
                    value = rep.call(holder, key, value);
                }

        // What happens next depends on the value's type.

                switch (typeof value) {
                case 'string':
                    return quote(value);

                case 'number':

        // JSON numbers must be finite. Encode non-finite numbers as null.

                    return isFinite(value) ? String(value) : 'null';

                case 'boolean':
                case 'null':

        // If the value is a boolean or null, convert it to a string. Note:
        // typeof null does not produce 'null'. The case is included here in
        // the remote chance that this gets fixed someday.

                    return String(value);

        // If the type is 'object', we might be dealing with an object or an array or
        // null.

                case 'object':

        // Due to a specification blunder in ECMAScript, typeof null is 'object',
        // so watch out for that case.

                    if (!value) {
                        return 'null';
                    }

        // Make an array to hold the partial results of stringifying this object value.

                    gap += indent;
                    partial = [];

        // Is the value an array?

                    if (Object.prototype.toString.apply(value) === '[object Array]') {

        // The value is an array. Stringify every element. Use null as a placeholder
        // for non-JSON values.

                        length = value.length;
                        for (i = 0; i < length; i += 1) {
                            partial[i] = str(i, value) || 'null';
                        }

        // Join all of the elements together, separated with commas, and wrap them in
        // brackets.

                        v = partial.length === 0
                            ? '[]'
                            : gap
                            ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                            : '[' + partial.join(',') + ']';
                        gap = mind;
                        return v;
                    }

        // If the replacer is an array, use it to select the members to be stringified.

                    if (rep && typeof rep === 'object') {
                        length = rep.length;
                        for (i = 0; i < length; i += 1) {
                            if (typeof rep[i] === 'string') {
                                k = rep[i];
                                v = str(k, value);
                                if (v) {
                                    partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                }
                            }
                        }
                    } else {

        // Otherwise, iterate through all of the keys in the object.

                        for (k in value) {
                            if (Object.prototype.hasOwnProperty.call(value, k)) {
                                v = str(k, value);
                                if (v) {
                                    partial.push(quote(k) + (gap ? ': ' : ':') + v);
                                }
                            }
                        }
                    }

        // Join all of the member texts together, separated with commas,
        // and wrap them in braces.

                    v = partial.length === 0
                        ? '{}'
                        : gap
                        ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                        : '{' + partial.join(',') + '}';
                    gap = mind;
                    return v;
                }
            }

        // If the JSON object does not yet have a stringify method, give it one.

            if (typeof JSON.stringify !== 'function') {
                JSON.stringify = function (value, replacer, space) {

        // The stringify method takes a value and an optional replacer, and an optional
        // space parameter, and returns a JSON text. The replacer can be a function
        // that can replace values, or an array of strings that will select the keys.
        // A default replacer method can be provided. Use of the space parameter can
        // produce text that is more easily readable.

                    var i;
                    gap = '';
                    indent = '';

        // If the space parameter is a number, make an indent string containing that
        // many spaces.

                    if (typeof space === 'number') {
                        for (i = 0; i < space; i += 1) {
                            indent += ' ';
                        }

        // If the space parameter is a string, it will be used as the indent string.

                    } else if (typeof space === 'string') {
                        indent = space;
                    }

        // If there is a replacer, it must be a function or an array.
        // Otherwise, throw an error.

                    rep = replacer;
                    if (replacer && typeof replacer !== 'function' &&
                            (typeof replacer !== 'object' ||
                            typeof replacer.length !== 'number')) {
                        throw new Error('JSON.stringify');
                    }

        // Make a fake root object containing our value under the key of ''.
        // Return the result of stringifying the value.

                    return str('', {'': value});
                };
            }


        // If the JSON object does not yet have a parse method, give it one.

            if (typeof JSON.parse !== 'function') {
                JSON.parse = function (text, reviver) {

        // The parse method takes a text and an optional reviver function, and returns
        // a JavaScript value if the text is a valid JSON text.

                    var j;

                    function walk(holder, key) {

        // The walk method is used to recursively walk the resulting structure so
        // that modifications can be made.

                        var k, v, value = holder[key];
                        if (value && typeof value === 'object') {
                            for (k in value) {
                                if (Object.prototype.hasOwnProperty.call(value, k)) {
                                    v = walk(value, k);
                                    if (v !== undefined) {
                                        value[k] = v;
                                    } else {
                                        delete value[k];
                                    }
                                }
                            }
                        }
                        return reviver.call(holder, key, value);
                    }


        // Parsing happens in four stages. In the first stage, we replace certain
        // Unicode characters with escape sequences. JavaScript handles many characters
        // incorrectly, either silently deleting them, or treating them as line endings.

                    text = String(text);
                    cx.lastIndex = 0;
                    if (cx.test(text)) {
                        text = text.replace(cx, function (a) {
                            return '\\u' +
                                ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                        });
                    }

        // In the second stage, we run the text against regular expressions that look
        // for non-JSON patterns. We are especially concerned with '()' and 'new'
        // because they can cause invocation, and '=' because it can cause mutation.
        // But just to be safe, we want to reject all unexpected forms.

        // We split the second stage into 4 regexp operations in order to work around
        // crippling inefficiencies in IE's and Safari's regexp engines. First we
        // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
        // replace all simple value tokens with ']' characters. Third, we delete all
        // open brackets that follow a colon or comma or that begin the text. Finally,
        // we look to see that the remaining characters are only whitespace or ']' or
        // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

                    if (/^[\],:{}\s]*$/
                            .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                                .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                                .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

        // In the third stage we use the eval function to compile the text into a
        // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
        // in JavaScript: it can begin a block or an object literal. We wrap the text
        // in parens to eliminate the ambiguity.

                        j = eval('(' + text + ')');

        // In the optional fourth stage, we recursively walk the new structure, passing
        // each name/value pair to a reviver function for possible transformation.

                        return typeof reviver === 'function'
                            ? walk({'': j}, '')
                            : j;
                    }

        // If the text is not JSON parseable, then a SyntaxError is thrown.

                    throw new SyntaxError('JSON.parse');
                };
            }
        }());
        -
        -
        - -
        -
        -
        -
        - -
        - - - -
        - -
        - - - - - - - - - - - - -
        -

        Markdown Cheat Sheet

        - -
        - -
        -
        -

        Format Text

        -

        Headers

        -
        -# This is an <h1> tag
        -## This is an <h2> tag
        -###### This is an <h6> tag
        -

        Text styles

        -
        -*This text will be italic*
        -_This will also be italic_
        -**This text will be bold**
        -__This will also be bold__
        -
        -*You **can** combine them*
        -
        -
        -
        -

        Lists

        -

        Unordered

        -
        -* Item 1
        -* Item 2
        -  * Item 2a
        -  * Item 2b
        -

        Ordered

        -
        -1. Item 1
        -2. Item 2
        -3. Item 3
        -   * Item 3a
        -   * Item 3b
        -
        -
        -

        Miscellaneous

        -

        Images

        -
        -![GitHub Logo](/images/logo.png)
        -Format: ![Alt Text](url)
        -
        -

        Links

        -
        -http://github.com - automatic!
        -[GitHub](http://github.com)
        -

        Blockquotes

        -
        -As Kanye West said:
        -
        -> We're living the future so
        -> the present is our past.
        -
        -
        -
        -
        - -

        Code Examples in Markdown

        -
        -

        Syntax highlighting with GFM

        -
        -```javascript
        -function fancyAlert(arg) {
        -  if(arg) {
        -    $.facebox({div:'#foo'})
        -  }
        +            Values that do not have JSON representations, such as undefined or
        +            functions, will not be serialized. Such values in objects will be
        +            dropped; in arrays they will be replaced with null. You can use
        +            a replacer function to replace those with JSON values.
        +            JSON.stringify(undefined) returns undefined.
        +
        +            The optional space parameter produces a stringification of the
        +            value that is filled with line breaks and indentation to make it
        +            easier to read.
        +
        +            If the space parameter is a non-empty string, then that string will
        +            be used for indentation. If the space parameter is a number, then
        +            the indentation will be that many spaces.
        +
        +            Example:
        +
        +            text = JSON.stringify(['e', {pluribus: 'unum'}]);
        +            // text is '["e",{"pluribus":"unum"}]'
        +
        +
        +            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
        +            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
        +
        +            text = JSON.stringify([new Date()], function (key, value) {
        +                return this[key] instanceof Date ?
        +                    'Date(' + this[key] + ')' : value;
        +            });
        +            // text is '["Date(---current time---)"]'
        +
        +
        +        JSON.parse(text, reviver)
        +            This method parses a JSON text to produce an object or array.
        +            It can throw a SyntaxError exception.
        +
        +            The optional reviver parameter is a function that can filter and
        +            transform the results. It receives each of the keys and values,
        +            and its return value is used instead of the original value.
        +            If it returns what it received, then the structure is not modified.
        +            If it returns undefined then the member is deleted.
        +
        +            Example:
        +
        +            // Parse the text. Values that look like ISO date strings will
        +            // be converted to Date objects.
        +
        +            myData = JSON.parse(text, function (key, value) {
        +                var a;
        +                if (typeof value === 'string') {
        +                    a =
        +/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
        +                    if (a) {
        +                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
        +                            +a[5], +a[6]));
        +                    }
        +                }
        +                return value;
        +            });
        +
        +            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
        +                var d;
        +                if (typeof value === 'string' &&
        +                        value.slice(0, 5) === 'Date(' &&
        +                        value.slice(-1) === ')') {
        +                    d = new Date(value.slice(5, -1));
        +                    if (d) {
        +                        return d;
        +                    }
        +                }
        +                return value;
        +            });
        +
        +
        +    This is a reference implementation. You are free to copy, modify, or
        +    redistribute.
        +*/
        +
        +/*jslint evil: true, regexp: true */
        +
        +/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
        +    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
        +    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
        +    lastIndex, length, parse, prototype, push, replace, slice, stringify,
        +    test, toJSON, toString, valueOf
        +*/
        +
        +
        +// Create a JSON object only if one does not already exist. We create the
        +// methods in a closure to avoid creating global variables.
        +
        +if (typeof JSON !== 'object') {
        +    JSON = {};
         }
        -```
        -
        -
        -

        Or, indent your code 4 spaces

        -
        -Here is a Python code example
        -without syntax highlighting:
        -
        -    def foo:
        -      if not bar:
        -        return true
        -
        -
        -

        Inline code for comments

        -
        -I think you should use an
        -`<addr>` element here instead.
        -
        -
        - -
        - - - -
        - - Something went wrong with that request. Please try again. - -
        - -
        -

        Looking for the GitHub logo?

        - -
        - - - - - - - +(function () { + 'use strict'; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + if (typeof Date.prototype.toJSON !== 'function') { + + Date.prototype.toJSON = function (key) { + + return isFinite(this.valueOf()) + ? this.getUTCFullYear() + '-' + + f(this.getUTCMonth() + 1) + '-' + + f(this.getUTCDate()) + 'T' + + f(this.getUTCHours()) + ':' + + f(this.getUTCMinutes()) + ':' + + f(this.getUTCSeconds()) + 'Z' + : null; + }; + + String.prototype.toJSON = + Number.prototype.toJSON = + Boolean.prototype.toJSON = function (key) { + return this.valueOf(); + }; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + +// If the string contains no control characters, no quote characters, and no +// backslash characters, then we can safely slap some quotes around it. +// Otherwise we must also replace the offending characters with safe escape +// sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' + ? c + : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + +// Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + +// If the value has a toJSON method, call it to obtain a replacement value. + + if (value && typeof value === 'object' && + typeof value.toJSON === 'function') { + value = value.toJSON(key); + } + +// If we were called with a replacer function, then call the replacer to +// obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + +// What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + +// JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + +// If the value is a boolean or null, convert it to a string. Note: +// typeof null does not produce 'null'. The case is included here in +// the remote chance that this gets fixed someday. + + return String(value); + +// If the type is 'object', we might be dealing with an object or an array or +// null. + + case 'object': + +// Due to a specification blunder in ECMAScript, typeof null is 'object', +// so watch out for that case. + + if (!value) { + return 'null'; + } + +// Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + +// Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + +// The value is an array. Stringify every element. Use null as a placeholder +// for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + +// Join all of the elements together, separated with commas, and wrap them in +// brackets. + + v = partial.length === 0 + ? '[]' + : gap + ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' + : '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + +// If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + +// Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + +// Join all of the member texts together, separated with commas, +// and wrap them in braces. + + v = partial.length === 0 + ? '{}' + : gap + ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' + : '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + +// If the JSON object does not yet have a stringify method, give it one. + + if (typeof JSON.stringify !== 'function') { + JSON.stringify = function (value, replacer, space) { + +// The stringify method takes a value and an optional replacer, and an optional +// space parameter, and returns a JSON text. The replacer can be a function +// that can replace values, or an array of strings that will select the keys. +// A default replacer method can be provided. Use of the space parameter can +// produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + +// If the space parameter is a number, make an indent string containing that +// many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + +// If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + +// If there is a replacer, it must be a function or an array. +// Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + +// Make a fake root object containing our value under the key of ''. +// Return the result of stringifying the value. + + return str('', {'': value}); + }; + } + + +// If the JSON object does not yet have a parse method, give it one. + + if (typeof JSON.parse !== 'function') { + JSON.parse = function (text, reviver) { + +// The parse method takes a text and an optional reviver function, and returns +// a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + +// The walk method is used to recursively walk the resulting structure so +// that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + +// Parsing happens in four stages. In the first stage, we replace certain +// Unicode characters with escape sequences. JavaScript handles many characters +// incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + +// In the second stage, we run the text against regular expressions that look +// for non-JSON patterns. We are especially concerned with '()' and 'new' +// because they can cause invocation, and '=' because it can cause mutation. +// But just to be safe, we want to reject all unexpected forms. + +// We split the second stage into 4 regexp operations in order to work around +// crippling inefficiencies in IE's and Safari's regexp engines. First we +// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we +// replace all simple value tokens with ']' characters. Third, we delete all +// open brackets that follow a colon or comma or that begin the text. Finally, +// we look to see that the remaining characters are only whitespace or ']' or +// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + +// In the third stage we use the eval function to compile the text into a +// JavaScript structure. The '{' operator is subject to a syntactic ambiguity +// in JavaScript: it can begin a block or an object literal. We wrap the text +// in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + +// In the optional fourth stage, we recursively walk the new structure, passing +// each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' + ? walk({'': j}, '') + : j; + } + +// If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + } +}()); diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index 687cf8b2..51d963fc 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -96,8 +96,7 @@ - + @@ -107,7 +106,7 @@
        - +
        @@ -140,9 +139,8 @@ - + Arthur Centeno.

        - Designed and coded by Sam Ockman, Xiaodong Zhou, Christian Fernandez, + Designed and coded by Sam Ockman, Xiaodong Zhou, + Christian Fernandez, Ning Liu, Rudi Alberts, Elissa Chesler, Jintao Wang, Kenneth Manly, Robert W. Williams, and colleagues.

        @@ -409,6 +408,8 @@ + + -- cgit v1.2.3 From 55d78345ba1cd2f56b1aecabf5bb3753bfd7ca13 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 24 Oct 2012 17:39:43 -0500 Subject: Now builds json datastructure for menus correctly --- wqflask/base/webqtlFormData.py | 57 +- wqflask/maintenance/gen_select_dataset.py | 97 +- wqflask/wqflask/correlation/CorrelationPage.py | 25 +- wqflask/wqflask/search_results.py | 67 +- .../static/new/javascript/dataset_menu_structure | 5984 ++++---------------- wqflask/wqflask/views.py | 9 +- 6 files changed, 1193 insertions(+), 5046 deletions(-) diff --git a/wqflask/base/webqtlFormData.py b/wqflask/base/webqtlFormData.py index 710c9f53..ff1db0e8 100755 --- a/wqflask/base/webqtlFormData.py +++ b/wqflask/base/webqtlFormData.py @@ -44,9 +44,9 @@ from utility import webqtlUtil -class webqtlFormData: +class webqtlFormData(object): 'Represents data from a WebQTL form page, needed to generate the next page' - + attrs = ('formID','RISet','genotype','samplelist','allsamplelist', 'display_variance' 'suggestive','significance','submitID','identification', 'enablevariance', 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo') @@ -62,7 +62,7 @@ class webqtlFormData: print("in webqtlFormData start_vars are:", pf(start_vars)) for item in webqtlFormData.attrs: self.__dict__[item] = None - + #ZS: This is only used in DataEditingPage.py (as far as I know) self.varianceDispName = None @@ -103,7 +103,7 @@ class webqtlFormData: self.ppolar = None self.mpolar = None - + print("[yellow] self.RISet is:", self.RISet) if self.RISet: #try: @@ -112,13 +112,13 @@ class webqtlFormData: #except: # f1 = f12 = self.mpolar = self.ppolar = None - + def set_number(stringy): return int(stringy) if stringy else 2000 # Rob asked to change the default value to 2000 self.nperm = set_number(self.nperm) self.nboot = set_number(self.nboot) - + #if self.allsamplelist: # self.allsamplelist = map(string.strip, string.split(self.allsamplelist)) @@ -134,6 +134,7 @@ class webqtlFormData: def __getitem__(self, key): + print("in __getitem__") return self.__dict__[key] def get(self, key, default=None): @@ -154,22 +155,22 @@ class webqtlFormData: '''read genotype from .geno file''' if self.RISet == 'BXD300': self.RISet = 'BXD' - + assert self.RISet, "self.RISet needs to be set" - + #genotype_1 is Dataset Object without parents and f1 #genotype_2 is Dataset Object with parents and f1 (not for intercross) - + self.genotype_1 = reaper.Dataset() - + full_filename = os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno') - + # reaper barfs on unicode filenames, so here we ensure it's a string full_filename = str(full_filename) self.genotype_1.read(full_filename) - + print("Got to after read") - + try: # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] @@ -186,16 +187,16 @@ class webqtlFormData: else: self.incparentsf1 = 0 self.genotype = self.genotype_1 - + self.samplelist = list(self.genotype.prgy) self.f1list = [] self.parlist = [] - + if _f1 and _f12: self.f1list = [_f1, _f12] if _mat and _pat: self.parlist = [_mat, _pat] - + def readData(self, samplelist, incf1=None): '''read user input data or from trait data and analysis form''' @@ -213,11 +214,11 @@ class webqtlFormData: #print("before traitfiledata self.traitfile is:", pf(self.traitfile)) - traitfiledata = getattr(self, "traitfile", None) - traitpastedata = getattr(self, "traitpaste", None) - variancefiledata = getattr(self, "variancefile", None) - variancepastedata = getattr(self, "variancepaste", None) - Nfiledata = getattr(self, "Nfile", None) + traitfiledata = getattr(self, "traitfile", None) + traitpastedata = getattr(self, "traitpaste", None) + variancefiledata = getattr(self, "variancefile", None) + variancepastedata = getattr(self, "variancepaste", None) + Nfiledata = getattr(self, "Nfile", None) #### Todo: Rewrite below when we get to someone submitting their own trait ##### @@ -246,7 +247,7 @@ class webqtlFormData: elif len(values) > len(samplelist): values = values[:len(samplelist)] print("now values is:", values) - + if variancefiledata: tt = variancefiledata.split() @@ -282,16 +283,16 @@ class webqtlFormData: def informativeStrains(self, samplelist=None, include_variances = None): '''if readData was called, use this to output informative samples (sample with values)''' - + if not samplelist: samplelist = self.samplelist - + samples = [] values = [] variances = [] - + #print("self.allTraitData is:", pf(self.allTraitData)) - + for sample in samplelist: if sample in self.allTraitData: _val, _var = self.allTraitData[sample].value, self.allTraitData[sample].variance @@ -305,13 +306,13 @@ class webqtlFormData: samples.append(sample) values.append(_val) variances.append(None) - + return samples, values, variances, len(samples) #def FormDataAsFloat(self, key): - # + # # #try: # # return float(self.key) # #except: diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index 33813051..9224b884 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -76,17 +76,22 @@ def get_types(groups): types[species] = {} for group_name, _group_full_name in group_dict: # make group an alias to shorten the code - group = types[species][group_name] = [("Phenotypes", "Phenotypes"), - ("Genotypes", "Genotypes")] - Cursor.execute("""select distinct Tissue.Name, concat(Tissue.Name, ' mRNA') from - ProbeFreeze, - ProbeSetFreeze, InbredSet, Tissue where ProbeFreeze.TissueId = Tissue.Id and + types[species][group_name] = [("Phenotypes", "Phenotypes"), ("Genotypes", "Genotypes")] + types[species][group_name] += build_types(species, group_name) + return types + + +def build_types(species, group): + Cursor.execute("""select distinct Tissue.Name, concat(Tissue.Name, ' mRNA') + from ProbeFreeze, ProbeSetFreeze, InbredSet, Tissue, Species + where Species.Name = %s and Species.Id = InbredSet.SpeciesId and + InbredSet.Name = %s and + ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = InbredSet.Id and - InbredSet.Name = %s and ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeSetFreeze.public > %s - order by Tissue.Name""", (group_name, webqtlConfig.PUBLICTHRESH)) - group += Cursor.fetchall() - return types + order by Tissue.Name""", (species, group, webqtlConfig.PUBLICTHRESH)) + return Cursor.fetchall() def get_datasets(types): @@ -97,39 +102,44 @@ def get_datasets(types): for group, type_list in group_dict.iteritems(): datasets[species][group] = {} for type_name, type_full_name in type_list: - dataset_text = dataset_value = None - if type_name == "Phenotypes": - dataset_value = "%sPublish" % group - if group == 'MDP': - dataset_text = "Mouse Phenome Database" - else: - dataset_text = "%s Published Phenotypes" % group - - elif type_name == "Genotypes": - dataset_value = "%sGeno" % group - dataset_text = "%s Genotypes" % group - - if dataset_value: - datasets[species][group][type_name] = [(dataset_value, dataset_text)] - else: - Cursor.execute("""select ProbeSetFreeze.Name, ProbeSetFreeze.FullName from - ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue where - ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and Tissue.Name = %s - and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = - InbredSet.Id and ProbeSetFreeze.public > %s order by - ProbeSetFreeze.CreateTime desc""", (type_name, - webqtlConfig.PUBLICTHRESH)) - datasets[species][group][type_name] = Cursor.fetchall() - + datasets[species][group][type_name] = build_datasets(species, group, type_name) return datasets +def build_datasets(species, group, type_name): + dataset_text = dataset_value = None + if type_name == "Phenotypes": + dataset_value = "%sPublish" % group + if group == 'MDP': + dataset_text = "Mouse Phenome Database" + else: + dataset_text = "%s Published Phenotypes" % group + + elif type_name == "Genotypes": + dataset_value = "%sGeno" % group + dataset_text = "%s Genotypes" % group + + if dataset_value: + return [(dataset_value, dataset_text)] + else: + Cursor.execute("""select ProbeSetFreeze.Name, ProbeSetFreeze.FullName from + ProbeSetFreeze, ProbeFreeze, InbredSet, Tissue, Species where + Species.Name = %s and Species.Id = InbredSet.SpeciesId and + InbredSet.Name = %s and + ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and Tissue.Name = %s + and ProbeFreeze.TissueId = Tissue.Id and ProbeFreeze.InbredSetId = + InbredSet.Id and ProbeSetFreeze.public > %s order by + ProbeSetFreeze.CreateTime desc""", ( + species, group, type_name, webqtlConfig.PUBLICTHRESH)) + return Cursor.fetchall() + + def main(): species = get_species() groups = get_groups(species) types = get_types(groups) datasets = get_datasets(types) - + species.append(('All Species', 'All Species')) groups['All Species'] = [('All Groups', 'All Groups')] types['All Species'] = {} @@ -137,18 +147,25 @@ def main(): datasets['All Species'] = {} datasets['All Species']['All Groups'] = {} datasets['All Species']['All Groups']['Phenotypes'] = [('All Phenotypes','All Phenotypes')] - + data = dict(species=species, groups=groups, types=types, datasets=datasets, ) - - output_file = """../wqflask/static/new/javascript/dataset_menu_structure.json""" - + + output_file = """../wqflask/static/new/javascript/dataset_menu_structure""" + with open(output_file, 'w') as fh: json.dump(data, fh, indent=" ", sort_keys=True) - + + print("\nWrote file to:", output_file) + +def test_it(): + types = build_types("Mouse", "BXD") + print("build_types:", pf(types)) + datasets = build_datasets("Mouse", "BXD", "Hippocampus") + print("build_datasets:", pf(datasets)) if __name__ == '__main__': - main() \ No newline at end of file + main() diff --git a/wqflask/wqflask/correlation/CorrelationPage.py b/wqflask/wqflask/correlation/CorrelationPage.py index a9db493b..e48ea412 100644 --- a/wqflask/wqflask/correlation/CorrelationPage.py +++ b/wqflask/wqflask/correlation/CorrelationPage.py @@ -54,9 +54,6 @@ from dbFunction import webqtlDatabaseFunction import utility.webqtlUtil #this is for parallel computing only. import correlationFunction -import logging -logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) -_log = logging.getLogger("correlation") METHOD_SAMPLE_PEARSON = "1" METHOD_SAMPLE_RANK = "2" @@ -72,9 +69,9 @@ class AuthException(Exception): pass class Trait(object): - - - def __init__(self, name, raw_values = None, lit_corr = None, tissue_corr = None, p_tissue = None): + + + def __init__(self, name, raw_values = None, lit_corr = None, tissue_corr = None, p_tissue = None): self.name = name self.raw_values = raw_values self.lit_corr = lit_corr @@ -281,12 +278,12 @@ class CorrelationPage(templatePage): def __init__(self, fd): #print("in CorrelationPage __init__ fd is:", pf(fd.__dict__)) # Call the superclass constructor - + # Put everything in fd into self self.__dict__.update(fd.__dict__) - + templatePage.__init__(self, fd) - + #print("in CorrelationPage __init__ now fd is:", pf(fd.__dict__)) # Connect to the database if not self.openMysql(): @@ -298,13 +295,13 @@ class CorrelationPage(templatePage): sample_list = get_sample_data(fd) print("sample_list is", pf(sample_list)) - + # Whether the user chose BXD Only, Non-BXD Only, or All Strains # (replace BXD with whatever the group/inbredset name is) # "mdp" stands for "mouse diversity panel" This is outdated; it now represents any # cases/strains from the non-primary group - mdp_choice = fd.MDPChoice if fd.allstrainlist else None - + mdp_choice = fd.MDPChoice if fd.allstrainlist else None + self.species = get_species(fd, self.cursor) #XZ, 09/18/2008: get all information about the user selected database. @@ -334,11 +331,11 @@ class CorrelationPage(templatePage): if len(self.sample_names) < self.corr_min_informative: detail = ['Fewer than %d strain data were entered for %s data set. No calculation of correlation has been attempted.' % (self.corr_min_informative, fd.RISet)] self.error(heading=None, detail=detail) - + for key, value in self.__dict__.items(): if key.startswith("corr"): print("[red] %s - %s" % (key, value)) - + #correlation_method = self.CORRELATION_METHODS[self.method] #rankOrder = self.RANK_ORDERS[self.method] diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 585deb8f..d44fbcef 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -36,17 +36,17 @@ from wqflask import parser from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction -import logging -logging.basicConfig(filename=app.config['LOGFILE'], level=logging.INFO) - -_log = logging.getLogger("search") -_ch = logging.StreamHandler() -_log.addHandler(_ch) +#import logging +#logging.basicConfig(filename=app.config['LOGFILE'], level=logging.INFO) +# +#_log = logging.getLogger("search") +#_ch = logging.StreamHandler() +#_log.addHandler(_ch) from utility import formatting import sys -_log.info("sys.path is: %s" % (sys.path)) +#_log.info("sys.path is: %s" % (sys.path)) #from base.JinjaPage import JinjaEnv, JinjaPage @@ -60,20 +60,29 @@ class SearchResultPage(templatePage): nkeywords = 0 def __init__(self, fd): + print("initing SearchResultPage") + import logging_tree + logging_tree.printout() self.fd = fd if not self.openMysql(): - return + print("ge0") + #return + print("ge0.5") + #causeerror + print("type of fd:", type(fd)) self.database = [fd['database']] - + print("ge0.55") if not self.database or self.database == 'spacer': #Error, No database selected heading = "Search Result" detail = ['''No database was selected for this search, please go back and SELECT at least one database.'''] + print("ge0.6") self.error(heading=heading,detail=detail,error="No Database Selected") - return + #return + print("ge1") ########################################### # Names and IDs of RISet / F2 set ########################################### @@ -102,12 +111,12 @@ class SearchResultPage(templatePage): # Can't use paramater substitution for table names apparently db_type = self.database[0].type + "Freeze" print("db_type [%s]: %s" % (type(db_type), db_type)) - + query = '''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM %s WHERE Name = %%s''' % (db_type) - + self.cursor.execute(query, (individualDB,)) - + (indId, indName, indFullName, @@ -140,6 +149,7 @@ class SearchResultPage(templatePage): self.error(heading=heading,detail=detail,error="No Database Selected") return + print("ge2") self.database[0].getRISet() self.databaseCrosses = [self.database[0].riset] self.databaseCrossIds = [self.database[0].risetid] @@ -159,6 +169,8 @@ class SearchResultPage(templatePage): detail = ["Search can only be performed among the same type of databases"] self.error(heading=heading,detail=detail,error="Error") return + + print("ge3") if self.dbType == "Publish": self.searchField = ['Phenotype.Post_publication_description', 'Phenotype.Pre_publication_description', @@ -182,7 +194,8 @@ class SearchResultPage(templatePage): 'RefSeq_TranscriptId'] elif self.dbType == "Geno": self.searchField = ['Name','Chr'] - + + print("ge4") self.do_search() ########################################### @@ -202,7 +215,7 @@ class SearchResultPage(templatePage): ########################################### # Generate Mysql Query ########################################### - + # Sam: We presume lines below aren't used... #geneIdListQuery = fd.get('geneId', '') #if geneIdListQuery: @@ -346,7 +359,7 @@ class SearchResultPage(templatePage): #self.dict['js1'] = '' #self.dict['js2'] = 'onLoad="pageOffset()"' #self.dict['layer'] = self.generateWarningLayer() - + def start_search(self): pass @@ -674,7 +687,7 @@ class SearchResultPage(templatePage): item = item['search_term'] self.nkeywords += 1 #ZS: If there are both AND and OR keywords, just use the OR keywords - if k >=len(self.ORkeyword2): + if k >=len(self.ORkeyword2): query = self.ANDQuery DescriptionText = self.ANDDescriptionText clausejoin = ' OR ' @@ -763,7 +776,7 @@ class SearchResultPage(templatePage): detail = ["Pattern search is not available for phenotype databases at this time."] self.error(heading=heading,detail=detail,error="Error") return 0 - elif (self.dbType == "ProbeSet" and + elif (self.dbType == "ProbeSet" and ((_2Cmds and reduce(lambda x, y: (y not in [ "MEAN", "LRS", "PVALUE", "TRANSLRS", "CISLRS", "RANGE", "H2" ]) or x, _2Cmds, False))\ @@ -877,29 +890,29 @@ class SearchResultPage(templatePage): query = self.ORQuery DescriptionText = self.ORDescriptionText itemCmd = item[0] - - + + chr_number = item[1] # chromosome number lower_limit = float(item[2]) upper_limit = float(item[3]) - + if self.dbType == "ProbeSet": fname = 'target genes' elif self.dbType == "Geno": fname = 'loci' - + if lower_limit > upper_limit: lower_limit, upper_limit = upper_limit, lower_limit - + clauseItem = " %s.Chr = '%s' and %s.Mb > %2.7f and %s.Mb < %2.7f " % ( self.dbType, chr_number, self.dbType, lower_limit, self.dbType, upper_limit) - - + + query.append(" (%s) " % clauseItem) self.orderByDefalut = itemCmd - - self.results_desc = dict() + + self.results_desc = dict() #DescriptionText.append(HT.Span(' with ', HT.U('target genes'), ' on chromosome %s between %g and %g Mb' % \ # (chr_number, min(lower_limit, upper_limit), max(lower_limit, upper_limit)))) diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure b/wqflask/wqflask/static/new/javascript/dataset_menu_structure index d25d3cf5..1b7e4090 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_menu_structure +++ b/wqflask/wqflask/static/new/javascript/dataset_menu_structure @@ -78,18 +78,6 @@ [ "B1MI0809R", "Barley1 Leaf MOCK TTKS (Aug09) RMA" - ], - [ - "B30_K_1206_M", - "Barley1 Leaf MAS 5.0 SCRI (Dec06)" - ], - [ - "B30_K_1206_R", - "Barley1 Leaf gcRMA SCRI (Dec06)" - ], - [ - "B30_K_1206_Rn", - "Barley1 Leaf gcRMAn SCRI (Dec06)" ] ], "Phenotypes": [ @@ -121,33 +109,17 @@ ] ], "Leaf": [ - [ - "B1LI0809R", - "Barley1 Leaf INOC TTKS (Aug09) RMA" - ], - [ - "B1LI0809M5", - "Barley1 Leaf INOC TTKS (Aug09) MAS5" - ], - [ - "B1MI0809M5", - "Barley1 Leaf MOCK TTKS (Aug09) MAS5" - ], - [ - "B1MI0809R", - "Barley1 Leaf MOCK TTKS (Aug09) RMA" - ], [ "B30_K_1206_M", "Barley1 Leaf MAS 5.0 SCRI (Dec06)" ], - [ - "B30_K_1206_R", - "Barley1 Leaf gcRMA SCRI (Dec06)" - ], [ "B30_K_1206_Rn", "Barley1 Leaf gcRMAn SCRI (Dec06)" + ], + [ + "B30_K_1206_R", + "Barley1 Leaf gcRMA SCRI (Dec06)" ] ], "Phenotypes": [ @@ -176,14 +148,6 @@ [ "NCSU_DrosWB_LC_RMA_0111", "NCSU Drosophila Whole Body (Jan11) RMA" - ], - [ - "UAB_DrosWB_LC_RMA_1009", - "UAB Whole body D.m. mRNA control (Oct09) RMA" - ], - [ - "UAB_DrosWB_LE_RMA_1009", - "UAB Whole body D.m. mRNA lead (pbAc) (Oct09) RMA" ] ] }, @@ -201,10 +165,6 @@ ] ], "Whole Body": [ - [ - "NCSU_DrosWB_LC_RMA_0111", - "NCSU Drosophila Whole Body (Jan11) RMA" - ], [ "UAB_DrosWB_LC_RMA_1009", "UAB Whole body D.m. mRNA control (Oct09) RMA" @@ -219,14 +179,6 @@ "human": { "AD-cases-controls": { "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], [ "GSE5281_F_RMA_N_0709", "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" @@ -235,14 +187,6 @@ "GSE5281_F_RMA_Alzh_0709", "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], [ "GSE5281_F_RMA0709", "GSE5281 Human Brain Full Liang (Jul09) RMA" @@ -250,4683 +194,881 @@ [ "GSE5281_RMA0709", "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], + ] + ], + "Genotypes": [ [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], + "AD-cases-controlsGeno", + "AD-cases-controls Genotypes" + ] + ], + "Phenotypes": [ [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], + "AD-cases-controlsPublish", + "AD-cases-controls Published Phenotypes" + ] + ] + }, + "AD-cases-controls-Myers": { + "Brain": [ [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" + "GSE15222_F_A_RI_0409", + "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" ], [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" + "GSE15222_F_N_RI_0409", + "GSE15222 Human Brain Normal Myers (Apr09) RankInv" ], [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], + "GSE15222_F_RI_0409", + "GSE15222 Human Brain Myers (Apr09) RankInv" + ] + ], + "Genotypes": [ [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], + "AD-cases-controls-MyersGeno", + "AD-cases-controls-Myers Genotypes" + ] + ], + "Phenotypes": [ [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], + "AD-cases-controls-MyersPublish", + "AD-cases-controls-Myers Published Phenotypes" + ] + ] + }, + "CANDLE": { + "Genotypes": [ [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], + "CANDLEGeno", + "CANDLE Genotypes" + ] + ], + "Newborn Cord Blood": [ [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], + "CANDLE_NB_0711", + "CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **" + ] + ], + "Phenotypes": [ [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], + "CANDLEPublish", + "CANDLE Published Phenotypes" + ] + ] + }, + "CEPH-2004": { + "Genotypes": [ [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], + "CEPH-2004Geno", + "CEPH-2004 Genotypes" + ] + ], + "Lymphoblast B-cell": [ [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" + "UT_CEPH_RankInv0909", + "UTHSC CEPH B-cells Illumina (Sep09) RankInv" ], [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], + "Human_1008", + "Monks CEPH B-cells Agilent (Dec04) Log10Ratio" + ] + ], + "Phenotypes": [ [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], + "CEPH-2004Publish", + "CEPH-2004 Published Phenotypes" + ] + ] + }, + "HB": { + "Cerebellum": [ [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" + "HBTRC-MLC_0611", + "HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio" ], [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" + "HBTRC-MLC_N_0611", + "HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio" ], [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" + "HBTRC-MLC_AD_0611", + "HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio" ], [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" + "HBTRC-MLC_HD_0611", + "HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio" ] ], "Genotypes": [ [ - "AD-cases-controlsGeno", - "AD-cases-controls Genotypes" + "HBGeno", + "HB Genotypes" ] ], "Phenotypes": [ [ - "AD-cases-controlsPublish", - "AD-cases-controls Published Phenotypes" + "HBPublish", + "HB Published Phenotypes" ] - ] - }, - "AD-cases-controls-Myers": { - "Brain": [ + ], + "Prefrontal Cortex": [ [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" + "HBTRC-MLPFC_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" ], [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" + "HBTRC-MLPFC_N_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" ], [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" + "HBTRC-MLPFC_AD_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" ], [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], + "HBTRC-MLPFC_HD_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" + ] + ], + "Primary Visual Cortex": [ [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" + "HBTRC-MLVC_0611", + "HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio" ], [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" + "HBTRC-MLVC_N_0611", + "HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio" ], [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" + "HBTRC-MLVC_AD_0611", + "HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio" ], [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], + "HBTRC-MLVC_HD_0611", + "HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio" + ] + ] + }, + "HLC": { + "Genotypes": [ [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], + "HLCGeno", + "HLC Genotypes" + ] + ], + "Liver": [ [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" + "HLC_0311", + "GSE9588 Human Liver Normal (Mar11) Both Sexes" ], [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" + "HLCM_0311", + "GSE9588 Human Liver Normal (Mar11) Males" ], [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], + "HLCF_0311", + "GSE9588 Human Liver Normal (Mar11) Females" + ] + ], + "Phenotypes": [ [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], + "HLCPublish", + "HLC Published Phenotypes" + ] + ] + }, + "HSB": { + "Amygdala": [ [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], + "KIN_YSM_AMY_0711", + "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Caudal Ganglionic Eminence": [ [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], + "KIN_YSM_CGE_0711", + "KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Cerebellar Cortex": [ [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], + "KIN_YSM_CBC_0711", + "KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Diencephalon": [ [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], + "KIN_YSM_DIE_0711", + "KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Dorsal Thalamus": [ [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], + "KIN_YSM_DTH_0711", + "KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Dorsolateral Prefrontal Cortex": [ [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], + "KIN_YSM_DFC_0711", + "KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Frontal Cerebral Wall": [ [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], + "KIN_YSM_FC_0711", + "KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Genotypes": [ [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], + "HSBGeno", + "HSB Genotypes" + ] + ], + "Hippocampus": [ [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], + "KIN_YSM_HIP_0711", + "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Inferior Temporal Cortex": [ [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], + "KIN_YSM_ITC_0711", + "KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Lateral Ganglionic Eminence": [ [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], + "KIN_YSM_LGE_0711", + "KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Medial Ganglionic Eminence": [ [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], + "KIN_YSM_MGE_0711", + "KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Medial Prefrontal Cortex": [ [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], + "KIN_YSM_MFC_0711", + "KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Mediodorsal Nucleus of Thalamus": [ [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], + "KIN_YSM_MD_0711", + "KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Occipital Cerebral Wall": [ [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], + "KIN_YSM_OC_0711", + "KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Orbital Prefrontal Cortex": [ [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], + "KIN_YSM_OFC_0711", + "KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Parietal Cerebral Wall": [ [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], + "KIN_YSM_PC_0711", + "KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Phenotypes": [ [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], + "HSBPublish", + "HSB Published Phenotypes" + ] + ], + "Posterior Inferior Parietal Cortex": [ [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" + "KIN_YSM_IPC_0711", + "KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Genotypes": [ + "Posterior Superior Temporal Cortex": [ [ - "AD-cases-controls-MyersGeno", - "AD-cases-controls-Myers Genotypes" + "KIN_YSM_STC_0711", + "KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Phenotypes": [ + "Primary Auditory (A1) Cortex": [ [ - "AD-cases-controls-MyersPublish", - "AD-cases-controls-Myers Published Phenotypes" + "KIN_YSM_A1C_0711", + "KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] - ] - }, - "CANDLE": { - "Genotypes": [ + ], + "Primary Motor (M1) Cortex": [ [ - "CANDLEGeno", - "CANDLE Genotypes" + "KIN_YSM_M1C_0711", + "KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Newborn Cord Blood": [ + "Primary Somatosensory (S1) Cortex": [ [ - "CANDLE_NB_0711", - "CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **" + "KIN_YSM_S1C_0711", + "KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Phenotypes": [ + "Primary Visual Cortex": [ [ - "CANDLEPublish", - "CANDLE Published Phenotypes" + "KIN_YSM_V1C_0711", + "KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] - ] - }, - "CEPH-2004": { - "Genotypes": [ + ], + "Striatum": [ [ - "CEPH-2004Geno", - "CEPH-2004 Genotypes" + "KIN_YSM_STR_0711", + "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Lymphoblast B-cell": [ + "Temporal Cerebral Wall": [ [ - "UT_CEPH_RankInv0909", - "UTHSC CEPH B-cells Illumina (Sep09) RankInv" - ], + "KIN_YSM_TC_0711", + "KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Upper (Rostral) Rhombic Lip": [ [ - "Human_1008", - "Monks CEPH B-cells Agilent (Dec04) Log10Ratio" + "KIN_YSM_URL_0711", + "KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ], - "Phenotypes": [ + "Ventral Forebrain": [ [ - "CEPH-2004Publish", - "CEPH-2004 Published Phenotypes" + "KIN_YSM_VF_0711", + "KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] - ] - }, - "HB": { - "Cerebellum": [ + ], + "Ventrolateral Prefrontal Cortex": [ [ - "HBTRC-MLC_0611", - "HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLC_N_0611", - "HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLC_AD_0611", - "HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLC_HD_0611", - "HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio" - ], - [ - "GCB_M2_0505_M", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) MAS5" - ], - [ - "GCB_M2_0505_R", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) RMA" - ], - [ - "GCB_M2_0505_P", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) PDNN" - ], - [ - "CB_M_0305_R", - "SJUT Cerebellum mRNA M430 (Mar05) RMA" - ], - [ - "CB_M_0305_M", - "SJUT Cerebellum mRNA M430 (Mar05) MAS5" - ], - [ - "CB_M_0305_P", - "SJUT Cerebellum mRNA M430 (Mar05) PDNN" - ], - [ - "CB_M_1004_R", - "SJUT Cerebellum mRNA M430 (Oct04) RMA" - ], - [ - "CB_M_1004_M", - "SJUT Cerebellum mRNA M430 (Oct04) MAS5" - ], - [ - "CB_M_1004_P", - "SJUT Cerebellum mRNA M430 (Oct04) PDNN" - ], - [ - "CB_M_1003_M", - "SJUT Cerebellum mRNA M430 (Oct03) MAS5" - ] - ], - "Genotypes": [ - [ - "HBGeno", - "HB Genotypes" - ] - ], - "Phenotypes": [ - [ - "HBPublish", - "HB Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "HBTRC-MLPFC_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_N_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_AD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_HD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" - ], - [ - "INIA_MacFas_Pf_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" - ], - [ - "INIA_MacFas_PfE_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" - ], - [ - "VCUSal_1006_R", - "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" - ], - [ - "VCUEtOH_1206_R", - "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" - ], - [ - "VCUSal_1206_R", - "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" - ], - [ - "VCU_PF_Air_0111_R", - "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_Et_0111_R", - "VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_AvE_0111_Ss", - "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" - ], - [ - "VCUEt_vs_Sal_0806_R", - "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" - ], - [ - "VCUEtOH_0806_R", - "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" - ], - [ - "VCUSal_0806_R", - "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" - ] - ], - "Primary Visual Cortex": [ - [ - "KIN_YSM_V1C_0711", - "KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "HBTRC-MLVC_0611", - "HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_N_0611", - "HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_AD_0611", - "HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_HD_0611", - "HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio" - ] - ] - }, - "HLC": { - "Genotypes": [ - [ - "HLCGeno", - "HLC Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Phenotypes": [ - [ - "HLCPublish", - "HLC Published Phenotypes" - ] - ] - }, - "HSB": { - "Amygdala": [ - [ - "KIN_YSM_AMY_0711", - "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "INIA_AmgCoh_0311", - "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" - ], - [ - "INIA_Amg_BLA_RMA_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" - ], - [ - "INIA_Amg_BLA_RMA_M_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" - ], - [ - "INIA_Amg_BLA_RMA_F_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" - ], - [ - "INIA_MacFas_AMGc_RMA_0110", - "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" - ], - [ - "INIA_MacFas_AMGe_RMA_0110", - "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" - ] - ], - "Caudal Ganglionic Eminence": [ - [ - "KIN_YSM_CGE_0711", - "KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Cerebellar Cortex": [ - [ - "KIN_YSM_CBC_0711", - "KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Diencephalon": [ - [ - "KIN_YSM_DIE_0711", - "KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Dorsal Thalamus": [ - [ - "KIN_YSM_DTH_0711", - "KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Dorsolateral Prefrontal Cortex": [ - [ - "KIN_YSM_DFC_0711", - "KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Frontal Cerebral Wall": [ - [ - "KIN_YSM_FC_0711", - "KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Genotypes": [ - [ - "HSBGeno", - "HSB Genotypes" - ] - ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], - [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" - ], - [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" - ], - [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], - [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], - [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], - [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ], - [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" - ] - ], - "Inferior Temporal Cortex": [ - [ - "KIN_YSM_ITC_0711", - "KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Lateral Ganglionic Eminence": [ - [ - "KIN_YSM_LGE_0711", - "KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Medial Ganglionic Eminence": [ - [ - "KIN_YSM_MGE_0711", - "KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Medial Prefrontal Cortex": [ - [ - "KIN_YSM_MFC_0711", - "KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Mediodorsal Nucleus of Thalamus": [ - [ - "KIN_YSM_MD_0711", - "KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Occipital Cerebral Wall": [ - [ - "KIN_YSM_OC_0711", - "KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Orbital Prefrontal Cortex": [ - [ - "KIN_YSM_OFC_0711", - "KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Parietal Cerebral Wall": [ - [ - "KIN_YSM_PC_0711", - "KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Phenotypes": [ - [ - "HSBPublish", - "HSB Published Phenotypes" - ] - ], - "Posterior Inferior Parietal Cortex": [ - [ - "KIN_YSM_IPC_0711", - "KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Posterior Superior Temporal Cortex": [ - [ - "KIN_YSM_STC_0711", - "KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Auditory (A1) Cortex": [ - [ - "KIN_YSM_A1C_0711", - "KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Motor (M1) Cortex": [ - [ - "KIN_YSM_M1C_0711", - "KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Somatosensory (S1) Cortex": [ - [ - "KIN_YSM_S1C_0711", - "KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Visual Cortex": [ - [ - "KIN_YSM_V1C_0711", - "KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "HBTRC-MLVC_0611", - "HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_N_0611", - "HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_AD_0611", - "HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_HD_0611", - "HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio" - ] - ], - "Striatum": [ - [ - "DevStriatum_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "KIN_YSM_STR_0711", - "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "OHSU_HS-CC_ILMStr_0211", - "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" - ], - [ - "UTHSC_Striatum_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" - ], - [ - "UTHSC_Str_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10) RankInv" - ], - [ - "UTHSC_1107_RankInv", - "HQF BXD Striatum ILM6.1 (Nov07) RankInv" - ], - [ - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ], - [ - "SA_M2_0905_M", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" - ], - [ - "SA_M2_0905_R", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" - ], - [ - "SA_M2_0405_MC", - "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" - ], - [ - "SA_M2_0405_RC", - "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" - ], - [ - "SA_M2_0405_PC", - "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" - ], - [ - "SA_M2_0405_SS", - "HBP Rosen Striatum M430V2 (Apr05) SScore" - ], - [ - "SA_M2_0405_RR", - "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" - ], - [ - "Striatum_Exon_0209", - "HQF Striatum Exon (Feb09) RMA" - ], - [ - "DevStriatum_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" - ] - ], - "Temporal Cerebral Wall": [ - [ - "KIN_YSM_TC_0711", - "KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Upper (Rostral) Rhombic Lip": [ - [ - "KIN_YSM_URL_0711", - "KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Ventral Forebrain": [ - [ - "KIN_YSM_VF_0711", - "KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Ventrolateral Prefrontal Cortex": [ - [ - "KIN_YSM_VFC_0711", - "KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ] - } - }, - "macaque monkey": { - "Macaca-fasicularis": { - "Amygdala": [ - [ - "KIN_YSM_AMY_0711", - "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "INIA_AmgCoh_0311", - "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" - ], - [ - "INIA_Amg_BLA_RMA_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" - ], - [ - "INIA_Amg_BLA_RMA_M_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" - ], - [ - "INIA_Amg_BLA_RMA_F_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" - ], - [ - "INIA_MacFas_AMGc_RMA_0110", - "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" - ], - [ - "INIA_MacFas_AMGe_RMA_0110", - "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" - ] - ], - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Genotypes": [ - [ - "Macaca-fasicularisGeno", - "Macaca-fasicularis Genotypes" - ] - ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], - [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" - ], - [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" - ], - [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], - [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], - [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], - [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ], - [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" - ] - ], - "Nucleus Accumbens": [ - [ - "INIA_MacFas_Ac_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens control (Jan10) RMA **" - ], - [ - "INIA_MacFas_Ae_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens ethanol (Jan10) RMA **" - ], - [ - "VCUSalo_1007_R", - "VCU BXD NA Sal M430 2.0 (Oct07) RMA" - ], - [ - "VCUEtOH_1007_R", - "VCU BXD NA EtOH M430 2.0 (Oct07) RMA **" - ], - [ - "VCUSal_1007_R", - "VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **" - ] - ], - "Phenotypes": [ - [ - "Macaca-fasicularisPublish", - "Macaca-fasicularis Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "HBTRC-MLPFC_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_N_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_AD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_HD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" - ], - [ - "INIA_MacFas_Pf_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" - ], - [ - "INIA_MacFas_PfE_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" - ], - [ - "VCUSal_1006_R", - "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" - ], - [ - "VCUEtOH_1206_R", - "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" - ], - [ - "VCUSal_1206_R", - "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" - ], - [ - "VCU_PF_Air_0111_R", - "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_Et_0111_R", - "VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_AvE_0111_Ss", - "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" - ], - [ - "VCUEt_vs_Sal_0806_R", - "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" - ], - [ - "VCUEtOH_0806_R", - "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" - ], - [ - "VCUSal_0806_R", - "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" - ] - ] - } - }, - "mouse": { - "AKXD": { - "Genotypes": [ - [ - "AKXDGeno", - "AKXD Genotypes" - ] - ], - "Mammary Tumors": [ - [ - "NCI_Mam_Tum_RMA_0409", - "NCI Mammary M430v2 (Apr09) RMA" - ], - [ - "NCI_Agil_Mam_Tum_RMA_0409", - "NCI Mammary LMT miRNA v2 (Apr09) RMA" - ], - [ - "MA_M_0704_R", - "NCI Mammary mRNA M430 (July04) RMA" - ], - [ - "MA_M_0704_M", - "NCI Mammary mRNA M430 (July04) MAS5" - ] - ], - "Phenotypes": [ - [ - "AKXDPublish", - "AKXD Published Phenotypes" - ] - ] - }, - "AXBXA": { - "Eye": [ - [ - "Eye_AXBXA_1008_RankInv", - "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" - ], - [ - "Eye_M2_0908_R", - "Eye M430v2 (Sep08) RMA" - ], - [ - "Eye_M2_0908_R_NB", - "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_ND", - "Eye M430v2 WT Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_WTWT", - "Eye M430v2 WT WT (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_WT", - "Eye M430v2 WT Tyrp1 (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_MT", - "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" - ], - [ - "BXD_GLA_0911", - "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" - ], - [ - "UIOWA_Eye_RMA_0906", - "UIOWA Eye mRNA RAE230v2 (Sep06) RMA" - ] - ], - "Genotypes": [ - [ - "AXBXAGeno", - "AXBXA Genotypes" - ] - ], - "Phenotypes": [ - [ - "AXBXAPublish", - "AXBXA Published Phenotypes" - ] - ] - }, - "B6BTBRF2": { - "Genotypes": [ - [ - "B6BTBRF2Geno", - "B6BTBRF2 Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Phenotypes": [ - [ - "B6BTBRF2Publish", - "B6BTBRF2 Published Phenotypes" - ] - ] - }, - "B6D2F2": { - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Genotypes": [ - [ - "B6D2F2Geno", - "B6D2F2 Genotypes" - ] - ], - "Phenotypes": [ - [ - "B6D2F2Publish", - "B6D2F2 Published Phenotypes" - ] - ] - }, - "BDF2-1999": { - "Genotypes": [ - [ - "BDF2-1999Geno", - "BDF2-1999 Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Phenotypes": [ - [ - "BDF2-1999Publish", - "BDF2-1999 Published Phenotypes" - ] - ] - }, - "BDF2-2005": { - "Genotypes": [ - [ - "BDF2-2005Geno", - "BDF2-2005 Genotypes" - ] - ], - "Phenotypes": [ - [ - "BDF2-2005Publish", - "BDF2-2005 Published Phenotypes" - ] - ], - "Striatum": [ - [ - "DevStriatum_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "KIN_YSM_STR_0711", - "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "OHSU_HS-CC_ILMStr_0211", - "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" - ], - [ - "UTHSC_Striatum_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" - ], - [ - "UTHSC_Str_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10) RankInv" - ], - [ - "UTHSC_1107_RankInv", - "HQF BXD Striatum ILM6.1 (Nov07) RankInv" - ], - [ - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ], - [ - "SA_M2_0905_M", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" - ], - [ - "SA_M2_0905_R", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" - ], - [ - "SA_M2_0405_MC", - "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" - ], - [ - "SA_M2_0405_RC", - "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" - ], - [ - "SA_M2_0405_PC", - "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" - ], - [ - "SA_M2_0405_SS", - "HBP Rosen Striatum M430V2 (Apr05) SScore" - ], - [ - "SA_M2_0405_RR", - "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" - ], - [ - "Striatum_Exon_0209", - "HQF Striatum Exon (Feb09) RMA" - ], - [ - "DevStriatum_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" - ] - ] - }, - "BHF2": { - "Adipose": [ - [ - "UCLA_BHF2_ADIPOSE_MALE", - "UCLA BHF2 Adipose Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_MALE", - "UCLA CTB6B6CTF2 Adipose Male mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", - "UCLA CTB6B6CTF2 Adipose Female mlratio **" - ], - [ - "UCLA_BHHBF2_ADIPOSE_MALE", - "UCLA BHHBF2 Adipose Male Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_FEMALE", - "UCLA BHHBF2 Adipose Female Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_2005", - "UCLA BHHBF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_2005", - "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_0605", - "UCLA BHF2 Adipose (June05) mlratio" - ] - ], - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Genotypes": [ - [ - "BHF2Geno", - "BHF2 Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Muscle": [ - [ - "EPFLMouseMuscleRMA1211", - "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleCDRMA1211", - "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleHFDRMA1211", - "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", - "UCLA CTB6B6CTF2 Muscle Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_MALE", - "UCLA CTB6B6CTF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_FEMALE", - "UCLA BHHBF2 Muscle Female Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_MALE", - "UCLA BHHBF2 Muscle Male Only" - ], - [ - "UCLA_BHF2_MUSCLE_MALE", - "UCLA BHF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_FEMALE", - "UCLA BHF2 Muscle Female mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_2005", - "UCLA BHHBF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_2005", - "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_0605", - "UCLA BHF2 Muscle (June05) mlratio **" - ] - ], - "Phenotypes": [ - [ - "BHF2Publish", - "BHF2 Published Phenotypes" - ] - ] - }, - "BHHBF2": { - "Adipose": [ - [ - "UCLA_BHF2_ADIPOSE_MALE", - "UCLA BHF2 Adipose Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_MALE", - "UCLA CTB6B6CTF2 Adipose Male mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", - "UCLA CTB6B6CTF2 Adipose Female mlratio **" - ], - [ - "UCLA_BHHBF2_ADIPOSE_MALE", - "UCLA BHHBF2 Adipose Male Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_FEMALE", - "UCLA BHHBF2 Adipose Female Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_2005", - "UCLA BHHBF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_2005", - "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_0605", - "UCLA BHF2 Adipose (June05) mlratio" - ] - ], - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Genotypes": [ - [ - "BHHBF2Geno", - "BHHBF2 Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Muscle": [ - [ - "EPFLMouseMuscleRMA1211", - "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleCDRMA1211", - "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleHFDRMA1211", - "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", - "UCLA CTB6B6CTF2 Muscle Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_MALE", - "UCLA CTB6B6CTF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_FEMALE", - "UCLA BHHBF2 Muscle Female Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_MALE", - "UCLA BHHBF2 Muscle Male Only" - ], - [ - "UCLA_BHF2_MUSCLE_MALE", - "UCLA BHF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_FEMALE", - "UCLA BHF2 Muscle Female mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_2005", - "UCLA BHHBF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_2005", - "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_0605", - "UCLA BHF2 Muscle (June05) mlratio **" - ] - ], - "Phenotypes": [ - [ - "BHHBF2Publish", - "BHHBF2 Published Phenotypes" - ] - ] - }, - "BXD": { - "Amygdala": [ - [ - "KIN_YSM_AMY_0711", - "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "INIA_AmgCoh_0311", - "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" - ], - [ - "INIA_Amg_BLA_RMA_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" - ], - [ - "INIA_Amg_BLA_RMA_M_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" - ], - [ - "INIA_Amg_BLA_RMA_F_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" - ], - [ - "INIA_MacFas_AMGc_RMA_0110", - "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" - ], - [ - "INIA_MacFas_AMGe_RMA_0110", - "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" - ] - ], - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Cartilage": [ - [ - "UCLA_BXDBXH_CARTILAGE_V2", - "UCLA BXD and BXH Cartilage v2" - ], - [ - "UCLA_BXHBXD_CARTILAGE_V2", - "UCLA BXH and BXD Cartilage v2" - ], - [ - "UCLA_BXDBXH_CARTILAGE", - "UCLA BXD and BXH Cartilage" - ], - [ - "UCLA_BXHBXD_CARTILAGE", - "UCLA BXH and BXD Cartilage" - ], - [ - "UCLA_BXD_CARTILAGE", - "UCLA BXD Cartilage" - ], - [ - "UCLA_BXH_CARTILAGE", - "UCLA BXH Cartilage" - ] - ], - "Cerebellum": [ - [ - "HBTRC-MLC_0611", - "HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLC_N_0611", - "HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLC_AD_0611", - "HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLC_HD_0611", - "HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio" - ], - [ - "GCB_M2_0505_M", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) MAS5" - ], - [ - "GCB_M2_0505_R", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) RMA" - ], - [ - "GCB_M2_0505_P", - "GE-NIAAA Cerebellum mRNA M430v2 (May05) PDNN" - ], - [ - "CB_M_0305_R", - "SJUT Cerebellum mRNA M430 (Mar05) RMA" - ], - [ - "CB_M_0305_M", - "SJUT Cerebellum mRNA M430 (Mar05) MAS5" - ], - [ - "CB_M_0305_P", - "SJUT Cerebellum mRNA M430 (Mar05) PDNN" - ], - [ - "CB_M_1004_R", - "SJUT Cerebellum mRNA M430 (Oct04) RMA" - ], - [ - "CB_M_1004_M", - "SJUT Cerebellum mRNA M430 (Oct04) MAS5" - ], - [ - "CB_M_1004_P", - "SJUT Cerebellum mRNA M430 (Oct04) PDNN" - ], - [ - "CB_M_1003_M", - "SJUT Cerebellum mRNA M430 (Oct03) MAS5" - ] - ], - "Eye": [ - [ - "Eye_AXBXA_1008_RankInv", - "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" - ], - [ - "Eye_M2_0908_R", - "Eye M430v2 (Sep08) RMA" - ], - [ - "Eye_M2_0908_R_NB", - "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_ND", - "Eye M430v2 WT Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_WTWT", - "Eye M430v2 WT WT (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_WT", - "Eye M430v2 WT Tyrp1 (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_MT", - "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" - ], - [ - "BXD_GLA_0911", - "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" - ], - [ - "UIOWA_Eye_RMA_0906", - "UIOWA Eye mRNA RAE230v2 (Sep06) RMA" - ] - ], - "Genotypes": [ - [ - "BXDGeno", - "BXD Genotypes" - ] - ], - "Hematopoietic Cells": [ - [ - "UMCG_0907_HemaStem_ori", - "UMCG Stem Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_HemaStem", - "UMCG Stem Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Pro_ori", - "UMCG Progenitor Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Pro", - "UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Eryth_ori", - "UMCG Erythroid Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Eryth", - "UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Myeloid_ori", - "UMCG Myeloid Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Myeloid", - "UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "HC_U_0304_R", - "GNF Stem Cells U74Av2 (Mar04) RMA" - ] - ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], - [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" - ], - [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" - ], - [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], - [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], - [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], - [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ], - [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" - ] - ], - "Hypothalamus": [ - [ - "INIA_Hyp_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)" - ], - [ - "INIA_Hyp_M_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male" - ], - [ - "INIA_Hyp_F_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female" - ] - ], - "Kidney": [ - [ - "MA_M2F_0706_R", - "Mouse kidney M430v2 Female (Aug06) RMA" - ], - [ - "MA_M2M_0706_R", - "Mouse kidney M430v2 Male (Aug06) RMA" - ], - [ - "MA_M2_0806_R", - "Mouse kidney M430v2 Sex Balanced (Aug06) RMA" - ], - [ - "MA_M2_0806_P", - "Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN" - ], - [ - "MA_M2_0706_P", - "Mouse Kidney M430v2 (Jul06) PDNN" - ], - [ - "MA_M2_0706_R", - "Mouse Kidney M430v2 (Jul06) RMA" - ], - [ - "KI_2A_0405_M", - "MDC/CAS/ICL Kidney 230A (Apr05) MAS5" - ], - [ - "KI_2A_0405_Rz", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8" - ], - [ - "KI_2A_0405_R", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA" - ] - ], - "Leucocytes": [ - [ - "Illum_BXD_PBL_1108", - "UWA Illumina PBL (Nov08) RSN **" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Lung": [ - [ - "OXUKHS_ILMLung_RI0510", - "OX UK HS ILM6v1.1 Lung (May 2010) RankInv" - ], - [ - "HZI_0408_R", - "HZI Lung M430v2 (Apr08) RMA" - ], - [ - "HZI_0408_M", - "HZI Lung M430v2 (Apr08) MAS5" - ] - ], - "Midbrain": [ - [ - "VUBXDMouseMidBrainQ0212", - "VU BXD Midbrain Agilent SurePrint G3 Mouse GE (Feb12) Quantile" - ] - ], - "Muscle": [ - [ - "EPFLMouseMuscleRMA1211", - "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleCDRMA1211", - "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleHFDRMA1211", - "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", - "UCLA CTB6B6CTF2 Muscle Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_MALE", - "UCLA CTB6B6CTF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_FEMALE", - "UCLA BHHBF2 Muscle Female Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_MALE", - "UCLA BHHBF2 Muscle Male Only" - ], - [ - "UCLA_BHF2_MUSCLE_MALE", - "UCLA BHF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_FEMALE", - "UCLA BHF2 Muscle Female mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_2005", - "UCLA BHHBF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_2005", - "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_0605", - "UCLA BHF2 Muscle (June05) mlratio **" - ] - ], - "Neocortex": [ - [ - "DevNeocortex_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevNeocortex_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "HQFNeoc_1210v2_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv" - ], - [ - "HQFNeoc_1210_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv" - ], - [ - "HQFNeoc_0208_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" - ], - [ - "DevNeocortex_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevNeocortex_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv **" - ] - ], - "Nucleus Accumbens": [ - [ - "INIA_MacFas_Ac_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens control (Jan10) RMA **" - ], - [ - "INIA_MacFas_Ae_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens ethanol (Jan10) RMA **" - ], - [ - "VCUSalo_1007_R", - "VCU BXD NA Sal M430 2.0 (Oct07) RMA" - ], - [ - "VCUEtOH_1007_R", - "VCU BXD NA EtOH M430 2.0 (Oct07) RMA **" - ], - [ - "VCUSal_1007_R", - "VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **" - ] - ], - "Phenotypes": [ - [ - "BXDPublish", - "BXD Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "HBTRC-MLPFC_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_N_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_AD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_HD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" - ], - [ - "INIA_MacFas_Pf_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" - ], - [ - "INIA_MacFas_PfE_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" - ], - [ - "VCUSal_1006_R", - "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" - ], - [ - "VCUEtOH_1206_R", - "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" - ], - [ - "VCUSal_1206_R", - "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" - ], - [ - "VCU_PF_Air_0111_R", - "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_Et_0111_R", - "VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_AvE_0111_Ss", - "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" - ], - [ - "VCUEt_vs_Sal_0806_R", - "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" - ], - [ - "VCUEtOH_0806_R", - "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" - ], - [ - "VCUSal_0806_R", - "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" - ] - ], - "Retina": [ - [ - "Illum_Retina_BXD_RankInv0410", - "HEI Retina Illumina V6.2 (April 2010) RankInv" - ], - [ - "B6D2ONCILM_0412", - "B6D2 ONC Illumina v6.1 (Apr12) RankInv **" - ], - [ - "ONCRetILM6_0412", - "ONC Retina Illumina V6.2 (Apr12) RankInv **" - ], - [ - "G2HEIONCRetILM6_0911", - "G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "HEIONCRetILM6_0911", - "HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "HEIONCvsCRetILM6_0911", - "HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "ILM_Retina_BXD_F_RankInv1210", - "HEI Retina Females Illumina V6.2 (Dec10) RankInv **" - ], - [ - "ILM_Retina_BXD_M_RankInv1210", - "HEI Retina Males Illumina V6.2 (Dec10) RankInv **" - ], - [ - "ILM_Retina_BXD_FM_RankInv1210", - "HEI Retina F-M Illumina V6.2 (Dec10) RankInv **" - ], - [ - "G2NEI_ILM_Retina_BXD_RI0410", - "G2NEI Retina Illumina V6.2 (April 2010) RankInv **" - ] - ], - "Spleen": [ - [ - "UTHSC_SPL_RMA_1210", - "UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA" - ], - [ - "UTHSC_SPL_RMA_1010", - "UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA" - ], - [ - "IoP_SPL_RMA_0509", - "IoP Affy MOE 430v2 Spleen (May09) RMA" - ], - [ - "Illum_BXD_Spl_1108", - "UWA Illumina Spleen (Nov08) RSN **" - ], - [ - "UTK_BXDSpl_VST_0110", - "UTK Spleen ILM6.1 (Jan10) VST" - ], - [ - "STSPL_1107_R", - "Stuart Spleen M430v2 (Nov07) RMA" - ] - ], - "Striatum": [ - [ - "DevStriatum_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "KIN_YSM_STR_0711", - "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "OHSU_HS-CC_ILMStr_0211", - "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" - ], - [ - "UTHSC_Striatum_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" - ], - [ - "UTHSC_Str_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10) RankInv" - ], - [ - "UTHSC_1107_RankInv", - "HQF BXD Striatum ILM6.1 (Nov07) RankInv" - ], - [ - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ], - [ - "SA_M2_0905_M", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" - ], - [ - "SA_M2_0905_R", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" - ], - [ - "SA_M2_0405_MC", - "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" - ], - [ - "SA_M2_0405_RC", - "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" - ], - [ - "SA_M2_0405_PC", - "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" - ], - [ - "SA_M2_0405_SS", - "HBP Rosen Striatum M430V2 (Apr05) SScore" - ], - [ - "SA_M2_0405_RR", - "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" - ], - [ - "Striatum_Exon_0209", - "HQF Striatum Exon (Feb09) RMA" - ], - [ - "DevStriatum_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" - ] - ], - "T Cell (helper)": [ - [ - "RTHC_0211_R", - "HZI Thelp M430v2 (Feb11) RMA" - ] - ], - "T Cell (regulatory)": [ - [ - "RTC_1106_R", - "HZI Treg M430v2 (Feb11) RMA" - ] - ], - "Thymus": [ - [ - "Illum_BXD_Thy_1108", - "UWA Illumina Thymus (Nov08) RSN **" - ] - ], - "Ventral Tegmental Area": [ - [ - "VCUEtvsSal_0609_R", - "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **" - ], - [ - "VCUEtOH_0609_R", - "VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **" - ], - [ - "VCUSal_0609_R", - "VCU BXD VTA Sal M430 2.0 (Jun09) RMA **" - ] - ] - }, - "BXH": { - "Cartilage": [ - [ - "UCLA_BXDBXH_CARTILAGE_V2", - "UCLA BXD and BXH Cartilage v2" - ], - [ - "UCLA_BXHBXD_CARTILAGE_V2", - "UCLA BXH and BXD Cartilage v2" - ], - [ - "UCLA_BXDBXH_CARTILAGE", - "UCLA BXD and BXH Cartilage" - ], - [ - "UCLA_BXHBXD_CARTILAGE", - "UCLA BXH and BXD Cartilage" - ], - [ - "UCLA_BXD_CARTILAGE", - "UCLA BXD Cartilage" - ], - [ - "UCLA_BXH_CARTILAGE", - "UCLA BXH Cartilage" - ] - ], - "Genotypes": [ - [ - "BXHGeno", - "BXH Genotypes" - ] - ], - "Phenotypes": [ - [ - "BXHPublish", - "BXH Published Phenotypes" - ] - ] - }, - "CTB6F2": { - "Adipose": [ - [ - "UCLA_BHF2_ADIPOSE_MALE", - "UCLA BHF2 Adipose Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_MALE", - "UCLA CTB6B6CTF2 Adipose Male mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", - "UCLA CTB6B6CTF2 Adipose Female mlratio **" - ], - [ - "UCLA_BHHBF2_ADIPOSE_MALE", - "UCLA BHHBF2 Adipose Male Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_FEMALE", - "UCLA BHHBF2 Adipose Female Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_2005", - "UCLA BHHBF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_2005", - "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" - ], - [ - "UCLA_BHF2_ADIPOSE_0605", - "UCLA BHF2 Adipose (June05) mlratio" - ] - ], - "Brain": [ - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ], - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "IBR_M_0606_R", - "INIA Brain mRNA M430 (Jun06) RMA" - ], - [ - "IBR_M_0106_P", - "INIA Brain mRNA M430 (Jan06) PDNN" - ], - [ - "IBR_M_0106_R", - "INIA Brain mRNA M430 (Jan06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Genotypes": [ - [ - "CTB6F2Geno", - "CTB6F2 Genotypes" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], - [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], - [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Muscle": [ - [ - "EPFLMouseMuscleRMA1211", - "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleCDRMA1211", - "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleHFDRMA1211", - "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", - "UCLA CTB6B6CTF2 Muscle Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_MALE", - "UCLA CTB6B6CTF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_FEMALE", - "UCLA BHHBF2 Muscle Female Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_MALE", - "UCLA BHHBF2 Muscle Male Only" - ], - [ - "UCLA_BHF2_MUSCLE_MALE", - "UCLA BHF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_FEMALE", - "UCLA BHF2 Muscle Female mlratio **" - ], - [ - "UCLA_BHHBF2_MUSCLE_2005", - "UCLA BHHBF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_2005", - "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_0605", - "UCLA BHF2 Muscle (June05) mlratio **" - ] - ], - "Phenotypes": [ - [ - "CTB6F2Publish", - "CTB6F2 Published Phenotypes" + "KIN_YSM_VFC_0711", + "KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" ] ] - }, - "CXB": { - "Genotypes": [ - [ - "CXBGeno", - "CXB Genotypes" - ] - ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], - [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" - ], - [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" - ], - [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], - [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], - [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], - [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ], - [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], + } + }, + "macaque monkey": { + "Macaca-fasicularis": { + "Amygdala": [ [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" + "INIA_MacFas_AMGc_RMA_0110", + "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" ], [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], + "INIA_MacFas_AMGe_RMA_0110", + "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" + ] + ], + "Brain": [ [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" + "INIA_MacFas_brain_RMA_0110", + "INIA Macaca fasicularis Brain (Jan10) RMA **" ] ], - "Phenotypes": [ + "Genotypes": [ [ - "CXBPublish", - "CXB Published Phenotypes" + "Macaca-fasicularisGeno", + "Macaca-fasicularis Genotypes" ] ], - "Spleen": [ + "Hippocampus": [ [ - "UTHSC_SPL_RMA_1210", - "UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA" + "INIA_MacFas_Hc_RMA_0110", + "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" ], [ - "UTHSC_SPL_RMA_1010", - "UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA" - ], + "INIA_MacFas_He_RMA_0110", + "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" + ] + ], + "Nucleus Accumbens": [ [ - "IoP_SPL_RMA_0509", - "IoP Affy MOE 430v2 Spleen (May09) RMA" + "INIA_MacFas_Ac_RMA_0110", + "INIA Macaca fasicularis Nucleus Accumbens control (Jan10) RMA **" ], [ - "Illum_BXD_Spl_1108", - "UWA Illumina Spleen (Nov08) RSN **" - ], + "INIA_MacFas_Ae_RMA_0110", + "INIA Macaca fasicularis Nucleus Accumbens ethanol (Jan10) RMA **" + ] + ], + "Phenotypes": [ [ - "UTK_BXDSpl_VST_0110", - "UTK Spleen ILM6.1 (Jan10) VST" + "Macaca-fasicularisPublish", + "Macaca-fasicularis Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ + [ + "INIA_MacFas_Pf_RMA_0110", + "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" ], [ - "STSPL_1107_R", - "Stuart Spleen M430v2 (Nov07) RMA" + "INIA_MacFas_PfE_RMA_0110", + "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" ] ] - }, - "HS": { + } + }, + "mouse": { + "AKXD": { "Genotypes": [ [ - "HSGeno", - "HS Genotypes" + "AKXDGeno", + "AKXD Genotypes" ] ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], + "Mammary Tumors": [ [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" + "NCI_Agil_Mam_Tum_RMA_0409", + "NCI Mammary LMT miRNA v2 (Apr09) RMA" ], [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" + "MA_M_0704_R", + "NCI Mammary mRNA M430 (July04) RMA" ], [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], + "MA_M_0704_M", + "NCI Mammary mRNA M430 (July04) MAS5" + ] + ], + "Phenotypes": [ [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], + "AKXDPublish", + "AKXD Published Phenotypes" + ] + ] + }, + "AXBXA": { + "Eye": [ [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], + "Eye_AXBXA_1008_RankInv", + "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" + ] + ], + "Genotypes": [ [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], + "AXBXAGeno", + "AXBXA Genotypes" + ] + ], + "Phenotypes": [ [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], + "AXBXAPublish", + "AXBXA Published Phenotypes" + ] + ] + }, + "B6BTBRF2": { + "Genotypes": [ [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], + "B6BTBRF2Geno", + "B6BTBRF2 Genotypes" + ] + ], + "Liver": [ [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" + "LVF2_M_0704_R", + "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" ], [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], + "LVF2_M_0704_M", + "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" + ] + ], + "Phenotypes": [ [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], + "B6BTBRF2Publish", + "B6BTBRF2 Published Phenotypes" + ] + ] + }, + "B6D2F2": { + "Brain": [ [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" + "BRF2_M_0805_R", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" ], [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" + "BRF2_M_0805_M", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" ], [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" + "BRF2_M_0805_P", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" ], [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" + "BRF2_M_0304_P", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" ], [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" + "BRF2_M_0304_R", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" ], [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], + "BRF2_M_0304_M", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" + ] + ], + "Genotypes": [ [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ], + "B6D2F2Geno", + "B6D2F2 Genotypes" + ] + ], + "Phenotypes": [ [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], + "B6D2F2Publish", + "B6D2F2 Published Phenotypes" + ] + ] + }, + "BDF2-1999": { + "Genotypes": [ [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], + "BDF2-1999Geno", + "BDF2-1999 Genotypes" + ] + ], + "Liver": [ [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" - ], + "UCLA_BDF2_LIVER_1999", + "UCLA BDF2 Liver (1999) mlratio" + ] + ], + "Phenotypes": [ [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], + "BDF2-1999Publish", + "BDF2-1999 Published Phenotypes" + ] + ] + }, + "BDF2-2005": { + "Genotypes": [ [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" + "BDF2-2005Geno", + "BDF2-2005 Genotypes" ] ], - "Liver": [ + "Phenotypes": [ [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], + "BDF2-2005Publish", + "BDF2-2005 Published Phenotypes" + ] + ], + "Striatum": [ [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" + "SA_M2_0905_R", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" ], [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" + "SA_M2_0905_M", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" ], [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], + "SA_M2_0905_P", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" + ] + ] + }, + "BHF2": { + "Adipose": [ [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" + "UCLA_BHF2_ADIPOSE_MALE", + "UCLA BHF2 Adipose Male mlratio" ], [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" + "UCLA_BHF2_ADIPOSE_FEMALE", + "UCLA BHF2 Adipose Female mlratio" ], [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], + "UCLA_BHF2_ADIPOSE_0605", + "UCLA BHF2 Adipose (June05) mlratio" + ] + ], + "Brain": [ [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" + "UCLA_BHF2_BRAIN_MALE", + "UCLA BHF2 Brain Male mlratio" ], [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" + "UCLA_BHF2_BRAIN_FEMALE", + "UCLA BHF2 Brain Female mlratio" ], [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], + "UCLA_BHF2_BRAIN_0605", + "UCLA BHF2 Brain (June05) mlratio" + ] + ], + "Genotypes": [ [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], + "BHF2Geno", + "BHF2 Genotypes" + ] + ], + "Liver": [ [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + "UCLA_BHF2_LIVER_MALE", + "UCLA BHF2 Liver Male mlratio" ], [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" + "UCLA_BHF2_LIVER_FEMALE", + "UCLA BHF2 Liver Female mlratio" ], [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], + "UCLA_BHF2_LIVER_0605", + "UCLA BHF2 Liver (June05) mlratio" + ] + ], + "Muscle": [ [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + "UCLA_BHF2_MUSCLE_MALE", + "UCLA BHF2 Muscle Male mlratio **" ], [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" + "UCLA_BHF2_MUSCLE_FEMALE", + "UCLA BHF2 Muscle Female mlratio **" ], [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], + "UCLA_BHF2_MUSCLE_0605", + "UCLA BHF2 Muscle (June05) mlratio **" + ] + ], + "Phenotypes": [ [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], + "BHF2Publish", + "BHF2 Published Phenotypes" + ] + ] + }, + "BHHBF2": { + "Adipose": [ [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" + "UCLA_BHHBF2_ADIPOSE_MALE", + "UCLA BHHBF2 Adipose Male Only" ], [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" + "UCLA_BHHBF2_ADIPOSE_FEMALE", + "UCLA BHHBF2 Adipose Female Only" ], [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" + "UCLA_BHHBF2_ADIPOSE_2005", + "UCLA BHHBF2 Adipose (2005) mlratio **" + ] + ], + "Brain": [ + [ + "UCLA_BHHBF2_BRAIN_MALE", + "UCLA BHHBF2 Brain Male Only" ], [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" + "UCLA_BHHBF2_BRAIN_FEMALE", + "UCLA BHHBF2 Brain Female Only" ], + [ + "UCLA_BHHBF2_BRAIN_2005", + "UCLA BHHBF2 Brain (2005) mlratio **" + ] + ], + "Genotypes": [ + [ + "BHHBF2Geno", + "BHHBF2 Genotypes" + ] + ], + "Liver": [ [ "UCLA_BHHBF2_LIVER_MALE", "UCLA BHHBF2 Liver Male Only" ], [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" + "UCLA_BHHBF2_LIVER_FEMALE", + "UCLA BHHBF2 Liver Female Only" ], [ "UCLA_BHHBF2_LIVER_2005", "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" ] ], - "Lung": [ + "Muscle": [ [ - "OXUKHS_ILMLung_RI0510", - "OX UK HS ILM6v1.1 Lung (May 2010) RankInv" + "UCLA_BHHBF2_MUSCLE_MALE", + "UCLA BHHBF2 Muscle Male Only" ], [ - "HZI_0408_R", - "HZI Lung M430v2 (Apr08) RMA" + "UCLA_BHHBF2_MUSCLE_FEMALE", + "UCLA BHHBF2 Muscle Female Only" ], [ - "HZI_0408_M", - "HZI Lung M430v2 (Apr08) MAS5" + "UCLA_BHHBF2_MUSCLE_2005", + "UCLA BHHBF2 Muscle (2005) mlratio **" ] ], "Phenotypes": [ [ - "HSPublish", - "HS Published Phenotypes" + "BHHBF2Publish", + "BHHBF2 Published Phenotypes" ] ] }, - "HS-CC": { - "Genotypes": [ - [ - "HS-CCGeno", - "HS-CC Genotypes" - ] - ], - "Phenotypes": [ - [ - "HS-CCPublish", - "HS-CC Published Phenotypes" - ] - ], - "Striatum": [ - [ - "DevStriatum_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "KIN_YSM_STR_0711", - "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], + "BXD": { + "Amygdala": [ [ - "OHSU_HS-CC_ILMStr_0211", - "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" + "INIA_AmgCoh_0311", + "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" ], [ - "UTHSC_Striatum_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" + "INIA_Amg_BLA_RMA_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" ], [ - "UTHSC_Str_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10) RankInv" + "INIA_Amg_BLA_RMA_M_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" ], [ - "UTHSC_1107_RankInv", - "HQF BXD Striatum ILM6.1 (Nov07) RankInv" - ], + "INIA_Amg_BLA_RMA_F_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" + ] + ], + "Brain": [ [ - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" + "BR_M2_1106_R", + "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" ], [ - "SA_M2_0905_M", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" + "BR_U_1105_P", + "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" ], [ - "SA_M2_0905_R", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" + "BR_U_0805_M", + "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" ], [ - "SA_M2_0405_MC", - "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" + "BR_U_0805_R", + "UTHSC Brain mRNA U74Av2 (Aug05) RMA" ], [ - "SA_M2_0405_RC", - "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" + "BR_U_0805_P", + "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" ], [ - "SA_M2_0405_PC", - "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" - ], + "CB_M_0204_P", + "INIA Brain mRNA M430 (Feb04) PDNN" + ] + ], + "Cartilage": [ [ - "SA_M2_0405_SS", - "HBP Rosen Striatum M430V2 (Apr05) SScore" + "UCLA_BXDBXH_CARTILAGE_V2", + "UCLA BXD and BXH Cartilage v2" ], [ - "SA_M2_0405_RR", - "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" + "UCLA_BXDBXH_CARTILAGE", + "UCLA BXD and BXH Cartilage" ], [ - "Striatum_Exon_0209", - "HQF Striatum Exon (Feb09) RMA" + "UCLA_BXD_CARTILAGE", + "UCLA BXD Cartilage" + ] + ], + "Cerebellum": [ + [ + "CB_M_1004_M", + "SJUT Cerebellum mRNA M430 (Oct04) MAS5" ], [ - "DevStriatum_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" + "CB_M_1004_R", + "SJUT Cerebellum mRNA M430 (Oct04) RMA" ], [ - "DevStriatum_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" - ] - ] - }, - "LXS": { - "Genotypes": [ + "CB_M_1004_P", + "SJUT Cerebellum mRNA M430 (Oct04) PDNN" + ], [ - "LXSGeno", - "LXS Genotypes" + "CB_M_1003_M", + "SJUT Cerebellum mRNA M430 (Oct03) MAS5" ] ], - "Hippocampus": [ + "Eye": [ [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + "Eye_M2_0908_R", + "Eye M430v2 (Sep08) RMA" ], [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" + "Eye_M2_0908_R_NB", + "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" ], [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" + "Eye_M2_0908_R_ND", + "Eye M430v2 WT Gpnmb (Sep08) RMA **" ], [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" + "Eye_M2_0908_R_WT", + "Eye M430v2 WT Tyrp1 (Sep08) RMA **" ], [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" + "Eye_M2_0908_WTWT", + "Eye M430v2 WT WT (Sep08) RMA **" ], [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" + "Eye_M2_0908_R_MT", + "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" ], [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" + "BXD_GLA_0911", + "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" + ] + ], + "Genotypes": [ + [ + "BXDGeno", + "BXD Genotypes" + ] + ], + "Hematopoietic Cells": [ + [ + "UMCG_0907_HemaStem_ori", + "UMCG Stem Cells ILM6v1.1 (Apr09) original" ], [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" + "UMCG_0907_HemaStem", + "UMCG Stem Cells ILM6v1.1 (Apr09) transformed" ], [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" + "UMCG_0907_Pro_ori", + "UMCG Progenitor Cells ILM6v1.1 (Apr09) original" ], [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" + "UMCG_0907_Pro", + "UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed" ], [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" + "UMCG_0907_Eryth_ori", + "UMCG Erythroid Cells ILM6v1.1 (Apr09) original" ], [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" + "UMCG_0907_Eryth", + "UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed" ], [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" + "UMCG_0907_Myeloid_ori", + "UMCG Myeloid Cells ILM6v1.1 (Apr09) original" ], [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" + "UMCG_0907_Myeloid", + "UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed" ], + [ + "HC_U_0304_R", + "GNF Stem Cells U74Av2 (Mar04) RMA" + ] + ], + "Hippocampus": [ [ "HC_M2_0606_P", "Hippocampus Consortium M430v2 (Jun06) PDNN" @@ -4939,14 +1081,6 @@ "HC_M2_0606_R", "Hippocampus Consortium M430v2 (Jun06) RMA" ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], [ "UMUTAffyExon_0209_RMA", "UMUTAffy Hippocampus Exon (Feb09) RMA" @@ -4970,63 +1104,169 @@ [ "UT_ILM_BXD_hipp_RSE_0909", "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" + ] + ], + "Hypothalamus": [ + [ + "INIA_Hyp_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)" ], [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" + "INIA_Hyp_M_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male" ], [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" + "INIA_Hyp_F_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female" + ] + ], + "Kidney": [ + [ + "MA_M2F_0706_R", + "Mouse kidney M430v2 Female (Aug06) RMA" ], [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" + "MA_M2M_0706_R", + "Mouse kidney M430v2 Male (Aug06) RMA" ], [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" + "MA_M2_0806_R", + "Mouse kidney M430v2 Sex Balanced (Aug06) RMA" ], [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" + "MA_M2_0806_P", + "Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN" + ], + [ + "MA_M2_0706_P", + "Mouse Kidney M430v2 (Jul06) PDNN" + ], + [ + "MA_M2_0706_R", + "Mouse Kidney M430v2 (Jul06) RMA" ] ], - "Phenotypes": [ + "Leucocytes": [ [ - "LXSPublish", - "LXS Published Phenotypes" + "Illum_BXD_PBL_1108", + "UWA Illumina PBL (Nov08) RSN **" ] ], - "Prefrontal Cortex": [ + "Liver": [ [ - "HBTRC-MLPFC_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" + "GSE16780_UCLA_ML0911", + "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" ], [ - "HBTRC-MLPFC_N_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" + "GenEx_BXD_liverSal_RMA_F_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" + ], + [ + "GenEx_BXD_liverSal_RMA_M_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" + ], + [ + "GenEx_BXD_liverSal_RMA_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + ], + [ + "GenEx_BXD_liverEt_RMA_F_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" + ], + [ + "GenEx_BXD_liverEt_RMA_M_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" + ], + [ + "GenEx_BXD_liverEt_RMA_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + ], + [ + "SUH_Liv_RMA_0611", + "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" + ] + ], + "Lung": [ + [ + "HZI_0408_R", + "HZI Lung M430v2 (Apr08) RMA" + ], + [ + "HZI_0408_M", + "HZI Lung M430v2 (Apr08) MAS5" + ] + ], + "Midbrain": [ + [ + "VUBXDMouseMidBrainQ0212", + "VU BXD Midbrain Agilent SurePrint G3 Mouse GE (Feb12) Quantile" + ] + ], + "Muscle": [ + [ + "EPFLMouseMuscleRMA1211", + "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ], + [ + "EPFLMouseMuscleHFDRMA1211", + "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ], + [ + "EPFLMouseMuscleCDRMA1211", + "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ] + ], + "Neocortex": [ + [ + "DevNeocortex_ILM6.2P14RInv_1111", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv **" + ], + [ + "DevNeocortex_ILM6.2P3RInv_1111", + "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv **" + ], + [ + "HQFNeoc_1210v2_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv" + ], + [ + "HQFNeoc_1210_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv" ], [ - "HBTRC-MLPFC_AD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" + "HQFNeoc_0208_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" ], [ - "HBTRC-MLPFC_HD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" + "DevNeocortex_ILM6.2P3RInv_1110", + "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv **" ], [ - "INIA_MacFas_Pf_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" - ], + "DevNeocortex_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv **" + ] + ], + "Nucleus Accumbens": [ [ - "INIA_MacFas_PfE_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" + "VCUSalo_1007_R", + "VCU BXD NA Sal M430 2.0 (Oct07) RMA" ], [ - "VCUSal_1006_R", - "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" + "VCUEtOH_1007_R", + "VCU BXD NA EtOH M430 2.0 (Oct07) RMA **" ], + [ + "VCUSal_1007_R", + "VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **" + ] + ], + "Phenotypes": [ + [ + "BXDPublish", + "BXD Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ [ "VCUEtOH_1206_R", "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" @@ -5035,6 +1275,10 @@ "VCUSal_1206_R", "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" ], + [ + "VCUSal_1006_R", + "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" + ], [ "VCU_PF_Air_0111_R", "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" @@ -5046,365 +1290,347 @@ [ "VCU_PF_AvE_0111_Ss", "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" - ], - [ - "VCUEt_vs_Sal_0806_R", - "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" - ], - [ - "VCUEtOH_0806_R", - "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" - ], - [ - "VCUSal_0806_R", - "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" - ] - ] - }, - "MDP": { - "Genotypes": [ - [ - "MDPGeno", - "MDP Genotypes" ] ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], + "Retina": [ [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" + "Illum_Retina_BXD_RankInv0410", + "HEI Retina Illumina V6.2 (April 2010) RankInv" ], [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" + "B6D2ONCILM_0412", + "B6D2 ONC Illumina v6.1 (Apr12) RankInv **" ], [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" + "ONCRetILM6_0412", + "ONC Retina Illumina V6.2 (Apr12) RankInv **" ], [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" + "HEIONCvsCRetILM6_0911", + "HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **" ], [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" + "G2HEIONCRetILM6_0911", + "G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" ], [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" + "HEIONCRetILM6_0911", + "HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" ], [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" + "ILM_Retina_BXD_F_RankInv1210", + "HEI Retina Females Illumina V6.2 (Dec10) RankInv **" ], [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" + "ILM_Retina_BXD_M_RankInv1210", + "HEI Retina Males Illumina V6.2 (Dec10) RankInv **" ], [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" + "ILM_Retina_BXD_FM_RankInv1210", + "HEI Retina F-M Illumina V6.2 (Dec10) RankInv **" ], [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], + "G2NEI_ILM_Retina_BXD_RI0410", + "G2NEI Retina Illumina V6.2 (April 2010) RankInv **" + ] + ], + "Spleen": [ [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" + "UTHSC_SPL_RMA_1210", + "UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA" ], [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" + "UTHSC_SPL_RMA_1010", + "UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA" ], [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" + "IoP_SPL_RMA_0509", + "IoP Affy MOE 430v2 Spleen (May09) RMA" ], [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" + "Illum_BXD_Spl_1108", + "UWA Illumina Spleen (Nov08) RSN **" ], [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], + "UTK_BXDSpl_VST_0110", + "UTK Spleen ILM6.1 (Jan10) VST" + ] + ], + "Striatum": [ [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" + "DevStriatum_ILM6.2P3RInv_1111", + "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" ], [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" + "DevStriatum_ILM6.2P14RInv_1111", + "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" ], [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" + "UTHSC_Striatum_RankInv_1210", + "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" ], [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" + "UTHSC_Str_RankInv_1210", + "HQF BXD Striatum ILM6.1 (Dec10) RankInv" ], [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" + "UTHSC_1107_RankInv", + "HQF BXD Striatum ILM6.1 (Nov07) RankInv" ], [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" + "SA_M2_0405_MC", + "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" ], [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" + "SA_M2_0405_RC", + "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" ], [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" + "SA_M2_0405_PC", + "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" ], [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" + "SA_M2_0405_SS", + "HBP Rosen Striatum M430V2 (Apr05) SScore" ], [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" + "SA_M2_0405_RR", + "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" ], [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" + "Striatum_Exon_0209", + "HQF Striatum Exon (Feb09) RMA" ], [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" + "DevStriatum_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" ], [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" + "DevStriatum_ILM6.2P3RInv_1110", + "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" ] ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], + "T Cell (helper)": [ [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], + "RTHC_0211_R", + "HZI Thelp M430v2 (Feb11) RMA" + ] + ], + "T Cell (regulatory)": [ [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], + "RTC_1106_R", + "HZI Treg M430v2 (Feb11) RMA" + ] + ], + "Thymus": [ [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], + "Illum_BXD_Thy_1108", + "UWA Illumina Thymus (Nov08) RSN **" + ] + ], + "Ventral Tegmental Area": [ [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" + "VCUEtOH_0609_R", + "VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **" ], [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" + "VCUSal_0609_R", + "VCU BXD VTA Sal M430 2.0 (Jun09) RMA **" ], [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], + "VCUEtvsSal_0609_R", + "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **" + ] + ] + }, + "BXH": { + "Cartilage": [ [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" + "UCLA_BXHBXD_CARTILAGE_V2", + "UCLA BXH and BXD Cartilage v2" ], [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" + "UCLA_BXHBXD_CARTILAGE", + "UCLA BXH and BXD Cartilage" ], [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], + "UCLA_BXH_CARTILAGE", + "UCLA BXH Cartilage" + ] + ], + "Genotypes": [ [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ], + "BXHGeno", + "BXH Genotypes" + ] + ], + "Phenotypes": [ [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], + "BXHPublish", + "BXH Published Phenotypes" + ] + ] + }, + "CTB6F2": { + "Adipose": [ [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" + "UCLA_CTB6B6CTF2_ADIPOSE_MALE", + "UCLA CTB6B6CTF2 Adipose Male mlratio **" ], [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" + "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", + "UCLA CTB6B6CTF2 Adipose Female mlratio **" ], [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], + "UCLA_CTB6B6CTF2_ADIPOSE_2005", + "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" + ] + ], + "Brain": [ [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" + "UCLA_CTB6B6CTF2_BRAIN_MALE", + "UCLA CTB6B6CTF2 Brain Male mlratio **" ], [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" + "UCLA_CTB6B6CTF2_BRAIN_FEMALE", + "UCLA CTB6B6CTF2 Brain Female mlratio **" ], [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], + "UCLA_CTB6B6CTF2_BRAIN_2005", + "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" + ] + ], + "Genotypes": [ [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" + "CTB6F2Geno", + "CTB6F2 Genotypes" + ] + ], + "Liver": [ + [ + "UCLA_CTB6B6CTF2_LIVER_MALE", + "UCLA CTB6B6CTF2 Liver Male mlratio **" ], [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" + "UCLA_CTB6B6CTF2_LIVER_FEMALE", + "UCLA CTB6B6CTF2 Liver Female mlratio **" ], [ "UCLA_CTB6B6CTF2_LIVER_2005", "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], + ] + ], + "Muscle": [ [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" + "UCLA_CTB6B6CTF2_MUSCLE_MALE", + "UCLA CTB6B6CTF2 Muscle Male mlratio **" ], [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" + "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", + "UCLA CTB6B6CTF2 Muscle Female mlratio **" ], [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" + "UCLA_CTB6B6CTF2_MUSCLE_2005", + "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" ] ], "Phenotypes": [ [ - "MDPPublish", - "Mouse Phenome Database" + "CTB6F2Publish", + "CTB6F2 Published Phenotypes" ] ] }, - "NZBXFVB-N2": { + "CXB": { "Genotypes": [ [ - "NZBXFVB-N2Geno", - "NZBXFVB-N2 Genotypes" + "CXBGeno", + "CXB Genotypes" ] ], - "Mammary Tumors": [ - [ - "NCI_Mam_Tum_RMA_0409", - "NCI Mammary M430v2 (Apr09) RMA" - ], - [ - "NCI_Agil_Mam_Tum_RMA_0409", - "NCI Mammary LMT miRNA v2 (Apr09) RMA" - ], + "Hippocampus": [ [ - "MA_M_0704_R", - "NCI Mammary mRNA M430 (July04) RMA" + "HC_M2CB_1205_R", + "Hippocampus Consortium M430v2 CXB (Dec05) RMA" ], [ - "MA_M_0704_M", - "NCI Mammary mRNA M430 (July04) MAS5" + "HC_M2CB_1205_P", + "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" ] ], "Phenotypes": [ [ - "NZBXFVB-N2Publish", - "NZBXFVB-N2 Published Phenotypes" + "CXBPublish", + "CXB Published Phenotypes" ] - ] - } - }, - "rat": { - "HXBBXH": { - "Adrenal Gland": [ + ], + "Spleen": [ [ - "HXB_Adrenal_1208", - "MDC/CAS/UCL Adrenal 230A (Dec08) RMA" + "STSPL_1107_R", + "Stuart Spleen M430v2 (Nov07) RMA" ] - ], + ] + }, + "HS": { "Genotypes": [ [ - "HXBBXHGeno", - "HXBBXH Genotypes" + "HSGeno", + "HS Genotypes" ] ], - "Heart": [ + "Hippocampus": [ [ - "HXB_Heart_1208", - "MDC/CAS/UCL Heart 230_V2 (Dec08) RMA" + "OXUKHS_ILMHipp_RI0510", + "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" ] ], - "Hippocampus": [ + "Liver": [ [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ], + "OXUKHS_ILMLiver_RI0510", + "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" + ] + ], + "Lung": [ [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], + "OXUKHS_ILMLung_RI0510", + "OX UK HS ILM6v1.1 Lung (May 2010) RankInv" + ] + ], + "Phenotypes": [ [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ], + "HSPublish", + "HS Published Phenotypes" + ] + ] + }, + "HS-CC": { + "Genotypes": [ [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ], + "HS-CCGeno", + "HS-CC Genotypes" + ] + ], + "Phenotypes": [ [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], + "HS-CCPublish", + "HS-CC Published Phenotypes" + ] + ], + "Striatum": [ [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ], + "OHSU_HS-CC_ILMStr_0211", + "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" + ] + ] + }, + "LXS": { + "Genotypes": [ [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ], + "LXSGeno", + "LXS Genotypes" + ] + ], + "Hippocampus": [ [ "Illum_LXS_Hipp_loess0807", "Hippocampus Illumina (Aug07) LOESS" @@ -5426,65 +1652,25 @@ "Hippocampus Illumina (Aug07) RSN" ], [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" + "Illum_LXS_Hipp_rsn_nb0807", + "Hippocampus Illumina (Aug07) RSN_NB" ], [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" + "Hipp_Illumina_RankInv_0507", + "Hippocampus Illumina (May07) RankInv" ], [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" + "Illum_LXS_Hipp_NOS_1008", + "Hippocampus Illumina NOS (Oct08) RankInv beta" ], [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" + "Illum_LXS_Hipp_NON_1008", + "Hippocampus Illumina NON (Oct08) RankInv beta" ], [ "Illum_LXS_Hipp_RSE_1008", "Hippocampus Illumina RSE (Oct08) RankInv beta" ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], [ "Illum_LXS_Hipp_NOE_1008", "Hippocampus Illumina NOE (Oct08) RankInv beta" @@ -5492,55 +1678,47 @@ [ "Illum_LXS_Hipp_RSS_1008", "Hippocampus Illumina RSS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" ] ], - "Kidney": [ - [ - "MA_M2F_0706_R", - "Mouse kidney M430v2 Female (Aug06) RMA" - ], - [ - "MA_M2M_0706_R", - "Mouse kidney M430v2 Male (Aug06) RMA" - ], + "Phenotypes": [ [ - "MA_M2_0806_R", - "Mouse kidney M430v2 Sex Balanced (Aug06) RMA" - ], + "LXSPublish", + "LXS Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ [ - "MA_M2_0806_P", - "Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN" + "VCUEtOH_0806_R", + "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" ], [ - "MA_M2_0706_P", - "Mouse Kidney M430v2 (Jul06) PDNN" + "VCUSal_0806_R", + "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" ], [ - "MA_M2_0706_R", - "Mouse Kidney M430v2 (Jul06) RMA" - ], + "VCUEt_vs_Sal_0806_R", + "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" + ] + ] + }, + "MDP": { + "Genotypes": [ [ - "KI_2A_0405_M", - "MDC/CAS/ICL Kidney 230A (Apr05) MAS5" - ], + "MDPGeno", + "MDP Genotypes" + ] + ], + "Hippocampus": [ [ - "KI_2A_0405_Rz", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8" + "UMUTAffyExon_0209_RMA_MDP", + "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" ], [ - "KI_2A_0405_R", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA" + "HC_M2_0606_MDP", + "Hippocampus Consortium M430v2 (Jun06) RMA MDP" ] ], "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], [ "JAX_CSB_L_0711", "JAX Liver Affy M430 2.0 (Jul11) MDP" @@ -5552,114 +1730,80 @@ [ "JAX_CSB_L_6C_0711", "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ], - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], + ] + ], + "Phenotypes": [ [ - "LV_G_0106_F", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females" - ], + "MDPPublish", + "Mouse Phenome Database" + ] + ] + }, + "NZBXFVB-N2": { + "Genotypes": [ [ - "LV_G_0106_M", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males" - ], + "NZBXFVB-N2Geno", + "NZBXFVB-N2 Genotypes" + ] + ], + "Mammary Tumors": [ [ - "LV_G_0106_B", - "UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes" - ], + "NCI_Mam_Tum_RMA_0409", + "NCI Mammary M430v2 (Apr09) RMA" + ] + ], + "Phenotypes": [ [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], + "NZBXFVB-N2Publish", + "NZBXFVB-N2 Published Phenotypes" + ] + ] + } + }, + "rat": { + "HXBBXH": { + "Adrenal Gland": [ [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], + "HXB_Adrenal_1208", + "MDC/CAS/UCL Adrenal 230A (Dec08) RMA" + ] + ], + "Genotypes": [ [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], + "HXBBXHGeno", + "HXBBXH Genotypes" + ] + ], + "Heart": [ [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], + "HXB_Heart_1208", + "MDC/CAS/UCL Heart 230_V2 (Dec08) RMA" + ] + ], + "Hippocampus": [ [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], + "UT_HippRatEx_RMA_0709", + "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" + ] + ], + "Kidney": [ [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + "KI_2A_0405_M", + "MDC/CAS/ICL Kidney 230A (Apr05) MAS5" ], [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" + "KI_2A_0405_Rz", + "MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8" ], [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ], + "KI_2A_0405_R", + "MDC/CAS/ICL Kidney 230A (Apr05) RMA" + ] + ], + "Liver": [ [ "HXB_Liver_1208", "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ], - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ], - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" ] ], "Peritoneal Fat": [ @@ -5681,38 +1825,6 @@ }, "SRxSHRSPF2": { "Eye": [ - [ - "Eye_AXBXA_1008_RankInv", - "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" - ], - [ - "Eye_M2_0908_R", - "Eye M430v2 (Sep08) RMA" - ], - [ - "Eye_M2_0908_R_NB", - "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_ND", - "Eye M430v2 WT Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_WTWT", - "Eye M430v2 WT WT (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_WT", - "Eye M430v2 WT Tyrp1 (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_MT", - "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" - ], - [ - "BXD_GLA_0911", - "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" - ], [ "UIOWA_Eye_RMA_0906", "UIOWA Eye mRNA RAE230v2 (Sep06) RMA" diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index e7e260fe..d639ed07 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -23,6 +23,10 @@ from base import webqtlFormData from pprint import pformat as pf +#import logging +#logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) +#_log = logging.getLogger("correlation") + @app.route("/") def index_page(): @@ -33,7 +37,7 @@ def index_page(): @app.route("/new") def new_index_page(): print("Sending index_page") - + return render_template("new_index_page.html") @app.route("/data_sharing") @@ -54,6 +58,7 @@ def data_sharing_page(): @app.route("/search") def search_page(): + print("in search_page") if 'info_database' in request.args: print("Going to sharing_info_page") template_vars = sharing_info_page() @@ -63,7 +68,9 @@ def search_page(): else: return render_template("data_sharing.html", **template_vars.__dict__) else: + print("calling search_results.SearchResultPage") the_search = search_results.SearchResultPage(request.args) + print("done calling") return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From fa3247c3284034357719f9234a2942f9cda8c2b6 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 25 Oct 2012 11:01:34 -0500 Subject: Looks like the code that imports logging was changed in runserver.py Small change to the code printing out fd in search_results.py --- wqflask/runserver.py | 17 +++++++++++++---- wqflask/wqflask/search_results.py | 12 +++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/wqflask/runserver.py b/wqflask/runserver.py index a61e4029..2a75faeb 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -11,12 +11,21 @@ from wqflask import app # # For more info see: http://www.cyberciti.biz/faq/iptables-block-port/ +#import logging +#logging.basicConfig(filename="/tmp/flask_gn_log", level=logging.INFO) +# +#_log = logging.getLogger("search") +#_ch = logging.StreamHandler() +#_log.addHandler(_ch) + import logging -logging.basicConfig(filename="/tmp/flask_gn_log", level=logging.INFO) +#from themodule import TheHandlerYouWant +file_handler = logging.FileHandler("/tmp/flask_gn_log") +file_handler.setLevel(logging.DEBUG) +app.logger.addHandler(file_handler) -_log = logging.getLogger("search") -_ch = logging.StreamHandler() -_log.addHandler(_ch) +import logging_tree +logging_tree.printout() app.run(host='0.0.0.0', use_debugger=False, diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index d44fbcef..1b846771 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -68,11 +68,13 @@ class SearchResultPage(templatePage): print("ge0") #return - print("ge0.5") - #causeerror - print("type of fd:", type(fd)) - self.database = [fd['database']] - print("ge0.55") + print("Start...") + print("Type of fd:", type(fd)) + print("Value of fd:", pf(fd)) + database = [fd['database']] + print("End...") + + # change back to self.database if not self.database or self.database == 'spacer': #Error, No database selected heading = "Search Result" -- cgit v1.2.3 From a3e23950f25863697128eb3e40fd346c848e7ae5 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 25 Oct 2012 15:48:14 -0500 Subject: Got the Make Default option working on the home page --- wqflask/cfg/default_settings.py | 4 + wqflask/cfg/zach_settings.py | 1 + wqflask/maintenance/gen_select_dataset.py | 33 +- .../static/new/javascript/dataset_menu_structure | 2904 -------------------- .../static/new/javascript/dataset_select_items.js | 773 ------ .../new/javascript/dataset_select_menu.coffee | 10 +- .../static/new/javascript/dataset_select_menu.js | 12 +- 7 files changed, 46 insertions(+), 3691 deletions(-) delete mode 100644 wqflask/wqflask/static/new/javascript/dataset_menu_structure delete mode 100755 wqflask/wqflask/static/new/javascript/dataset_select_items.js diff --git a/wqflask/cfg/default_settings.py b/wqflask/cfg/default_settings.py index 30ad51d1..1811ccfd 100644 --- a/wqflask/cfg/default_settings.py +++ b/wqflask/cfg/default_settings.py @@ -1 +1,5 @@ LOGFILE = """/tmp/flask_gn_log""" + +#This is needed because Flask turns key errors into a +#400 bad request response with no exception/log +TRAP_BAD_REQUEST_ERRORS = True diff --git a/wqflask/cfg/zach_settings.py b/wqflask/cfg/zach_settings.py index 30ad51d1..ed97f222 100644 --- a/wqflask/cfg/zach_settings.py +++ b/wqflask/cfg/zach_settings.py @@ -1 +1,2 @@ LOGFILE = """/tmp/flask_gn_log""" +TRAP_BAD_REQUEST_ERRORS = True diff --git a/wqflask/maintenance/gen_select_dataset.py b/wqflask/maintenance/gen_select_dataset.py index 9224b884..4c544192 100644 --- a/wqflask/maintenance/gen_select_dataset.py +++ b/wqflask/maintenance/gen_select_dataset.py @@ -1,3 +1,10 @@ +"""Script that generates the data for the main dropdown menus on the home page + +Writes out data as /static/new/javascript/dataset_menu_structure.json +It needs to be run manually when database has been changed. + +""" + # Copyright (C) University of Tennessee Health Science Center, Memphis, TN. # # This program is free software: you can redistribute it and/or modify it @@ -13,16 +20,13 @@ # This program is available from Source Forge: at GeneNetwork Project # (sourceforge.net/projects/genenetwork/). # -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# Contact Drs. Robert W. Williams +# at rwilliams@uthsc.edu # # # # This module is used by GeneNetwork project (www.genenetwork.org) -# This script is to generate the data for the main menus on the home page -# It needs to be run manually when database has been changed . - from __future__ import print_function, division import sys @@ -39,7 +43,8 @@ from base import webqtlConfig # build MySql database connection -Con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, +Con = MySQLdb.Connect(db=webqtlConfig.DB_NAME, + host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER, passwd=webqtlConfig.DB_PASSWD) Cursor = Con.cursor() @@ -82,6 +87,12 @@ def get_types(groups): def build_types(species, group): + """Fetches tissues + + Gets the tissues with data for this species/group + (all types except phenotype/genotype are tissues) + + """ Cursor.execute("""select distinct Tissue.Name, concat(Tissue.Name, ' mRNA') from ProbeFreeze, ProbeSetFreeze, InbredSet, Tissue, Species where Species.Name = %s and Species.Id = InbredSet.SpeciesId and @@ -101,12 +112,13 @@ def get_datasets(types): datasets[species] = {} for group, type_list in group_dict.iteritems(): datasets[species][group] = {} - for type_name, type_full_name in type_list: + for type_name, _type_full_name in type_list: datasets[species][group][type_name] = build_datasets(species, group, type_name) return datasets def build_datasets(species, group, type_name): + """Gets dataset names from database""" dataset_text = dataset_value = None if type_name == "Phenotypes": dataset_value = "%sPublish" % group @@ -135,6 +147,7 @@ def build_datasets(species, group, type_name): def main(): + """Generates and outputs (as json file) the data for the main dropdown menus on the home page""" species = get_species() groups = get_groups(species) types = get_types(groups) @@ -154,14 +167,16 @@ def main(): datasets=datasets, ) - output_file = """../wqflask/static/new/javascript/dataset_menu_structure""" + output_file = """../wqflask/static/new/javascript/dataset_menu_structure.json""" with open(output_file, 'w') as fh: json.dump(data, fh, indent=" ", sort_keys=True) print("\nWrote file to:", output_file) -def test_it(): + +def _test_it(): + """Used for internal testing only""" types = build_types("Mouse", "BXD") print("build_types:", pf(types)) datasets = build_datasets("Mouse", "BXD", "Hippocampus") diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure b/wqflask/wqflask/static/new/javascript/dataset_menu_structure deleted file mode 100644 index 1b7e4090..00000000 --- a/wqflask/wqflask/static/new/javascript/dataset_menu_structure +++ /dev/null @@ -1,2904 +0,0 @@ -{ - "datasets": { - "All Species": { - "All Groups": { - "Phenotypes": [ - [ - "All Phenotypes", - "All Phenotypes" - ] - ] - } - }, - "arabidopsis": { - "BayXSha": { - "Genotypes": [ - [ - "BayXShaGeno", - "BayXSha Genotypes" - ] - ], - "Phenotypes": [ - [ - "BayXShaPublish", - "BayXSha Published Phenotypes" - ] - ] - }, - "ColXBur": { - "Genotypes": [ - [ - "ColXBurGeno", - "ColXBur Genotypes" - ] - ], - "Phenotypes": [ - [ - "ColXBurPublish", - "ColXBur Published Phenotypes" - ] - ] - }, - "ColXCvi": { - "Genotypes": [ - [ - "ColXCviGeno", - "ColXCvi Genotypes" - ] - ], - "Phenotypes": [ - [ - "ColXCviPublish", - "ColXCvi Published Phenotypes" - ] - ] - } - }, - "barley": { - "QSM": { - "Genotypes": [ - [ - "QSMGeno", - "QSM Genotypes" - ] - ], - "Leaf": [ - [ - "B1LI0809R", - "Barley1 Leaf INOC TTKS (Aug09) RMA" - ], - [ - "B1LI0809M5", - "Barley1 Leaf INOC TTKS (Aug09) MAS5" - ], - [ - "B1MI0809M5", - "Barley1 Leaf MOCK TTKS (Aug09) MAS5" - ], - [ - "B1MI0809R", - "Barley1 Leaf MOCK TTKS (Aug09) RMA" - ] - ], - "Phenotypes": [ - [ - "QSMPublish", - "QSM Published Phenotypes" - ] - ] - }, - "SXM": { - "Embryo": [ - [ - "B139_K_1206_R", - "Barley1 Embryo gcRMA SCRI (Dec06)" - ], - [ - "B139_K_1206_M", - "Barley1 Embryo MAS 5.0 SCRI (Dec06)" - ], - [ - "B150_K_0406_R", - "Barley1 Embryo0 gcRMA SCRI (Apr06)" - ] - ], - "Genotypes": [ - [ - "SXMGeno", - "SXM Genotypes" - ] - ], - "Leaf": [ - [ - "B30_K_1206_M", - "Barley1 Leaf MAS 5.0 SCRI (Dec06)" - ], - [ - "B30_K_1206_Rn", - "Barley1 Leaf gcRMAn SCRI (Dec06)" - ], - [ - "B30_K_1206_R", - "Barley1 Leaf gcRMA SCRI (Dec06)" - ] - ], - "Phenotypes": [ - [ - "SXMPublish", - "SXM Published Phenotypes" - ] - ] - } - }, - "drosophila": { - "DGRP": { - "Genotypes": [ - [ - "DGRPGeno", - "DGRP Genotypes" - ] - ], - "Phenotypes": [ - [ - "DGRPPublish", - "DGRP Published Phenotypes" - ] - ], - "Whole Body": [ - [ - "NCSU_DrosWB_LC_RMA_0111", - "NCSU Drosophila Whole Body (Jan11) RMA" - ] - ] - }, - "Oregon-R_x_2b3": { - "Genotypes": [ - [ - "Oregon-R_x_2b3Geno", - "Oregon-R_x_2b3 Genotypes" - ] - ], - "Phenotypes": [ - [ - "Oregon-R_x_2b3Publish", - "Oregon-R_x_2b3 Published Phenotypes" - ] - ], - "Whole Body": [ - [ - "UAB_DrosWB_LC_RMA_1009", - "UAB Whole body D.m. mRNA control (Oct09) RMA" - ], - [ - "UAB_DrosWB_LE_RMA_1009", - "UAB Whole body D.m. mRNA lead (pbAc) (Oct09) RMA" - ] - ] - } - }, - "human": { - "AD-cases-controls": { - "Brain": [ - [ - "GSE5281_F_RMA_N_0709", - "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA_Alzh_0709", - "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" - ], - [ - "GSE5281_F_RMA0709", - "GSE5281 Human Brain Full Liang (Jul09) RMA" - ], - [ - "GSE5281_RMA0709", - "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" - ] - ], - "Genotypes": [ - [ - "AD-cases-controlsGeno", - "AD-cases-controls Genotypes" - ] - ], - "Phenotypes": [ - [ - "AD-cases-controlsPublish", - "AD-cases-controls Published Phenotypes" - ] - ] - }, - "AD-cases-controls-Myers": { - "Brain": [ - [ - "GSE15222_F_A_RI_0409", - "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_N_RI_0409", - "GSE15222 Human Brain Normal Myers (Apr09) RankInv" - ], - [ - "GSE15222_F_RI_0409", - "GSE15222 Human Brain Myers (Apr09) RankInv" - ] - ], - "Genotypes": [ - [ - "AD-cases-controls-MyersGeno", - "AD-cases-controls-Myers Genotypes" - ] - ], - "Phenotypes": [ - [ - "AD-cases-controls-MyersPublish", - "AD-cases-controls-Myers Published Phenotypes" - ] - ] - }, - "CANDLE": { - "Genotypes": [ - [ - "CANDLEGeno", - "CANDLE Genotypes" - ] - ], - "Newborn Cord Blood": [ - [ - "CANDLE_NB_0711", - "CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **" - ] - ], - "Phenotypes": [ - [ - "CANDLEPublish", - "CANDLE Published Phenotypes" - ] - ] - }, - "CEPH-2004": { - "Genotypes": [ - [ - "CEPH-2004Geno", - "CEPH-2004 Genotypes" - ] - ], - "Lymphoblast B-cell": [ - [ - "UT_CEPH_RankInv0909", - "UTHSC CEPH B-cells Illumina (Sep09) RankInv" - ], - [ - "Human_1008", - "Monks CEPH B-cells Agilent (Dec04) Log10Ratio" - ] - ], - "Phenotypes": [ - [ - "CEPH-2004Publish", - "CEPH-2004 Published Phenotypes" - ] - ] - }, - "HB": { - "Cerebellum": [ - [ - "HBTRC-MLC_0611", - "HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLC_N_0611", - "HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLC_AD_0611", - "HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLC_HD_0611", - "HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio" - ] - ], - "Genotypes": [ - [ - "HBGeno", - "HB Genotypes" - ] - ], - "Phenotypes": [ - [ - "HBPublish", - "HB Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "HBTRC-MLPFC_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_N_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_AD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLPFC_HD_0611", - "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" - ] - ], - "Primary Visual Cortex": [ - [ - "HBTRC-MLVC_0611", - "HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_N_0611", - "HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_AD_0611", - "HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio" - ], - [ - "HBTRC-MLVC_HD_0611", - "HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio" - ] - ] - }, - "HLC": { - "Genotypes": [ - [ - "HLCGeno", - "HLC Genotypes" - ] - ], - "Liver": [ - [ - "HLC_0311", - "GSE9588 Human Liver Normal (Mar11) Both Sexes" - ], - [ - "HLCM_0311", - "GSE9588 Human Liver Normal (Mar11) Males" - ], - [ - "HLCF_0311", - "GSE9588 Human Liver Normal (Mar11) Females" - ] - ], - "Phenotypes": [ - [ - "HLCPublish", - "HLC Published Phenotypes" - ] - ] - }, - "HSB": { - "Amygdala": [ - [ - "KIN_YSM_AMY_0711", - "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Caudal Ganglionic Eminence": [ - [ - "KIN_YSM_CGE_0711", - "KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Cerebellar Cortex": [ - [ - "KIN_YSM_CBC_0711", - "KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Diencephalon": [ - [ - "KIN_YSM_DIE_0711", - "KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Dorsal Thalamus": [ - [ - "KIN_YSM_DTH_0711", - "KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Dorsolateral Prefrontal Cortex": [ - [ - "KIN_YSM_DFC_0711", - "KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Frontal Cerebral Wall": [ - [ - "KIN_YSM_FC_0711", - "KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Genotypes": [ - [ - "HSBGeno", - "HSB Genotypes" - ] - ], - "Hippocampus": [ - [ - "KIN_YSM_HIP_0711", - "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Inferior Temporal Cortex": [ - [ - "KIN_YSM_ITC_0711", - "KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Lateral Ganglionic Eminence": [ - [ - "KIN_YSM_LGE_0711", - "KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Medial Ganglionic Eminence": [ - [ - "KIN_YSM_MGE_0711", - "KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Medial Prefrontal Cortex": [ - [ - "KIN_YSM_MFC_0711", - "KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Mediodorsal Nucleus of Thalamus": [ - [ - "KIN_YSM_MD_0711", - "KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Occipital Cerebral Wall": [ - [ - "KIN_YSM_OC_0711", - "KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Orbital Prefrontal Cortex": [ - [ - "KIN_YSM_OFC_0711", - "KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Parietal Cerebral Wall": [ - [ - "KIN_YSM_PC_0711", - "KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Phenotypes": [ - [ - "HSBPublish", - "HSB Published Phenotypes" - ] - ], - "Posterior Inferior Parietal Cortex": [ - [ - "KIN_YSM_IPC_0711", - "KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Posterior Superior Temporal Cortex": [ - [ - "KIN_YSM_STC_0711", - "KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Auditory (A1) Cortex": [ - [ - "KIN_YSM_A1C_0711", - "KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Motor (M1) Cortex": [ - [ - "KIN_YSM_M1C_0711", - "KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Somatosensory (S1) Cortex": [ - [ - "KIN_YSM_S1C_0711", - "KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Primary Visual Cortex": [ - [ - "KIN_YSM_V1C_0711", - "KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Striatum": [ - [ - "KIN_YSM_STR_0711", - "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Temporal Cerebral Wall": [ - [ - "KIN_YSM_TC_0711", - "KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Upper (Rostral) Rhombic Lip": [ - [ - "KIN_YSM_URL_0711", - "KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Ventral Forebrain": [ - [ - "KIN_YSM_VF_0711", - "KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ], - "Ventrolateral Prefrontal Cortex": [ - [ - "KIN_YSM_VFC_0711", - "KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" - ] - ] - } - }, - "macaque monkey": { - "Macaca-fasicularis": { - "Amygdala": [ - [ - "INIA_MacFas_AMGc_RMA_0110", - "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" - ], - [ - "INIA_MacFas_AMGe_RMA_0110", - "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" - ] - ], - "Brain": [ - [ - "INIA_MacFas_brain_RMA_0110", - "INIA Macaca fasicularis Brain (Jan10) RMA **" - ] - ], - "Genotypes": [ - [ - "Macaca-fasicularisGeno", - "Macaca-fasicularis Genotypes" - ] - ], - "Hippocampus": [ - [ - "INIA_MacFas_Hc_RMA_0110", - "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" - ], - [ - "INIA_MacFas_He_RMA_0110", - "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" - ] - ], - "Nucleus Accumbens": [ - [ - "INIA_MacFas_Ac_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens control (Jan10) RMA **" - ], - [ - "INIA_MacFas_Ae_RMA_0110", - "INIA Macaca fasicularis Nucleus Accumbens ethanol (Jan10) RMA **" - ] - ], - "Phenotypes": [ - [ - "Macaca-fasicularisPublish", - "Macaca-fasicularis Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "INIA_MacFas_Pf_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" - ], - [ - "INIA_MacFas_PfE_RMA_0110", - "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" - ] - ] - } - }, - "mouse": { - "AKXD": { - "Genotypes": [ - [ - "AKXDGeno", - "AKXD Genotypes" - ] - ], - "Mammary Tumors": [ - [ - "NCI_Agil_Mam_Tum_RMA_0409", - "NCI Mammary LMT miRNA v2 (Apr09) RMA" - ], - [ - "MA_M_0704_R", - "NCI Mammary mRNA M430 (July04) RMA" - ], - [ - "MA_M_0704_M", - "NCI Mammary mRNA M430 (July04) MAS5" - ] - ], - "Phenotypes": [ - [ - "AKXDPublish", - "AKXD Published Phenotypes" - ] - ] - }, - "AXBXA": { - "Eye": [ - [ - "Eye_AXBXA_1008_RankInv", - "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" - ] - ], - "Genotypes": [ - [ - "AXBXAGeno", - "AXBXA Genotypes" - ] - ], - "Phenotypes": [ - [ - "AXBXAPublish", - "AXBXA Published Phenotypes" - ] - ] - }, - "B6BTBRF2": { - "Genotypes": [ - [ - "B6BTBRF2Geno", - "B6BTBRF2 Genotypes" - ] - ], - "Liver": [ - [ - "LVF2_M_0704_R", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" - ], - [ - "LVF2_M_0704_M", - "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" - ] - ], - "Phenotypes": [ - [ - "B6BTBRF2Publish", - "B6BTBRF2 Published Phenotypes" - ] - ] - }, - "B6D2F2": { - "Brain": [ - [ - "BRF2_M_0805_R", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" - ], - [ - "BRF2_M_0805_M", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" - ], - [ - "BRF2_M_0805_P", - "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" - ], - [ - "BRF2_M_0304_P", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" - ], - [ - "BRF2_M_0304_R", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" - ], - [ - "BRF2_M_0304_M", - "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" - ] - ], - "Genotypes": [ - [ - "B6D2F2Geno", - "B6D2F2 Genotypes" - ] - ], - "Phenotypes": [ - [ - "B6D2F2Publish", - "B6D2F2 Published Phenotypes" - ] - ] - }, - "BDF2-1999": { - "Genotypes": [ - [ - "BDF2-1999Geno", - "BDF2-1999 Genotypes" - ] - ], - "Liver": [ - [ - "UCLA_BDF2_LIVER_1999", - "UCLA BDF2 Liver (1999) mlratio" - ] - ], - "Phenotypes": [ - [ - "BDF2-1999Publish", - "BDF2-1999 Published Phenotypes" - ] - ] - }, - "BDF2-2005": { - "Genotypes": [ - [ - "BDF2-2005Geno", - "BDF2-2005 Genotypes" - ] - ], - "Phenotypes": [ - [ - "BDF2-2005Publish", - "BDF2-2005 Published Phenotypes" - ] - ], - "Striatum": [ - [ - "SA_M2_0905_R", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" - ], - [ - "SA_M2_0905_M", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" - ], - [ - "SA_M2_0905_P", - "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" - ] - ] - }, - "BHF2": { - "Adipose": [ - [ - "UCLA_BHF2_ADIPOSE_MALE", - "UCLA BHF2 Adipose Male mlratio" - ], - [ - "UCLA_BHF2_ADIPOSE_FEMALE", - "UCLA BHF2 Adipose Female mlratio" - ], - [ - "UCLA_BHF2_ADIPOSE_0605", - "UCLA BHF2 Adipose (June05) mlratio" - ] - ], - "Brain": [ - [ - "UCLA_BHF2_BRAIN_MALE", - "UCLA BHF2 Brain Male mlratio" - ], - [ - "UCLA_BHF2_BRAIN_FEMALE", - "UCLA BHF2 Brain Female mlratio" - ], - [ - "UCLA_BHF2_BRAIN_0605", - "UCLA BHF2 Brain (June05) mlratio" - ] - ], - "Genotypes": [ - [ - "BHF2Geno", - "BHF2 Genotypes" - ] - ], - "Liver": [ - [ - "UCLA_BHF2_LIVER_MALE", - "UCLA BHF2 Liver Male mlratio" - ], - [ - "UCLA_BHF2_LIVER_FEMALE", - "UCLA BHF2 Liver Female mlratio" - ], - [ - "UCLA_BHF2_LIVER_0605", - "UCLA BHF2 Liver (June05) mlratio" - ] - ], - "Muscle": [ - [ - "UCLA_BHF2_MUSCLE_MALE", - "UCLA BHF2 Muscle Male mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_FEMALE", - "UCLA BHF2 Muscle Female mlratio **" - ], - [ - "UCLA_BHF2_MUSCLE_0605", - "UCLA BHF2 Muscle (June05) mlratio **" - ] - ], - "Phenotypes": [ - [ - "BHF2Publish", - "BHF2 Published Phenotypes" - ] - ] - }, - "BHHBF2": { - "Adipose": [ - [ - "UCLA_BHHBF2_ADIPOSE_MALE", - "UCLA BHHBF2 Adipose Male Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_FEMALE", - "UCLA BHHBF2 Adipose Female Only" - ], - [ - "UCLA_BHHBF2_ADIPOSE_2005", - "UCLA BHHBF2 Adipose (2005) mlratio **" - ] - ], - "Brain": [ - [ - "UCLA_BHHBF2_BRAIN_MALE", - "UCLA BHHBF2 Brain Male Only" - ], - [ - "UCLA_BHHBF2_BRAIN_FEMALE", - "UCLA BHHBF2 Brain Female Only" - ], - [ - "UCLA_BHHBF2_BRAIN_2005", - "UCLA BHHBF2 Brain (2005) mlratio **" - ] - ], - "Genotypes": [ - [ - "BHHBF2Geno", - "BHHBF2 Genotypes" - ] - ], - "Liver": [ - [ - "UCLA_BHHBF2_LIVER_MALE", - "UCLA BHHBF2 Liver Male Only" - ], - [ - "UCLA_BHHBF2_LIVER_FEMALE", - "UCLA BHHBF2 Liver Female Only" - ], - [ - "UCLA_BHHBF2_LIVER_2005", - "UCLA BHHBF2 Liver (2005) mlratio **" - ] - ], - "Muscle": [ - [ - "UCLA_BHHBF2_MUSCLE_MALE", - "UCLA BHHBF2 Muscle Male Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_FEMALE", - "UCLA BHHBF2 Muscle Female Only" - ], - [ - "UCLA_BHHBF2_MUSCLE_2005", - "UCLA BHHBF2 Muscle (2005) mlratio **" - ] - ], - "Phenotypes": [ - [ - "BHHBF2Publish", - "BHHBF2 Published Phenotypes" - ] - ] - }, - "BXD": { - "Amygdala": [ - [ - "INIA_AmgCoh_0311", - "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" - ], - [ - "INIA_Amg_BLA_RMA_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" - ], - [ - "INIA_Amg_BLA_RMA_M_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" - ], - [ - "INIA_Amg_BLA_RMA_F_1110", - "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" - ] - ], - "Brain": [ - [ - "BR_M2_1106_R", - "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" - ], - [ - "BR_U_1105_P", - "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" - ], - [ - "BR_U_0805_M", - "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" - ], - [ - "BR_U_0805_R", - "UTHSC Brain mRNA U74Av2 (Aug05) RMA" - ], - [ - "BR_U_0805_P", - "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" - ], - [ - "CB_M_0204_P", - "INIA Brain mRNA M430 (Feb04) PDNN" - ] - ], - "Cartilage": [ - [ - "UCLA_BXDBXH_CARTILAGE_V2", - "UCLA BXD and BXH Cartilage v2" - ], - [ - "UCLA_BXDBXH_CARTILAGE", - "UCLA BXD and BXH Cartilage" - ], - [ - "UCLA_BXD_CARTILAGE", - "UCLA BXD Cartilage" - ] - ], - "Cerebellum": [ - [ - "CB_M_1004_M", - "SJUT Cerebellum mRNA M430 (Oct04) MAS5" - ], - [ - "CB_M_1004_R", - "SJUT Cerebellum mRNA M430 (Oct04) RMA" - ], - [ - "CB_M_1004_P", - "SJUT Cerebellum mRNA M430 (Oct04) PDNN" - ], - [ - "CB_M_1003_M", - "SJUT Cerebellum mRNA M430 (Oct03) MAS5" - ] - ], - "Eye": [ - [ - "Eye_M2_0908_R", - "Eye M430v2 (Sep08) RMA" - ], - [ - "Eye_M2_0908_R_NB", - "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_ND", - "Eye M430v2 WT Gpnmb (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_WT", - "Eye M430v2 WT Tyrp1 (Sep08) RMA **" - ], - [ - "Eye_M2_0908_WTWT", - "Eye M430v2 WT WT (Sep08) RMA **" - ], - [ - "Eye_M2_0908_R_MT", - "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" - ], - [ - "BXD_GLA_0911", - "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" - ] - ], - "Genotypes": [ - [ - "BXDGeno", - "BXD Genotypes" - ] - ], - "Hematopoietic Cells": [ - [ - "UMCG_0907_HemaStem_ori", - "UMCG Stem Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_HemaStem", - "UMCG Stem Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Pro_ori", - "UMCG Progenitor Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Pro", - "UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Eryth_ori", - "UMCG Erythroid Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Eryth", - "UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "UMCG_0907_Myeloid_ori", - "UMCG Myeloid Cells ILM6v1.1 (Apr09) original" - ], - [ - "UMCG_0907_Myeloid", - "UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed" - ], - [ - "HC_U_0304_R", - "GNF Stem Cells U74Av2 (Mar04) RMA" - ] - ], - "Hippocampus": [ - [ - "HC_M2_0606_P", - "Hippocampus Consortium M430v2 (Jun06) PDNN" - ], - [ - "HC_M2_0606_M", - "Hippocampus Consortium M430v2 (Jun06) MAS5" - ], - [ - "HC_M2_0606_R", - "Hippocampus Consortium M430v2 (Jun06) RMA" - ], - [ - "UMUTAffyExon_0209_RMA", - "UMUTAffy Hippocampus Exon (Feb09) RMA" - ], - [ - "UT_ILM_BXD_hipp_NON_0909", - "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOS_0909", - "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_NOE_0909", - "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSS_0909", - "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" - ], - [ - "UT_ILM_BXD_hipp_RSE_0909", - "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" - ] - ], - "Hypothalamus": [ - [ - "INIA_Hyp_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)" - ], - [ - "INIA_Hyp_M_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male" - ], - [ - "INIA_Hyp_F_RMA_1110", - "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female" - ] - ], - "Kidney": [ - [ - "MA_M2F_0706_R", - "Mouse kidney M430v2 Female (Aug06) RMA" - ], - [ - "MA_M2M_0706_R", - "Mouse kidney M430v2 Male (Aug06) RMA" - ], - [ - "MA_M2_0806_R", - "Mouse kidney M430v2 Sex Balanced (Aug06) RMA" - ], - [ - "MA_M2_0806_P", - "Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN" - ], - [ - "MA_M2_0706_P", - "Mouse Kidney M430v2 (Jul06) PDNN" - ], - [ - "MA_M2_0706_R", - "Mouse Kidney M430v2 (Jul06) RMA" - ] - ], - "Leucocytes": [ - [ - "Illum_BXD_PBL_1108", - "UWA Illumina PBL (Nov08) RSN **" - ] - ], - "Liver": [ - [ - "GSE16780_UCLA_ML0911", - "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" - ], - [ - "GenEx_BXD_liverSal_RMA_F_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverSal_RMA_M_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverSal_RMA_0211", - "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "GenEx_BXD_liverEt_RMA_F_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" - ], - [ - "GenEx_BXD_liverEt_RMA_M_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" - ], - [ - "GenEx_BXD_liverEt_RMA_0211", - "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" - ], - [ - "SUH_Liv_RMA_0611", - "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" - ] - ], - "Lung": [ - [ - "HZI_0408_R", - "HZI Lung M430v2 (Apr08) RMA" - ], - [ - "HZI_0408_M", - "HZI Lung M430v2 (Apr08) MAS5" - ] - ], - "Midbrain": [ - [ - "VUBXDMouseMidBrainQ0212", - "VU BXD Midbrain Agilent SurePrint G3 Mouse GE (Feb12) Quantile" - ] - ], - "Muscle": [ - [ - "EPFLMouseMuscleRMA1211", - "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleHFDRMA1211", - "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ], - [ - "EPFLMouseMuscleCDRMA1211", - "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" - ] - ], - "Neocortex": [ - [ - "DevNeocortex_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevNeocortex_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "HQFNeoc_1210v2_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv" - ], - [ - "HQFNeoc_1210_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv" - ], - [ - "HQFNeoc_0208_RankInv", - "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" - ], - [ - "DevNeocortex_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevNeocortex_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv **" - ] - ], - "Nucleus Accumbens": [ - [ - "VCUSalo_1007_R", - "VCU BXD NA Sal M430 2.0 (Oct07) RMA" - ], - [ - "VCUEtOH_1007_R", - "VCU BXD NA EtOH M430 2.0 (Oct07) RMA **" - ], - [ - "VCUSal_1007_R", - "VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **" - ] - ], - "Phenotypes": [ - [ - "BXDPublish", - "BXD Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "VCUEtOH_1206_R", - "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" - ], - [ - "VCUSal_1206_R", - "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" - ], - [ - "VCUSal_1006_R", - "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" - ], - [ - "VCU_PF_Air_0111_R", - "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_Et_0111_R", - "VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **" - ], - [ - "VCU_PF_AvE_0111_Ss", - "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" - ] - ], - "Retina": [ - [ - "Illum_Retina_BXD_RankInv0410", - "HEI Retina Illumina V6.2 (April 2010) RankInv" - ], - [ - "B6D2ONCILM_0412", - "B6D2 ONC Illumina v6.1 (Apr12) RankInv **" - ], - [ - "ONCRetILM6_0412", - "ONC Retina Illumina V6.2 (Apr12) RankInv **" - ], - [ - "HEIONCvsCRetILM6_0911", - "HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "G2HEIONCRetILM6_0911", - "G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "HEIONCRetILM6_0911", - "HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" - ], - [ - "ILM_Retina_BXD_F_RankInv1210", - "HEI Retina Females Illumina V6.2 (Dec10) RankInv **" - ], - [ - "ILM_Retina_BXD_M_RankInv1210", - "HEI Retina Males Illumina V6.2 (Dec10) RankInv **" - ], - [ - "ILM_Retina_BXD_FM_RankInv1210", - "HEI Retina F-M Illumina V6.2 (Dec10) RankInv **" - ], - [ - "G2NEI_ILM_Retina_BXD_RI0410", - "G2NEI Retina Illumina V6.2 (April 2010) RankInv **" - ] - ], - "Spleen": [ - [ - "UTHSC_SPL_RMA_1210", - "UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA" - ], - [ - "UTHSC_SPL_RMA_1010", - "UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA" - ], - [ - "IoP_SPL_RMA_0509", - "IoP Affy MOE 430v2 Spleen (May09) RMA" - ], - [ - "Illum_BXD_Spl_1108", - "UWA Illumina Spleen (Nov08) RSN **" - ], - [ - "UTK_BXDSpl_VST_0110", - "UTK Spleen ILM6.1 (Jan10) VST" - ] - ], - "Striatum": [ - [ - "DevStriatum_ILM6.2P3RInv_1111", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" - ], - [ - "DevStriatum_ILM6.2P14RInv_1111", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" - ], - [ - "UTHSC_Striatum_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" - ], - [ - "UTHSC_Str_RankInv_1210", - "HQF BXD Striatum ILM6.1 (Dec10) RankInv" - ], - [ - "UTHSC_1107_RankInv", - "HQF BXD Striatum ILM6.1 (Nov07) RankInv" - ], - [ - "SA_M2_0405_MC", - "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" - ], - [ - "SA_M2_0405_RC", - "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" - ], - [ - "SA_M2_0405_PC", - "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" - ], - [ - "SA_M2_0405_SS", - "HBP Rosen Striatum M430V2 (Apr05) SScore" - ], - [ - "SA_M2_0405_RR", - "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" - ], - [ - "Striatum_Exon_0209", - "HQF Striatum Exon (Feb09) RMA" - ], - [ - "DevStriatum_ILM6.2P14RInv_1110", - "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" - ], - [ - "DevStriatum_ILM6.2P3RInv_1110", - "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" - ] - ], - "T Cell (helper)": [ - [ - "RTHC_0211_R", - "HZI Thelp M430v2 (Feb11) RMA" - ] - ], - "T Cell (regulatory)": [ - [ - "RTC_1106_R", - "HZI Treg M430v2 (Feb11) RMA" - ] - ], - "Thymus": [ - [ - "Illum_BXD_Thy_1108", - "UWA Illumina Thymus (Nov08) RSN **" - ] - ], - "Ventral Tegmental Area": [ - [ - "VCUEtOH_0609_R", - "VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **" - ], - [ - "VCUSal_0609_R", - "VCU BXD VTA Sal M430 2.0 (Jun09) RMA **" - ], - [ - "VCUEtvsSal_0609_R", - "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **" - ] - ] - }, - "BXH": { - "Cartilage": [ - [ - "UCLA_BXHBXD_CARTILAGE_V2", - "UCLA BXH and BXD Cartilage v2" - ], - [ - "UCLA_BXHBXD_CARTILAGE", - "UCLA BXH and BXD Cartilage" - ], - [ - "UCLA_BXH_CARTILAGE", - "UCLA BXH Cartilage" - ] - ], - "Genotypes": [ - [ - "BXHGeno", - "BXH Genotypes" - ] - ], - "Phenotypes": [ - [ - "BXHPublish", - "BXH Published Phenotypes" - ] - ] - }, - "CTB6F2": { - "Adipose": [ - [ - "UCLA_CTB6B6CTF2_ADIPOSE_MALE", - "UCLA CTB6B6CTF2 Adipose Male mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", - "UCLA CTB6B6CTF2 Adipose Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_ADIPOSE_2005", - "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" - ] - ], - "Brain": [ - [ - "UCLA_CTB6B6CTF2_BRAIN_MALE", - "UCLA CTB6B6CTF2 Brain Male mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_FEMALE", - "UCLA CTB6B6CTF2 Brain Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_BRAIN_2005", - "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" - ] - ], - "Genotypes": [ - [ - "CTB6F2Geno", - "CTB6F2 Genotypes" - ] - ], - "Liver": [ - [ - "UCLA_CTB6B6CTF2_LIVER_MALE", - "UCLA CTB6B6CTF2 Liver Male mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_FEMALE", - "UCLA CTB6B6CTF2 Liver Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_LIVER_2005", - "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" - ] - ], - "Muscle": [ - [ - "UCLA_CTB6B6CTF2_MUSCLE_MALE", - "UCLA CTB6B6CTF2 Muscle Male mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", - "UCLA CTB6B6CTF2 Muscle Female mlratio **" - ], - [ - "UCLA_CTB6B6CTF2_MUSCLE_2005", - "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" - ] - ], - "Phenotypes": [ - [ - "CTB6F2Publish", - "CTB6F2 Published Phenotypes" - ] - ] - }, - "CXB": { - "Genotypes": [ - [ - "CXBGeno", - "CXB Genotypes" - ] - ], - "Hippocampus": [ - [ - "HC_M2CB_1205_R", - "Hippocampus Consortium M430v2 CXB (Dec05) RMA" - ], - [ - "HC_M2CB_1205_P", - "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" - ] - ], - "Phenotypes": [ - [ - "CXBPublish", - "CXB Published Phenotypes" - ] - ], - "Spleen": [ - [ - "STSPL_1107_R", - "Stuart Spleen M430v2 (Nov07) RMA" - ] - ] - }, - "HS": { - "Genotypes": [ - [ - "HSGeno", - "HS Genotypes" - ] - ], - "Hippocampus": [ - [ - "OXUKHS_ILMHipp_RI0510", - "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" - ] - ], - "Liver": [ - [ - "OXUKHS_ILMLiver_RI0510", - "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" - ] - ], - "Lung": [ - [ - "OXUKHS_ILMLung_RI0510", - "OX UK HS ILM6v1.1 Lung (May 2010) RankInv" - ] - ], - "Phenotypes": [ - [ - "HSPublish", - "HS Published Phenotypes" - ] - ] - }, - "HS-CC": { - "Genotypes": [ - [ - "HS-CCGeno", - "HS-CC Genotypes" - ] - ], - "Phenotypes": [ - [ - "HS-CCPublish", - "HS-CC Published Phenotypes" - ] - ], - "Striatum": [ - [ - "OHSU_HS-CC_ILMStr_0211", - "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" - ] - ] - }, - "LXS": { - "Genotypes": [ - [ - "LXSGeno", - "LXS Genotypes" - ] - ], - "Hippocampus": [ - [ - "Illum_LXS_Hipp_loess0807", - "Hippocampus Illumina (Aug07) LOESS" - ], - [ - "Illum_LXS_Hipp_loess_nb0807", - "Hippocampus Illumina (Aug07) LOESS_NB" - ], - [ - "Illum_LXS_Hipp_quant0807", - "Hippocampus Illumina (Aug07) QUANT" - ], - [ - "Illum_LXS_Hipp_quant_nb0807", - "Hippocampus Illumina (Aug07) QUANT_NB" - ], - [ - "Illum_LXS_Hipp_rsn0807", - "Hippocampus Illumina (Aug07) RSN" - ], - [ - "Illum_LXS_Hipp_rsn_nb0807", - "Hippocampus Illumina (Aug07) RSN_NB" - ], - [ - "Hipp_Illumina_RankInv_0507", - "Hippocampus Illumina (May07) RankInv" - ], - [ - "Illum_LXS_Hipp_NOS_1008", - "Hippocampus Illumina NOS (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NON_1008", - "Hippocampus Illumina NON (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_RSE_1008", - "Hippocampus Illumina RSE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_NOE_1008", - "Hippocampus Illumina NOE (Oct08) RankInv beta" - ], - [ - "Illum_LXS_Hipp_RSS_1008", - "Hippocampus Illumina RSS (Oct08) RankInv beta" - ] - ], - "Phenotypes": [ - [ - "LXSPublish", - "LXS Published Phenotypes" - ] - ], - "Prefrontal Cortex": [ - [ - "VCUEtOH_0806_R", - "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" - ], - [ - "VCUSal_0806_R", - "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" - ], - [ - "VCUEt_vs_Sal_0806_R", - "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" - ] - ] - }, - "MDP": { - "Genotypes": [ - [ - "MDPGeno", - "MDP Genotypes" - ] - ], - "Hippocampus": [ - [ - "UMUTAffyExon_0209_RMA_MDP", - "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" - ], - [ - "HC_M2_0606_MDP", - "Hippocampus Consortium M430v2 (Jun06) RMA MDP" - ] - ], - "Liver": [ - [ - "JAX_CSB_L_0711", - "JAX Liver Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_HF_0711", - "JAX Liver HF Affy M430 2.0 (Jul11) MDP" - ], - [ - "JAX_CSB_L_6C_0711", - "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" - ] - ], - "Phenotypes": [ - [ - "MDPPublish", - "Mouse Phenome Database" - ] - ] - }, - "NZBXFVB-N2": { - "Genotypes": [ - [ - "NZBXFVB-N2Geno", - "NZBXFVB-N2 Genotypes" - ] - ], - "Mammary Tumors": [ - [ - "NCI_Mam_Tum_RMA_0409", - "NCI Mammary M430v2 (Apr09) RMA" - ] - ], - "Phenotypes": [ - [ - "NZBXFVB-N2Publish", - "NZBXFVB-N2 Published Phenotypes" - ] - ] - } - }, - "rat": { - "HXBBXH": { - "Adrenal Gland": [ - [ - "HXB_Adrenal_1208", - "MDC/CAS/UCL Adrenal 230A (Dec08) RMA" - ] - ], - "Genotypes": [ - [ - "HXBBXHGeno", - "HXBBXH Genotypes" - ] - ], - "Heart": [ - [ - "HXB_Heart_1208", - "MDC/CAS/UCL Heart 230_V2 (Dec08) RMA" - ] - ], - "Hippocampus": [ - [ - "UT_HippRatEx_RMA_0709", - "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" - ] - ], - "Kidney": [ - [ - "KI_2A_0405_M", - "MDC/CAS/ICL Kidney 230A (Apr05) MAS5" - ], - [ - "KI_2A_0405_Rz", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8" - ], - [ - "KI_2A_0405_R", - "MDC/CAS/ICL Kidney 230A (Apr05) RMA" - ] - ], - "Liver": [ - [ - "HXB_Liver_1208", - "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" - ] - ], - "Peritoneal Fat": [ - [ - "FT_2A_0805_M", - "MDC/CAS/ICL Peritoneal Fat 230A (Aug05) MAS5" - ], - [ - "FT_2A_0605_Rz", - "MDC/CAS/ICL Peritoneal Fat 230A (Jun05) RMA 2z+8" - ] - ], - "Phenotypes": [ - [ - "HXBBXHPublish", - "HXBBXH Published Phenotypes" - ] - ] - }, - "SRxSHRSPF2": { - "Eye": [ - [ - "UIOWA_Eye_RMA_0906", - "UIOWA Eye mRNA RAE230v2 (Sep06) RMA" - ] - ], - "Genotypes": [ - [ - "SRxSHRSPF2Geno", - "SRxSHRSPF2 Genotypes" - ] - ], - "Phenotypes": [ - [ - "SRxSHRSPF2Publish", - "SRxSHRSPF2 Published Phenotypes" - ] - ] - } - }, - "soybean": { - "J12XJ58F2": { - "Genotypes": [ - [ - "J12XJ58F2Geno", - "J12XJ58F2 Genotypes" - ] - ], - "Phenotypes": [ - [ - "J12XJ58F2Publish", - "J12XJ58F2 Published Phenotypes" - ] - ] - } - }, - "tomato": { - "LXP": { - "Genotypes": [ - [ - "LXPGeno", - "LXP Genotypes" - ] - ], - "Phenotypes": [ - [ - "LXPPublish", - "LXP Published Phenotypes" - ] - ] - } - } - }, - "groups": { - "All Species": [ - [ - "All Groups", - "All Groups" - ] - ], - "arabidopsis": [ - [ - "BayXSha", - "BayXSha" - ], - [ - "ColXBur", - "ColXBur" - ], - [ - "ColXCvi", - "ColXCvi" - ] - ], - "barley": [ - [ - "QSM", - "QSM" - ], - [ - "SXM", - "SXM" - ] - ], - "drosophila": [ - [ - "DGRP", - "Drosophila Genetic Reference Panel" - ], - [ - "Oregon-R_x_2b3", - "Oregon-R x 2b3" - ] - ], - "human": [ - [ - "AD-cases-controls", - "AD Cases & Controls (Liang)" - ], - [ - "AD-cases-controls-Myers", - "AD Cases & Controls (Myers)" - ], - [ - "CANDLE", - "CANDLE" - ], - [ - "CEPH-2004", - "CEPH Families" - ], - [ - "HB", - "Harvard Brain Tissue Resource Center" - ], - [ - "HLC", - "Human Liver Cohort" - ], - [ - "HSB", - "KIN/YSM" - ] - ], - "macaque monkey": [ - [ - "Macaca-fasicularis", - "Macaca fasicularis (Cynomolgus monkey)" - ] - ], - "mouse": [ - [ - "AKXD", - "AKXD" - ], - [ - "AXBXA", - "AXB/BXA" - ], - [ - "B6BTBRF2", - "B6BTBRF2" - ], - [ - "B6D2F2", - "B6D2F2" - ], - [ - "BDF2-1999", - "BDF2 UCLA" - ], - [ - "BDF2-2005", - "BDF2-2005" - ], - [ - "BHF2", - "BHF2 (Apoe Null) UCLA" - ], - [ - "BHHBF2", - "BH/HB F2 UCLA" - ], - [ - "BXD", - "BXD" - ], - [ - "BXH", - "BXH" - ], - [ - "CTB6F2", - "CastB6/B6Cast F2 UCLA" - ], - [ - "CXB", - "CXB" - ], - [ - "HS", - "Heterogeneous Stock" - ], - [ - "HS-CC", - "Heterogeneous Stock Collaborative Cross" - ], - [ - "LXS", - "LXS" - ], - [ - "MDP", - "Mouse Diversity Panel" - ], - [ - "NZBXFVB-N2", - "NZB/FVB N2 NCI" - ] - ], - "rat": [ - [ - "HXBBXH", - "HXB/BXH" - ], - [ - "SRxSHRSPF2", - "UIOWA SRxSHRSP F2" - ] - ], - "soybean": [ - [ - "J12XJ58F2", - "J12XJ58F2" - ] - ], - "tomato": [ - [ - "LXP", - "LXP" - ] - ] - }, - "species": [ - [ - "human", - "Human" - ], - [ - "macaque monkey", - "Macaque monkey" - ], - [ - "mouse", - "Mouse" - ], - [ - "rat", - "Rat" - ], - [ - "drosophila", - "Drosophila" - ], - [ - "arabidopsis", - "Arabidopsis thaliana" - ], - [ - "barley", - "Barley" - ], - [ - "soybean", - "Soybean" - ], - [ - "tomato", - "Tomato" - ], - [ - "All Species", - "All Species" - ] - ], - "types": { - "All Species": { - "All Groups": [ - [ - "Phenotypes", - "Phenotypes" - ] - ] - }, - "arabidopsis": { - "BayXSha": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ] - ], - "ColXBur": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ] - ], - "ColXCvi": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ] - ] - }, - "barley": { - "QSM": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Leaf", - "Leaf mRNA" - ] - ], - "SXM": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Embryo", - "Embryo mRNA" - ], - [ - "Leaf", - "Leaf mRNA" - ] - ] - }, - "drosophila": { - "DGRP": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Whole Body", - "Whole Body mRNA" - ] - ], - "Oregon-R_x_2b3": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Whole Body", - "Whole Body mRNA" - ] - ] - }, - "human": { - "AD-cases-controls": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Brain", - "Brain mRNA" - ] - ], - "AD-cases-controls-Myers": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Brain", - "Brain mRNA" - ] - ], - "CANDLE": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Newborn Cord Blood", - "Newborn Cord Blood mRNA" - ] - ], - "CEPH-2004": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Lymphoblast B-cell", - "Lymphoblast B-cell mRNA" - ] - ], - "HB": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Cerebellum", - "Cerebellum mRNA" - ], - [ - "Prefrontal Cortex", - "Prefrontal Cortex mRNA" - ], - [ - "Primary Visual Cortex", - "Primary Visual Cortex mRNA" - ] - ], - "HLC": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Liver", - "Liver mRNA" - ] - ], - "HSB": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Amygdala", - "Amygdala mRNA" - ], - [ - "Caudal Ganglionic Eminence", - "Caudal Ganglionic Eminence mRNA" - ], - [ - "Cerebellar Cortex", - "Cerebellar Cortex mRNA" - ], - [ - "Diencephalon", - "Diencephalon mRNA" - ], - [ - "Dorsal Thalamus", - "Dorsal Thalamus mRNA" - ], - [ - "Dorsolateral Prefrontal Cortex", - "Dorsolateral Prefrontal Cortex mRNA" - ], - [ - "Frontal Cerebral Wall", - "Frontal Cerebral Wall mRNA" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Inferior Temporal Cortex", - "Inferior Temporal Cortex mRNA" - ], - [ - "Lateral Ganglionic Eminence", - "Lateral Ganglionic Eminence mRNA" - ], - [ - "Medial Ganglionic Eminence", - "Medial Ganglionic Eminence mRNA" - ], - [ - "Medial Prefrontal Cortex", - "Medial Prefrontal Cortex mRNA" - ], - [ - "Mediodorsal Nucleus of Thalamus", - "Mediodorsal Nucleus of Thalamus mRNA" - ], - [ - "Occipital Cerebral Wall", - "Occipital Cerebral Wall mRNA" - ], - [ - "Orbital Prefrontal Cortex", - "Orbital Prefrontal Cortex mRNA" - ], - [ - "Parietal Cerebral Wall", - "Parietal Cerebral Wall mRNA" - ], - [ - "Posterior Inferior Parietal Cortex", - "Posterior Inferior Parietal Cortex mRNA" - ], - [ - "Posterior Superior Temporal Cortex", - "Posterior Superior Temporal Cortex mRNA" - ], - [ - "Primary Auditory (A1) Cortex", - "Primary Auditory (A1) Cortex mRNA" - ], - [ - "Primary Motor (M1) Cortex", - "Primary Motor (M1) Cortex mRNA" - ], - [ - "Primary Somatosensory (S1) Cortex", - "Primary Somatosensory (S1) Cortex mRNA" - ], - [ - "Primary Visual Cortex", - "Primary Visual Cortex mRNA" - ], - [ - "Striatum", - "Striatum mRNA" - ], - [ - "Temporal Cerebral Wall", - "Temporal Cerebral Wall mRNA" - ], - [ - "Upper (Rostral) Rhombic Lip", - "Upper (Rostral) Rhombic Lip mRNA" - ], - [ - "Ventral Forebrain", - "Ventral Forebrain mRNA" - ], - [ - "Ventrolateral Prefrontal Cortex", - "Ventrolateral Prefrontal Cortex mRNA" - ] - ] - }, - "macaque monkey": { - "Macaca-fasicularis": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Amygdala", - "Amygdala mRNA" - ], - [ - "Brain", - "Brain mRNA" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Nucleus Accumbens", - "Nucleus Accumbens mRNA" - ], - [ - "Prefrontal Cortex", - "Prefrontal Cortex mRNA" - ] - ] - }, - "mouse": { - "AKXD": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Mammary Tumors", - "Mammary Tumors mRNA" - ] - ], - "AXBXA": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Eye", - "Eye mRNA" - ] - ], - "B6BTBRF2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Liver", - "Liver mRNA" - ] - ], - "B6D2F2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Brain", - "Brain mRNA" - ] - ], - "BDF2-1999": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Liver", - "Liver mRNA" - ] - ], - "BDF2-2005": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Striatum", - "Striatum mRNA" - ] - ], - "BHF2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Adipose", - "Adipose mRNA" - ], - [ - "Brain", - "Brain mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Muscle", - "Muscle mRNA" - ] - ], - "BHHBF2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Adipose", - "Adipose mRNA" - ], - [ - "Brain", - "Brain mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Muscle", - "Muscle mRNA" - ] - ], - "BXD": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Amygdala", - "Amygdala mRNA" - ], - [ - "Brain", - "Brain mRNA" - ], - [ - "Cartilage", - "Cartilage mRNA" - ], - [ - "Cerebellum", - "Cerebellum mRNA" - ], - [ - "Eye", - "Eye mRNA" - ], - [ - "Hematopoietic Cells", - "Hematopoietic Cells mRNA" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Hypothalamus", - "Hypothalamus mRNA" - ], - [ - "Kidney", - "Kidney mRNA" - ], - [ - "Leucocytes", - "Leucocytes mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Lung", - "Lung mRNA" - ], - [ - "Midbrain", - "Midbrain mRNA" - ], - [ - "Muscle", - "Muscle mRNA" - ], - [ - "Neocortex", - "Neocortex mRNA" - ], - [ - "Nucleus Accumbens", - "Nucleus Accumbens mRNA" - ], - [ - "Prefrontal Cortex", - "Prefrontal Cortex mRNA" - ], - [ - "Retina", - "Retina mRNA" - ], - [ - "Spleen", - "Spleen mRNA" - ], - [ - "Striatum", - "Striatum mRNA" - ], - [ - "T Cell (helper)", - "T Cell (helper) mRNA" - ], - [ - "T Cell (regulatory)", - "T Cell (regulatory) mRNA" - ], - [ - "Thymus", - "Thymus mRNA" - ], - [ - "Ventral Tegmental Area", - "Ventral Tegmental Area mRNA" - ] - ], - "BXH": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Cartilage", - "Cartilage mRNA" - ] - ], - "CTB6F2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Adipose", - "Adipose mRNA" - ], - [ - "Brain", - "Brain mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Muscle", - "Muscle mRNA" - ] - ], - "CXB": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Spleen", - "Spleen mRNA" - ] - ], - "HS": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Lung", - "Lung mRNA" - ] - ], - "HS-CC": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Striatum", - "Striatum mRNA" - ] - ], - "LXS": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Prefrontal Cortex", - "Prefrontal Cortex mRNA" - ] - ], - "MDP": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Liver", - "Liver mRNA" - ] - ], - "NZBXFVB-N2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Mammary Tumors", - "Mammary Tumors mRNA" - ] - ] - }, - "rat": { - "HXBBXH": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Adrenal Gland", - "Adrenal Gland mRNA" - ], - [ - "Heart", - "Heart mRNA" - ], - [ - "Hippocampus", - "Hippocampus mRNA" - ], - [ - "Kidney", - "Kidney mRNA" - ], - [ - "Liver", - "Liver mRNA" - ], - [ - "Peritoneal Fat", - "Peritoneal Fat mRNA" - ] - ], - "SRxSHRSPF2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ], - [ - "Eye", - "Eye mRNA" - ] - ] - }, - "soybean": { - "J12XJ58F2": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ] - ] - }, - "tomato": { - "LXP": [ - [ - "Phenotypes", - "Phenotypes" - ], - [ - "Genotypes", - "Genotypes" - ] - ] - } - } -} \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_items.js b/wqflask/wqflask/static/new/javascript/dataset_select_items.js deleted file mode 100755 index 33ff34cb..00000000 --- a/wqflask/wqflask/static/new/javascript/dataset_select_items.js +++ /dev/null @@ -1,773 +0,0 @@ -window.sArr = [ -{txt:'',val:''}, -{txt:'Human',val:'human'}, -{txt:'Macaque monkey',val:'macaque monkey'}, -{txt:'Mouse',val:'mouse'}, -{txt:'Rat',val:'rat'}, -{txt:'Drosophila',val:'drosophila'}, -{txt:'Arabidopsis thaliana',val:'arabidopsis'}, -{txt:'Barley',val:'barley'}, -{txt:'Soybean',val:'soybean'}, -{txt:'Tomato',val:'tomato'}, -{txt:'All Species',val:'All Species'}]; - -window.gArr = [ -{txt:'',val:''}, -{txt:'AD Cases & Controls (Liang)',val:'AD-cases-controls'}, -{txt:'AD Cases & Controls (Myers)',val:'AD-cases-controls-Myers'}, -{txt:'AKXD',val:'AKXD'}, -{txt:'AXB/BXA',val:'AXBXA'}, -{txt:'B6BTBRF2',val:'B6BTBRF2'}, -{txt:'B6D2F2',val:'B6D2F2'}, -{txt:'BayXSha',val:'BayXSha'}, -{txt:'BDF2 UCLA',val:'BDF2-1999'}, -{txt:'BDF2-2005',val:'BDF2-2005'}, -{txt:'BHF2 (Apoe Null) UCLA',val:'BHF2'}, -{txt:'BH/HB F2 UCLA',val:'BHHBF2'}, -{txt:'BXD',val:'BXD'}, -{txt:'BXH',val:'BXH'}, -{txt:'CANDLE',val:'CANDLE'}, -{txt:'CEPH Families',val:'CEPH-2004'}, -{txt:'ColXBur',val:'ColXBur'}, -{txt:'ColXCvi',val:'ColXCvi'}, -{txt:'CastB6/B6Cast F2 UCLA',val:'CTB6F2'}, -{txt:'CXB',val:'CXB'}, -{txt:'Drosophila Genetic Reference Panel',val:'DGRP'}, -{txt:'Harvard Brain Tissue Resource Center',val:'HB'}, -{txt:'Human Liver Cohort',val:'HLC'}, -{txt:'Heterogeneous Stock',val:'HS'}, -{txt:'Heterogeneous Stock Collaborative Cross',val:'HS-CC'}, -{txt:'KIN/YSM',val:'HSB'}, -{txt:'HXB/BXH',val:'HXBBXH'}, -{txt:'J12XJ58F2',val:'J12XJ58F2'}, -{txt:'LXP',val:'LXP'}, -{txt:'LXS',val:'LXS'}, -{txt:'Macaca fasicularis (Cynomolgus monkey)',val:'Macaca-fasicularis'}, -{txt:'Mouse Diversity Panel',val:'MDP'}, -{txt:'NZB/FVB N2 NCI',val:'NZBXFVB-N2'}, -{txt:'Oregon-R x 2b3',val:'Oregon-R_x_2b3'}, -{txt:'QSM',val:'QSM'}, -{txt:'UIOWA SRxSHRSP F2',val:'SRxSHRSPF2'}, -{txt:'SXM',val:'SXM'}, -{txt:'All Groups',val:'all groups'}]; - -window.tArr = [ -{txt:'',val:''}, -{txt:'Adipose mRNA',val:'Adipose'}, -{txt:'Adrenal Gland mRNA',val:'Adrenal Gland'}, -{txt:'Amygdala mRNA',val:'Amygdala'}, -{txt:'Brain mRNA',val:'Brain'}, -{txt:'Cartilage mRNA',val:'Cartilage'}, -{txt:'Caudal Ganglionic Eminence mRNA',val:'Caudal Ganglionic Eminence'}, -{txt:'Cerebellar Cortex mRNA',val:'Cerebellar Cortex'}, -{txt:'Cerebellum mRNA',val:'Cerebellum'}, -{txt:'Diencephalon mRNA',val:'Diencephalon'}, -{txt:'Dorsal Thalamus mRNA',val:'Dorsal Thalamus'}, -{txt:'Dorsolateral Prefrontal Cortex mRNA',val:'Dorsolateral Prefrontal Cortex'}, -{txt:'Embryo mRNA',val:'Embryo'}, -{txt:'Eye mRNA',val:'Eye'}, -{txt:'Frontal Cerebral Wall mRNA',val:'Frontal Cerebral Wall'}, -{txt:'Heart mRNA',val:'Heart'}, -{txt:'Hematopoietic Cells mRNA',val:'Hematopoietic Cells'}, -{txt:'Hippocampus mRNA',val:'Hippocampus'}, -{txt:'Hypothalamus mRNA',val:'Hypothalamus'}, -{txt:'Inferior Temporal Cortex mRNA',val:'Inferior Temporal Cortex'}, -{txt:'Kidney mRNA',val:'Kidney'}, -{txt:'Lateral Ganglionic Eminence mRNA',val:'Lateral Ganglionic Eminence'}, -{txt:'Leaf mRNA',val:'Leaf'}, -{txt:'Leucocytes mRNA',val:'Leucocytes'}, -{txt:'Liver mRNA',val:'Liver'}, -{txt:'Lung mRNA',val:'Lung'}, -{txt:'Lymphoblast B-cell mRNA',val:'Lymphoblast B-cell'}, -{txt:'Mammary Tumors mRNA',val:'Mammary Tumors'}, -{txt:'Medial Ganglionic Eminence mRNA',val:'Medial Ganglionic Eminence'}, -{txt:'Medial Prefrontal Cortex mRNA',val:'Medial Prefrontal Cortex'}, -{txt:'Mediodorsal Nucleus of Thalamus mRNA',val:'Mediodorsal Nucleus of Thalamus'}, -{txt:'Midbrain mRNA',val:'Midbrain'}, -{txt:'Muscle mRNA',val:'Muscle'}, -{txt:'Neocortex mRNA',val:'Neocortex'}, -{txt:'Newborn Cord Blood mRNA',val:'Newborn Cord Blood'}, -{txt:'Nucleus Accumbens mRNA',val:'Nucleus Accumbens'}, -{txt:'Occipital Cerebral Wall mRNA',val:'Occipital Cerebral Wall'}, -{txt:'Orbital Prefrontal Cortex mRNA',val:'Orbital Prefrontal Cortex'}, -{txt:'Parietal Cerebral Wall mRNA',val:'Parietal Cerebral Wall'}, -{txt:'Peritoneal Fat mRNA',val:'Peritoneal Fat'}, -{txt:'Posterior Inferior Parietal Cortex mRNA',val:'Posterior Inferior Parietal Cortex'}, -{txt:'Posterior Superior Temporal Cortex mRNA',val:'Posterior Superior Temporal Cortex'}, -{txt:'Prefrontal Cortex mRNA',val:'Prefrontal Cortex'}, -{txt:'Primary Auditory (A1) Cortex mRNA',val:'Primary Auditory (A1) Cortex'}, -{txt:'Primary Motor (M1) Cortex mRNA',val:'Primary Motor (M1) Cortex'}, -{txt:'Primary Somatosensory (S1) Cortex mRNA',val:'Primary Somatosensory (S1) Cortex'}, -{txt:'Primary Visual Cortex mRNA',val:'Primary Visual Cortex'}, -{txt:'Retina mRNA',val:'Retina'}, -{txt:'Spleen mRNA',val:'Spleen'}, -{txt:'Striatum mRNA',val:'Striatum'}, -{txt:'T Cell (helper) mRNA',val:'T Cell (helper)'}, -{txt:'T Cell (regulatory) mRNA',val:'T Cell (regulatory)'}, -{txt:'Temporal Cerebral Wall mRNA',val:'Temporal Cerebral Wall'}, -{txt:'Thymus mRNA',val:'Thymus'}, -{txt:'Upper (Rostral) Rhombic Lip mRNA',val:'Upper (Rostral) Rhombic Lip'}, -{txt:'Ventral Forebrain mRNA',val:'Ventral Forebrain'}, -{txt:'Ventral Tegmental Area mRNA',val:'Ventral Tegmental Area'}, -{txt:'Ventrolateral Prefrontal Cortex mRNA',val:'Ventrolateral Prefrontal Cortex'}, -{txt:'Whole Body mRNA',val:'Whole Body'}, -{txt:'Phenotypes',val:'Phenotypes'}, -{txt:'Genotypes',val:'Genotypes'}]; - -window.dArr = [ -{txt:'',val:''}, -{txt:'GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv',val:'GSE15222_F_A_RI_0409'}, -{txt:'GSE15222 Human Brain Normal Myers (Apr09) RankInv',val:'GSE15222_F_N_RI_0409'}, -{txt:'Normal HEI Retina (April 2010) RankInv',val:'G2NEI_ILM_Retina_BXD_RI0410'}, -{txt:'Full HEI Retina (April 2010) RankInv',val:'Illum_Retina_BXD_RankInv0410'}, -{txt:'ONC HEI Retina (April 2012) RankInv',val:'ONCRetILM6_0412'}, -{txt:'B6D2 ONC Retina (April 2012) RankInv **',val:'B6D2ONCILM_0412'}, -{txt:'INIA Macaca fasicularis Nucleus Accumbens (Jan10) RMA **',val:'INIA_MacFas_Ac_RMA_0110'}, -{txt:'UCLA CTB6/B6CTF2 Liver (2005) mlratio',val:'UCLA_CTB6B6CTF2_LIVER_2005'}, -{txt:'UCLA CTB6/B6CTF2 Adipose (2005) mlratio',val:'UCLA_CTB6B6CTF2_ADIPOSE_2005'}, -{txt:'UCLA CTB6/B6CTF2 Brain (2005) mlratio',val:'UCLA_CTB6B6CTF2_BRAIN_2005'}, -{txt:'UCLA CTB6/B6CTF2 Muscle (2005) mlratio',val:'UCLA_CTB6B6CTF2_MUSCLE_2005'}, -{txt:'INIA Macaca fasicularis Hippocampus (Jan10) RMA **',val:'INIA_MacFas_Hc_RMA_0110'}, -{txt:'UCLA CTB6B6CTF2 Muscle Female mlratio **',val:'UCLA_CTB6B6CTF2_MUSCLE_FEMALE'}, -{txt:'INIA Macaca fasicularis Amygdala (Jan10) RMA **',val:'INIA_MacFas_AMG_RMA_0110'}, -{txt:'UCLA CTB6B6CTF2 Adipose Female mlratio **',val:'UCLA_CTB6B6CTF2_ADIPOSE_FEMALE'}, -{txt:'UCLA CTB6B6CTF2 Brain Female mlratio **',val:'UCLA_CTB6B6CTF2_BRAIN_FEMALE'}, -{txt:'UCLA CTB6B6CTF2 Liver Female mlratio **',val:'UCLA_CTB6B6CTF2_LIVER_FEMALE'}, -{txt:'VU BXD Midbrain Agilent SurePrint G3 Mouse GE (May12) Quantile **',val:'VUBXDMouseMidBrainQ0512'}, -{txt:'GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA',val:'GSE16780_UCLA_ML0911'}, -{txt:'EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleRMA1211'}, -{txt:'EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleHFDRMA1211'}, -{txt:'EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **',val:'EPFLMouseMuscleCDRMA1211'}, -{txt:'BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **',val:'DevStriatum_ILM6.2P14RInv_1111'}, -{txt:'BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **',val:'DevStriatum_ILM6.2P3RInv_1111'}, -{txt:'BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv',val:'DevNeocortex_ILM6.2P14RInv_1111'}, -{txt:'BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv',val:'DevNeocortex_ILM6.2P3RInv_1111'}, -{txt:'G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **',val:'G2HEIONCRetILM6_0911'}, -{txt:'HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **',val:'HEIONCvsCRetILM6_0911'}, -{txt:'JAX Liver Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_0711'}, -{txt:'JAX Liver HF Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_HF_0711'}, -{txt:'JAX Liver 6C Affy M430 2.0 (Jul11) MDP',val:'JAX_CSB_L_6C_0711'}, -{txt:'CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **',val:'CANDLE_NB_0711'}, -{txt:'KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_AMY_0711'}, -{txt:'KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_A1C_0711'}, -{txt:'KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_TC_0711'}, -{txt:'KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_CBC_0711'}, -{txt:'KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_CGE_0711'}, -{txt:'KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_FC_0711'}, -{txt:'KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_S1C_0711'}, -{txt:'KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_STR_0711'}, -{txt:'KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_URL_0711'}, -{txt:'KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_V1C_0711'}, -{txt:'KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_VF_0711'}, -{txt:'KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_VFC_0711'}, -{txt:'KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_STC_0711'}, -{txt:'KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_ITC_0711'}, -{txt:'KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_LGE_0711'}, -{txt:'KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_M1C_0711'}, -{txt:'KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MD_0711'}, -{txt:'KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_IPC_0711'}, -{txt:'KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_HIP_0711'}, -{txt:'KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MFC_0711'}, -{txt:'KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DFC_0711'}, -{txt:'KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DIE_0711'}, -{txt:'KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_MGE_0711'}, -{txt:'KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_DTH_0711'}, -{txt:'KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_PC_0711'}, -{txt:'KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_OC_0711'}, -{txt:'KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **',val:'KIN_YSM_OFC_0711'}, -{txt:'HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio',val:'HBTRC-MLC_0611'}, -{txt:'HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio',val:'HBTRC-MLC_N_0611'}, -{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio',val:'HBTRC-MLPFC_0611'}, -{txt:'HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio',val:'HBTRC-MLC_AD_0611'}, -{txt:'HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio',val:'HBTRC-MLVC_0611'}, -{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio',val:'HBTRC-MLPFC_N_0611'}, -{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio',val:'HBTRC-MLPFC_AD_0611'}, -{txt:'HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio',val:'HBTRC-MLC_HD_0611'}, -{txt:'HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio',val:'HBTRC-MLVC_N_0611'}, -{txt:'HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio',val:'HBTRC-MLPFC_HD_0611'}, -{txt:'HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio',val:'HBTRC-MLVC_AD_0611'}, -{txt:'HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio',val:'HBTRC-MLVC_HD_0611'}, -{txt:'INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA',val:'INIA_AmgCoh_0311'}, -{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA',val:'INIA_Amg_BLA_RMA_1110'}, -{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male',val:'INIA_Amg_BLA_RMA_M_1110'}, -{txt:'INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female',val:'INIA_Amg_BLA_RMA_F_1110'}, -{txt:'GSE9588 Human Liver Normal (Mar11) Both Sexes',val:'HLC_0311'}, -{txt:'GSE9588 Human Liver Normal (Mar11) Males',val:'HLCM_0311'}, -{txt:'HZI Thelp M430v2 (Feb11) RMA',val:'RTHC_0211_R'}, -{txt:'GSE5281 Human Brain Normal Full Liang (Jul09) RMA',val:'GSE5281_F_RMA_N_0709'}, -{txt:'GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA',val:'GSE5281_F_RMA_Alzh_0709'}, -{txt:'OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv',val:'OHSU_HS-CC_ILMStr_0211'}, -{txt:'NCSU Drosophila Whole Body (Jan11) RMA',val:'NCSU_DrosWB_LC_RMA_0111'}, -{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Females',val:'LV_G_0106_F'}, -{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Males',val:'LV_G_0106_M'}, -{txt:'UNC Agilent G4121A Liver LOWESS Stanford (Jan06) Both Sexes',val:'LV_G_0106_B'}, -{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **',val:'GenEx_BXD_liverSal_RMA_F_0211'}, -{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **',val:'GenEx_BXD_liverSal_RMA_M_0211'}, -{txt:'GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **',val:'GenEx_BXD_liverSal_RMA_0211'}, -{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **',val:'GenEx_BXD_liverEt_RMA_F_0211'}, -{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **',val:'GenEx_BXD_liverEt_RMA_M_0211'}, -{txt:'GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **',val:'GenEx_BXD_liverEt_RMA_0211'}, -{txt:'SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **',val:'SUH_Liv_RMA_0611'}, -{txt:'HQF BXD Striatum ILM6.1 (Dec10v2) RankInv',val:'UTHSC_Striatum_RankInv_1210'}, -{txt:'HQF BXD Striatum ILM6.1 (Dec10) RankInv',val:'UTHSC_Str_RankInv_1210'}, -{txt:'HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv',val:'HQFNeoc_1210v2_RankInv'}, -{txt:'UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA',val:'UTHSC_SPL_RMA_1210'}, -{txt:'HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv',val:'HQFNeoc_1210_RankInv'}, -{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)',val:'INIA_Hyp_RMA_1110'}, -{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male',val:'INIA_Hyp_M_RMA_1110'}, -{txt:'INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female',val:'INIA_Hyp_F_RMA_1110'}, -{txt:'UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA',val:'UTHSC_SPL_RMA_1010'}, -{txt:'Hippocampus Consortium M430v2 (Jun06) RMA MDP',val:'HC_M2_0606_MDP'}, -{txt:'UMUTAffy Hippocampus Exon (Feb09) RMA MDP',val:'UMUTAffyExon_0209_RMA_MDP'}, -{txt:'OX UK HS ILM6v1.1 Lung (May 2010) RankInv',val:'OXUKHS_ILMLung_RI0510'}, -{txt:'OX UK HS ILM6v1.1 Liver (May 2010) RankInv',val:'OXUKHS_ILMLiver_RI0510'}, -{txt:'OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv',val:'OXUKHS_ILMHipp_RI0510'}, -{txt:'INIA Macaca fasicularis Prefrontal Cortex (Jan10) RMA **',val:'INIA_MacFas_Pf_RMA_0110'}, -{txt:'INIA Macaca fasicularis Brain (Jan10) RMA **',val:'INIA_MacFas_brain_RMA_0110'}, -{txt:'UAB Whole body D.m. mRNA control (Oct09) RMA',val:'UAB_DrosWB_LC_RMA_1009'}, -{txt:'UAB Whole body D.m. mRNA lead (pbAc) (Oct09) RMA',val:'UAB_DrosWB_LE_RMA_1009'}, -{txt:'UMCG Stem Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_HemaStem_ori'}, -{txt:'UMCG Stem Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_HemaStem'}, -{txt:'UMCG Progenitor Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Pro_ori'}, -{txt:'UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Pro'}, -{txt:'UMCG Erythroid Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Eryth_ori'}, -{txt:'UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Eryth'}, -{txt:'UMCG Myeloid Cells ILM6v1.1 (Apr09) original',val:'UMCG_0907_Myeloid_ori'}, -{txt:'UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed',val:'UMCG_0907_Myeloid'}, -{txt:'UTHSC CEPH B-cells Illumina (Sep09) RankInv',val:'UT_CEPH_RankInv0909'}, -{txt:'Mouse kidney M430v2 Female (Aug06) RMA',val:'MA_M2F_0706_R'}, -{txt:'Mouse kidney M430v2 Male (Aug06) RMA',val:'MA_M2M_0706_R'}, -{txt:'Barley1 Leaf INOC TTKS (Aug09) RMA',val:'B1LI0809R'}, -{txt:'Barley1 Leaf INOC TTKS (Aug09) MAS5',val:'B1LI0809M5'}, -{txt:'Barley1 Leaf MOCK TTKS (Aug09) MAS5',val:'B1MI0809M5'}, -{txt:'Barley1 Leaf MOCK TTKS (Aug09) RMA',val:'B1MI0809R'}, -{txt:'GSE15222 Human Brain Myers (Apr09) RankInv',val:'GSE15222_F_RI_0409'}, -{txt:'GSE5281 Human Brain Full Liang (Jul09) RMA',val:'GSE5281_F_RMA0709'}, -{txt:'GSE5281 Human Brain Best 102 Liang (Jul09) RMA',val:'GSE5281_RMA0709'}, -{txt:'UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA',val:'UT_HippRatEx_RMA_0709'}, -{txt:'VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **',val:'VCUEtOH_0609_R'}, -{txt:'VCU BXD VTA Sal M430 2.0 (Jun09) RMA **',val:'VCUSal_0609_R'}, -{txt:'VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **',val:'VCUEtvsSal_0609_R'}, -{txt:'IoP Affy MOE 430v2 Spleen (May09) RMA',val:'IoP_SPL_RMA_0509'}, -{txt:'NCI Mammary M430v2 (Apr09) RMA',val:'NCI_Mam_Tum_RMA_0409'}, -{txt:'NCI Mammary LMT miRNA v2 (Apr09) RMA',val:'NCI_Agil_Mam_Tum_RMA_0409'}, -{txt:'MDC/CAS/UCL Liver 230v2 (Dec08) RMA',val:'HXB_Liver_1208'}, -{txt:'MDC/CAS/UCL Heart 230_V2 (Dec08) RMA',val:'HXB_Heart_1208'}, -{txt:'MDC/CAS/UCL Adrenal 230A (Dec08) RMA',val:'HXB_Adrenal_1208'}, -{txt:'UWA Illumina PBL (Nov08) RSN **',val:'Illum_BXD_PBL_1108'}, -{txt:'UWA Illumina Thymus (Nov08) RSN **',val:'Illum_BXD_Thy_1108'}, -{txt:'UWA Illumina Spleen (Nov08) RSN **',val:'Illum_BXD_Spl_1108'}, -{txt:'Monks CEPH B-cells Agilent (Dec04) Log10Ratio',val:'Human_1008'}, -{txt:'UTK Spleen ILM6.1 (Jan10) VST',val:'UTK_BXDSpl_VST_0110'}, -{txt:'Eye AXBXA Illumina V6.2(Oct08) RankInv Beta',val:'Eye_AXBXA_1008_RankInv'}, -{txt:'Eye M430v2 (Sep08) RMA',val:'Eye_M2_0908_R'}, -{txt:'Eye M430v2 Mutant Gpnmb (Sep08) RMA **',val:'Eye_M2_0908_R_NB'}, -{txt:'Eye M430v2 WT Gpnmb (Sep08) RMA **',val:'Eye_M2_0908_R_ND'}, -{txt:'Eye M430v2 Mutant Tyrp1 (Sep08) RMA **',val:'Eye_M2_0908_R_MT'}, -{txt:'Eye M430v2 WT WT (Sep08) RMA **',val:'Eye_M2_0908_WTWT'}, -{txt:'Eye M430v2 WT Tyrp1 (Sep08) RMA **',val:'Eye_M2_0908_R_WT'}, -{txt:'BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **',val:'BXD_GLA_0911'}, -{txt:'UCLA BXH and BXD Cartilage v2',val:'UCLA_BXHBXD_CARTILAGE_V2'}, -{txt:'UCLA BXD and BXH Cartilage v2',val:'UCLA_BXDBXH_CARTILAGE_V2'}, -{txt:'UCLA BXD and BXH Cartilage',val:'UCLA_BXDBXH_CARTILAGE'}, -{txt:'UCLA BXH and BXD Cartilage',val:'UCLA_BXHBXD_CARTILAGE'}, -{txt:'UCLA BHF2 Brain Male mlratio',val:'UCLA_BHF2_BRAIN_MALE'}, -{txt:'UCLA BHF2 Brain Female mlratio',val:'UCLA_BHF2_BRAIN_FEMALE'}, -{txt:'UCLA BHF2 Adipose Female mlratio',val:'UCLA_BHF2_ADIPOSE_FEMALE'}, -{txt:'UCLA BHF2 Adipose Male mlratio',val:'UCLA_BHF2_ADIPOSE_MALE'}, -{txt:'UCLA CTB6B6CTF2 Muscle Male mlratio **',val:'UCLA_CTB6B6CTF2_MUSCLE_MALE'}, -{txt:'UCLA CTB6B6CTF2 Liver Male mlratio **',val:'UCLA_CTB6B6CTF2_LIVER_MALE'}, -{txt:'UCLA CTB6B6CTF2 Brain Male mlratio **',val:'UCLA_CTB6B6CTF2_BRAIN_MALE'}, -{txt:'UCLA CTB6B6CTF2 Adipose Male mlratio **',val:'UCLA_CTB6B6CTF2_ADIPOSE_MALE'}, -{txt:'UCLA BHF2 Liver Male mlratio',val:'UCLA_BHF2_LIVER_MALE'}, -{txt:'UCLA BHF2 Liver Female mlratio',val:'UCLA_BHF2_LIVER_FEMALE'}, -{txt:'UCLA BHHBF2 Brain Female Only',val:'UCLA_BHHBF2_BRAIN_FEMALE'}, -{txt:'UCLA BHHBF2 Liver Female Only',val:'UCLA_BHHBF2_LIVER_FEMALE'}, -{txt:'UCLA BHHBF2 Muscle Male Only',val:'UCLA_BHHBF2_MUSCLE_MALE'}, -{txt:'UCLA BHHBF2 Muscle Female Only',val:'UCLA_BHHBF2_MUSCLE_FEMALE'}, -{txt:'UCLA BHHBF2 Liver Male Only',val:'UCLA_BHHBF2_LIVER_MALE'}, -{txt:'UCLA BHHBF2 Brain Male Only',val:'UCLA_BHHBF2_BRAIN_MALE'}, -{txt:'UCLA BHHBF2 Adipose Female Only',val:'UCLA_BHHBF2_ADIPOSE_FEMALE'}, -{txt:'UCLA BHHBF2 Adipose Male Only',val:'UCLA_BHHBF2_ADIPOSE_MALE'}, -{txt:'UCLA BHF2 Muscle Female mlratio **',val:'UCLA_BHF2_MUSCLE_FEMALE'}, -{txt:'UCLA BHF2 Muscle Male mlratio **',val:'UCLA_BHF2_MUSCLE_MALE'}, -{txt:'UCLA BXH Cartilage',val:'UCLA_BXH_CARTILAGE'}, -{txt:'UCLA BXD Cartilage',val:'UCLA_BXD_CARTILAGE'}, -{txt:'UCLA BHHBF2 Adipose (2005) mlratio **',val:'UCLA_BHHBF2_ADIPOSE_2005'}, -{txt:'UCLA BHHBF2 Brain (2005) mlratio **',val:'UCLA_BHHBF2_BRAIN_2005'}, -{txt:'UCLA BHHBF2 Liver (2005) mlratio **',val:'UCLA_BHHBF2_LIVER_2005'}, -{txt:'UCLA BHHBF2 Muscle (2005) mlratio **',val:'UCLA_BHHBF2_MUSCLE_2005'}, -{txt:'UCLA BHF2 Adipose (June05) mlratio',val:'UCLA_BHF2_ADIPOSE_0605'}, -{txt:'UCLA BDF2 Liver (1999) mlratio',val:'UCLA_BDF2_LIVER_1999'}, -{txt:'UCLA BHF2 Muscle (June05) mlratio **',val:'UCLA_BHF2_MUSCLE_0605'}, -{txt:'UCLA BHF2 Brain (June05) mlratio',val:'UCLA_BHF2_BRAIN_0605'}, -{txt:'UCLA BHF2 Liver (June05) mlratio',val:'UCLA_BHF2_LIVER_0605'}, -{txt:'HZI Lung M430v2 (Apr08) RMA',val:'HZI_0408_R'}, -{txt:'HZI Lung M430v2 (Apr08) MAS5',val:'HZI_0408_M'}, -{txt:'HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv',val:'HQFNeoc_0208_RankInv'}, -{txt:'VCU BXD NA Sal M430 2.0 (Oct07) RMA',val:'VCUSalo_1007_R'}, -{txt:'VCU BXD NA EtOH M430 2.0 (Oct07) RMA **',val:'VCUEtOH_1007_R'}, -{txt:'VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **',val:'VCUSal_1007_R'}, -{txt:'Stuart Spleen M430v2 (Nov07) RMA',val:'STSPL_1107_R'}, -{txt:'HQF BXD Striatum ILM6.1 (Nov07) RankInv',val:'UTHSC_1107_RankInv'}, -{txt:'Hippocampus Illumina (Aug07) LOESS',val:'Illum_LXS_Hipp_loess0807'}, -{txt:'Hippocampus Illumina (Aug07) LOESS_NB',val:'Illum_LXS_Hipp_loess_nb0807'}, -{txt:'Hippocampus Illumina (Aug07) QUANT',val:'Illum_LXS_Hipp_quant0807'}, -{txt:'Hippocampus Illumina (Aug07) QUANT_NB',val:'Illum_LXS_Hipp_quant_nb0807'}, -{txt:'Hippocampus Illumina (Aug07) RSN',val:'Illum_LXS_Hipp_rsn0807'}, -{txt:'Hippocampus Illumina (Aug07) RSN_NB',val:'Illum_LXS_Hipp_rsn_nb0807'}, -{txt:'VCU BXD PFC EtOH M430 2.0 (Dec06) RMA',val:'VCUEtOH_1206_R'}, -{txt:'VCU BXD PFC Sal M430 2.0 (Dec06) RMA',val:'VCUSal_1206_R'}, -{txt:'VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore',val:'VCUSal_1006_R'}, -{txt:'VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **',val:'VCU_PF_Air_0111_R'}, -{txt:'VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **',val:'VCU_PF_Et_0111_R'}, -{txt:'VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **',val:'VCU_PF_AvE_0111_Ss'}, -{txt:'Hippocampus Illumina (May07) RankInv',val:'Hipp_Illumina_RankInv_0507'}, -{txt:'VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **',val:'VCUEtOH_0806_R'}, -{txt:'VCU LXS PFC Sal M430A 2.0 (Aug06) RMA',val:'VCUSal_0806_R'}, -{txt:'VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **',val:'VCUEt_vs_Sal_0806_R'}, -{txt:'Barley1 Embryo gcRMA SCRI (Dec06)',val:'B139_K_1206_R'}, -{txt:'Barley1 Leaf MAS 5.0 SCRI (Dec06)',val:'B30_K_1206_M'}, -{txt:'Barley1 Leaf gcRMAn SCRI (Dec06)',val:'B30_K_1206_Rn'}, -{txt:'Barley1 Leaf gcRMA SCRI (Dec06)',val:'B30_K_1206_R'}, -{txt:'Barley1 Embryo MAS 5.0 SCRI (Dec06)',val:'B139_K_1206_M'}, -{txt:'UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA',val:'BR_M2_1106_R'}, -{txt:'HZI Treg M430v2 (Feb11) RMA',val:'RTC_1106_R'}, -{txt:'UIOWA Eye mRNA RAE230v2 (Sep06) RMA',val:'UIOWA_Eye_RMA_0906'}, -{txt:'Mouse kidney M430v2 Sex Balanced (Aug06) RMA',val:'MA_M2_0806_R'}, -{txt:'Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN',val:'MA_M2_0806_P'}, -{txt:'Mouse Kidney M430v2 (Jul06) PDNN',val:'MA_M2_0706_P'}, -{txt:'Mouse Kidney M430v2 (Jul06) RMA',val:'MA_M2_0706_R'}, -{txt:'Barley1 Embryo0 gcRMA SCRI (Apr06)',val:'B150_K_0406_R'}, -{txt:'INIA Brain mRNA M430 (Jun06) RMA',val:'IBR_M_0606_R'}, -{txt:'Hippocampus Consortium M430v2 (Jun06) PDNN',val:'HC_M2_0606_P'}, -{txt:'Hippocampus Consortium M430v2 (Jun06) MAS5',val:'HC_M2_0606_M'}, -{txt:'Hippocampus Consortium M430v2 (Jun06) RMA',val:'HC_M2_0606_R'}, -{txt:'INIA Brain mRNA M430 (Jan06) RMA',val:'IBR_M_0106_R'}, -{txt:'INIA Brain mRNA M430 (Jan06) PDNN',val:'IBR_M_0106_P'}, -{txt:'Hippocampus Consortium M430v2 CXB (Dec05) RMA',val:'HC_M2CB_1205_R'}, -{txt:'Hippocampus Consortium M430v2 CXB (Dec05) PDNN',val:'HC_M2CB_1205_P'}, -{txt:'UTHSC Brain mRNA U74Av2 (Nov05) PDNN',val:'BR_U_1105_P'}, -{txt:'UMUTAffy Hippocampus Exon (Feb09) RMA',val:'UMUTAffyExon_0209_RMA'}, -{txt:'UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NON_0909'}, -{txt:'UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NOS_0909'}, -{txt:'UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv',val:'UT_ILM_BXD_hipp_NOE_0909'}, -{txt:'UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv',val:'UT_ILM_BXD_hipp_RSS_0909'}, -{txt:'UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv',val:'UT_ILM_BXD_hipp_RSE_0909'}, -{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN',val:'SA_M2_0905_P'}, -{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA',val:'SA_M2_0905_R'}, -{txt:'OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5',val:'SA_M2_0905_M'}, -{txt:'UTHSC Brain mRNA U74Av2 (Aug05) RMA',val:'BR_U_0805_R'}, -{txt:'UTHSC Brain mRNA U74Av2 (Aug05) PDNN',val:'BR_U_0805_P'}, -{txt:'UTHSC Brain mRNA U74Av2 (Aug05) MAS5',val:'BR_U_0805_M'}, -{txt:'MDC/CAS/ICL Peritoneal Fat 230A (Aug05) MAS5',val:'FT_2A_0805_M'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA',val:'BRF2_M_0805_R'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN',val:'BRF2_M_0805_P'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5',val:'BRF2_M_0805_M'}, -{txt:'MDC/CAS/ICL Peritoneal Fat 230A (Jun05) RMA 2z+8',val:'FT_2A_0605_Rz'}, -{txt:'HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean',val:'SA_M2_0405_MC'}, -{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) PDNN',val:'GCB_M2_0505_P'}, -{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) RMA',val:'GCB_M2_0505_R'}, -{txt:'GE-NIAAA Cerebellum mRNA M430v2 (May05) MAS5',val:'GCB_M2_0505_M'}, -{txt:'MDC/CAS/ICL Kidney 230A (Apr05) MAS5',val:'KI_2A_0405_M'}, -{txt:'HBP Rosen Striatum M430V2 (Apr05) RMA Clean',val:'SA_M2_0405_RC'}, -{txt:'HBP Rosen Striatum M430V2 (Apr05) PDNN Clean',val:'SA_M2_0405_PC'}, -{txt:'HBP Rosen Striatum M430V2 (Apr05) SScore',val:'SA_M2_0405_SS'}, -{txt:'HBP Rosen Striatum M430V2 (Apr05) RMA Orig',val:'SA_M2_0405_RR'}, -{txt:'MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8',val:'KI_2A_0405_Rz'}, -{txt:'MDC/CAS/ICL Kidney 230A (Apr05) RMA',val:'KI_2A_0405_R'}, -{txt:'SJUT Cerebellum mRNA M430 (Mar05) PDNN',val:'CB_M_0305_P'}, -{txt:'SJUT Cerebellum mRNA M430 (Mar05) MAS5',val:'CB_M_0305_M'}, -{txt:'SJUT Cerebellum mRNA M430 (Mar05) RMA',val:'CB_M_0305_R'}, -{txt:'HQF Striatum Exon (Feb09) RMA',val:'Striatum_Exon_0209'}, -{txt:'BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv',val:'DevNeocortex_ILM6.2P14RInv_1110'}, -{txt:'BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **',val:'DevStriatum_ILM6.2P14RInv_1110'}, -{txt:'BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **',val:'DevStriatum_ILM6.2P3RInv_1110'}, -{txt:'BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv',val:'DevNeocortex_ILM6.2P3RInv_1110'}, -{txt:'SJUT Cerebellum mRNA M430 (Oct04) MAS5',val:'CB_M_1004_M'}, -{txt:'SJUT Cerebellum mRNA M430 (Oct04) PDNN',val:'CB_M_1004_P'}, -{txt:'SJUT Cerebellum mRNA M430 (Oct04) RMA',val:'CB_M_1004_R'}, -{txt:'(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5',val:'LVF2_M_0704_M'}, -{txt:'(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA',val:'LVF2_M_0704_R'}, -{txt:'NCI Mammary mRNA M430 (July04) MAS5',val:'MA_M_0704_M'}, -{txt:'NCI Mammary mRNA M430 (July04) RMA',val:'MA_M_0704_R'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN',val:'BRF2_M_0304_P'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA',val:'BRF2_M_0304_R'}, -{txt:'OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5',val:'BRF2_M_0304_M'}, -{txt:'GNF Stem Cells U74Av2 (Mar04) RMA',val:'HC_U_0304_R'}, -{txt:'INIA Brain mRNA M430 (Feb04) PDNN',val:'CB_M_0204_P'}, -{txt:'SJUT Cerebellum mRNA M430 (Oct03) MAS5',val:'CB_M_1003_M'}, -{txt:'Hippocampus Illumina NOS (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NOS_1008'}, -{txt:'Hippocampus Illumina RSE (Oct08) RankInv beta',val:'Illum_LXS_Hipp_RSE_1008'}, -{txt:'GSE9588 Human Liver Normal (Mar11) Females',val:'HLCF_0311'}, -{txt:'Hippocampus Illumina RSS (Oct08) RankInv beta',val:'Illum_LXS_Hipp_RSS_1008'}, -{txt:'Hippocampus Illumina NOE (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NOE_1008'}, -{txt:'Hippocampus Illumina NON (Oct08) RankInv beta',val:'Illum_LXS_Hipp_NON_1008'}, -{txt:'CANDLE Published Phenotypes',val:'CANDLEPublish'}, -{txt:'HLC Published Phenotypes',val:'HLCPublish'}, -{txt:'AKXD Genotypes',val:'AKXDGeno'}, -{txt:'AXBXA Published Phenotypes',val:'AXBXAPublish'}, -{txt:'AXBXA Genotypes',val:'AXBXAGeno'}, -{txt:'B6BTBRF2 Published Phenotypes',val:'B6BTBRF2Publish'}, -{txt:'B6BTBRF2 Genotypes',val:'B6BTBRF2Geno'}, -{txt:'B6D2F2 Genotypes',val:'B6D2F2Geno'}, -{txt:'BDF2-1999 Genotypes',val:'BDF2-1999Geno'}, -{txt:'BDF2-2005 Genotypes',val:'BDF2-2005Geno'}, -{txt:'BHF2 Genotypes',val:'BHF2Geno'}, -{txt:'BHHBF2 Genotypes',val:'BHHBF2Geno'}, -{txt:'BXD Published Phenotypes',val:'BXDPublish'}, -{txt:'BXD Genotypes',val:'BXDGeno'}, -{txt:'BXH Published Phenotypes',val:'BXHPublish'}, -{txt:'BXH Genotypes',val:'BXHGeno'}, -{txt:'CTB6F2 Published Phenotypes',val:'CTB6F2Publish'}, -{txt:'CTB6F2 Genotypes',val:'CTB6F2Geno'}, -{txt:'CXB Published Phenotypes',val:'CXBPublish'}, -{txt:'CXB Genotypes',val:'CXBGeno'}, -{txt:'LXS Published Phenotypes',val:'LXSPublish'}, -{txt:'LXS Genotypes',val:'LXSGeno'}, -{txt:'Mouse Phenome Database',val:'MDPPublish'}, -{txt:'MDP Genotypes',val:'MDPGeno'}, -{txt:'NZBXFVB-N2 Published Phenotypes',val:'NZBXFVB-N2Publish'}, -{txt:'HXBBXH Published Phenotypes',val:'HXBBXHPublish'}, -{txt:'HXBBXH Genotypes',val:'HXBBXHGeno'}, -{txt:'BayXSha Published Phenotypes',val:'BayXShaPublish'}, -{txt:'BayXSha Genotypes',val:'BayXShaGeno'}, -{txt:'ColXBur Published Phenotypes',val:'ColXBurPublish'}, -{txt:'ColXBur Genotypes',val:'ColXBurGeno'}, -{txt:'ColXCvi Published Phenotypes',val:'ColXCviPublish'}, -{txt:'ColXCvi Genotypes',val:'ColXCviGeno'}, -{txt:'SXM Published Phenotypes',val:'SXMPublish'}, -{txt:'SXM Genotypes',val:'SXMGeno'}, -{txt:'J12XJ58F2 Published Phenotypes',val:'J12XJ58F2Publish'}, -{txt:'LXP Published Phenotypes',val:'LXPPublish'}, -{txt:'All Phenotypes',val:'_allPublish'}]; - -window.lArr = [ - null, -[1,1,4,79], -[1,1,4,80], -[1,1,4,127], -[1,1,4,128], -[1,2,4,1], -[1,2,4,2], -[1,2,4,126], -[1,14,59,288], -[1,14,34,32], -[1,15,26,119], -[1,15,26,142], -[1,21,8,60], -[1,21,8,61], -[1,21,8,63], -[1,21,8,67], -[1,21,42,62], -[1,21,42,65], -[1,21,42,66], -[1,21,42,69], -[1,21,46,64], -[1,21,46,68], -[1,21,46,70], -[1,21,46,71], -[1,22,59,289], -[1,22,24,76], -[1,22,24,77], -[1,22,24,284], -[1,25,3,33], -[1,25,6,37], -[1,25,7,36], -[1,25,9,54], -[1,25,10,56], -[1,25,11,53], -[1,25,14,38], -[1,25,17,51], -[1,25,19,46], -[1,25,21,47], -[1,25,28,55], -[1,25,29,52], -[1,25,30,49], -[1,25,36,58], -[1,25,37,59], -[1,25,38,57], -[1,25,40,50], -[1,25,41,45], -[1,25,43,34], -[1,25,44,48], -[1,25,45,39], -[1,25,46,42], -[1,25,49,40], -[1,25,52,35], -[1,25,54,41], -[1,25,55,43], -[1,25,57,44], -[2,30,3,14], -[2,30,4,108], -[2,30,17,12], -[2,30,35,7], -[2,30,42,107], -[3,3,60,290], -[3,3,27,135], -[3,3,27,274], -[3,3,27,275], -[3,4,59,291], -[3,4,60,292], -[3,4,13,144], -[3,5,59,293], -[3,5,60,294], -[3,5,24,272], -[3,5,24,273], -[3,6,60,295], -[3,6,4,246], -[3,6,4,247], -[3,6,4,248], -[3,6,4,276], -[3,6,4,277], -[3,6,4,278], -[3,8,60,296], -[3,8,24,183], -[3,9,60,297], -[3,9,49,239], -[3,9,49,240], -[3,9,49,241], -[3,10,60,298], -[3,10,1,158], -[3,10,1,159], -[3,10,1,182], -[3,10,4,156], -[3,10,4,157], -[3,10,4,185], -[3,10,24,164], -[3,10,24,165], -[3,10,24,186], -[3,10,32,174], -[3,10,32,175], -[3,10,32,184], -[3,11,60,299], -[3,11,1,172], -[3,11,1,173], -[3,11,1,178], -[3,11,4,166], -[3,11,4,171], -[3,11,4,179], -[3,11,24,167], -[3,11,24,170], -[3,11,24,180], -[3,11,32,168], -[3,11,32,169], -[3,11,32,181], -[3,12,59,300], -[3,12,60,301], -[3,12,3,72], -[3,12,3,73], -[3,12,3,74], -[3,12,3,75], -[3,12,4,216], -[3,12,4,224], -[3,12,4,228], -[3,12,4,229], -[3,12,4,232], -[3,12,4,242], -[3,12,4,243], -[3,12,4,244], -[3,12,4,280], -[3,12,5,153], -[3,12,5,154], -[3,12,5,177], -[3,12,8,251], -[3,12,8,252], -[3,12,8,253], -[3,12,8,261], -[3,12,8,262], -[3,12,8,263], -[3,12,8,269], -[3,12,8,270], -[3,12,8,271], -[3,12,8,281], -[3,12,13,145], -[3,12,13,146], -[3,12,13,147], -[3,12,13,148], -[3,12,13,149], -[3,12,13,150], -[3,12,13,151], -[3,12,16,111], -[3,12,16,112], -[3,12,16,113], -[3,12,16,114], -[3,12,16,115], -[3,12,16,116], -[3,12,16,117], -[3,12,16,118], -[3,12,16,279], -[3,12,17,225], -[3,12,17,226], -[3,12,17,227], -[3,12,17,233], -[3,12,17,234], -[3,12,17,235], -[3,12,17,236], -[3,12,17,237], -[3,12,17,238], -[3,12,18,98], -[3,12,18,99], -[3,12,18,100], -[3,12,20,120], -[3,12,20,121], -[3,12,20,219], -[3,12,20,220], -[3,12,20,221], -[3,12,20,222], -[3,12,23,139], -[3,12,24,19], -[3,12,24,83], -[3,12,24,84], -[3,12,24,85], -[3,12,24,86], -[3,12,24,87], -[3,12,24,88], -[3,12,24,89], -[3,12,24,90], -[3,12,24,91], -[3,12,24,92], -[3,12,25,187], -[3,12,25,188], -[3,12,31,18], -[3,12,32,20], -[3,12,32,21], -[3,12,32,22], -[3,12,33,25], -[3,12,33,26], -[3,12,33,95], -[3,12,33,97], -[3,12,33,189], -[3,12,33,265], -[3,12,33,268], -[3,12,35,190], -[3,12,35,191], -[3,12,35,192], -[3,12,42,201], -[3,12,42,202], -[3,12,42,203], -[3,12,42,204], -[3,12,42,205], -[3,12,42,206], -[3,12,47,3], -[3,12,47,4], -[3,12,47,5], -[3,12,47,6], -[3,12,47,27], -[3,12,47,28], -[3,12,48,96], -[3,12,48,101], -[3,12,48,133], -[3,12,48,141], -[3,12,48,143], -[3,12,49,23], -[3,12,49,24], -[3,12,49,93], -[3,12,49,94], -[3,12,49,194], -[3,12,49,250], -[3,12,49,255], -[3,12,49,256], -[3,12,49,257], -[3,12,49,258], -[3,12,49,264], -[3,12,49,266], -[3,12,49,267], -[3,12,50,78], -[3,12,51,217], -[3,12,53,140], -[3,12,56,130], -[3,12,56,131], -[3,12,56,132], -[3,13,59,302], -[3,13,60,303], -[3,13,5,152], -[3,13,5,155], -[3,13,5,176], -[3,18,59,304], -[3,18,60,305], -[3,18,1,9], -[3,18,1,15], -[3,18,1,163], -[3,18,4,10], -[3,18,4,16], -[3,18,4,162], -[3,18,24,8], -[3,18,24,17], -[3,18,24,161], -[3,18,32,11], -[3,18,32,13], -[3,18,32,160], -[3,19,59,306], -[3,19,60,307], -[3,19,17,230], -[3,19,17,231], -[3,19,48,193], -[3,23,17,106], -[3,23,24,105], -[3,23,25,104], -[3,24,49,81], -[3,29,59,308], -[3,29,60,309], -[3,29,17,195], -[3,29,17,196], -[3,29,17,197], -[3,29,17,198], -[3,29,17,199], -[3,29,17,200], -[3,29,17,207], -[3,29,17,282], -[3,29,17,283], -[3,29,17,285], -[3,29,17,286], -[3,29,17,287], -[3,29,42,208], -[3,29,42,209], -[3,29,42,210], -[3,31,59,310], -[3,31,60,311], -[3,31,17,102], -[3,31,17,103], -[3,31,24,29], -[3,31,24,30], -[3,31,24,31], -[3,32,59,312], -[3,32,27,134], -[4,26,59,313], -[4,26,60,314], -[4,26,2,138], -[4,26,15,137], -[4,26,17,129], -[4,26,20,254], -[4,26,20,259], -[4,26,20,260], -[4,26,24,136], -[4,26,39,245], -[4,26,39,249], -[4,35,13,218], -[5,20,58,82], -[5,33,58,109], -[5,33,58,110], -[6,7,59,315], -[6,7,60,316], -[6,16,59,317], -[6,16,60,318], -[6,17,59,319], -[6,17,60,320], -[7,34,22,122], -[7,34,22,123], -[7,34,22,124], -[7,34,22,125], -[7,36,59,321], -[7,36,60,322], -[7,36,12,211], -[7,36,12,215], -[7,36,12,223], -[7,36,22,212], -[7,36,22,213], -[7,36,22,214], -[8,27,59,323], -[9,28,59,324], -[10,37,59,325]]; - - diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee index df891826..a58efe2e 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee @@ -7,7 +7,7 @@ $ -> populate_species() apply_default() - $.ajax '/static/new/javascript/dataset_menu_structure', + $.ajax '/static/new/javascript/dataset_menu_structure.json', dataType: 'json' success: process_json @@ -15,6 +15,7 @@ $ -> species_list = @jdata.species redo_dropdown($('#species'), species_list) populate_group() + window.populate_species = populate_species populate_group = -> console.log("in populate group") @@ -22,6 +23,7 @@ $ -> group_list = @jdata.groups[species] redo_dropdown($('#group'), group_list) populate_type() + window.populate_group = populate_group populate_type = -> species = $('#species').val() @@ -29,6 +31,7 @@ $ -> type_list = @jdata.types[species][group] redo_dropdown($('#type'), type_list) populate_dataset() + window.populate_type = populate_type populate_dataset = -> species = $('#species').val() @@ -38,6 +41,7 @@ $ -> dataset_list = @jdata.datasets[species][group][type] console.log("pop_dataset:", dataset_list) redo_dropdown($('#dataset'), dataset_list) + window.populate_dataset = populate_dataset redo_dropdown = (dropdown, items) -> console.log("in redo:", dropdown, items) @@ -99,7 +103,9 @@ $ -> $("##{item[0]}").val(defaults[item[0]]) if item[1] - window["populate_" + item[1]] + populate_function = "populate_" + item[1] + console.log("Calling:", populate_function) + window[populate_function]() diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js index 655aac15..681e4301 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js @@ -9,7 +9,7 @@ populate_species(); return apply_default(); }; - $.ajax('/static/new/javascript/dataset_menu_structure', { + $.ajax('/static/new/javascript/dataset_menu_structure.json', { dataType: 'json', success: process_json }); @@ -19,6 +19,7 @@ redo_dropdown($('#species'), species_list); return populate_group(); }; + window.populate_species = populate_species; populate_group = function() { var group_list, species; console.log("in populate group"); @@ -27,6 +28,7 @@ redo_dropdown($('#group'), group_list); return populate_type(); }; + window.populate_group = populate_group; populate_type = function() { var group, species, type_list; species = $('#species').val(); @@ -35,6 +37,7 @@ redo_dropdown($('#type'), type_list); return populate_dataset(); }; + window.populate_type = populate_type; populate_dataset = function() { var dataset_list, group, species, type; species = $('#species').val(); @@ -45,6 +48,7 @@ console.log("pop_dataset:", dataset_list); return redo_dropdown($('#dataset'), dataset_list); }; + window.populate_dataset = populate_dataset; redo_dropdown = function(dropdown, items) { var item, _i, _len, _results; console.log("in redo:", dropdown, items); @@ -99,7 +103,7 @@ }); }; apply_default = function() { - var defaults, item, _i, _len, _ref, _results; + var defaults, item, populate_function, _i, _len, _ref, _results; defaults = $.cookie('search_defaults'); if (!defaults) { return; @@ -111,7 +115,9 @@ item = _ref[_i]; $("#" + item[0]).val(defaults[item[0]]); if (item[1]) { - _results.push(window["populate_" + item[1]]); + populate_function = "populate_" + item[1]; + console.log("Calling:", populate_function); + _results.push(window[populate_function]()); } else { _results.push(void 0); } -- cgit v1.2.3 From f2b695eefb0cfede23ab56884c9fc3301a293667 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 25 Oct 2012 16:53:27 -0500 Subject: Created header and set defaults for the search dropdown options --- misc/todo.txt | 3 +- .../new/javascript/dataset_select_menu.coffee | 437 ++------------------- .../static/new/javascript/dataset_select_menu.js | 12 +- wqflask/wqflask/templates/new_index_page.html | 12 +- 4 files changed, 43 insertions(+), 421 deletions(-) diff --git a/misc/todo.txt b/misc/todo.txt index d5374490..609e053f 100644 --- a/misc/todo.txt +++ b/misc/todo.txt @@ -1,2 +1 @@ -- Fix issue with parents appearing twice in primary samples table -- Check standard deviation value against GeneNetwork's standard deviation value \ No newline at end of file +- Read about grep/locate/find \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee index a58efe2e..16590e26 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.coffee @@ -24,7 +24,7 @@ $ -> redo_dropdown($('#group'), group_list) populate_type() window.populate_group = populate_group - + populate_type = -> species = $('#species').val() group = $('#group').val() @@ -32,7 +32,7 @@ $ -> redo_dropdown($('#type'), type_list) populate_dataset() window.populate_type = populate_type - + populate_dataset = -> species = $('#species').val() group = $('#group').val() @@ -59,11 +59,13 @@ $ -> populate_dataset() ## Info buttons - + open_window = (url, name) -> options = "menubar=1,toolbar=1,location=1,resizable=1,status=1,scrollbars=1,directories=1,width=900" open(url, name, options).focus() + # Link to info on selected group; use of "Cross" + # in the url is outdated and should be changed to group group_info = -> species = $('#species').val() group = $('#group').val() @@ -72,6 +74,7 @@ $ -> $('#group_info').click(group_info) + # Link to dataset info dataset_info = -> dataset = $('#dataset').val() url = "/webqtl/main.py?FormID=sharinginfo&InfoPageName=" + dataset @@ -81,7 +84,7 @@ $ -> ## Handle setting new default drop downs - + make_default = -> holder = {} for item in ['species', 'group', 'type', 'dataset'] @@ -89,425 +92,31 @@ $ -> jholder = JSON.stringify(holder) $.cookie('search_defaults', jholder, expires: 365) - + apply_default = -> defaults = $.cookie('search_defaults') - if not defaults - return - defaults = $.parseJSON(defaults) - + if defaults + # defaults are stored as a JSON string in a cookie + defaults = $.parseJSON(defaults) + else + # If user hasn't set a default we use this + # (Most of GN's data is from BXD mice) + defaults = + species: "mouse" + group: "BXD" + type: "Hippocampus" + dataset: "HC_M2_0606_P" + for item in [['species', 'group'] ['group', 'type'] ['type', 'dataset'], ['dataset', null]] - $("##{item[0]}").val(defaults[item[0]]) + if item[1] populate_function = "populate_" + item[1] console.log("Calling:", populate_function) window[populate_function]() - - - - $("#make_default").click(make_default) - -## -##* function: based on different browser use, will have different initial actions; -##* Once the index.html page is loaded, this function will be called -## -# -#$ -> -# -# fillSpecies = -> -# -# -# -# -# sArr =window.sArr # species -# gArr = window.gArr # group -# tArr = window.tArr -# dArr = window.dArr -# lArr = window.lArr -# -# console.log("sArr is now [jersey]:", sArr) -# console.log("gArr is now [jersey]:", gArr) -# -# initialDatasetSelection = -> -# defaultSpecies = getDefaultValue("species") -# defaultSet = getDefaultValue("cross") -# defaultType = getDefaultValue("tissue") -# defaultDB = getDefaultValue("database") -# if navigator.userAgent.indexOf("MSIE") >= 0 -# sOptions = fillOptionsForIE(null, defaultSpecies) -# menu0 = "" -# document.getElementById("menu0").innerHTML = menu0 -# gOptions = fillOptionsForIE("species", defaultSet) -# menu1 = "" -# document.getElementById("menu1").innerHTML = menu1 -# tOptions = fillOptionsForIE("cross", defaultType) -# menu2 = "" -# document.getElementById("menu2").innerHTML = menu2 -# dOptions = fillOptionsForIE("tissue", defaultDB) -# menu3 = "" -# document.getElementById("menu3").innerHTML = menu3 -# else -# fillOptions null -# searchtip() -# -# -# # -# #* input: selectObjId (designated select menu, such as species, cross, etc... ) -# #* defaultValue (default Value of species, cross,tissue or database) -# #* function: special for IE browser,setting options value for select menu dynamically based on linkage array(lArr), -# #* output: options string -# # -# fillOptionsForIE = (selectObjId, defaultValue) -> -# options = "" -# unless selectObjId? -# len = sArr.length -# i = 1 -# -# while i < len -# -# # setting Species' option -# if sArr[i].val is defaultValue -# options = options + "" -# else -# options = options + "" -# i++ -# else if selectObjId is "species" -# speciesObj = document.getElementById("species") -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# -# #get group(cross) info from lArr -# arr[idx++] = lArr[i][1] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and not Contains(arr, lArr[i][1]) -# i++ -# idx = 0 -# len = arr.length -# removeOptions "cross" -# i = 0 -# -# while i < len -# -# # setting Group's option -# if gArr[arr[i]].val is defaultValue -# options = options + "" -# else -# options = options + "" -# i++ -# else if selectObjId is "cross" -# speciesObj = document.getElementById("species") -# groupObj = document.getElementById("cross") -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# -# #get type(tissue) info from lArr -# arr[idx++] = lArr[i][2] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and not Contains(arr, lArr[i][2]) -# i++ -# idx = 0 -# len = arr.length -# removeOptions "tissue" -# i = 0 -# -# while i < len -# -# # setting Type's option -# if tArr[arr[i]].val is defaultValue -# options = options + "" -# else -# options = options + "" -# i++ -# else if selectObjId is "tissue" -# speciesObj = document.getElementById("species") -# groupObj = document.getElementById("cross") -# typeObj = document.getElementById("tissue") -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# -# #get dataset(database) info from lArr -# arr[idx++] = lArr[i][3] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and lArr[i][2] is (getIndexByValue("tissue", typeObj.value)).toString() and not Contains(arr, lArr[i][3]) -# i++ -# idx = 0 -# len = arr.length -# removeOptions "database" -# i = 0 -# -# while i < len -# -# # setting Database's option -# if dArr[arr[i]].val is defaultValue -# options = options + "" -# else -# options = options + "" -# i++ -# options -# -# # -# #* input: selectObjId (designated select menu, such as species, cross, etc... ) -# #* function: setting options value for select menu dynamically based on linkage array(lArr) -# #* output: null -# # -# fillOptions = (selectObjId) -> -# console.log("[vacuum] selectObjId:", selectObjId) -# unless selectObjId? -# speciesObj = document.getElementById("species") -# console.log("speciesObj:", speciesObj) -# len = sArr.length -# i = 1 -# -# while i < len -# -# # setting Species' option -# speciesObj.options[i - 1] = new Option(sArr[i].txt, sArr[i].val) -# console.log("speciesObj.options:", speciesObj.options[i - 1]) -# i++ -# updateChoice "species" -# else if selectObjId is "species" -# speciesObj = document.getElementById("species") -# console.log("speciesObj:", speciesObj) -# groupObj = document.getElementById("cross") -# console.log("groupObj:", groupObj) -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# #get group(cross) info from lArr -# index_value = getIndexByValue("species", speciesObj.value).toString() -# if lArr[i][0] is (index_value and not Contains(arr, lArr[i][1])) -# arr[idx++] = lArr[i][1] -# i++ -# idx = 0 -# len = arr.length -# removeOptions "cross" -# i = 0 -# -# while i < len -# # setting Group's option -# groupObj.options[idx++] = new Option(gArr[arr[i]].txt, gArr[arr[i]].val) -# i++ -# updateChoice "cross" -# else if selectObjId is "cross" -# speciesObj = document.getElementById("species") -# groupObj = document.getElementById("cross") -# typeObj = document.getElementById("tissue") -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# -# #get type(tissue) info from lArr -# arr[idx++] = lArr[i][2] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and not Contains(arr, lArr[i][2]) -# i++ -# idx = 0 -# len = arr.length -# removeOptions "tissue" -# i = 0 -# -# while i < len -# -# # setting Type's option -# typeObj.options[idx++] = new Option(tArr[arr[i]].txt, tArr[arr[i]].val) -# i++ -# updateChoice "tissue" -# else if selectObjId is "tissue" -# speciesObj = document.getElementById("species") -# groupObj = document.getElementById("cross") -# typeObj = document.getElementById("tissue") -# databaseObj = document.getElementById("database") -# len = lArr.length -# arr = [] -# idx = 0 -# i = 1 -# -# while i < len -# -# #get dataset(database) info from lArr -# arr[idx++] = lArr[i][3] if lArr[i][0] is (getIndexByValue("species", speciesObj.value)).toString() and lArr[i][1] is (getIndexByValue("cross", groupObj.value)).toString() and lArr[i][2] is (getIndexByValue("tissue", typeObj.value)).toString() and not Contains(arr, lArr[i][3]) -# i++ -# idx = 0 -# len = arr.length -# removeOptions "database" -# i = 0 -# -# while i < len -# -# # setting Database's option -# databaseObj.options[idx++] = new Option(dArr[arr[i]].txt, dArr[arr[i]].val) -# i++ -# updateChoice "database" -# -# # -# #* input: arr (targeted array); obj (targeted value) -# #* function: check whether targeted array contains targeted value or not -# #* output: return true, if array contains targeted value, otherwise return false -# # -# Contains = (arr, obj) -> -# i = arr.length -# return true if arr[i] is obj while i-- -# false -# -# # -# #* input: selectObj (designated select menu, such as species, cross, etc... ) -# #* function: clear designated select menu's option -# #* output: null -# # -# removeOptions = (selectObj) -> -# selectObj = document.getElementById(selectObj) unless typeof selectObj is "object" -# len = selectObj.options.length -# i = 0 -# -# while i < len -# -# # clear current selection -# selectObj.options[0] = null -# i++ -# -# # -# #* input: selectObjId (designated select menu, such as species, cross, etc... ) -# #* Value: target value -# #* function: retrieve Index info of target value in designated array -# #* output: index info -# # -# getIndexByValue = (selectObjId, val) -> -# if selectObjId is "species" -# i = 1 -# -# while i < sArr.length -# return i if sArr[i].val is val -# i++ -# else if selectObjId is "cross" -# i = 1 -# -# while i < gArr.length -# return i if gArr[i].val is val -# i++ -# else if selectObjId is "tissue" -# i = 1 -# -# while i < tArr.length -# return i if tArr[i].val is val -# i++ -# else -# return -# -# # -# #* input: objId (designated select menu, such as species, cross, etc... ) -# #* val(targeted value) -# #* function: setting option's selected status for designated select menu based on target value, also update the following select menu in the main search page -# #* output: return true if selected status has been set, otherwise return false. -# # -# setChoice = (objId, val) -> -# console.log("objId:", objId) -# console.log("val:", val) -# Obj = document.getElementById(objId) -# console.log("Obj:", Obj) -# idx = -1 -# i = 0 -# while i < Obj.options.length -# if Obj.options[i].value is val -# idx = i -# break -# i++ -# if idx >= 0 -# -# #setting option's selected status -# Obj.options[idx].selected = true -# -# #update the following select menu -# fillOptions objId -# else -# Obj.options[0].selected = true -# fillOptions objId -# -# # setting option's selected status based on default setting or cookie setting for Species, Group, Type and Database select menu in the main search page http://www.genenetwork.org/ -# updateChoice = (selectObjId) -> -# if selectObjId is "species" -# defaultSpecies = getDefaultValue("species") -# -# #setting option's selected status -# setChoice "species", defaultSpecies -# else if selectObjId is "cross" -# defaultSet = getDefaultValue("cross") -# -# #setting option's selected status -# setChoice "cross", defaultSet -# else if selectObjId is "tissue" -# defaultType = getDefaultValue("tissue") -# -# #setting option's selected status -# setChoice "tissue", defaultType -# else if selectObjId is "database" -# defaultDB = getDefaultValue("database") -# -# #setting option's selected status -# setChoice "database", defaultDB -# -# #get default value;if cookie exists, then use cookie value, otherwise use default value -# getDefaultValue = (selectObjId) -> -# -# #define default value -# defaultSpecies = "mouse" -# defaultSet = "BXD" -# defaultType = "Hippocampus" -# defaultDB = "HC_M2_0606_P" -# if selectObjId is "species" -# -# #if cookie exists, then use cookie value, otherwise use default value -# cookieSpecies = getCookie("defaultSpecies") -# defaultSpecies = cookieSpecies if cookieSpecies -# defaultSpecies -# else if selectObjId is "cross" -# cookieSet = getCookie("defaultSet") -# defaultSet = cookieSet if cookieSet -# defaultSet -# else if selectObjId is "tissue" -# cookieType = getCookie("defaultType") -# defaultType = cookieType if cookieType -# defaultType -# else if selectObjId is "database" -# cookieDB = getCookie("defaultDB") -# defaultDB = cookieDB if cookieDB -# defaultDB -# -# #setting default value into cookies for the dropdown menus: Species,Group, Type, and Database -# setDefault = (thisform) -> -# setCookie "cookieTest", "cookieTest", 1 -# cookieTest = getCookie("cookieTest") -# delCookie "cookieTest" -# if cookieTest -# defaultSpecies = thisform.species.value -# setCookie "defaultSpecies", defaultSpecies, 10 -# defaultSet = thisform.cross.value -# setCookie "defaultSet", defaultSet, 10 -# defaultType = thisform.tissue.value -# setCookie "defaultType", defaultType, 10 -# defaultDB = thisform.database.value -# setCookie "defaultDB", defaultDB, 10 -# updateChoice "species" -# updateChoice "cross" -# updateChoice "tissue" -# updateChoice "database" -# alert "The current settings are now your default" -# else -# alert "You need to enable Cookies in your browser." -# -# # run it -# initialDatasetSelection() \ No newline at end of file + + $("#make_default").click(make_default) \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js index 681e4301..5e19ca46 100644 --- a/wqflask/wqflask/static/new/javascript/dataset_select_menu.js +++ b/wqflask/wqflask/static/new/javascript/dataset_select_menu.js @@ -105,10 +105,16 @@ apply_default = function() { var defaults, item, populate_function, _i, _len, _ref, _results; defaults = $.cookie('search_defaults'); - if (!defaults) { - return; + if (defaults) { + defaults = $.parseJSON(defaults); + } else { + defaults = { + species: "mouse", + group: "BXD", + type: "Hippocampus", + dataset: "HC_M2_0606_P" + }; } - defaults = $.parseJSON(defaults); _ref = [['species', 'group'], ['group', 'type'], ['type', 'dataset'], ['dataset', null]]; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html index 51d963fc..695129a9 100644 --- a/wqflask/wqflask/templates/new_index_page.html +++ b/wqflask/wqflask/templates/new_index_page.html @@ -35,8 +35,16 @@
      • Home
      • -
      • - Search +
      • Help -- cgit v1.2.3 From 82bcb31455d658a462bfde711c862480fc9acd05 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 25 Oct 2012 18:09:11 -0500 Subject: Worked on search page code; got to the part that actually does the search Renamed RISet and cross to "group" throughout webqtlDataset.py and search_results.py --- web/javascript/header.js | 122 ++--- wqflask/base/webqtlDataset.py | 28 +- wqflask/wqflask/search_results.py | 215 ++++----- wqflask/wqflask/templates/index_page.html | 669 +++++++++++++++----------- wqflask/wqflask/templates/new_index_page.html | 423 ---------------- wqflask/wqflask/templates/old_index_page.html | 320 ++++++++++++ wqflask/wqflask/views.py | 7 - 7 files changed, 882 insertions(+), 902 deletions(-) delete mode 100644 wqflask/wqflask/templates/new_index_page.html create mode 100644 wqflask/wqflask/templates/old_index_page.html diff --git a/web/javascript/header.js b/web/javascript/header.js index 59fcacd8..65ba1bd6 100755 --- a/web/javascript/header.js +++ b/web/javascript/header.js @@ -1,62 +1,62 @@ -ctext = '' -ctext += ' ' -ctext += '' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += '
        ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' ' -ctext += ' WebQTL' -ctext += '
        ' -ctext += '' -ctext += ' ' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '' -ctext += '
        ' -ctext += '   |   ' -ctext += '' -ctext += 'Home' -ctext += '   |   ' -ctext += '' -ctext += 'Search' -ctext += '   |   ' -ctext += '' -ctext += 'Help' -ctext += '   |   ' -ctext += '' -ctext += '' -ctext += 'News' -ctext += '   |   ' -ctext += '' -ctext += '' -ctext += 'References' -ctext += '   |   ' -ctext += '' -ctext += 'Policies' -ctext += '   |   ' -ctext += '' -ctext += '' -ctext += 'Links' -ctext += '   |   ' -ctext += '' -ctext += '   ' -ctext += '
        ' -ctext += '' +ctext = '' +ctext += ' ' +ctext += '' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += '
        ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' ' +ctext += ' WebQTL' +ctext += '
        ' +ctext += '' +ctext += ' ' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '' +ctext += '
        ' +ctext += '   |   ' +ctext += '' +ctext += 'Home' +ctext += '   |   ' +ctext += '' +ctext += 'Search' +ctext += '   |   ' +ctext += '' +ctext += 'Help' +ctext += '   |   ' +ctext += '' +ctext += '' +ctext += 'News' +ctext += '   |   ' +ctext += '' +ctext += '' +ctext += 'References' +ctext += '   |   ' +ctext += '' +ctext += 'Policies' +ctext += '   |   ' +ctext += '' +ctext += '' +ctext += 'Links' +ctext += '   |   ' +ctext += '' +ctext += '   ' +ctext += '
        ' +ctext += '' document.write(ctext) \ No newline at end of file diff --git a/wqflask/base/webqtlDataset.py b/wqflask/base/webqtlDataset.py index 4f98e90c..933077fd 100755 --- a/wqflask/base/webqtlDataset.py +++ b/wqflask/base/webqtlDataset.py @@ -34,6 +34,7 @@ class webqtlDataset: """ Dataset class defines a dataset in webqtl, can be either Microarray, Published phenotype, genotype, or user input dataset(temp) + """ def __init__(self, dbName, cursor=None): @@ -42,7 +43,7 @@ class webqtlDataset: self.id = 0 self.name = '' self.type = '' - self.riset = '' + self.group = '' self.cursor = cursor #temporary storage @@ -81,14 +82,15 @@ class webqtlDataset: self.name = dbName if self.cursor and self.id == 0: self.retrieveName() - - def __str__(self): - return self.name - - __repr__ = __str__ + + + # Delete this eventually + @property + def riset(): + Weve_Renamed_This_As_Group - def getRISet(self): + def get_group(self): assert self.cursor if self.type == 'Publish': query = ''' @@ -124,12 +126,12 @@ class webqtlDataset: else: return "" self.cursor.execute(query) - RISet, RIID = self.cursor.fetchone() - if RISet == 'BXD300': - RISet = "BXD" - self.riset = RISet - self.risetid = RIID - return RISet + group, RIID = self.cursor.fetchone() + if group == 'BXD300': + group = "BXD" + self.group = group + self.group_id = RIID + return group def retrieveName(self): diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 1b846771..2269b9e7 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -36,17 +36,9 @@ from wqflask import parser from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction -#import logging -#logging.basicConfig(filename=app.config['LOGFILE'], level=logging.INFO) -# -#_log = logging.getLogger("search") -#_ch = logging.StreamHandler() -#_log.addHandler(_ch) - from utility import formatting import sys -#_log.info("sys.path is: %s" % (sys.path)) #from base.JinjaPage import JinjaEnv, JinjaPage @@ -64,116 +56,112 @@ class SearchResultPage(templatePage): import logging_tree logging_tree.printout() self.fd = fd - if not self.openMysql(): - print("ge0") - #return - - print("Start...") - print("Type of fd:", type(fd)) - print("Value of fd:", pf(fd)) - database = [fd['database']] - print("End...") - - # change back to self.database - if not self.database or self.database == 'spacer': - #Error, No database selected + templatePage.__init__(self, fd) + assert self.openMysql(), "Couldn't open MySQL" + + print("fd is:", pf(fd)) + self.dataset = fd['dataset'] + + # change back to self.dataset + if not self.dataset or self.dataset == 'spacer': + #Error, No dataset selected heading = "Search Result" - detail = ['''No database was selected for this search, please - go back and SELECT at least one database.'''] - print("ge0.6") - self.error(heading=heading,detail=detail,error="No Database Selected") - #return + detail = ['''No dataset was selected for this search, please + go back and SELECT at least one dataset.'''] + self.error(heading=heading,detail=detail,error="No dataset Selected") + return - print("ge1") ########################################### # Names and IDs of RISet / F2 set ########################################### - if self.database == ['_allPublish']: + if self.dataset == "All Phenotypes": self.cursor.execute(""" select PublishFreeze.Name, InbredSet.Name, InbredSet.Id from PublishFreeze, InbredSet where PublishFreeze.Name not like 'BXD300%' and InbredSet.Id = PublishFreeze.InbredSetId""") results = self.cursor.fetchall() - self.database = map(lambda x: webqtlDataset(x[0], self.cursor), results) - self.databaseCrosses = map(lambda x: x[1], results) - self.databaseCrossIds = map(lambda x: x[2], results) - self.singleCross = False + self.dataset = map(lambda x: webqtlDataset(x[0], self.cursor), results) + self.datasetGroups = map(lambda x: x[1], results) + self.datasetGroupIds = map(lambda x: x[2], results) + self.single_group = False else: - self.database = map(lambda x: webqtlDataset(x, self.cursor), self.database) + print("self.dataset is:", pf(self.dataset)) + self.dataset = webqtlDataset(self.dataset, self.cursor) + print("self.dataset is now:", pf(self.dataset)) + #self.dataset = map(lambda x: webqtlDataset(x, self.cursor), self.dataset) #currently, webqtl won't allow multiple crosses #for other than multiple publish db search - #so we can use the first database as example - if self.database[0].type=="Publish": - pass - elif self.database[0].type in ("Geno", "ProbeSet"): + #so we can use the first dataset as example + #if self.dataset.type=="Publish": + # pass + if self.dataset.type in ("Geno", "ProbeSet"): #userExist = None - - for individualDB in self.database: - # Can't use paramater substitution for table names apparently - db_type = self.database[0].type + "Freeze" - print("db_type [%s]: %s" % (type(db_type), db_type)) - - query = '''SELECT Id, Name, FullName, confidentiality, - AuthorisedUsers FROM %s WHERE Name = %%s''' % (db_type) - - self.cursor.execute(query, (individualDB,)) - - (indId, - indName, - indFullName, - confidential, - AuthorisedUsers) = self.cursor.fetchall()[0] - - if confidential: - access_to_confidential_dataset = 0 - - #for the dataset that confidentiality is 1 - #1. 'admin' and 'root' can see all of the dataset - #2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) - if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: - access_to_confidential_dataset = 1 - else: - AuthorisedUsersList=AuthorisedUsers.split(',') - if AuthorisedUsersList.__contains__(self.userName): - access_to_confidential_dataset = 1 - - if not access_to_confidential_dataset: - #Error, No database selected - heading = "Search Result" - detail = ["The %s database you selected is not open to the public at this time, please go back and SELECT other database." % indFullName] - self.error(heading=heading,detail=detail,error="Confidential Database") - return - else: - heading = "Search Result" - detail = ['''The database has not been established yet, please - go back and SELECT at least one database.'''] - self.error(heading=heading,detail=detail,error="No Database Selected") - return - - print("ge2") - self.database[0].getRISet() - self.databaseCrosses = [self.database[0].riset] - self.databaseCrossIds = [self.database[0].risetid] - self.singleCross = True - #XZ, August 24,2010: Since self.singleCross = True, it's safe to assign one species Id. - self.speciesId = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.database[0].riset) + # Can't use paramater substitution for table names apparently + db_type = self.dataset.type + "Freeze" + print("db_type [%s]: %s" % (type(db_type), db_type)) + + query = '''SELECT Id, Name, FullName, confidentiality, + AuthorisedUsers FROM %s WHERE Name = %%s''' % (db_type) + + self.cursor.execute(query, self.dataset.name) + + (indId, + indName, + indFullName, + confidential, + AuthorisedUsers) = self.cursor.fetchall()[0] + + if confidential: + # Allow confidential data later + NoConfindetialDataForYouTodaySorry + #access_to_confidential_dataset = 0 + # + ##for the dataset that confidentiality is 1 + ##1. 'admin' and 'root' can see all of the dataset + ##2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) + #if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: + # access_to_confidential_dataset = 1 + #else: + # AuthorisedUsersList=AuthorisedUsers.split(',') + # if AuthorisedUsersList.__contains__(self.userName): + # access_to_confidential_dataset = 1 + # + #if not access_to_confidential_dataset: + # #Error, No dataset selected + # heading = "Search Result" + # detail = ["The %s dataset you selected is not open to the public at this time, please go back and SELECT other dataset." % indFullName] + # self.error(heading=heading,detail=detail,error="Confidential dataset") + # return + #else: + # heading = "Search Result" + # detail = ['''The dataset has not been established yet, please + # go back and SELECT at least one dataset.'''] + # self.error(heading=heading,detail=detail,error="No dataset Selected") + # return + + self.dataset.get_group() + self.single_group = True + #XZ, August 24,2010: Since self.single_group = True, it's safe to assign one species Id. + self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, + self.dataset.group) ########################################### - # make sure search from same type of databases + # make sure search from same type of datasets ########################################### - #dbTypes = map(lambda X: X.type, self.database) - dbTypes = [table.type for table in self.database] - self.dbType = dbTypes[0] - for item in dbTypes: - if item != self.dbType: - heading = "Search Result" - detail = ["Search can only be performed among the same type of databases"] - self.error(heading=heading,detail=detail,error="Error") - return - - print("ge3") - if self.dbType == "Publish": + #dbTypes = map(lambda X: X.type, self.dataset) + #db_types = [table.type for table in self.dataset] + #self.db_type = db_types[0] + #for item in dbTypes: + # if item != self.dbType: + # heading = "Search Result" + # detail = ["Search can only be performed among the same type of datasets"] + # self.error(heading=heading,detail=detail,error="Error") + # return + + + #self.db_type = self.dataset.type + if self.dataset.type == "Publish": self.searchField = ['Phenotype.Post_publication_description', 'Phenotype.Pre_publication_description', 'Phenotype.Pre_publication_abbreviation', @@ -185,7 +173,7 @@ class SearchResultPage(templatePage): 'Publication.Authors', 'PublishXRef.Id'] - elif self.dbType == "ProbeSet": + elif self.dataset.type == "ProbeSet": self.searchField = ['Name', 'Description', 'Probe_Target_Description', @@ -194,11 +182,12 @@ class SearchResultPage(templatePage): 'GenbankId', 'UniGeneId', 'RefSeq_TranscriptId'] - elif self.dbType == "Geno": + elif self.dataset.type == "Geno": self.searchField = ['Name','Chr'] - print("ge4") + self.do_search() + self.gen_search_result() ########################################### # Search Options @@ -272,11 +261,11 @@ class SearchResultPage(templatePage): # return #self.nresults = self.executeQuery() # - #if len(self.database) > 1: - # dbUrl = "Multiple phenotype databases" + #if len(self.dataset) > 1: + # dbUrl = "Multiple phenotype datasets" # dbUrlLink = " were" #else: - # dbUrl = self.database[0].genHTML() + # dbUrl = self.dataset[0].genHTML() # dbUrlLink = " was" #SearchText = HT.Blockquote('GeneNetwork searched the ', dbUrl, ' for all records ') @@ -355,17 +344,13 @@ class SearchResultPage(templatePage): #TD_LR.append(HT.Paragraph('Search Results', Class="title"), SearchText) - self.start_search() - self.genSearchResultTable() #self.dict['body'] = str(TD_LR) #self.dict['js1'] = '' #self.dict['js2'] = 'onLoad="pageOffset()"' #self.dict['layer'] = self.generateWarningLayer() - def start_search(self): - pass - def genSearchResultTable(self): + def gen_search_result(self): #pageTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="100%",border=0) @@ -399,8 +384,8 @@ class SearchResultPage(templatePage): #tbl = HT.TableLite(cellSpacing=2,cellPadding=0,width="90%",border=0) #seq = self.pageNumber*self.NPerPage+1 //Edited out because we show all results in one page now - Zach 2/22/11 seq = 1 - RISet = self.databaseCrosses[i] - self.thisFormName = thisFormName = 'showDatabase'+RISet + group = self.databaseCrosses[i] + self.thisFormName = thisFormName = 'showDatabase'+group #selectall = HT.Href(url="#", onClick="checkAll(document.getElementsByName('%s')[0]);" % thisFormName) #selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;") #selectall.append(selectall_img) @@ -423,7 +408,7 @@ class SearchResultPage(templatePage): tblobj = {} mainfmName = thisFormName - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=RISet) + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) if thisTrait.db.type=="Geno": tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) @@ -480,7 +465,7 @@ class SearchResultPage(templatePage): #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) - hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','RISet':RISet} + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} hddn['incparentsf1']='ON' # for key in hddn.keys(): # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index db0b2d9e..695129a9 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -1,320 +1,423 @@ -{% extends "base.html" %} -{% block title %}GeneNetwork{% endblock %} -{% block content %} - - - - - - - + - - -
        -

        Select and - Search

        - - - -

         ______________________________________________________

        - -

          Quick HELP - Examples and User's Guide

          You can also use advanced - commands. Copy these simple examples
        -   into the Get Any or Combined search fields: - -
          -
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on - chromosome 1 between 25 and 30 Mb.
        • - -
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds - highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46.
        • - -
        • RIF=mitochondrial searches RNA databases for GeneRIF links.
        • - -
        • WIKI=nicotine searches GeneWiki for genes that you or other users have annotated - with the word nicotine.
        • - -
        • GO:0045202 searches for synapse-associated genes listed in the - Gene Ontology.
        • - -
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)
          - in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores - between 9 and 999.
        • - -
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
          - in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS - scores between 9 and 999.
        • + + + + + GeneNetwork + + + + + + + + + + + + + + + + + +
          +
          +

          GeneNetwork

          +

          Open source bioinformatics for systems genetics
          + Brought to you by the University of Tennessee

          +
          +
          + + +
        -

        Websites Affiliated with - GeneNetwork

        +
        + -
      • Optional: Use the Make Default button to save your preferences
      • - +
        + -

        ____________________________

        +
          +
        1. Select Species (or All)
        2. -

          How to Use - GeneNetwork

          +
        3. Select Group (a specific sample)
        4. -
          -

          Take a 20-40 minute - GeneNetwork Tour that includes screen shots and - typical steps in the analysis.

          -
          +
        5. Select Type of data: -
          -

          For information about - resources and methods, select the INFO buttons.

          +
            +
          • Phenotype (traits)
          • -

            Try the Workstation site to explore data and features that are - being implemented.

            +
          • Genotype (markers)
          • -

            Review the Conditions - and Contacts pages for information on the status of data sets - and advice on their use and citation.

            -
          +
        6. Expression (mRNAs)
        7. + + -

          Mirror and Development - Sites

          +
        8. Select a Database
        9. -
        -
      • Germany at the HZI
      • +

        User Guide

        +
        Read the + + user guide.
        -
      • Netherlands at the Hubrecht - (Development)
      • +
        -
      • Memphis at the U of M
      • -
      • Singapore at the NUS
      • +
        + -
      • Switzerland at the EPFL
      • - +

        GeneNetwork supports a variety of advanced searches.

        -

        History and - Archive

        - -
        -

        GeneNetwork's Time - Machine links to earlier versions that correspond to specific - publication dates.

        -
        -
        - - - - - -{% endblock %} +

        To try them out copy these examples into the search field:

        + +
          +
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on + chromosome 1 between 25 and 30 Mb.
        • +
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds + highly expressed genes (15 to 16 log2 units) AND with peak LRS + linkage between 23 and 46.
        • + +
        • RIF=mitochondrial searches RNA databases for + GeneRIF links.
        • + +
        • WIKI=nicotine searches + GeneWiki for genes that you or other users have annotated + with the word nicotine.
        • + +
        • GO:0045202 searches for synapse-associated genes listed in the + + Gene Ontology.
        • + +
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10) + finds synapse-associated genes with + cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores + between 9 and 999.
        • + +
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10) + finds diabetes-associated transcripts with peak + trans eQTLs on Chr 2 between 100 and 105 Mb with LRS + scores between 9 and 999.
        • +
        + + +
        + + +

        Thirty minute tour

        +

        + Take the 30 minute + GeneNetwork tour that includes screen shots and + typical steps in the analysis. +

        + +

        Even more info

        +

        + For information about + resources and methods, select the Info buttons next to the Group + and Database fields above. +

        + +

        The conditions + and contact + pages have information on the status of data sets + and advice on their use and citation.

        + +
        + +
        + +

        Websites affiliated with GeneNetwork

        + +

        Mirror and development sites

        + +

        History and archive

        + +

        The + + time machine + has earlier versions that correspond to specific publication dates. +

        + +

        The next generation

        +

        Try the + development site to explore experimental data and features.

        +
        + + + + + + + + + + + + + + + + + + diff --git a/wqflask/wqflask/templates/new_index_page.html b/wqflask/wqflask/templates/new_index_page.html deleted file mode 100644 index 695129a9..00000000 --- a/wqflask/wqflask/templates/new_index_page.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - - GeneNetwork - - - - - - - - - - - - - - - - - -
        -
        -

        GeneNetwork

        -

        Open source bioinformatics for systems genetics
        - Brought to you by the University of Tennessee

        -
        -
        - - -
        -
        - - -
        - - -
        - - -
          -
        1. Select Species (or All)
        2. - -
        3. Select Group (a specific sample)
        4. - -
        5. Select Type of data: - -
            -
          • Phenotype (traits)
          • - -
          • Genotype (markers)
          • - -
          • Expression (mRNAs)
          • -
          -
        6. - -
        7. Select a Database
        8. - -
        9. Enter terms in the search field: words, - genes, ID numbers, probes, advanced search commands
        10. - -
        11. Click the Search button
        12. - -
        13. Optional: Use the Make Default button to save your preferences
        14. -
        - -

        User Guide

        -
        Read the - - user guide.
        - -
        - - -
        - - -

        GeneNetwork supports a variety of advanced searches.

        - -

        To try them out copy these examples into the search field:

        - -
          -
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on - chromosome 1 between 25 and 30 Mb.
        • - -
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds - highly expressed genes (15 to 16 log2 units) AND with peak LRS - linkage between 23 and 46.
        • - -
        • RIF=mitochondrial searches RNA databases for - GeneRIF links.
        • - -
        • WIKI=nicotine searches - GeneWiki for genes that you or other users have annotated - with the word nicotine.
        • - -
        • GO:0045202 searches for synapse-associated genes listed in the - - Gene Ontology.
        • - -
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10) - finds synapse-associated genes with - cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores - between 9 and 999.
        • - -
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10) - finds diabetes-associated transcripts with peak - trans eQTLs on Chr 2 between 100 and 105 Mb with LRS - scores between 9 and 999.
        • -
        -
        - -
        - - -

        Thirty minute tour

        -

        - Take the 30 minute - GeneNetwork tour that includes screen shots and - typical steps in the analysis. -

        - -

        Even more info

        -

        - For information about - resources and methods, select the Info buttons next to the Group - and Database fields above. -

        - -

        The conditions - and contact - pages have information on the status of data sets - and advice on their use and citation.

        - -
        - -
        - -

        Websites affiliated with GeneNetwork

        - -

        Mirror and development sites

        - -

        History and archive

        - -

        The - - time machine - has earlier versions that correspond to specific publication dates. -

        - -

        The next generation

        -

        Try the - development site to explore experimental data and features.

        -
        -
        -
        -
        - - - - - - - - - - - - - - - diff --git a/wqflask/wqflask/templates/old_index_page.html b/wqflask/wqflask/templates/old_index_page.html new file mode 100644 index 00000000..db0b2d9e --- /dev/null +++ b/wqflask/wqflask/templates/old_index_page.html @@ -0,0 +1,320 @@ +{% extends "base.html" %} +{% block title %}GeneNetwork{% endblock %} +{% block content %} + + + + + + + + + + +
        +

        Select and + Search

        + + + +

         ______________________________________________________

        + +

          Quick HELP + Examples and User's Guide

          You can also use advanced + commands. Copy these simple examples
        +   into the Get Any or Combined search fields: + +
          +
        • POSITION=(chr1 25 30) finds genes, markers, or transcripts on + chromosome 1 between 25 and 30 Mb.
        • + +
        • MEAN=(15 16) LRS=(23 46) in the Combined field finds + highly expressed genes (15 to 16 log2 units) AND with peak LRS linkage between 23 and 46.
        • + +
        • RIF=mitochondrial searches RNA databases for GeneRIF links.
        • + +
        • WIKI=nicotine searches GeneWiki for genes that you or other users have annotated + with the word nicotine.
        • + +
        • GO:0045202 searches for synapse-associated genes listed in the + Gene Ontology.
        • + +
        • GO:0045202 LRS=(9 99 Chr4 122 155) cisLRS=(9 999 10)
          + in Combined finds synapse-associated genes with cis eQTL on Chr 4 from 122 and 155 Mb with LRS scores + between 9 and 999.
        • + +
        • RIF=diabetes LRS=(9 999 Chr2 100 105) transLRS=(9 999 10)
          + in Combined finds diabetes-associated transcripts with peak trans eQTLs on Chr 2 between 100 and 105 Mb with LRS + scores between 9 and 999.
        • +
        +
        +

        Websites Affiliated with + GeneNetwork

        + +

        + + + +

        ____________________________

        + +

        Getting Started +   

        + +
          +
        1. Select Species (or select All)
        2. + +
        3. Select Group (a specific sample)
        4. + +
        5. Select Type of data: + +
            +
          • Phenotype (traits)
          • + +
          • Genotype (markers)
          • + +
          • Expression (mRNAs)
          • +
          +
        6. + +
        7. Select a Database
        8. + +
        9. Enter search terms in the Get Any or Combined field: words, + genes, ID numbers, probes, advanced search commands
        10. + +
        11. Click on the Search button
        12. + +
        13. Optional: Use the Make Default button to save your preferences
        14. +
        + +

        ____________________________

        + +

        How to Use + GeneNetwork

        + +
        +

        Take a 20-40 minute + GeneNetwork Tour that includes screen shots and + typical steps in the analysis.

        +
        + +
        +

        For information about + resources and methods, select the INFO buttons.

        + +

        Try the Workstation site to explore data and features that are + being implemented.

        + +

        Review the Conditions + and Contacts pages for information on the status of data sets + and advice on their use and citation.

        +
        + +

        Mirror and Development + Sites

        + + + +

        History and + Archive

        + +
        +

        GeneNetwork's Time + Machine links to earlier versions that correspond to specific + publication dates.

        +
        +
        + + + + + +{% endblock %} + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index d639ed07..629a5b15 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -33,13 +33,6 @@ def index_page(): print("Sending index_page") return render_template("index_page.html") - -@app.route("/new") -def new_index_page(): - print("Sending index_page") - - return render_template("new_index_page.html") - @app.route("/data_sharing") def data_sharing_page(): print("In data_sharing") -- cgit v1.2.3 From 5083b031f0041f6df3c99180bd06243625af728e Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 26 Oct 2012 17:02:42 -0500 Subject: Got search page working for mice with a single gene search --- wqflask/base/templatePage.py | 20 +- wqflask/base/webqtlTrait.py | 2 +- wqflask/wqflask/search_results.py | 370 ++++++++++++---------- wqflask/wqflask/templates/search_result_page.html | 52 ++- wqflask/wqflask/views.py | 3 +- 5 files changed, 231 insertions(+), 216 deletions(-) diff --git a/wqflask/base/templatePage.py b/wqflask/base/templatePage.py index 7ef58a72..a94d5153 100755 --- a/wqflask/base/templatePage.py +++ b/wqflask/base/templatePage.py @@ -155,29 +155,29 @@ class templatePage: def openMysql(self): try: - self.con = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \ + self.db_conn = MySQLdb.Connect(db=webqtlConfig.DB_NAME,host=webqtlConfig.MYSQL_SERVER, \ user=webqtlConfig.DB_USER,passwd=webqtlConfig.DB_PASSWD) - self.cursor = self.con.cursor() - return 1 - except: + self.cursor = self.db_conn.cursor() + return True + except Exception: heading = "Connect MySQL Server" detail = ["Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_SERVER+"':100061. \ The server may be down at this time"] self.error(heading=heading,detail=detail,error="Error 2003") - return 0 + return False def updMysql(self): try: - self.con = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \ + self.db_conn = MySQLdb.Connect(db=webqtlConfig.DB_UPDNAME,host=webqtlConfig.MYSQL_UPDSERVER, \ user=webqtlConfig.DB_UPDUSER,passwd=webqtlConfig.DB_UPDPASSWD) - self.cursor = self.con.cursor() - return 1 - except: + self.cursor = self.db_conn.cursor() + return True + except Exception: heading = "Connect MySQL Server" detail = ["update: Can't connect to MySQL server on '"+ webqtlConfig.MYSQL_UPDSERVER+"':100061. \ The server may be down at this time "] self.error(heading=heading,detail=detail,error="Error 2003") - return 0 + return False def error(self,heading="",intro=[],detail=[],title="Error",error="Error"): 'generating a WebQTL style error page' diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index d6d537b7..46af6683 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -67,7 +67,7 @@ class webqtlTrait: ''', self.name) self.riset = self.cursor.fetchone()[0] else: - self.riset = self.db.getRISet() + self.riset = self.db.get_group() # # In ProbeSet, there are maybe several annotations match one sequence diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 2269b9e7..8fc12b16 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -81,8 +81,8 @@ class SearchResultPage(templatePage): PublishFreeze.InbredSetId""") results = self.cursor.fetchall() self.dataset = map(lambda x: webqtlDataset(x[0], self.cursor), results) - self.datasetGroups = map(lambda x: x[1], results) - self.datasetGroupIds = map(lambda x: x[2], results) + self.dataset_groups = map(lambda x: x[1], results) + self.dataset_group_ids = map(lambda x: x[2], results) self.single_group = False else: print("self.dataset is:", pf(self.dataset)) @@ -162,7 +162,7 @@ class SearchResultPage(templatePage): #self.db_type = self.dataset.type if self.dataset.type == "Publish": - self.searchField = ['Phenotype.Post_publication_description', + self.search_fields = ['Phenotype.Post_publication_description', 'Phenotype.Pre_publication_description', 'Phenotype.Pre_publication_abbreviation', 'Phenotype.Post_publication_abbreviation', @@ -174,7 +174,7 @@ class SearchResultPage(templatePage): 'PublishXRef.Id'] elif self.dataset.type == "ProbeSet": - self.searchField = ['Name', + self.search_fields = ['Name', 'Description', 'Probe_Target_Description', 'Symbol', @@ -183,7 +183,7 @@ class SearchResultPage(templatePage): 'UniGeneId', 'RefSeq_TranscriptId'] elif self.dataset.type == "Geno": - self.searchField = ['Name','Chr'] + self.search_fields = ['Name','Chr'] self.do_search() @@ -354,17 +354,23 @@ class SearchResultPage(templatePage): #pageTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="100%",border=0) - lastone = False - for i, item in enumerate(self.results): - if not item: - continue - lastone = False + #last_result = False - self.traitList = [] - for k, item2 in enumerate(item): - j, ProbeSetID = item2[:2] - thisTrait = webqtlTrait(db=self.database[j], name=ProbeSetID, cursor=self.cursor) - self.traitList.append(thisTrait) + self.trait_list = [] + for result in self.results: + if not result: + continue + #last_result = False + + #for item in result: + print("foo locals are:", locals()) + probe_set_id = result[1] + print("probe_set_id is:", pf(probe_set_id)) + this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) + this_trait.retrieveInfo(QTL=True) + print("this_trait is:", pf(this_trait)) + self.trait_list.append(this_trait) + print("self.trait_list is:", pf(self.trait_list)) ############## # Excel file # @@ -378,63 +384,45 @@ class SearchResultPage(templatePage): #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. - #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=thisTrait.db, returnNumber=len(self.traitList)) + #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) newrow = 7 + + #### Excel file stuff stops #tbl = HT.TableLite(cellSpacing=2,cellPadding=0,width="90%",border=0) #seq = self.pageNumber*self.NPerPage+1 //Edited out because we show all results in one page now - Zach 2/22/11 seq = 1 - group = self.databaseCrosses[i] - self.thisFormName = thisFormName = 'showDatabase'+group - #selectall = HT.Href(url="#", onClick="checkAll(document.getElementsByName('%s')[0]);" % thisFormName) - #selectall_img = HT.Image("/images/select_all2_final.jpg", name="selectall", alt="Select All", title="Select All", style="border:none;") - #selectall.append(selectall_img) - #reset = HT.Href(url="#", onClick="checkNone(document.getElementsByName('%s')[0]);" % thisFormName) - #reset_img = HT.Image("/images/select_none2_final.jpg", alt="Select None", title="Select None", style="border:none;") - #reset.append(reset_img) - #selectinvert = HT.Href(url="#", onClick="checkInvert(document.getElementsByName('%s')[0]);" % thisFormName) - #selectinvert_img = HT.Image("/images/invert_selection2_final.jpg", name="selectinvert", alt="Invert Selection", title="Invert Selection", style="border:none;") - #selectinvert.append(selectinvert_img) - #addselect = HT.Href(url="#") - #addselect_img = HT.Image("/images/add_collection1_final.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") - #addselect.append(addselect_img) - - #optionsTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="20%",border=0) - #optionsRow = HT.TR(HT.TD(selectall, width="25%"), HT.TD(reset, width="25%"), HT.TD(selectinvert, width="25%"), HT.TD(addselect, width="25%")) - #labelsRow = HT.TR(HT.TD(" "*2,"Select", width="25%"), HT.TD(" ","Deselect", width="255"), HT.TD(" "*3,"Invert", width="25%"), HT.TD(" "*4,"Add", width="25%")) - #optionsTable.append(optionsRow, labelsRow) - - #pageTable.append(HT.TR(HT.TD(optionsTable)), HT.TR(HT.TD(xlsUrl, height=40))) + group = self.dataset.group + self.form_name = form_name = 'show_dataset_'+group tblobj = {} - mainfmName = thisFormName species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) - if thisTrait.db.type=="Geno": + if this_trait.db.type=="Geno": tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) newrow += 1 sortby = self.getSortByValue(datasetType="Geno") - tblobj['body'] = self.getTableBodyForGeno(traitList=self.traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow) + #tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) #workbook.close() - objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - cPickle.dump(tblobj, objfile) - objfile.close() - - div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() - pageTable.append(HT.TR(HT.TD(div))) + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + # + #pageTable.append(HT.TR(HT.TD(div))) - elif thisTrait.db.type=="Publish": + elif this_trait.db.type=="Publish": #tblobj['header'] = self.getTableHeaderForPublish(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - newrow += 1 + #newrow += 1 sortby = self.getSortByValue(datasetType="Publish") - #tblobj['body'] = self.getTableBodyForPublish(traitList=self.traitList, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + #tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) #workbook.close() #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') @@ -445,19 +433,19 @@ class SearchResultPage(templatePage): #pageTable.append(HT.TR(HT.TD(div))) - elif thisTrait.db.type=="ProbeSet": + elif this_trait.db.type=="ProbeSet": #tblobj['header'] = self.getTableHeaderForProbeSet(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - newrow += 1 + #newrow += 1 sortby = self.getSortByValue(datasetType="ProbeSet") - tblobj['body'] = self.getTableBodyForProbeSet(traitList=self.traitList, formName=mainfmName, newrow=newrow, species=species) - + tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) + # #workbook.close() - objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - cPickle.dump(tblobj, objfile) - objfile.close() + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") @@ -474,8 +462,8 @@ class SearchResultPage(templatePage): # # TD_LR.append(traitForm) # if len(self.results) > 1 and i < len(self.results) - 1: - # lastone = True - #if lastone: + # last_result = True + #if last_result: # TD_LR.contents.pop() def executeQuery(self): @@ -571,7 +559,7 @@ class SearchResultPage(templatePage): if self.ANDQuery or self.ORQuery: clause = self.ORQuery[:] - for j, database in enumerate(self.database): + for j, database in enumerate(self.dataset): if self.ANDQuery: clause.append(" (%s) " % string.join(self.ANDQuery, " AND ")) @@ -594,7 +582,7 @@ class SearchResultPage(templatePage): PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %d""" % (j, incGenoTbl, - self.databaseCrossIds[j], item, database.id)) + self.dataset_group_ids[j], item, database.id)) elif self.dbType == "ProbeSet": if item.find("GOgene") < 0: incGoTbl = "" @@ -667,51 +655,87 @@ class SearchResultPage(templatePage): #self.ORkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ORkeyword2) #self.ORkeyword2 = self.encregexp(self.ORkeyword2) - if self.ORkeyword2 or self.ANDkeyword2: - ANDFulltext = [] - ORFulltext = [] - for k, item in enumerate(self.ORkeyword2 + self.ANDkeyword2): - item = item['search_term'] - self.nkeywords += 1 - #ZS: If there are both AND and OR keywords, just use the OR keywords - if k >=len(self.ORkeyword2): - query = self.ANDQuery - DescriptionText = self.ANDDescriptionText - clausejoin = ' OR ' - fulltext = ANDFulltext - else: - query = self.ORQuery - DescriptionText = self.ORDescriptionText - clausejoin = ' OR ' - fulltext = ORFulltext - - if self.dbType == "ProbeSet" and item.find('.') < 0 and item.find('\'') < 0: - fulltext.append(item) - else: - if self.matchwhole and item.find("'") < 0: - item = "[[:<:]]"+ item+"[[:>:]]" - clause2 = [] - for field in self.searchField: - if self.dbType == "Publish": - clause2.append("%s REGEXP \"%s\"" % (field,item)) - else: - clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dbType,field),item)) - clauseItem = "(%s)" % string.join(clause2, clausejoin) - query.append(" (%s) " % clauseItem) - if ANDFulltext: - clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, - alias,GenbankId, UniGeneId, Probe_Target_Description) - AGAINST ('+%s' IN BOOLEAN MODE) """ % string.join(ANDFulltext, " +") - self.ANDQuery.append(" (%s) " % clauseItem) - if ORFulltext: - clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias, - GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) - """ % string.join(ORFulltext, " ") - self.ORQuery.append(" (%s) " % clauseItem) - else: - pass - return 1 - + #if self.search_terms: + #full_text = [] + #ANDFulltext = [] + #ORFulltext = [] + for item in self.search_terms: + search_term = item['search_term'] + # self.nkeywords += 1 + # #ZS: If there are both AND and OR keywords, just use the OR keywords + # if k >=len(self.ORkeyword2): + # query = self.ANDQuery + # DescriptionText = self.ANDDescriptionText + # clausejoin = ' OR ' + # fulltext = ANDFulltext + # else: + # query = self.ORQuery + # DescriptionText = self.ORDescriptionText + # clausejoin = ' OR ' + # fulltext = ORFulltext + + print("item is:", pf(search_term)) + + if self.dataset.type == "ProbeSet": + query = ( +"""SELECT distinct 0, ProbeSet.Name as TNAME, 0 as thistable, + ProbeSetXRef.Mean as TMEAN, + ProbeSetXRef.LRS as TLRS, + ProbeSetXRef.PVALUE as TPVALUE, + ProbeSet.Chr_num as TCHR_NUM, + ProbeSet.Mb as TMB, + ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, + ProbeSet WHERE (MATCH (ProbeSet.Name, ProbeSet.description, ProbeSet.symbol, + alias, GenbankId, UniGeneId, Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.db_conn.escape_string(search_term), + self.db_conn.escape_string(str(self.dataset.id)))) + + print("query is:", query) + self.cursor.execute(query) + #print("query is:", pf(self.query)) + + #self.cursor.execute(self.query) + self.results = self.cursor.fetchall() + + print("self.results is:", pf(self.results)) + + +#["(SELECT distinct 0, ProbeSet.Name as TNAME, 0 as thistable,\n\t\t\t\t\t\tProbeSetXRef.Mean as TMEAN, +# ProbeSetXRef.LRS as TLRS, ProbeSetXRef.PVALUE as TPVALUE,\n\t\t\t\t\t\tProbeSet.Chr_num as TCHR_NUM, +# Pr beSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL,\n\t\t\t\t\t\tProbeSet.name_num as TNAME_NUM FROM +# ProbeSetXRef, ProbeSet \n\t\t\t\t\t\tWHERE ( MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, +# alias GenbankId, UniGeneId, Probe_Target_Description) +# AGAINST ('shh' IN BOOLEAN MODE) ) +# and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = 112\n\t\t\t\t\t\t)"] + + + #if self.dataset.type == "ProbeSet" and search_term.find('.') < 0 and search_term.find('\'') < 0: + # full_text.append(search_term) + #else: + # if self.matchwhole and search_term.find("'") < 0: + # search_term = "[[:<:]]"+ search_term+"[[:>:]]" + # clause2 = [] + # for field in self.search_fields: + # if self.dataset.type == "Publish": + # clause2.append("%s REGEXP \"%s\"" % (field,search_term)) + # else: + # clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dataset.type,field),search_term)) + # clause_item = "(%s)" % string.join(clause2, clausejoin) + # query.append(" (%s) " % clause_item) + #if ANDFulltext: + # clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, + # alias,GenbankId, UniGeneId, Probe_Target_Description) + # AGAINST ('+%s' IN BOOLEAN MODE) """ % string.join(ANDFulltext, " +") + # self.ANDQuery.append(" (%s) " % clauseItem) + #if ORFulltext: + #clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias, + #GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) + #""" % string.join(full_text, " ") + #self.query.append(" (%s) " % clauseItem) def encregexp(self,str): @@ -981,44 +1005,44 @@ class SearchResultPage(templatePage): return tblobj_header - def getTableBodyForGeno(self, traitList, formName=None, worksheet=None, newrow=None): + def getTableBodyForGeno(self, trait_list, formName=None, worksheet=None, newrow=None): tblobj_body = [] className = "fs12 fwn ffl b1 c222" - for thisTrait in traitList: + for this_trait in trait_list: tr = [] - if not thisTrait.haveinfo: - thisTrait.retrieveInfo() + if not this_trait.haveinfo: + this_trait.retrieveInfo() - trId = str(thisTrait) + trId = str(this_trait) tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) - tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name, thisTrait.name), Class="fs12 fwn ffl"),align="left", Class=className), text=thisTrait.name, val=thisTrait.name.upper())) + tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name, this_trait.name), Class="fs12 fwn ffl"),align="left", Class=className), text=this_trait.name, val=this_trait.name.upper())) #XZ: trait_location_value is used for sorting trait_location_repr = 'N/A' trait_location_value = 1000000 - if thisTrait.chr and thisTrait.mb: + if this_trait.chr and this_trait.mb: try: - trait_location_value = int(thisTrait.chr)*1000 + thisTrait.mb + trait_location_value = int(this_trait.chr)*1000 + this_trait.mb except: - if thisTrait.chr.upper() == 'X': - trait_location_value = 20*1000 + thisTrait.mb + if this_trait.chr.upper() == 'X': + trait_location_value = 20*1000 + this_trait.mb else: - trait_location_value = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb + trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - trait_location_repr = 'Chr%s: %.6f' % (thisTrait.chr, float(thisTrait.mb) ) + trait_location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb) ) tr.append(TDCell(HT.TD(trait_location_repr, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value)) tblobj_body.append(tr) - for ncol, item in enumerate([thisTrait.name, trait_location_repr]): + for ncol, item in enumerate([this_trait.name, trait_location_repr]): worksheet.write([newrow, ncol], item) newrow += 1 @@ -1045,40 +1069,40 @@ class SearchResultPage(templatePage): return tblobj_header - def getTableBodyForPublish(self, traitList, formName=None, worksheet=None, newrow=None, species=''): + def getTableBodyForPublish(self, trait_list, formName=None, worksheet=None, newrow=None, species=''): tblobj_body = [] className = "fs12 fwn b1 c222" - for thisTrait in traitList: + for this_trait in trait_list: tr = [] - if not thisTrait.haveinfo: - thisTrait.retrieveInfo(QTL=1) + if not this_trait.haveinfo: + this_trait.retrieveInfo(QTL=1) - trId = str(thisTrait) + trId = str(this_trait) tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) - tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name, thisTrait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class=className),str(thisTrait.name), thisTrait.name)) + tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name, this_trait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class=className),str(this_trait.name), this_trait.name)) - PhenotypeString = thisTrait.post_publication_description - if thisTrait.confidential: - if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=thisTrait.authorized_users): - PhenotypeString = thisTrait.pre_publication_description + PhenotypeString = this_trait.post_publication_description + if this_trait.confidential: + if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): + PhenotypeString = this_trait.pre_publication_description tr.append(TDCell(HT.TD(PhenotypeString, Class=className), PhenotypeString, PhenotypeString.upper())) - tr.append(TDCell(HT.TD(thisTrait.authors, Class="fs12 fwn b1 c222 fsI"),thisTrait.authors, thisTrait.authors.strip().upper())) + tr.append(TDCell(HT.TD(this_trait.authors, Class="fs12 fwn b1 c222 fsI"),this_trait.authors, this_trait.authors.strip().upper())) try: - PubMedLinkText = myear = repr = int(thisTrait.year) + PubMedLinkText = myear = repr = int(this_trait.year) except: PubMedLinkText = repr = "N/A" myear = 0 - if thisTrait.pubmed_id: - PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % thisTrait.pubmed_id,target='_blank', Class="fs12 fwn") + if this_trait.pubmed_id: + PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id,target='_blank', Class="fs12 fwn") else: PubMedLink = repr @@ -1092,9 +1116,9 @@ class SearchResultPage(templatePage): LRS_flag = 1 - if thisTrait.lrs: - LRS_score_repr = '%3.1f' % thisTrait.lrs - LRS_score_value = thisTrait.lrs + if this_trait.lrs: + LRS_score_repr = '%3.1f' % this_trait.lrs + LRS_score_value = this_trait.lrs tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) self.cursor.execute(""" @@ -1102,7 +1126,7 @@ class SearchResultPage(templatePage): where Species.Name = '%s' and Geno.Name = '%s' and Geno.SpeciesId = Species.Id - """ % (species, thisTrait.locus)) + """ % (species, this_trait.locus)) result = self.cursor.fetchone() if result: @@ -1130,7 +1154,7 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - for ncol, item in enumerate([thisTrait.name, PhenotypeString, thisTrait.authors, thisTrait.year, thisTrait.pubmed_id, LRS_score_repr, LRS_location_repr]): + for ncol, item in enumerate([this_trait.name, PhenotypeString, this_trait.authors, this_trait.year, this_trait.pubmed_id, LRS_score_repr, LRS_location_repr]): worksheet.write([newrow, ncol], item) newrow += 1 @@ -1158,54 +1182,54 @@ class SearchResultPage(templatePage): return tblobj_header - def getTableBodyForProbeSet(self, traitList=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): - # Note: setting traitList to [] is probably not a great idea. + def getTableBodyForProbeSet(self, trait_list=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): + # Note: setting trait_list to [] is probably not a great idea. tblobj_body = [] className = "fs12 fwn b1 c222" - for thisTrait in traitList: + for this_trait in trait_list: - if not thisTrait.haveinfo: - thisTrait.retrieveInfo(QTL=1) + if not this_trait.haveinfo: + this_trait.retrieveInfo(QTL=1) - if thisTrait.symbol: + if this_trait.symbol: pass else: - thisTrait.symbol = "N/A" + this_trait.symbol = "N/A" tr = [] - trId = str(thisTrait) + trId = str(this_trait) #XZ, 12/08/2008: checkbox #tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId)) #XZ, 12/08/2008: probeset name - #if thisTrait.cellid: - # tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name, url="javascript:showDatabase3('%s','%s','%s','%s')" % (formName, thisTrait.db.name,thisTrait.name,thisTrait.cellid), Class="fs12 fwn"), Class=className), thisTrait.name, thisTrait.name.upper())) + #if this_trait.cellid: + # tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name, url="javascript:showDatabase3('%s','%s','%s','%s')" % (formName, this_trait.db.name,this_trait.name,this_trait.cellid), Class="fs12 fwn"), Class=className), this_trait.name, this_trait.name.upper())) #else: - # tr.append(TDCell(HT.TD(HT.Href(text=thisTrait.name, url="javascript:showDatabase3('%s','%s','%s','')" % (formName, thisTrait.db.name,thisTrait.name), Class="fs12 fwn"), Class=className), thisTrait.name, thisTrait.name.upper())) + # tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name, url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name,this_trait.name), Class="fs12 fwn"), Class=className), this_trait.name, this_trait.name.upper())) # - #if thisTrait.geneid: - # symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % thisTrait.geneid, Class="font_black fs12 fwn") + #if this_trait.geneid: + # symbolurl = HT.Href(text=this_trait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % this_trait.geneid, Class="font_black fs12 fwn") #else: - # symbolurl = HT.Href(text=thisTrait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % thisTrait.symbol, Class="font_black fs12 fwn") + # symbolurl = HT.Href(text=this_trait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % this_trait.symbol, Class="font_black fs12 fwn") # ##XZ, 12/08/2008: gene symbol - #tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),thisTrait.symbol, thisTrait.symbol.upper())) + #tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),this_trait.symbol, this_trait.symbol.upper())) #XZ, 12/08/2008: description #XZ, 06/05/2009: Rob asked to add probe target description - description_string = str(thisTrait.description).strip() - target_string = str(thisTrait.probe_target_description).strip() + description_string = str(this_trait.description).strip() + target_string = str(this_trait.probe_target_description).strip() description_display = '' if len(description_string) > 1 and description_string != 'None': description_display = description_string else: - description_display = thisTrait.symbol + description_display = this_trait.symbol if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': description_display = description_display + '; ' + target_string.strip() @@ -1213,24 +1237,24 @@ class SearchResultPage(templatePage): #tr.append(TDCell(HT.TD(description_display, Class=className), description_display, description_display)) # Save it for the jinja2 tablet - thisTrait.description_display = description_display + this_trait.description_display = description_display #XZ: trait_location_value is used for sorting trait_location_repr = 'N/A' trait_location_value = 1000000 - if thisTrait.chr and thisTrait.mb: + if this_trait.chr and this_trait.mb: try: - trait_location_value = int(thisTrait.chr)*1000 + thisTrait.mb + trait_location_value = int(this_trait.chr)*1000 + this_trait.mb except: - if thisTrait.chr.upper() == 'X': - trait_location_value = 20*1000 + thisTrait.mb + if this_trait.chr.upper() == 'X': + trait_location_value = 20*1000 + this_trait.mb else: - trait_location_value = ord(str(thisTrait.chr).upper()[0])*1000 + thisTrait.mb + trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - trait_location_repr = 'Chr%s: %.6f' % (thisTrait.chr, float(thisTrait.mb) ) - thisTrait.trait_location_repr = trait_location_repr - #thisTrait.trait_location_value = trait_location_value + trait_location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb) ) + this_trait.trait_location_repr = trait_location_repr + #this_trait.trait_location_value = trait_location_value tr.append(TDCell(HT.TD(trait_location_repr, Class=className, nowrap="on"), trait_location_repr, trait_location_value)) #XZ, 01/12/08: This SQL query is much faster. @@ -1239,7 +1263,7 @@ class SearchResultPage(templatePage): where ProbeSetXRef.ProbeSetFreezeId = %d and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSet.Name = '%s' - """ % (thisTrait.db.id, thisTrait.name)) + """ % (this_trait.db.id, this_trait.name)) result = self.cursor.fetchone() if result: if result[0]: @@ -1250,7 +1274,7 @@ class SearchResultPage(templatePage): mean = 0 #XZ, 06/05/2009: It is neccessary to turn on nowrap - thisTrait.mean = repr = "%2.3f" % mean + this_trait.mean = repr = "%2.3f" % mean tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean)) #LRS and its location @@ -1261,13 +1285,13 @@ class SearchResultPage(templatePage): LRS_flag = 1 #Max LRS and its Locus location - if thisTrait.lrs and thisTrait.locus: + if this_trait.lrs and this_trait.locus: self.cursor.execute(""" select Geno.Chr, Geno.Mb from Geno, Species where Species.Name = '%s' and Geno.Name = '%s' and Geno.SpeciesId = Species.Id - """ % (species, thisTrait.locus)) + """ % (species, this_trait.locus)) result = self.cursor.fetchone() if result: @@ -1284,12 +1308,12 @@ class SearchResultPage(templatePage): else: LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) - thisTrait.LRS_score_repr = LRS_score_repr = '%3.1f' % thisTrait.lrs - thisTrait.LRS_score_value = LRS_score_value = thisTrait.lrs - thisTrait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) + this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs + this_trait.LRS_score_value = LRS_score_value = this_trait.lrs + this_trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) LRS_flag = 0 - #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, thisTrait.db.shortname, thisTrait.name), Class="fs12 fwn"), Class=className, align='right', nowrap="on"),LRS_score_repr, LRS_score_value)) + #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, this_trait.db.shortname, this_trait.name), Class="fs12 fwn"), Class=className, align='right', nowrap="on"),LRS_score_repr, LRS_score_value)) tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value)) tr.append(TDCell(HT.TD(LRS_location_repr, Class=className, nowrap="on"), LRS_location_repr, LRS_location_value)) @@ -1303,7 +1327,7 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - #for ncol, item in enumerate([thisTrait.name, thisTrait.geneid, thisTrait.homologeneid, thisTrait.symbol, description_display, trait_location_repr, mean, LRS_score_repr, LRS_location_repr]): + #for ncol, item in enumerate([this_trait.name, this_trait.geneid, this_trait.homologeneid, this_trait.symbol, description_display, trait_location_repr, mean, LRS_score_repr, LRS_location_repr]): # worksheet.write([newrow, ncol], item) diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index c20efe40..06458818 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -8,32 +8,22 @@

        Search Results

        -
        GeneNetwork searched the following databases: - - +
        GeneNetwork searched: + {{ dataset.fullname }} +
        + For all records that match:
          - {% if ORkeyword2 %} -
        • - {% for word in ORkeyword2 %} - {{word}} {% if not loop.last %} or {% endif %} - {% endfor %} -
        • - {% endif %} - {% if ANDkeyword2 %} + {% if search_terms %}
        • - {% for word in ANDkeyword2 %} - {{word}} {% if not loop.last %} and {% endif %} + {% for word in search_terms %} + {{word.search_term}} {% if not loop.last %} or {% endif %} {% endfor %}
        • {% endif %}
        -

        GeneNetwork found {{ numify(nresults, "record", "records") }}.

        +

        GeneNetwork found {{ numify(results|count, "record", "records") }}.

        To study a record, click on its ID below.

        @@ -166,27 +156,27 @@ - {% for thisTrait in traitList %} - + {% for this_trait in trait_list %} + {{ loop.index }} - + - {# - #} - - {{ thisTrait.name.upper() }} + {# - #} + + {{ this_trait.name.upper() }} - - {{ thisTrait.symbol }} + + {{ this_trait.symbol }} - {{ thisTrait.description_display }} - {{ thisTrait.trait_location_repr }} - {{ thisTrait.mean }} - {{ thisTrait.LRS_score_repr }} - {{ thisTrait.LRS_location_repr }} + {{ this_trait.description_display }} + {{ this_trait.trait_location_repr }} + {{ this_trait.mean }} + {{ this_trait.LRS_score_repr }} + {{ this_trait.LRS_location_repr }} {% endfor %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 629a5b15..dd95f7ca 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -63,7 +63,8 @@ def search_page(): else: print("calling search_results.SearchResultPage") the_search = search_results.SearchResultPage(request.args) - print("done calling") + print("template_vars is:", pf(the_search.__dict__)) + print("trait_list is:", pf(the_search.__dict__['trait_list'][0].__dict__)) return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From cf86b790abe5955ab8384aed89d7c0cceb58004b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 26 Oct 2012 17:12:00 -0500 Subject: Put footer/head into base.html; was previously just in index_page.html --- wqflask/wqflask/templates/base.html | 352 ++++++++++++------------------ wqflask/wqflask/templates/index_page.html | 161 +------------- 2 files changed, 153 insertions(+), 360 deletions(-) diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index f52041b1..385512e3 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -1,218 +1,156 @@ + - {% block head %} - {% block title %}{% endblock %} - GeneNetwork - - - - - - - - - - - - - - + + GeneNetwork + + + - - - - - - - - - + + + + - - {% endblock %} - - - - - - - - - - - - - - - - - - - - - - -
        {% block content %}{% endblock %}
        - - - - - -
          - - - - - - -
        - - - - - - - - - WebQTL -
        -
         
        - - - - - -
        -    |    - - Home -    |    - - Search -    |    - - Help -    |    - - - News -    |    - - - References -    |    - - Policies -    |    - - - Links -    |    - - Welcome! Login    -
        -
        - - - - - - - - - - - - - - -
        - - CITG - -WWW service initiated January, 1994 as The Portable Dictionary of the Mouse Genome and June 15, 2001 as WebQTL. - -This site is currently operated by - Rob Williams, - Lei Yan, - Zachary Sloan, - Arthur Centeno. Design and code by Xiaodong Zhou, Christian Fernandez, Ning Liu, Rudi Alberts, Elissa Chesler, Jintao Wang, Kenneth Manly, Robert W. Williams, and colleagues. - - - - - Python Powered - - - Registered with Nif -
        - GeneNetwork support from: - -
        -     It took 0.041 second(s) for spring211.uthsc.edu to generate this page -
        -
        - - - - - - - - + + + + + + + + + + diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index 695129a9..2d7ba44c 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -1,71 +1,9 @@ - - - - - GeneNetwork - - - - - - - - - - - - - - - - +{% extends "base.html" %} +{% block title %}GeneNetwork{% endblock %} +{% block content %} + + +
        @@ -181,7 +119,7 @@
    • -
    • Select a Database
    • +
    • Select a Dataset
    • Enter terms in the search field: words, genes, ID numbers, probes, advanced search commands
    • @@ -337,87 +275,4 @@ - - - - - - - - - - - - - - +{%endblock%} \ No newline at end of file -- cgit v1.2.3 From 4353a903c4661f5c12c4d653044122cf59ef373a Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 26 Oct 2012 18:27:22 -0500 Subject: Changed search page appearance using bootstrap Headers/information displays correctly for single mRNA expression trait searches --- wqflask/wqflask/search_results.py | 33 ++- .../wqflask/static/packages/bootstrap/css/docs.css | 2 +- wqflask/wqflask/templates/search_result_page.html | 269 +++++++-------------- wqflask/wqflask/views.py | 2 +- 4 files changed, 106 insertions(+), 200 deletions(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 8fc12b16..a2b0596c 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -182,6 +182,14 @@ class SearchResultPage(templatePage): 'GenbankId', 'UniGeneId', 'RefSeq_TranscriptId'] + self.header_fields = ['', + 'ID', + 'Symbol', + 'Description', + 'Location', + 'Mean Expr', + 'Max LRS', + 'Max LRS Location'] elif self.dataset.type == "Geno": self.search_fields = ['Name','Chr'] @@ -693,8 +701,7 @@ class SearchResultPage(templatePage): and ProbeSetXRef.ProbeSetFreezeId = %s """ % (self.db_conn.escape_string(search_term), self.db_conn.escape_string(str(self.dataset.id)))) - - print("query is:", query) + self.cursor.execute(query) #print("query is:", pf(self.query)) @@ -1252,19 +1259,25 @@ class SearchResultPage(templatePage): else: trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - trait_location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb) ) + trait_location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) this_trait.trait_location_repr = trait_location_repr #this_trait.trait_location_value = trait_location_value tr.append(TDCell(HT.TD(trait_location_repr, Class=className, nowrap="on"), trait_location_repr, trait_location_value)) #XZ, 01/12/08: This SQL query is much faster. - self.cursor.execute(""" - select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet - where ProbeSetXRef.ProbeSetFreezeId = %d and - ProbeSet.Id = ProbeSetXRef.ProbeSetId and - ProbeSet.Name = '%s' - """ % (this_trait.db.id, this_trait.name)) + query = ( +"""select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet + where ProbeSetXRef.ProbeSetFreezeId = %s and + ProbeSet.Id = ProbeSetXRef.ProbeSetId and + ProbeSet.Name = '%s' + """ % (self.db_conn.escape_string(str(this_trait.db.id)), + self.db_conn.escape_string(this_trait.name))) + + print("query is:", pf(query)) + + self.cursor.execute(query) result = self.cursor.fetchone() + if result: if result[0]: mean = result[0] @@ -1310,7 +1323,7 @@ class SearchResultPage(templatePage): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) LRS_flag = 0 #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, this_trait.db.shortname, this_trait.name), Class="fs12 fwn"), Class=className, align='right', nowrap="on"),LRS_score_repr, LRS_score_value)) diff --git a/wqflask/wqflask/static/packages/bootstrap/css/docs.css b/wqflask/wqflask/static/packages/bootstrap/css/docs.css index a6fff3c3..7efd72cd 100644 --- a/wqflask/wqflask/static/packages/bootstrap/css/docs.css +++ b/wqflask/wqflask/static/packages/bootstrap/css/docs.css @@ -560,7 +560,7 @@ h2 + .row { /* Echo out a label for the example */ .bs-docs-example:after { - content: "Example"; + content: "Results"; position: absolute; top: -1px; left: -1px; diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 06458818..abf2dba7 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -2,195 +2,88 @@ {% block title %}Search Results{% endblock %} {% block content %} - - - - - - -
      -

      Search Results

      -
      GeneNetwork searched: - {{ dataset.fullname }} -
      - - For all records that match: -
        - {% if search_terms %} -
      • - {% for word in search_terms %} - {{word.search_term}} {% if not loop.last %} or {% endif %} - {% endfor %} -
      • - {% endif %} -
      +
      +
      +

      Search Results

      +

      + GeneNetwork found {{ numify(results|count, "record", "records") }}. +

      +
      +
      -

      GeneNetwork found {{ numify(results|count, "record", "records") }}.

      - -

      To study a record, click on its ID below.

      - -

      To add one or more records to your Selection window, use the checkbox and then click the Add to Collection button.

      -
      -
      - - - - - - - -

      - - - - - - - - - - -
      - - - - - - - - - - - - -
      - - Select All - - - Select None - - - - Invert Selection - - - - Add To Collection - -
        Select Deselect   Invert    Add
      -
      - -
      -
      - - - - - - - - - - - - {% for this_trait in trait_list %} - - - - - - - - - - - {% endfor %} -
      - - Record -
      ID
      - -
      - Symbol

      -
      - sortupon.gif - - sortdown.gif - -
      -
      - Description

      - -
      Location
      Chr and Mb
      - -
      Mean
      Expr
      - -
      Max
      LRS
      - -
      Max LRS Location
      Chr and Mb
      - -
      {{ loop.index }} - - - {# - #} - - {{ this_trait.name.upper() }} - - - - {{ this_trait.symbol }} - - {{ this_trait.description_display }}{{ this_trait.trait_location_repr }}{{ this_trait.mean }}{{ this_trait.LRS_score_repr }}{{ this_trait.LRS_location_repr }}
      -
      -
      - -

      -
      - - +
      + + +

      We searched {{ dataset.fullname }} + +

      To find all records that match:

      +
        + {% if search_terms %} +
      • + {% for word in search_terms %} + {{word.search_term}} {% if not loop.last %} or {% endif %} + {% endfor %} +
      • + {% endif %} +
      + +

      To study a record, click on its ID below.
      + Check records below and click Add button to add to selection.

      + +
      + + + + {% for header in header_fields %} + + {% endfor %} + + + + {% for this_trait in trait_list %} + + + + + + + + + + + {% endfor %} + + +
      {{header}}
      + + + + {{ this_trait.name.upper() }} + + + + {{ this_trait.symbol }} + + {{ this_trait.description_display }}{{ this_trait.trait_location_repr }}{{ this_trait.mean }}{{ this_trait.LRS_score_repr }}{{ this_trait.LRS_location_repr }}
      + +
      + + + + + + +
      + +
      + {% endblock %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index dd95f7ca..41d1d714 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -64,7 +64,7 @@ def search_page(): print("calling search_results.SearchResultPage") the_search = search_results.SearchResultPage(request.args) print("template_vars is:", pf(the_search.__dict__)) - print("trait_list is:", pf(the_search.__dict__['trait_list'][0].__dict__)) + #print("trait_list is:", pf(the_search.__dict__['trait_list'][0].__dict__)) return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From dbda821555f2e9293d824b7c3662d251c0004252 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 30 Oct 2012 17:47:13 -0500 Subject: Did some work converting show_trait.html to using bootstrap for styling --- wqflask/wqflask/templates/show_trait.html | 2558 +++++++++++++++-------------- 1 file changed, 1302 insertions(+), 1256 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index d48f9487..ab662a77 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -1,1380 +1,1426 @@ +{% extends "base.html" %} +{% block title %}Trait Data and Analysis{% endblock %} +{% block content %} + +
      +
      +

      {{ this_trait.symbol}}

      +

      + {{ this_trait.name }}: {{ this_trait.description_fmt }} +

      +
      +
      + + + +
      + + +
      +
      Aliases
      +
      {{ this_trait.alias_fmt }}
      + +
      Location
      +
      {{ this_trait.location_fmt }}
      + +
      Database
      +
      + + {{ this_trait.database.name }} + +
      + +
      + + BLAT Specifity + +
      +
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      + +
      BLAT Score
      +
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      +
      + + + + + + + -
    • Probability Plot
    • + + -
    • Bar Graph (by name)
    • + -
    • Bar Graph (by rank)
    • + -
    • Box Plot
    • - + -
      -
      +
      + {# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #} + {% for key in hddn %} + + {% endfor %} +
      +
      + Trait Data and Analysis  for Record ID 1441186_at +
      +
      + +

        Details and Links

      + +

      + + + + + + + + + + + + + + + + + + + + + + - {% extends "base.html" %} - {% block title %}Trait Data and Analysis{% endblock %} - {% block content %} - - - + -
      Gene Symbol:{{ this_trait.symbol }}
      Aliases:{{ this_trait.alias_fmt }}
      Description:
      - - - -
      - - {# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #} - {% for key in hddn %} - - {% endfor %} -
      -
      - Trait Data and Analysis  for Record ID 1441186_at -
      -
      - -

        Details and Links

      - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + - + + + + + + + + + + - - - - - - - - - - - - - -
      Gene Symbol:{{ this_trait.symbol }}
      Aliases:{{ this_trait.alias_fmt }}
      Description:{{ this_trait.description_fmt }}
      Location:{{ this_trait.location_fmt }}
      Target Score: - - - BLAT specificity - : {{ "%.1f" % (this_trait.probe_set_specificity) }}    - Score: {{ "%i" % (this_trait.probe_set_blat_score) }}   - -
      Species and Group:{{ this_trait.species.capitalize() }}, {{fd.RISet}}
      Database: - {{ this_trait.database.name }} -
      Resource Links:{{ this_trait.description_fmt }}
      Location: - - - - Gene - + {{ this_trait.location_fmt }}
      Target Score: + + + BLAT specificity + : {{ "%.1f" % (this_trait.probe_set_specificity) }}    + Score: {{ "%i" % (this_trait.probe_set_blat_score) }}   -   UniGene  GenBank  HomoloGene  
      UCSC  BioGPS  STRING  PANTHER  Gemma  SynDB  ABA  

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      -- -  Check probe locations at UCSC  Write or review comments about this gene -  View SNPs and Indels -  View probes, SNPs, and RNA-seq at UTHSC -  Check sequence of probes
      AddFindVerifyGeneWikiSNPsRNA-seqProbes
      - -

        Basic Statistics

      - - -

      Include: -
      -
      -
      -
      - +
      +
      {{ this_trait.species.capitalize() }}, {{fd.RISet}}
      - - + -
    • Probability Plot
    • + -
    • Bar Graph (by name)
    • + + -
    • Bar Graph (by rank)
    • + + + -
    • Box Plot
    • - + + -
      -
      - {% for sd in stats_data %} -
      -
      Database: + {{ this_trait.database.name }} +
      Resource Links:
      - - - -
      - - - + - - + + + + + + + + + + + + + + +
      StatisticValue
      + + + + Gene + + +   UniGene  GenBank  HomoloGene  
      UCSC  BioGPS  STRING  PANTHER  Gemma  SynDB  ABA  

      + + + + + + + + + + + + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      ++ +  Check probe locations at UCSC  Write or review comments about this gene +  View SNPs and Indels
      N of Samples +  View probes, SNPs, and RNA-seq at UTHSC +  Check sequence of probes {{ sd.N }}
      Mean{{ "%2.3f" % sd.traitmean }}
      Median{{ "%2.3f" % sd.traitmedian }}
      Standard Error (SE){{ "%2.3f" % sd.traitsem }}
      Standard Deviation (SD){{ "%2.3f" % sd.traitstdev }}
      Minimum{{ "%2.3f" % sd.min }}
      Maximum{{ "%2.3f" % sd.max }}
      Range (log2){{ "%2.3f" % sd.range_log2 }}
      Range (fold){{ "%2.3f" % sd.range_fold }}
      Interquartile Range{{ "%2.3f" % sd.interquartile }}
      -
      - - -
      - - - - - - - - -
      nP_OE9u7BSx.gif

      -
      - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      -
      - More about Normal Probability Plots and more - about interpreting these plots from the glossary
      -
      - -
      - - - - -
      - Box_gUFtEOVI.gif - -

      More about Box Plots

      -
      -
      - -
      - - - - -
      Bar_y7L2rYlL.gif
      -
      - -
      - - - - -
      Bar_1Z4GjYFq.gif
      -
      - - {% endfor %} - {# Not used now - Todo: Delete after we're sure this is right. -
      -
      AddFindVerifyGeneWiki
      - - - -
      - - - + - - + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      StatisticSNPsValue
      RNA-seq
      N of SamplesProbes71
      Mean6.109
      Median6.084
      Standard Error (SE)0.022
      Standard Deviation (SD)0.187
      Minimum5.782
      Maximum6.579
      Range (log2)0.797
      Range (fold)1.74
      Interquartile Range1.13
      -
      -
      - -
      - - - - - - - - -
      nP_eSYO7ZQg.gif

      -
      - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      -
      - More about Normal Probability Plots and more - about interpreting these plots from the glossary
      -
      - -
      - - - - -
      - Box_PWNWQMfj.gif - -

      More about Box Plots

      -
      -
      - -
      - - - - -
      Bar_VuPqYbR6.gif
      -
      - -
      - - - - -
      Bar_9PbdvXZ9.gif
      -
      - + + + -
      +

        Basic Statistics

      -
        -
      • Basic Table
      • +

        Include: +
        +
        +
        +
        + -
      • Bar Graph (by rank)
      • +
        -
      • Box Plot
      • -
      + + + - -
      + {% for sd in stats_data %} +
      +
        +
      • Basic Table
      • -
        - - - + -
        -
        - - - +
      • Probability Plot
      • - - +
      • Bar Graph (by name)
      • - - +
      • Bar Graph (by rank)
      • - - +
      • Box Plot
      • + - - +
        +
        StatisticValue
        N of Samples32
        Mean
        + + - -
        + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - -
        Statistic6.176
        Value
        Median
        N of Samples6.170
        {{ sd.N }}
        Standard Error (SE)
        Mean0.027
        {{ "%2.3f" % sd.traitmean }}
        Standard Deviation (SD)
        Median0.150
        {{ "%2.3f" % sd.traitmedian }}
        Minimum
        Standard Error (SE)5.906
        {{ "%2.3f" % sd.traitsem }}
        Maximum
        Standard Deviation (SD)6.485
        {{ "%2.3f" % sd.traitstdev }}
        Range (log2)
        Minimum0.579
        {{ "%2.3f" % sd.min }}
        Range (fold)
        Maximum1.49
        {{ "%2.3f" % sd.max }}
        Interquartile Range
        Range (log2)1.15
        -
        - +
        {{ "%2.3f" % sd.range_log2 }}
        - - - + + - - - -
        nP_swDAFlJy.gif
        Range (fold)

        -
        - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
        -
        - More about Normal Probability Plots and more - about interpreting these plots from the glossary
        -
        - -
        - - - - -
        - Box_6sQJ8xhK.gif - -

        More about Box Plots

        -
        -
        - -
        - - - - -
        Bar_QMWE2VEp.gif
        -
        - -
        - - - - -
        Bar_X07QmgsX.gif
        -
        -
      -
      - #} + {{ "%2.3f" % sd.range_fold }} + -

        Calculate Correlations

      - -

      - - - - - -
      -
      -
      - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      Method: - -
      Database: - -
      Return:
      Samples: - -
      -
      -
      - Pearson -     - Spearman Rank -
      -
      - -

      - - - The Sample Correlation - is computed - between trait data and any
      - other traits in the sample database selected above. Use - Spearman - Rank
      - when the sample size is small (<20) or when there are influential outliers. -
      - - - -
      -
      -
      -
      -
      + + Interquartile Range -

        Mapping Tools

      + {{ "%2.3f" % sd.interquartile }} + + + + + +
      -

      +

      More about Box Plots

      + + + + - - - - -
      -
      -
      + {% endfor %} + {# Not used now - Todo: Delete after we're sure this is right. +
      + +
    • Bar Graph (by name)
    • -
      - - - - - - - - -
      - - - +
    • Bar Graph (by rank)
    • - - -
      Chromosome: + + + +
      + + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - + + - - - + + - - + + - + +
      StatisticValue
      N of Samples71
      Mean6.109
      Median6.084
      Standard Error (SE)0.022
      Standard Deviation (SD)0.187
      Minimum5.782
      Maximum6.579
      Range (log2)0.797
      Range (fold)
      1.74
      Mapping Scale:
      Interquartile Range1.13
      +
      + - -

      - Permutation Test (n=2000)
      - Bootstrap Test (n=2000)
      - Use Parents
      - Use Weighted
      -
      -
      -
      -
      Interval Mapping computes linkage maps - for the entire genome or single
      - chromosomes. The Permutation Test estimates suggestive and - significant
      - linkage scores. The Bootstrap Test estimates the precision of the QTL - location.

      -
      - -
      - - - - - - - - -
      - - - - - - - - - - - - - - - - - - -
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      -
      -
      -
      Marker regression computes and displays LRS - values for individual markers.
      - This function also lists additive effects (phenotype units per allele) and
      - dominance deviations for some datasets.

      -
      - -
      - - - - - - - - -
      - - - - - + +
      Chromosome: + + + + + + + +
      nP_eSYO7ZQg.gif

      +
      + This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      +
      + More about Normal Probability Plots and more + about interpreting these plots from the glossary
      + - +
      + + + + +
      + Box_PWNWQMfj.gif - +

      More about Box Plots

      +
      +
      - +
      + + + + +
      Bar_VuPqYbR6.gif
      +
      - +
      + + + + +
      Bar_9PbdvXZ9.gif
      +
      + - +
      - - + - +
      + + + - - - - - -
      + + + - + + - + + - + + - + + - + + - + + - + + - - - + + - - + + - + - - - - - - - - - -
      StatisticValue
      N of Samples32
      Mean6.176
      Median6.170
      Standard Error (SE)
      Mapping Scale:0.027
      Standard Deviation (SD)
      Control Locus:

      - Permutation Test (n=2000)
      - Bootstrap Test (n=2000)
      - Use Parents
      -
      -
      -
      -
      Composite Interval Mapping allows you to control - for a single marker as
      - a cofactor. To find a control marker, run the Marker Regression function.

      -
      - -
      - - - + +
      - - - - - + - - - + + - - + + - + - + + - + + + + + + + + + + + + + + + + + +
      Sort by:0.150
      Minimum
      Return:5.906
      Maximum6.485
      Range (log2)0.579
      Range (fold)1.49
      Interquartile Range1.15
      +
      +
      + +
      + + + + + + + + +
      nP_swDAFlJy.gif

      +
      + This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      +
      + More about Normal Probability Plots and more + about interpreting these plots from the glossary
      +
      + +
      + + + + +
      + Box_6sQJ8xhK.gif + +

      More about Box Plots

      +
      +
      + +
      + + + + +
      Bar_QMWE2VEp.gif
      +
      + +
      + + + + +
      Bar_X07QmgsX.gif
      +
      +
      +
      + #} + +

        Calculate Correlations

      + +

      + + + + + +
      +
      +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      Method: + +
      Database: + +
      Return:
      Samples: + +
      +
      +
      + Pearson +     + Spearman Rank +
      +
      + +

      + + + The Sample Correlation + is computed + between trait data and any
      + other traits in the sample database selected above. Use + Spearman + Rank
      + when the sample size is small (<20) or when there are influential outliers. +
      + + + +
      +
      +
      +
      +
      + +

        Mapping Tools

      + +

      + + + + + +
      +
      + + +
      + + + + + + + + +
      + + + + + + + + + + + + +
      Chromosome:
      Mapping Scale:

      + Permutation Test (n=2000)
      + Bootstrap Test (n=2000)
      + Use Parents
      + Use Weighted
      +
      +
      +
      +
      Interval Mapping computes linkage maps + for the entire genome or single
      + chromosomes. The Permutation Test estimates suggestive and + significant
      + linkage scores. The Bootstrap Test estimates the precision of the QTL + location.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + + + + + + + +
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      +
      +
      +
      Marker regression computes and displays LRS + values for individual markers.
      + This function also lists additive effects (phenotype units per allele) and
      + dominance deviations for some datasets.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + + + + + + + +
      Chromosome:
      Mapping Scale:
      Control Locus:

      + Permutation Test (n=2000)
      + Bootstrap Test (n=2000)
      + Use Parents
      +
      +
      +
      +
      Composite Interval Mapping allows you to control + for a single marker as
      + a cofactor. To find a control marker, run the Marker Regression function.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + +
      Sort by:
      Return:

      + Permutation Test + (n=500)
      +
      +
      +
      +
      Pair-Scan searches for pairs of chromosomal regions + that are
      + involved in two-locus epistatic interactions.

      +
      +
      +
      + +

        Review and Edit Data

      + + + +

      -
      + + - -
      +
      +
      +
      + Block samples +

      Edit or delete values in the Trait Data boxes, and use the + Reset option as + needed. +

      + + +
      + + + + +

      - Permutation Test - (n=500)
      + + + + +
      -
      + + {% if sample_groups[0].attributes %} +
      + + + + +
      + {% endif %}
      -
      Pair-Scan searches for pairs of chromosomal regions - that are
      - involved in two-locus epistatic interactions.

      -
      -
      -
      - -

        Review and Edit Data

      - - - -

      - -
      - - - -
      -
      -
      -
      - Block samples -

      Edit or delete values in the Trait Data boxes, and use the - Reset option as - needed. -

      - - -
      - - - - - - +
      + + + + + + + +
      +
      +
      +
      +

      Outliers highlighted in + yellow + can be hidden using + the Hide Outliers button. +

      + +

      Samples with no value (x) can be hidden by clicking + Hide No Value button. +

      - -
      - {% if sample_groups[0].attributes %} -
      - - + + + + + + + {% if sample_type.se_exists() %} + + + + {% endif %} + + {% for attribute in sample_type.attributes|sort() %} + + {% endfor %} + + + {% for sample in sample_type.sample_list %} + + + + + + {# Todo: Add IDs #} + + + {% if sample_type.se_exists() %} + + + {# Todo: Add IDs #} + + {% endif %} + + {# Loop through each attribute type and input value #} + {% for attribute in sample_type.attributes|sort() %} + {% endfor %} - - - + + {% endfor %} + +
      IndexSampleValue SE + {{ sample_type.attributes[attribute].name }} +
      + {{ loop.index }} + + + + {{ sample.name }} + + + + + ± + + + + {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} +
      +
      - {% endif %} -
      -
      - - - - - - - -
      - -
      -
      -

      Outliers highlighted in - yellow - can be hidden using - the Hide Outliers button. -

      - -

      Samples with no value (x) can be hidden by clicking - Hide No Value button. -

      -
      -
      -
      - - - -
      - {% for sample_type in sample_groups %} -
      -

      {{ sample_type.header }}

      - -
      - - - - - - - - {% if sample_type.se_exists() %} - - - - {% endif %} - - {% for attribute in sample_type.attributes|sort() %} - - {% endfor %} - - - {% for sample in sample_type.sample_list %} - - - - - - {# Todo: Add IDs #} - - - {% if sample_type.se_exists() %} - - - {# Todo: Add IDs #} - - {% endif %} - - {# Loop through each attribute type and input value #} - {% for attribute in sample_type.attributes|sort() %} - - {% endfor %} - {% endfor %} - -
      IndexSampleValue SE - {{ sample_type.attributes[attribute].name }} -
      - {{ loop.index }} - - - - {{ sample.name }} - - - - - ± - - - - {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} -
      -
      -
      - {% endfor %} -
      - -
      - - - - - - - - + + + + + + + + + + + + + @@ -1382,16 +1428,16 @@ --> - + - + - - - - - {% endblock %} + + + + +{% endblock %} -- cgit v1.2.3 From 45b6e6a5eea13dbd06045e8307e371994b8c3083 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 30 Oct 2012 18:22:27 -0500 Subject: Worked on search_result.py code related to adding clause item to queries Continued work on redesigning the trait data page design --- wqflask/base/webqtlTrait.py | 12 +- wqflask/wqflask/search_results.py | 249 ++++++++++++++++------------- wqflask/wqflask/templates/show_trait.html | 253 ++++-------------------------- 3 files changed, 177 insertions(+), 337 deletions(-) diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 46af6683..51d36ab2 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -226,7 +226,7 @@ class webqtlTrait: def retrieveData(self, samplelist=None): - + if samplelist == None: samplelist = [] assert self.db and self.cursor @@ -331,7 +331,7 @@ class webqtlTrait: self.cursor.execute(query) results = self.cursor.fetchall() self.data.clear() - + if results: self.mysqlid = results[0][-1] #if samplelist: @@ -345,7 +345,7 @@ class webqtlTrait: name = item[0] self.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) #end for - # else: + # else: # for item in results: # val = item[1] # if val != None: @@ -604,7 +604,7 @@ class webqtlTrait: formatted += "; " + self.probe_target_description else: formatted = "Not available" - return formatted + return formatted.capitalize() @property def alias_fmt(self): @@ -660,7 +660,7 @@ class webqtlTrait: else: return dict(name = self.db.fullname, url = webqtlConfig.INFOPAGEHREF % self.db.name) - + def calculate_correlation(self, values, method): """Calculate the correlation value and p value according to the method specified""" @@ -693,4 +693,4 @@ class webqtlTrait: else: ZValue = 0.5*log((1.0+self.correlation)/(1.0-self.correlation)) ZValue = ZValue*sqrt(self.overlap-3) - self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue))) + self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue))) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index a2b0596c..29a497fa 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -365,114 +365,111 @@ class SearchResultPage(templatePage): #last_result = False self.trait_list = [] - for result in self.results: - if not result: - continue - #last_result = False - - #for item in result: - print("foo locals are:", locals()) - probe_set_id = result[1] - print("probe_set_id is:", pf(probe_set_id)) - this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) - this_trait.retrieveInfo(QTL=True) - print("this_trait is:", pf(this_trait)) - self.trait_list.append(this_trait) - print("self.trait_list is:", pf(self.trait_list)) - - ############## - # Excel file # - ############## - - # Todo: Replace this with official Python temp file naming functions? - filename= webqtlUtil.genRandStr("Search_") - #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') - # Create a new Excel workbook - #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) - #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") - - #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. - #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) - newrow = 7 - - #### Excel file stuff stops + # result_set represents the results for each search term; a search of + # "shh grin2b" would have two sets of results, one for each term + for result_set in self.results: + for result in result_set: + if not result: + continue + #last_result = False - #tbl = HT.TableLite(cellSpacing=2,cellPadding=0,width="90%",border=0) - #seq = self.pageNumber*self.NPerPage+1 //Edited out because we show all results in one page now - Zach 2/22/11 - seq = 1 - group = self.dataset.group - self.form_name = form_name = 'show_dataset_'+group + seq = 1 + group = self.dataset.group + self.form_name = form_name = 'show_dataset_'+group - tblobj = {} - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) + tblobj = {} + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) - if this_trait.db.type=="Geno": - tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + #### Excel file - newrow += 1 - sortby = self.getSortByValue(datasetType="Geno") + # Todo: Replace this with official Python temp file naming functions? + filename= webqtlUtil.genRandStr("Search_") + #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') + # Create a new Excel workbook + #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) + #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") - #tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) + #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. + #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) + newrow = 7 - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() + #### Excel file stuff stops - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - # - #pageTable.append(HT.TR(HT.TD(div))) + if self.dataset.type == "ProbeSet": + #for item in result: + print("foo locals are:", locals()) + probe_set_id = result[1] + print("probe_set_id is:", pf(probe_set_id)) + this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) + this_trait.retrieveInfo(QTL=True) + print("this_trait is:", pf(this_trait)) + self.trait_list.append(this_trait) + print("self.trait_list is:", pf(self.trait_list)) - elif this_trait.db.type=="Publish": - #tblobj['header'] = self.getTableHeaderForPublish(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + #tblobj['header'] = self.getTableHeaderForProbeSet(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - #newrow += 1 + #newrow += 1 - sortby = self.getSortByValue(datasetType="Publish") + sortby = self.getSortByValue(datasetType="ProbeSet") - #tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() + #workbook.close() + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - #pageTable.append(HT.TR(HT.TD(div))) + #pageTable.append(HT.TR(HT.TD(div))) + elif self.dataset.type == "Publish": + #tblobj['header'] = self.getTableHeaderForPublish(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - elif this_trait.db.type=="ProbeSet": - #tblobj['header'] = self.getTableHeaderForProbeSet(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + #newrow += 1 - #newrow += 1 + sortby = self.getSortByValue(datasetType="Publish") - sortby = self.getSortByValue(datasetType="ProbeSet") + #tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) - tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) - # - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() + #workbook.close() + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - #pageTable.append(HT.TR(HT.TD(div))) + #pageTable.append(HT.TR(HT.TD(div))) + elif self.dataset.type == "Geno": + tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) + newrow += 1 + sortby = self.getSortByValue(datasetType="Geno") - #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) - hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} - hddn['incparentsf1']='ON' - # for key in hddn.keys(): - # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) - # - # traitForm.append(HT.P(),pageTable) - # - # TD_LR.append(traitForm) - # if len(self.results) > 1 and i < len(self.results) - 1: - # last_result = True - #if last_result: - # TD_LR.contents.pop() + #tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) + + #workbook.close() + #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + #cPickle.dump(tblobj, objfile) + #objfile.close() + + #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") + # + #pageTable.append(HT.TR(HT.TD(div))) + + + #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} + hddn['incparentsf1']='ON' + # for key in hddn.keys(): + # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + # + # traitForm.append(HT.P(),pageTable) + # + # TD_LR.append(traitForm) + # if len(self.results) > 1 and i < len(self.results) - 1: + # last_result = True + #if last_result: + # TD_LR.contents.pop() def executeQuery(self): @@ -642,6 +639,8 @@ class SearchResultPage(templatePage): print("fd.search_terms:", self.fd['search_terms']) self.search_terms = parser.parse(self.fd['search_terms']) print("After parsing:", self.search_terms) + + #print("ORkeyword is:", pf(self.ORkeyword)) #self.ANDkeyword2 = parser.parse(self.ANDkeyword) #self.ORkeyword2 = parser.parse(self.ORkeyword) @@ -662,11 +661,8 @@ class SearchResultPage(templatePage): ###remove remain parethesis, could be input with syntax error #self.ORkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ORkeyword2) #self.ORkeyword2 = self.encregexp(self.ORkeyword2) - - #if self.search_terms: - #full_text = [] - #ANDFulltext = [] - #ORFulltext = [] + + self.results = [] for item in self.search_terms: search_term = item['search_term'] # self.nkeywords += 1 @@ -683,8 +679,19 @@ class SearchResultPage(templatePage): # fulltext = ORFulltext print("item is:", pf(search_term)) - + + + clause_item = ( +""" MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) if self.dataset.type == "ProbeSet": + query = ( """SELECT distinct 0, ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -693,31 +700,55 @@ class SearchResultPage(templatePage): ProbeSet.Chr_num as TCHR_NUM, ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, - ProbeSet WHERE (MATCH (ProbeSet.Name, ProbeSet.description, ProbeSet.symbol, - alias, GenbankId, UniGeneId, Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s + ProbeSet.name_num as TNAME_NUM + FROM ProbeSetXRef, ProbeSet + WHERE %s + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s """ % (self.db_conn.escape_string(search_term), + self.db_conn.escape_string(clause_item), self.db_conn.escape_string(str(self.dataset.id)))) + + elif self.dataset.type == "Publish": + include_geno = "" + if search_term.find("Geno.name") >= 0: + include_geno = " Geno, " + + query = ( +"""SELECT 0, PublishXRef.Id, PublishFreeze.createtime as thistable, + Publication.PubMed_ID as Publication_PubMed_ID, + Phenotype.Post_publication_description as Phenotype_Name + FROM %s PublishFreeze, Publication, PublishXRef, Phenotype + WHERE PublishXRef.InbredSetId = %s and %s and + PublishXRef.PhenotypeId = Phenotype.Id and + PublishXRef.PublicationId = Publication.Id and + PublishFreeze.Id = %s + """ % (include_geno, + self.db_conn.escape_string(str(self.dataset.group_id)), + self.db_conn.escape_string(clause_item), + self.db_conn.escape_string(str(self.dataset.id)))) + + elif self.dataset.type == "Geno": + query = ( +"""SELECT 0, Geno.Name, GenoFreeze.createtime as thistable, + Geno.Name as Geno_Name, + Geno.Source2 as Geno_Source2, + Geno.chr_num as Geno_chr_num, + Geno.Mb as Geno_Mb + FROM GenoXRef, GenoFreeze, Geno + WHERE %s and Geno.Id = GenoXRef.GenoId and + GenoXRef.GenoFreezeId = GenoFreeze.Id and + GenoFreeze.Id = %d + """% (self.db_conn.escape_string(clause_item), + self.db_conn.escape_string(str(self.dataset.id)))) - self.cursor.execute(query) - #print("query is:", pf(self.query)) - #self.cursor.execute(self.query) - self.results = self.cursor.fetchall() + self.cursor.execute(query) + self.results.append(self.cursor.fetchall()) print("self.results is:", pf(self.results)) -#["(SELECT distinct 0, ProbeSet.Name as TNAME, 0 as thistable,\n\t\t\t\t\t\tProbeSetXRef.Mean as TMEAN, -# ProbeSetXRef.LRS as TLRS, ProbeSetXRef.PVALUE as TPVALUE,\n\t\t\t\t\t\tProbeSet.Chr_num as TCHR_NUM, -# Pr beSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL,\n\t\t\t\t\t\tProbeSet.name_num as TNAME_NUM FROM -# ProbeSetXRef, ProbeSet \n\t\t\t\t\t\tWHERE ( MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, -# alias GenbankId, UniGeneId, Probe_Target_Description) -# AGAINST ('shh' IN BOOLEAN MODE) ) -# and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = 112\n\t\t\t\t\t\t)"] #if self.dataset.type == "ProbeSet" and search_term.find('.') < 0 and search_term.find('\'') < 0: diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index ab662a77..d7b81562 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -48,240 +48,49 @@
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      - - - - - - -
      -
      - {# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #} - {% for key in hddn %} - - {% endfor %} -
      -
      - Trait Data and Analysis  for Record ID 1441186_at -
      -
      - -

        Details and Links

      - -

      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + {% for key in hddn %} + + {% endfor %} - - - +
      +
      + -
      - - - - - - + - - - + + - - - - - - - -
      Gene Symbol:{{ this_trait.symbol }}
      Aliases:{{ this_trait.alias_fmt }}
      Description:{{ this_trait.description_fmt }}
      Location:{{ this_trait.location_fmt }}
      Target Score: - - - BLAT specificity - : {{ "%.1f" % (this_trait.probe_set_specificity) }}    - Score: {{ "%i" % (this_trait.probe_set_blat_score) }}   - -
      Species and Group:{{ this_trait.species.capitalize() }}, {{fd.RISet}}
      Database: - {{ this_trait.database.name }} -
      Resource Links: - - - - Gene - - -   UniGene  GenBank  HomoloGene  
      UCSC  BioGPS  STRING  PANTHER  Gemma  SynDB  ABA  

      - - - - - - - - - - - - - - - - - - - +
      -
      - + - + - + - + - + - + - - - -
      -- -  Check probe locations at UCSC  Write or review comments about this gene -  View SNPs and Indels -  View probes, SNPs, and RNA-seq at UTHSC -  Check sequence of probes
      AddFindVerifyGeneWikiSNPsRNA-seqProbes

        Basic Statistics

      -- cgit v1.2.3 From 29de88e179b735a26a2134db4d10d88905afad32 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 31 Oct 2012 18:30:39 -0500 Subject: Did work with writing the search page query functions for some ProbeSet and Phenotype searches --- wqflask/wqflask/do_search.py | 180 ++++++++++++++++++++++++++++++++++++++ wqflask/wqflask/search_results.py | 52 +++++++---- 2 files changed, 217 insertions(+), 15 deletions(-) create mode 100644 wqflask/wqflask/do_search.py diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py new file mode 100644 index 00000000..cfa73334 --- /dev/null +++ b/wqflask/wqflask/do_search.py @@ -0,0 +1,180 @@ +#!/usr/bin/python + + +from __future__ import print_function, division + +from pprint import pformat as pf + + +class DoSearch(object): + def __init__(self, search_term, dataset, cursor, db_conn): + self.search_term = search_term + self.dataset = dataset + self.db_conn = db_conn + self.cursor = cursor + + def execute(self, query): + query = self.normalize_spaces(query) + print("query is:", pf(query)) + self.cursor.execute(query) + results = self.cursor.fetchall() + return results + + def escape(self, stringy): + """Shorter name than self.db_conn.escape_string""" + return self.db_conn.escape_string(str(stringy)) + + def normalize_spaces(self, stringy): + """Strips out newlines extra spaces and replaces them with just spaces""" + step_one = " ".join(stringy.split()) + return step_one + + + +class ProbeSetSearch(DoSearch): + base_query = """SELECT ProbeSet.Name as TNAME, + 0 as thistable, + ProbeSetXRef.Mean as TMEAN, + ProbeSetXRef.LRS as TLRS, + ProbeSetXRef.PVALUE as TPVALUE, + ProbeSet.Chr_num as TCHR_NUM, + ProbeSet.Mb as TMB, + ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM + FROM ProbeSetXRef, ProbeSet """ + + def run(self): + + query = (self.base_query + + """WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(self.search_term), + self.escape(dataset.id))) + + return self.execute(query) + + +class PhenotypeSearch(DoSearch): + base_query = """SELECT PublishXRef.Id, + PublishFreeze.createtime as thistable, + Publication.PubMed_ID as Publication_PubMed_ID, + Phenotype.Post_publication_description as Phenotype_Name + FROM Phenotype, PublishFreeze, Publication, PublishXRef """ + + search_fields = ('Phenotype.Post_publication_description', + 'Phenotype.Pre_publication_description', + 'Phenotype.Pre_publication_abbreviation', + 'Phenotype.Post_publication_abbreviation', + 'Phenotype.Lab_code', + 'Publication.PubMed_ID', + 'Publication.Abstract', + 'Publication.Title', + 'Publication.Authors', + 'PublishXRef.Id') + + def run(self): + #Todo: Zach will figure out exactly what both these lines mean + #and comment here + if "'" not in self.search_term: + search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + + where_clause = [] + for field in self.search_fields: + where_clause.append('''%s REGEXP "%s"''' % (field, search_term)) + + where_clause = "(%s)" % ' OR '.join(where_clause) + + #Get group information for dataset + self.dataset.get_group() + + print("before query where clause is:", where_clause) + + query = (self.base_query + + """WHERE %s and + PublishXRef.InbredSetId = %s and + PublishXRef.PhenotypeId = Phenotype.Id and + PublishXRef.PublicationId = Publication.Id and + PublishFreeze.Id = %s""" % ( + where_clause, + self.escape(self.dataset.group_id), + self.escape(self.dataset.id))) + + + + return self.execute(query) + + +class GenotypeSearch(DoSearch): + def __init__(self): + pass + +class GoSearch(ProbeSetSearch): + """searches for synapse-associated genes listed in the Gene Ontology.""" + + def run(self): + field = 'GOterm.acc' + go_id = 'GO:' + ('0000000'+self.search_term)[-7:] + + statements = ("""%s.symbol=GOgene_product.symbol and + GOassociation.gene_product_id=GOgene_product.id and + GOterm.id=GOassociation.term_id""" % ( + self.db_conn.escape_string(self.dataset.type))) + + clause_item = " %s = '%s' and %s " % (field, go_id, statements) + + gene_ontology_from_table = """ , db_GeneOntology.term as GOterm, + db_GeneOntology.association as GOassociation, + db_GeneOntology.gene_product as GOgene_product """ + + gene_ontology_from_table = self.normalize_spaces(gene_ontology_from_table) + #gene_ontology_from_table = " ".join(gene_ontology_from_table.splitlines()) + + query = (self.base_query + + """%s + WHERE %s + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.db_conn.escape_string(gene_ontology_from_table), + clause_item, + self.db_conn.escape_string(str(self.dataset.id)))) + + return self.execute(query) + + + +if __name__ == "__main__": + + import MySQLdb + import sys + sys.path.append("/home/zas1024/gene/wqflask") + print("Path is:", sys.path) + + + from base import webqtlConfig + from base.webqtlDataset import webqtlDataset + from base.templatePage import templatePage + from utility import webqtlUtil + from dbFunction import webqtlDatabaseFunction + + db_conn = MySQLdb.Connect(db=webqtlConfig.DB_NAME, + host=webqtlConfig.MYSQL_SERVER, + user=webqtlConfig.DB_USER, + passwd=webqtlConfig.DB_PASSWD) + cursor = db_conn.cursor() + + dataset_name = "HC_M2_0606_P" + dataset = webqtlDataset(dataset_name, cursor) + + #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() + #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() + + results = GoSearch("0045202", dataset, cursor, db_conn).run() + print("results are:", pf(results)) \ No newline at end of file diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 29a497fa..02d2bef2 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -681,15 +681,15 @@ class SearchResultPage(templatePage): print("item is:", pf(search_term)) - clause_item = ( -""" MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) +# clause_item = ( +#""" MATCH (ProbeSet.Name, +# ProbeSet.description, +# ProbeSet.symbol, +# alias, +# GenbankId, +# UniGeneId, +# Probe_Target_Description) +# AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) if self.dataset.type == "ProbeSet": query = ( @@ -702,11 +702,17 @@ class SearchResultPage(templatePage): ProbeSet.Symbol as TSYMBOL, ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, ProbeSet - WHERE %s + WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %s """ % (self.db_conn.escape_string(search_term), - self.db_conn.escape_string(clause_item), self.db_conn.escape_string(str(self.dataset.id)))) elif self.dataset.type == "Publish": @@ -719,13 +725,21 @@ class SearchResultPage(templatePage): Publication.PubMed_ID as Publication_PubMed_ID, Phenotype.Post_publication_description as Phenotype_Name FROM %s PublishFreeze, Publication, PublishXRef, Phenotype - WHERE PublishXRef.InbredSetId = %s and %s and + WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) and + PublishXRef.InbredSetId = %s and PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %s """ % (include_geno, + self.db_conn.escape_string(search_term), self.db_conn.escape_string(str(self.dataset.group_id)), - self.db_conn.escape_string(clause_item), self.db_conn.escape_string(str(self.dataset.id)))) elif self.dataset.type == "Geno": @@ -736,10 +750,18 @@ class SearchResultPage(templatePage): Geno.chr_num as Geno_chr_num, Geno.Mb as Geno_Mb FROM GenoXRef, GenoFreeze, Geno - WHERE %s and Geno.Id = GenoXRef.GenoId and + WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) and + and Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and GenoFreeze.Id = %d - """% (self.db_conn.escape_string(clause_item), + """% (self.db_conn.escape_string(search_term), self.db_conn.escape_string(str(self.dataset.id)))) -- cgit v1.2.3 From c0097b0021b0bff5b42658a279043a16bb4e9ad9 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 1 Nov 2012 17:29:21 -0500 Subject: Began integrating do_search.py's DoSearch object into search_results.py, with simple searches returning correct results Still need to make results display in the table Sam also did some work with the bootstrap styling --- misc/notes.txt | 2 +- wqflask/wqflask/do_search.py | 140 +++++++--- wqflask/wqflask/search_results.py | 306 +++++++++++----------- wqflask/wqflask/templates/base.html | 13 +- wqflask/wqflask/templates/index_page.html | 8 +- wqflask/wqflask/templates/search_result_page.html | 27 +- wqflask/wqflask/templates/show_trait.html | 32 +-- 7 files changed, 281 insertions(+), 247 deletions(-) diff --git a/misc/notes.txt b/misc/notes.txt index e7b94087..b3678a04 100644 --- a/misc/notes.txt +++ b/misc/notes.txt @@ -41,7 +41,7 @@ Go to /tmp and tail -f flask_gn_log Coffeescript Stuff: coffee -c (filename) -coffee -c -w (to watch for changes and recompile) +coffee -c -w . (to watch for changes and recompile in current directory; the "." is for current directory) coffee --help (for information about setting options) =========================================== diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index cfa73334..19c6fa74 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -7,31 +7,35 @@ from pprint import pformat as pf class DoSearch(object): + """Parent class containing parameters/functions used for all searches""" + def __init__(self, search_term, dataset, cursor, db_conn): self.search_term = search_term self.dataset = dataset self.db_conn = db_conn self.cursor = cursor - + def execute(self, query): + """Executes query and returns results""" query = self.normalize_spaces(query) - print("query is:", pf(query)) + print("in do_search query is:", pf(query)) self.cursor.execute(query) results = self.cursor.fetchall() return results - + def escape(self, stringy): """Shorter name than self.db_conn.escape_string""" return self.db_conn.escape_string(str(stringy)) - + def normalize_spaces(self, stringy): - """Strips out newlines extra spaces and replaces them with just spaces""" + """Strips out newlines extra spaces and replaces them with just spaces""" step_one = " ".join(stringy.split()) return step_one - - + class ProbeSetSearch(DoSearch): + """A search within an mRNA expression dataset""" + base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -42,9 +46,11 @@ class ProbeSetSearch(DoSearch): ProbeSet.Symbol as TSYMBOL, ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, ProbeSet """ - + def run(self): + """Generates and runs a simple search of an mRNA expression dataset""" + print("Running ProbeSetSearch") query = (self.base_query + """WHERE (MATCH (ProbeSet.Name, ProbeSet.description, @@ -57,18 +63,22 @@ class ProbeSetSearch(DoSearch): and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %s """ % (self.escape(self.search_term), - self.escape(dataset.id))) - + self.escape(self.dataset.id))) + + print("final query is:", pf(query)) + return self.execute(query) class PhenotypeSearch(DoSearch): + """A search within a phenotype dataset""" + base_query = """SELECT PublishXRef.Id, PublishFreeze.createtime as thistable, Publication.PubMed_ID as Publication_PubMed_ID, Phenotype.Post_publication_description as Phenotype_Name FROM Phenotype, PublishFreeze, Publication, PublishXRef """ - + search_fields = ('Phenotype.Post_publication_description', 'Phenotype.Pre_publication_description', 'Phenotype.Pre_publication_abbreviation', @@ -78,65 +88,108 @@ class PhenotypeSearch(DoSearch): 'Publication.Abstract', 'Publication.Title', 'Publication.Authors', - 'PublishXRef.Id') - - def run(self): + 'PublishXRef.Id') + + def get_where_clause(self): + """Generate clause for WHERE portion of query""" + #Todo: Zach will figure out exactly what both these lines mean #and comment here if "'" not in self.search_term: search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + # This adds a clause to the query that matches the search term + # against each field in the search_fields tuple where_clause = [] for field in self.search_fields: where_clause.append('''%s REGEXP "%s"''' % (field, search_term)) - where_clause = "(%s)" % ' OR '.join(where_clause) + return where_clause + + def run(self): + """Generates and runs a simple search of a phenotype dataset""" + #Get group information for dataset self.dataset.get_group() - - print("before query where clause is:", where_clause) - + query = (self.base_query + """WHERE %s and PublishXRef.InbredSetId = %s and PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %s""" % ( - where_clause, + self.get_where_clause(), self.escape(self.dataset.group_id), self.escape(self.dataset.id))) + return self.execute(query) +class GenotypeSearch(DoSearch): + """A search within a genotype dataset""" + + base_query = """SELECT Geno.Name, + GenoFreeze.createtime as thistable, + Geno.Name as Geno_Name, + Geno.Source2 as Geno_Source2, + Geno.chr_num as Geno_chr_num, + Geno.Mb as Geno_Mb + FROM GenoXRef, GenoFreeze, Geno """ + + search_fields = ('Name', 'Chr') + + def get_where_clause(self): + """Generate clause for WHERE portion of query""" + + # This adds a clause to the query that matches the search term + # against each field in search_fields (above) + where_clause = [] + for field in self.search_fields: + where_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % (self.dataset.type, field), + self.search_term)) + where_clause = "(%s)" % ' OR '.join(where_clause) + + return where_clause + + def run(self): + """Generates and runs a simple search of a genotype dataset""" + #Todo: Zach will figure out exactly what both these lines mean + #and comment here + if "'" not in self.search_term: + search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + + query = (self.base_query + + """WHERE %s and + Geno.Id = GenoXRef.GenoId and + GenoXRef.GenoFreezeId = GenoFreeze.Id and + GenoFreeze.Id = %s"""% ( + self.get_where_clause(), + self.escape(self.dataset.id))) + return self.execute(query) - -class GenotypeSearch(DoSearch): - def __init__(self): - pass - class GoSearch(ProbeSetSearch): - """searches for synapse-associated genes listed in the Gene Ontology.""" - + """Searches for synapse-associated genes listed in the Gene Ontology.""" + def run(self): field = 'GOterm.acc' go_id = 'GO:' + ('0000000'+self.search_term)[-7:] - + statements = ("""%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id""" % ( self.db_conn.escape_string(self.dataset.type))) - + clause_item = " %s = '%s' and %s " % (field, go_id, statements) - + + # gene_ontology_from_table = """ , db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product """ - + gene_ontology_from_table = self.normalize_spaces(gene_ontology_from_table) - #gene_ontology_from_table = " ".join(gene_ontology_from_table.splitlines()) - + query = (self.base_query + """%s WHERE %s @@ -145,36 +198,37 @@ class GoSearch(ProbeSetSearch): """ % (self.db_conn.escape_string(gene_ontology_from_table), clause_item, self.db_conn.escape_string(str(self.dataset.id)))) - + return self.execute(query) - if __name__ == "__main__": - + ### Usually this will be used as a library, but call it from the command line for testing + ### And it runs the code below + import MySQLdb import sys sys.path.append("/home/zas1024/gene/wqflask") print("Path is:", sys.path) - - + + from base import webqtlConfig from base.webqtlDataset import webqtlDataset from base.templatePage import templatePage from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction - + db_conn = MySQLdb.Connect(db=webqtlConfig.DB_NAME, host=webqtlConfig.MYSQL_SERVER, user=webqtlConfig.DB_USER, passwd=webqtlConfig.DB_PASSWD) cursor = db_conn.cursor() - + dataset_name = "HC_M2_0606_P" dataset = webqtlDataset(dataset_name, cursor) - - #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() + + results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() - - results = GoSearch("0045202", dataset, cursor, db_conn).run() + #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() + #results = GoSearch("0045202", dataset, cursor, db_conn).run() print("results are:", pf(results)) \ No newline at end of file diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 02d2bef2..51204ddf 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -33,14 +33,12 @@ from base.webqtlDataset import webqtlDataset from base.webqtlTrait import webqtlTrait from base.templatePage import templatePage from wqflask import parser +from wqflask import do_search from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction from utility import formatting -import sys - - #from base.JinjaPage import JinjaEnv, JinjaPage @@ -194,7 +192,7 @@ class SearchResultPage(templatePage): self.search_fields = ['Name','Chr'] - self.do_search() + self.search() self.gen_search_result() ########################################### @@ -635,167 +633,167 @@ class SearchResultPage(templatePage): return 0 - def do_search(self): + def search(self): print("fd.search_terms:", self.fd['search_terms']) self.search_terms = parser.parse(self.fd['search_terms']) print("After parsing:", self.search_terms) - - - #print("ORkeyword is:", pf(self.ORkeyword)) - #self.ANDkeyword2 = parser.parse(self.ANDkeyword) - #self.ORkeyword2 = parser.parse(self.ORkeyword) - #print("ORkeyword2 is:", pf(parser.parse(self.ORkeyword))) - - #self.ANDkeyword2 = re.sub(self._1mPattern, '', self.ANDkeyword) - #self.ANDkeyword2 = re.sub(self._2mPattern, '', self.ANDkeyword2) - #self.ANDkeyword2 = re.sub(self._3mPattern, '', self.ANDkeyword2) - #self.ANDkeyword2 = re.sub(self._5mPattern, '', self.ANDkeyword2) - ###remove remain parethesis, could be input with syntax error - #self.ANDkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ANDkeyword2) - #self.ANDkeyword2 = self.encregexp(self.ANDkeyword2) - - #self.ORkeyword2 = re.sub(self._1mPattern, '', self.ORkeyword) - #self.ORkeyword2 = re.sub(self._2mPattern, '', self.ORkeyword2) - #self.ORkeyword2 = re.sub(self._3mPattern, '', self.ORkeyword2) - #self.ORkeyword2 = re.sub(self._5mPattern, '', self.ORkeyword2) - ###remove remain parethesis, could be input with syntax error - #self.ORkeyword2 = re.sub(re.compile('\s*\([\s\S]*\)'), '', self.ORkeyword2) - #self.ORkeyword2 = self.encregexp(self.ORkeyword2) self.results = [] - for item in self.search_terms: - search_term = item['search_term'] - # self.nkeywords += 1 - # #ZS: If there are both AND and OR keywords, just use the OR keywords - # if k >=len(self.ORkeyword2): - # query = self.ANDQuery - # DescriptionText = self.ANDDescriptionText - # clausejoin = ' OR ' - # fulltext = ANDFulltext - # else: - # query = self.ORQuery - # DescriptionText = self.ORDescriptionText - # clausejoin = ' OR ' - # fulltext = ORFulltext - - print("item is:", pf(search_term)) - - -# clause_item = ( -#""" MATCH (ProbeSet.Name, + for a_search in self.search_terms: + print("[kodak] item is:", pf(a_search)) + search_term = None + search_type = None + if "search_term" in a_search: + search_term = a_search['search_term'] + elif key in a_search: + search_type = a_search['key'] + + + if search_term: + if self.dataset.type == "ProbeSet": + search_ob = "ProbeSetSearch" + elif self.dataset.type == "Publish": + search_ob = "PhenotypeSearch" + elif self.dataset.type == "Geno": + search_ob = "GenotypeSearch" + else: + SearchTermNeedsToBeDefined # Cause an error on purpose + search_class = getattr(do_search, search_ob) + results = search_class(search_term, + self.dataset, + self.cursor, + self.db_conn).run() + + print("in the search results are:", results) +# +# +## clause_item = ( +##""" MATCH (ProbeSet.Name, +## ProbeSet.description, +## ProbeSet.symbol, +## alias, +## GenbankId, +## UniGeneId, +## Probe_Target_Description) +## AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) +# if self.dataset.type == "ProbeSet": +# +# query = ( +#"""SELECT distinct 0, +# ProbeSet.Name as TNAME, +# 0 as thistable, +# ProbeSetXRef.Mean as TMEAN, +# ProbeSetXRef.LRS as TLRS, +# ProbeSetXRef.PVALUE as TPVALUE, +# ProbeSet.Chr_num as TCHR_NUM, +# ProbeSet.Mb as TMB, +# ProbeSet.Symbol as TSYMBOL, +# ProbeSet.name_num as TNAME_NUM +# FROM ProbeSetXRef, ProbeSet +# WHERE (MATCH (ProbeSet.Name, # ProbeSet.description, # ProbeSet.symbol, # alias, # GenbankId, # UniGeneId, # Probe_Target_Description) -# AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) - if self.dataset.type == "ProbeSet": - - query = ( -"""SELECT distinct 0, ProbeSet.Name as TNAME, 0 as thistable, - ProbeSetXRef.Mean as TMEAN, - ProbeSetXRef.LRS as TLRS, - ProbeSetXRef.PVALUE as TPVALUE, - ProbeSet.Chr_num as TCHR_NUM, - ProbeSet.Mb as TMB, - ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM - FROM ProbeSetXRef, ProbeSet - WHERE (MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.db_conn.escape_string(search_term), - self.db_conn.escape_string(str(self.dataset.id)))) - - elif self.dataset.type == "Publish": - include_geno = "" - if search_term.find("Geno.name") >= 0: - include_geno = " Geno, " - - query = ( -"""SELECT 0, PublishXRef.Id, PublishFreeze.createtime as thistable, - Publication.PubMed_ID as Publication_PubMed_ID, - Phenotype.Post_publication_description as Phenotype_Name - FROM %s PublishFreeze, Publication, PublishXRef, Phenotype - WHERE (MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) and - PublishXRef.InbredSetId = %s and - PublishXRef.PhenotypeId = Phenotype.Id and - PublishXRef.PublicationId = Publication.Id and - PublishFreeze.Id = %s - """ % (include_geno, - self.db_conn.escape_string(search_term), - self.db_conn.escape_string(str(self.dataset.group_id)), - self.db_conn.escape_string(str(self.dataset.id)))) - - elif self.dataset.type == "Geno": - query = ( -"""SELECT 0, Geno.Name, GenoFreeze.createtime as thistable, - Geno.Name as Geno_Name, - Geno.Source2 as Geno_Source2, - Geno.chr_num as Geno_chr_num, - Geno.Mb as Geno_Mb - FROM GenoXRef, GenoFreeze, Geno - WHERE (MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) and - and Geno.Id = GenoXRef.GenoId and - GenoXRef.GenoFreezeId = GenoFreeze.Id and - GenoFreeze.Id = %d - """% (self.db_conn.escape_string(search_term), - self.db_conn.escape_string(str(self.dataset.id)))) - - - self.cursor.execute(query) - self.results.append(self.cursor.fetchall()) - - print("self.results is:", pf(self.results)) - - - - - #if self.dataset.type == "ProbeSet" and search_term.find('.') < 0 and search_term.find('\'') < 0: - # full_text.append(search_term) - #else: - # if self.matchwhole and search_term.find("'") < 0: - # search_term = "[[:<:]]"+ search_term+"[[:>:]]" - # clause2 = [] - # for field in self.search_fields: - # if self.dataset.type == "Publish": - # clause2.append("%s REGEXP \"%s\"" % (field,search_term)) - # else: - # clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dataset.type,field),search_term)) - # clause_item = "(%s)" % string.join(clause2, clausejoin) - # query.append(" (%s) " % clause_item) - #if ANDFulltext: - # clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, - # alias,GenbankId, UniGeneId, Probe_Target_Description) - # AGAINST ('+%s' IN BOOLEAN MODE) """ % string.join(ANDFulltext, " +") - # self.ANDQuery.append(" (%s) " % clauseItem) - #if ORFulltext: - #clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias, - #GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) - #""" % string.join(full_text, " ") - #self.query.append(" (%s) " % clauseItem) +# AGAINST ('%s' IN BOOLEAN MODE)) +# and ProbeSet.Id = ProbeSetXRef.ProbeSetId +# and ProbeSetXRef.ProbeSetFreezeId = %s +# """ % (self.db_conn.escape_string(search_term), +# self.db_conn.escape_string(str(self.dataset.id)))) +# +# elif self.dataset.type == "Publish": +# include_geno = "" +# if search_term.find("Geno.name") >= 0: +# include_geno = " Geno, " +# +# if self.matchwhole and item.find("'") < 0: +# item = "[[:<:]]"+ item+"[[:>:]]" +# clause2 = [] +# for field in self.searchField: +# if self.dbType == "Publish": +# clause2.append("%s REGEXP \"%s\"" % (field,item)) +# else: +# clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dbType,field),item)) +# +# +# query = ( +#"""SELECT 0, PublishXRef.Id, PublishFreeze.createtime as thistable, +# Publication.PubMed_ID as Publication_PubMed_ID, +# Phenotype.Post_publication_description as Phenotype_Name +# FROM %s PublishFreeze, Publication, PublishXRef, Phenotype +# WHERE (MATCH (ProbeSet.Name, +# ProbeSet.description, +# ProbeSet.symbol, +# alias, +# GenbankId, +# UniGeneId, +# Probe_Target_Description) +# AGAINST ('%s' IN BOOLEAN MODE)) and +# PublishXRef.InbredSetId = %s and +# PublishXRef.PhenotypeId = Phenotype.Id and +# PublishXRef.PublicationId = Publication.Id and +# PublishFreeze.Id = %s +# """ % (include_geno, +# self.db_conn.escape_string(search_term), +# self.db_conn.escape_string(str(self.dataset.group_id)), +# self.db_conn.escape_string(str(self.dataset.id)))) +# +# elif self.dataset.type == "Geno": +# query = ( +#"""SELECT 0, Geno.Name, GenoFreeze.createtime as thistable, +# Geno.Name as Geno_Name, +# Geno.Source2 as Geno_Source2, +# Geno.chr_num as Geno_chr_num, +# Geno.Mb as Geno_Mb +# FROM GenoXRef, GenoFreeze, Geno +# WHERE (MATCH (ProbeSet.Name, +# ProbeSet.description, +# ProbeSet.symbol, +# alias, +# GenbankId, +# UniGeneId, +# Probe_Target_Description) +# AGAINST ('%s' IN BOOLEAN MODE)) and +# and Geno.Id = GenoXRef.GenoId and +# GenoXRef.GenoFreezeId = GenoFreeze.Id and +# GenoFreeze.Id = %d +# """% (self.db_conn.escape_string(search_term), +# self.db_conn.escape_string(str(self.dataset.id)))) +# +# +# self.cursor.execute(query) +# self.results.append(self.cursor.fetchall()) +# +# print("self.results is:", pf(self.results)) +# +# +# +# +# #if self.dataset.type == "ProbeSet" and search_term.find('.') < 0 and search_term.find('\'') < 0: +# # full_text.append(search_term) +# #else: +# # if self.matchwhole and search_term.find("'") < 0: +# # search_term = "[[:<:]]"+ search_term+"[[:>:]]" +# # clause2 = [] +# # for field in self.search_fields: +# # if self.dataset.type == "Publish": +# # clause2.append("%s REGEXP \"%s\"" % (field,search_term)) +# # else: +# # clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dataset.type,field),search_term)) +# # clause_item = "(%s)" % string.join(clause2, clausejoin) +# # query.append(" (%s) " % clause_item) +# #if ANDFulltext: +# # clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, +# # alias,GenbankId, UniGeneId, Probe_Target_Description) +# # AGAINST ('+%s' IN BOOLEAN MODE) """ % string.join(ANDFulltext, " +") +# # self.ANDQuery.append(" (%s) " % clauseItem) +# #if ORFulltext: +# #clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias, +# #GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) +# #""" % string.join(full_text, " ") +# #self.query.append(" (%s) " % clauseItem) def encregexp(self,str): diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 385512e3..b54d3424 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -1,7 +1,7 @@ - + GeneNetwork @@ -67,9 +67,9 @@ - + {% block content %}{% endblock %} - +
      @@ -146,11 +146,10 @@ } }) - - - - + + {% block js %} + {% endblock %} diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index 2d7ba44c..a113bc15 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {% block title %}GeneNetwork{% endblock %} -{% block content %} +{% block content %} @@ -275,4 +275,8 @@ -{%endblock%} \ No newline at end of file +{%endblock%} + +{% block js %} + +{% endblock %} diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index abf2dba7..65182e1f 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -15,9 +15,9 @@ - +

      We searched {{ dataset.fullname }} - +

      To find all records that match:

        {% if search_terms %} @@ -28,10 +28,10 @@ {% endif %}
      - +

      To study a record, click on its ID below.
      Check records below and click Add button to add to selection.

      - +
      @@ -40,7 +40,7 @@ {% endfor %} - + {% for this_trait in trait_list %} @@ -56,12 +56,7 @@ {{ this_trait.name.upper() }} - + @@ -70,20 +65,20 @@ {% endfor %} - +
      {{header}}
      - - {{ this_trait.symbol }} - - {{ this_trait.symbol }} {{ this_trait.description_display }} {{ this_trait.trait_location_repr }} {{ this_trait.mean }}
      - +
      - +
      - + - + {% endblock %} diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index d7b81562..79f6e78e 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -106,14 +106,6 @@


      -
      @@ -669,13 +661,7 @@

        Mapping Tools

      -

      +

      @@ -1055,7 +1041,7 @@

        Review and Edit Data

      -
      +

      @@ -1230,6 +1216,12 @@ + + + +{% endblock %} + +{% block js %} @@ -1240,13 +1232,5 @@ - - - - - - - - {% endblock %} -- cgit v1.2.3 From 63faa277e4bf484f42e96e5064fbe6e31dfb331b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 1 Nov 2012 17:35:21 -0500 Subject: Changed the if/elif statements for the different dataset types to use a dictionary instead --- wqflask/wqflask/search_results.py | 22 ++++++++++++++-------- wqflask/wqflask/templates/base.html | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 51204ddf..c82f16c1 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -650,12 +650,19 @@ class SearchResultPage(templatePage): if search_term: - if self.dataset.type == "ProbeSet": - search_ob = "ProbeSetSearch" - elif self.dataset.type == "Publish": - search_ob = "PhenotypeSearch" - elif self.dataset.type == "Geno": - search_ob = "GenotypeSearch" + searches = dict( + ProbeSet = "ProbeSetSearch", + Publish = "PhenotypeSearch", + Geno = "GenotypeSearch", + ) + if self.dataset.type in searches: + search_ob = searches[self.dataset.type] + #if self.dataset.type == "ProbeSet": + # search_ob = "ProbeSetSearch" + #elif self.dataset.type == "Publish": + # search_ob = "PhenotypeSearch" + #elif self.dataset.type == "Geno": + # search_ob = "GenotypeSearch" else: SearchTermNeedsToBeDefined # Cause an error on purpose search_class = getattr(do_search, search_ob) @@ -665,8 +672,7 @@ class SearchResultPage(templatePage): self.db_conn).run() print("in the search results are:", results) -# -# + ## clause_item = ( ##""" MATCH (ProbeSet.Name, ## ProbeSet.description, diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index b54d3424..21b93004 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -148,7 +148,7 @@ - + {% block js %} {% endblock %} -- cgit v1.2.3 From 65a6a9c5f21d42fa43d13823be632760abbc4891 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 2 Nov 2012 18:11:55 -0500 Subject: Created search objects for GeneRIF and GeneWiki searches Got search results to display Refactored the template for show_trait page --- web/webqtl/base/webqtlTrait.py | 9 + wqflask/wqflask/do_search.py | 89 +- wqflask/wqflask/parser.py | 7 +- wqflask/wqflask/search_results.py | 966 +------ .../new/javascript/dataset_menu_structure.json | 2904 ++++++++++++++++++++ wqflask/wqflask/templates/show_trait.html | 1218 +------- .../show_trait_calculate_correlations.html | 130 + wqflask/wqflask/templates/show_trait_details.html | 63 + .../wqflask/templates/show_trait_edit_data.html | 163 ++ .../templates/show_trait_mapping_tools.html | 382 +++ .../wqflask/templates/show_trait_statistics.html | 433 +++ 11 files changed, 4249 insertions(+), 2115 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/dataset_menu_structure.json create mode 100644 wqflask/wqflask/templates/show_trait_calculate_correlations.html create mode 100644 wqflask/wqflask/templates/show_trait_details.html create mode 100644 wqflask/wqflask/templates/show_trait_edit_data.html create mode 100644 wqflask/wqflask/templates/show_trait_mapping_tools.html create mode 100644 wqflask/wqflask/templates/show_trait_statistics.html diff --git a/web/webqtl/base/webqtlTrait.py b/web/webqtl/base/webqtlTrait.py index f5051e45..2469504f 100644 --- a/web/webqtl/base/webqtlTrait.py +++ b/web/webqtl/base/webqtlTrait.py @@ -9,6 +9,10 @@ from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil +from __future__ import print_function, division + +from pprint import pformat as pf + class webqtlTrait: """ Trait class defines a trait in webqtl, can be either Microarray, @@ -215,6 +219,9 @@ class webqtlTrait: def retrieveData(self, strainlist=[]): assert self.db and self.cursor + debug_file = open("/home/zas1024/gn/web/traitlist_debug.txt", "w") + debug_file.write("strianlist is:" + strainlist + "\n") + if self.db.type == 'Temp': query = ''' SELECT @@ -341,6 +348,8 @@ class webqtlTrait: #end if else: pass + + debug_file.write("self.data is:", pf(self.data) + "\n") def keys(self): return self.__dict__.keys() diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 19c6fa74..2641431c 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -9,6 +9,9 @@ from pprint import pformat as pf class DoSearch(object): """Parent class containing parameters/functions used for all searches""" + # Used to translate search phrases into classes + search_types = dict() + def __init__(self, search_term, dataset, cursor, db_conn): self.search_term = search_term self.dataset = dataset @@ -28,14 +31,20 @@ class DoSearch(object): return self.db_conn.escape_string(str(stringy)) def normalize_spaces(self, stringy): - """Strips out newlines extra spaces and replaces them with just spaces""" + """Strips out newlines/extra spaces and replaces them with just spaces""" step_one = " ".join(stringy.split()) return step_one + + @classmethod + def get_search(cls, search_type): + return cls.search_types[search_type] class ProbeSetSearch(DoSearch): """A search within an mRNA expression dataset""" + DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" + base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -47,6 +56,24 @@ class ProbeSetSearch(DoSearch): ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, ProbeSet """ + def compile_final_query(self, from_clause, where_clause): + """Generates the final query string""" + + from_clause = self.normalize_spaces(from_clause) + + query = (self.base_query + + """%s + WHERE %s + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(from_clause), + where_clause, + self.escape(self.dataset.id))) + + print("query is:", pf(query)) + + return query + def run(self): """Generates and runs a simple search of an mRNA expression dataset""" @@ -73,6 +100,8 @@ class ProbeSetSearch(DoSearch): class PhenotypeSearch(DoSearch): """A search within a phenotype dataset""" + DoSearch.search_types['Publish'] = "PhenotypeSearch" + base_query = """SELECT PublishXRef.Id, PublishFreeze.createtime as thistable, Publication.PubMed_ID as Publication_PubMed_ID, @@ -128,6 +157,8 @@ class PhenotypeSearch(DoSearch): class GenotypeSearch(DoSearch): """A search within a genotype dataset""" + + DoSearch.search_types['Geno'] = "GenotypeSearch" base_query = """SELECT Geno.Name, GenoFreeze.createtime as thistable, @@ -169,9 +200,42 @@ class GenotypeSearch(DoSearch): return self.execute(query) +class RifSearch(ProbeSetSearch): + """Searches for traits with a Gene RIF entry including the search term.""" + + DoSearch.search_types['RIF'] = "RifSearch" + + def run(self): + where_clause = """( %s.symbol = GeneRIF_BASIC.symbol and + MATCH (GeneRIF_BASIC.comment) + AGAINST ('+%s' IN BOOLEAN MODE)) """ % (self.dataset.type, self.search_term) + + from_clause = ", GeneRIF_BASIC " + query = self.compile_final_query(from_clause, where_clause) + + return self.execute(query) + +class WikiSearch(ProbeSetSearch): + """Searches GeneWiki for traits other people have annotated""" + + DoSearch.search_types['WIKI'] = "WikiSearch" + + def run(self): + where_clause = """%s.symbol = GeneRIF.symbol + and GeneRIF.versionId=0 and GeneRIF.display>0 + and (GeneRIF.comment REGEXP '%s' or GeneRIF.initial = '%s') + """ % (self.dataset.type, "[[:<:]]"+self.search_term+"[[:>:]]", self.search_term) + + from_clause = ", GeneRIF " + query = self.compile_final_query(from_clause, where_clause) + + return self.execute(query) + class GoSearch(ProbeSetSearch): """Searches for synapse-associated genes listed in the Gene Ontology.""" + DoSearch.search_types['GO'] = "GoSearch" + def run(self): field = 'GOterm.acc' go_id = 'GO:' + ('0000000'+self.search_term)[-7:] @@ -181,23 +245,13 @@ class GoSearch(ProbeSetSearch): GOterm.id=GOassociation.term_id""" % ( self.db_conn.escape_string(self.dataset.type))) - clause_item = " %s = '%s' and %s " % (field, go_id, statements) + where_clause = " %s = '%s' and %s " % (field, go_id, statements) - # - gene_ontology_from_table = """ , db_GeneOntology.term as GOterm, + from_clause = """ , db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product """ - - gene_ontology_from_table = self.normalize_spaces(gene_ontology_from_table) - - query = (self.base_query + - """%s - WHERE %s - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.db_conn.escape_string(gene_ontology_from_table), - clause_item, - self.db_conn.escape_string(str(self.dataset.id)))) + + query = self.compile_final_query(from_clause, where_clause) return self.execute(query) @@ -227,8 +281,11 @@ if __name__ == "__main__": dataset_name = "HC_M2_0606_P" dataset = webqtlDataset(dataset_name, cursor) - results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() + #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() + #results = RifSearch("diabetes", dataset, cursor, db_conn).run() + results = WikiSearch("nicotine", dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() + print("results are:", pf(results)) \ No newline at end of file diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index e34992a0..e693b2b8 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -4,6 +4,7 @@ import re from pprint import pformat as pf + def parse(pstring): pstring = re.split(r"""(?:(\w+\s*=\s*\([^)]*\))|(\w+\s*[=:]\w+)|(\w+))""", pstring) pstring = [item.strip() for item in pstring if item and item.strip()] @@ -28,9 +29,11 @@ def parse(pstring): value = [value.strip() for value in values if value.strip()] term = dict(key=key, seperator=seperator, - value=value) + search_term=value) else: - term = dict(search_term = item) + term = dict(key=None, + seperator=None, + search_term = item) items.append(term) print(pf(items)) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index c82f16c1..a97ea8fd 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -42,7 +42,6 @@ from utility import formatting #from base.JinjaPage import JinjaEnv, JinjaPage - class SearchResultPage(templatePage): maxReturn = 3000 @@ -144,20 +143,6 @@ class SearchResultPage(templatePage): self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) - ########################################### - # make sure search from same type of datasets - ########################################### - #dbTypes = map(lambda X: X.type, self.dataset) - #db_types = [table.type for table in self.dataset] - #self.db_type = db_types[0] - #for item in dbTypes: - # if item != self.dbType: - # heading = "Search Result" - # detail = ["Search can only be performed among the same type of datasets"] - # self.error(heading=heading,detail=detail,error="Error") - # return - - #self.db_type = self.dataset.type if self.dataset.type == "Publish": self.search_fields = ['Phenotype.Post_publication_description', @@ -191,273 +176,61 @@ class SearchResultPage(templatePage): elif self.dataset.type == "Geno": self.search_fields = ['Name','Chr'] - self.search() self.gen_search_result() - ########################################### - # Search Options - ########################################### - #self.matchwhole = fd['matchwhole'] - #split result into pages - #self.pageNumber = fd.get('pageno', 0) - # - #try: - # self.pageNumber = int(self.pageNumber) - #except Exception as why: - # print(why) - # self.pageNumber = 0 - - - ########################################### - # Generate Mysql Query - ########################################### - - # Sam: We presume lines below aren't used... - #geneIdListQuery = fd.get('geneId', '') - #if geneIdListQuery: - # geneIdListQuery = string.replace(geneIdListQuery, ",", " ") - # geneIdListQuery = " geneId=%s" % string.join(string.split(geneIdListQuery), "-") - - #self.ANDkeyword = fd.get('ANDkeyword', "") - #self.ORkeyword = fd.get('ORkeyword', "") - - #self.ORkeyword += geneIdListQuery - - #self.ANDkeyword = self.ANDkeyword.replace("\\", "").strip() - #self.ORkeyword = self.ORkeyword.replace("\\", "").strip() - #user defined sort option - #self.orderByUserInput = fd.get('orderByUserInput', "").strip() - #default sort option if user have not defined - #self.orderByDefalut = "" - - #XZ, Dec/16/2010: I add examples to help understand this block of code. See details in function pattersearch. - # - ##XZ: self._1mPattern examples: WIKI=xxx, RIF=xxx, GO:0045202 - #self._1mPattern = re.compile('\s*(\S+)\s*[:=]\s*([a-zA-Z-\+\d\.]+)\s*') - # - ##XZ: self._2mPattern examples: Mean=(15.0 16.0), Range=(10 100), LRS=(Low_LRS_limit, High_LRS_limit), pvalue=(Low_limit, High_limit), Range=(10 100) - #self._2mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*([-\d\.]+)[, \t]+([-\d\.]+)[, \t]*([-\d\.]*)\s*\)') - # - ##XZ: self._3mPattern examples: Position=(Chr1 98 104), Pos=(Chr1 98 104), Mb=(Chr1 98 104), CisLRS=(Low_LRS_limit, High_LRS_limit, Mb_buffer), TransLRS=(Low_LRS_limit, High_LRS_limit, Mb_buffer) - #self._3mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*[Cc][Hh][Rr]([^, \t]+)[, \t]+([-\d\.]+)[, \t]+([-\d\.]+)\s*\)') - # - ##XZ: self._5mPattern examples: LRS=(Low_LRS_limit, High_LRS_limit, ChrNN, Mb_Low_Limit, Mb_High_Limit) - #self._5mPattern = re.compile('\s*(\S+)\s*[=in]{1,2}\s*\(\s*([-\d\.]+)[, \t]+([-\d\.]+)[, \t]+[Cc][Hh][Rr]([^, \t]+)[, \t]+([-\d\.]+)[, \t]+([-\d\.]+)\s*\)') - - #Error, No keyword input - #if not (self.ORkeyword or self.ANDkeyword): - # heading = "Search Result" - # detail = ["Please make sure to enter either your search terms (genes, traits, markers), or advanced search commands."] - # self.error(heading=heading,detail=detail,error="No search terms were entered") - # return - - #query clauses - #self.ANDQuery = [] - #self.ORQuery = [] - ##descriptions, one for OR search, one for AND search - #self.ANDDescriptionText = [] - #self.ORDescriptionText = [] - - #if not self.normalSearch(): - # return - #if not self.patternSearch(): - # return - #if not self.assembleQuery(): - # return - #self.nresults = self.executeQuery() - # - #if len(self.dataset) > 1: - # dbUrl = "Multiple phenotype datasets" - # dbUrlLink = " were" - #else: - # dbUrl = self.dataset[0].genHTML() - # dbUrlLink = " was" - - #SearchText = HT.Blockquote('GeneNetwork searched the ', dbUrl, ' for all records ') - #if self.ORkeyword2: - # NNN = len(self.ORkeyword2) - # if NNN > 1: - # SearchText.append(' that match the terms ') - # else: - # SearchText.append(' that match the term ') - # for j, term in enumerate(self.ORkeyword2): - # SearchText.append(HT.U(term)) - # if NNN > 1 and j < NNN-2: - # SearchText.append(", ") - # elif j == NNN-2: - # SearchText.append(", or ") - # else: - # pass - #if self.ORDescriptionText: - # if self.ORkeyword2: - # SearchText.append("; ") - # else: - # SearchText.append(" ") - # for j, item in enumerate(self.ORDescriptionText): - # SearchText.append(item) - # if j < len(self.ORDescriptionText) -1: - # SearchText.append(";") - # - #if (self.ORkeyword2 or self.ORDescriptionText) and (self.ANDkeyword2 or self.ANDDescriptionText): - # SearchText.append("; ") - #if self.ANDkeyword2: - # if (self.ORkeyword2 or self.ORDescriptionText): - # SearchText.append(' records') - # NNN = len(self.ANDkeyword2) - # if NNN > 1: - # SearchText.append(' that match the terms ') - # else: - # SearchText.append(' that match the term ') - # for j, term in enumerate(self.ANDkeyword2): - # SearchText.append(HT.U(term)) - # if NNN > 1 and j < NNN-2: - # SearchText.append(", ") - # elif j == NNN-2: - # SearchText.append(", and ") - # else: - # pass - #if self.ANDDescriptionText: - # if self.ANDkeyword2: - # SearchText.append(" and ") - # else: - # SearchText.append(" ") - # for j, item in enumerate(self.ANDDescriptionText): - # SearchText.append(item) - # if j < len(self.ANDDescriptionText) -1: - # SearchText.append(" and ") - # - #SearchText.append(". ") - #if self.nresults == 0: - # heading = "Search Result" - # detail = ["Sorry, GeneNetwork did not find any records matching your request. Please check the syntax or try the ANY rather than the ALL field."] - # self.error(heading=heading,intro = SearchText.contents,detail=detail,error="Not Found") - # return - #elif self.nresults == 1: - # SearchText.append(HT.P(), 'GeneNetwork found one record that matches your request. To study this record, click on its text below. To add this record to your Selection window, use the checkbox and then click the ', HT.Strong('Add to Collection'),' button. ') - #elif self.nresults >= 1 and self.nresults <= self.maxReturn: - # SearchText.append(HT.P(), 'GeneNetwork found a total of ', HT.Span(self.nresults, Class='fwb cr'), ' records. To study any one of these records, click on its ID below. To add one or more records to your Selection window, use the checkbox and then click the ' , HT.Strong('Add to Collection'),' button. ') - #else: - # SearchText.append(' A total of ',HT.Span(self.nresults, Class='fwb cr'), ' records were found.') - # heading = "Search Result" - # # Modified by Hongqiang Li - # # detail = ["The terms you entered match %d records. Please modify your search to generate %d or fewer matches, or review " % (self.nresults, self.maxReturn), HT.Href(text='Search Help', target='_blank', url='http://web2qtl.utmem.edu/searchHelp.html', Class='fs14'), " to learn more about syntax and the use of wildcard characters."] - # detail = ["The terms you entered match %d records. Please modify your search to generate %d or fewer matches, or review " % (self.nresults, self.maxReturn), HT.Href(text='Search Help', target='_blank', url='%s/searchHelp.html' % webqtlConfig.PORTADDR, Class='fs14'), " to learn more about syntax and the use of wildcard characters."] - # # - # self.error(heading=heading,intro = SearchText.contents,detail=detail,error="Over %d" % self.maxReturn) - # return - - - #TD_LR.append(HT.Paragraph('Search Results', Class="title"), SearchText) - - #self.dict['body'] = str(TD_LR) - #self.dict['js1'] = '' - #self.dict['js2'] = 'onLoad="pageOffset()"' - #self.dict['layer'] = self.generateWarningLayer() - def gen_search_result(self): - #pageTable = HT.TableLite(cellSpacing=2,cellPadding=0,width="100%",border=0) - - #last_result = False - self.trait_list = [] # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term - for result_set in self.results: - for result in result_set: - if not result: - continue - #last_result = False - - seq = 1 - group = self.dataset.group - self.form_name = form_name = 'show_dataset_'+group - - tblobj = {} - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) - - #### Excel file - - # Todo: Replace this with official Python temp file naming functions? - filename= webqtlUtil.genRandStr("Search_") - #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') - # Create a new Excel workbook - #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) - #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") - - #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. - #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) - newrow = 7 - - #### Excel file stuff stops - - if self.dataset.type == "ProbeSet": - #for item in result: - print("foo locals are:", locals()) - probe_set_id = result[1] - print("probe_set_id is:", pf(probe_set_id)) - this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) - this_trait.retrieveInfo(QTL=True) - print("this_trait is:", pf(this_trait)) - self.trait_list.append(this_trait) - print("self.trait_list is:", pf(self.trait_list)) - - #tblobj['header'] = self.getTableHeaderForProbeSet(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - - #newrow += 1 - - sortby = self.getSortByValue(datasetType="ProbeSet") - - tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) - - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() - - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - - #pageTable.append(HT.TR(HT.TD(div))) - elif self.dataset.type == "Publish": - #tblobj['header'] = self.getTableHeaderForPublish(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - - #newrow += 1 - - sortby = self.getSortByValue(datasetType="Publish") - - #tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) - - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() - - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - - #pageTable.append(HT.TR(HT.TD(div))) - elif self.dataset.type == "Geno": - tblobj['header'] = self.getTableHeaderForGeno(worksheet=worksheet, newrow=newrow, headingStyle=headingStyle) - - newrow += 1 - sortby = self.getSortByValue(datasetType="Geno") - - #tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) - - #workbook.close() - #objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - #cPickle.dump(tblobj, objfile) - #objfile.close() - - #div = HT.Div(webqtlUtil.genTableObj(tblobj, filename, sortby), Id="sortable") - # - #pageTable.append(HT.TR(HT.TD(div))) - - - #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) - hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} - hddn['incparentsf1']='ON' + print("self.results is:", pf(self.results)) + for result in self.results: + if not result: + continue + + seq = 1 + group = self.dataset.group + self.form_name = form_name = 'show_dataset_'+group + + tblobj = {} + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) + + #### Excel file + + # Todo: Replace this with official Python temp file naming functions? + filename= webqtlUtil.genRandStr("Search_") + #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') + # Create a new Excel workbook + #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) + #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") + + #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. + #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) + newrow = 7 + + #### Excel file stuff stops + + if self.dataset.type == "ProbeSet": + #for item in result: + print("foo locals are:", locals()) + probe_set_id = result[0] + print("probe_set_id is:", pf(probe_set_id)) + this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) + this_trait.retrieveInfo(QTL=True) + print("this_trait is:", pf(this_trait)) + self.trait_list.append(this_trait) + elif self.dataset.type == "Publish": + newrow += 1 + tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + elif self.dataset.type == "Geno": + newrow += 1 + tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) + + #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} + hddn['incparentsf1']='ON' # for key in hddn.keys(): # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) # @@ -468,169 +241,13 @@ class SearchResultPage(templatePage): # last_result = True #if last_result: # TD_LR.contents.pop() - - def executeQuery(self): - - ##construct sorting - if self.dbType == "Publish": - sortQuery = " order by Publication_PubMed_ID desc, Phenotype_Name, thistable" - elif self.dbType == "Geno": - if not self.orderByUserInput: - if self.orderByDefalut: - self.orderByUserInput = self.orderByDefalut - else: - self.orderByUserInput = "POSITION" - if self.orderByUserInput.upper() in ["POS", "POSITION", "MB"]: - self.orderByUserInput = "POSITION" - else: - pass - self.orderByUserInput = self.orderByUserInput.upper() - self.orderByUserInputOrig = self.orderByUserInput[:] - if self.orderByUserInput == "NAME": - sortQuery = " order by Geno_Name, Geno_chr_num, Geno_Mb" - elif self.orderByUserInput == "SOURCE": - sortQuery = " order by Geno_Source2, Geno_chr_num, Geno_Mb" - else: - sortQuery = " order by Geno_chr_num, Geno_Mb" - #ProbeSet - else: - if not self.orderByUserInput: - if self.orderByDefalut: - self.orderByUserInput = self.orderByDefalut - else: - self.orderByUserInput = "POSITION" - - self.orderByUserInput = self.orderByUserInput.upper() - self.orderByUserInputOrig = self.orderByUserInput[:] - #XZ: 8/18/2009: "POSITION-" - if self.orderByUserInput[-1] == '-': - self.orderByUserInput = self.orderByUserInput[:-1] - sortDesc = 'desc' - else: - sortDesc = '' - - if self.orderByUserInput in ["MEAN", "LRS", "PVALUE"]: - #sortQuery = " order by T%s %s, TNAME, thistable desc" % (self.orderByUserInput, sortDesc) - sortQuery = " order by T%s desc, TNAME, thistable desc" % self.orderByUserInput - elif self.orderByUserInput in ["POS", "POSITION", "MB"]: - sortQuery = " order by TCHR_NUM %s, TMB %s, TNAME, thistable desc" % (sortDesc, sortDesc) - elif self.orderByUserInput == 'SYMBOL': - sortQuery = " order by TSYMBOL, thistable desc" - else: - sortQuery = " order by TNAME_NUM, thistable desc" - - if self.singleCross: - if len(self.query) > 1: - searchQuery = map(lambda X:'(%s)' % X, self.query) - searchQuery = string.join(searchQuery, ' UNION ALL ') - else: - searchQuery = self.query[0] - searchQuery += sortQuery - #searchCountQuery retrieve all the results - searchCountQuery = [searchQuery] - #searchQuery = searchQuery + " limit %d,%d" % (self.pageNumber*self.NPerPage, self.NPerPage) // We removed the page limit - Zach 2/22/11 - searchQuery = [searchQuery] - else: - searchCountQuery = searchQuery = map(lambda X: X+sortQuery, self.query) - - allResults = [] - self.results = [] - for item in searchCountQuery: - start_time = datetime.datetime.now() - _log.info("Executing query: %s"%(item)) - self.cursor.execute(item) - allResults.append(self.cursor.fetchall()) - end_time = datetime.datetime.now() - _log.info("Total time: %s"%(end_time-start_time)) - - _log.info("Done executing queries") - - #searchCountQuery retrieve all the results, for counting use only - if searchCountQuery != searchQuery: - for item in searchQuery: - self.cursor.execute(item) - self.results.append(self.cursor.fetchall()) - else: - self.results = allResults - - nresults = reduce(lambda Y,X:len(X)+Y, allResults, 0) - return nresults - - - def assembleQuery(self): - self.query = [] - if self.ANDQuery or self.ORQuery: - clause = self.ORQuery[:] - - for j, database in enumerate(self.dataset): - if self.ANDQuery: - clause.append(" (%s) " % string.join(self.ANDQuery, " AND ")) - - newclause = [] - - for item in clause: - ##need to retrieve additional field which won't be used - ##in the future, for sorting purpose only - if self.dbType == "Publish": - if item.find("Geno.name") < 0: - incGenoTbl = "" - else: - incGenoTbl = " Geno, " - newclause.append("""SELECT %d, PublishXRef.Id, - PublishFreeze.createtime as thistable, - Publication.PubMed_ID as Publication_PubMed_ID, - Phenotype.Post_publication_description as Phenotype_Name - FROM %s PublishFreeze, Publication, PublishXRef, - Phenotype WHERE PublishXRef.InbredSetId = %d and %s and - PublishXRef.PhenotypeId = Phenotype.Id and - PublishXRef.PublicationId = Publication.Id and - PublishFreeze.Id = %d""" % (j, incGenoTbl, - self.dataset_group_ids[j], item, database.id)) - elif self.dbType == "ProbeSet": - if item.find("GOgene") < 0: - incGoTbl = "" - else: - incGoTbl = """ ,db_GeneOntology.term as GOterm, - db_GeneOntology.association as GOassociation, - db_GeneOntology.gene_product as GOgene_product """ - if item.find("Geno.name") < 0: - incGenoTbl = "" - else: - incGenoTbl = " Geno, " - if item.find("GeneRIF_BASIC.") < 0: - incGeneRIFTbl = "" - else: - incGeneRIFTbl = " GeneRIF_BASIC, " - if item.find("GeneRIF.") < 0: - incGeneRIFTbl += "" - else: - incGeneRIFTbl += " GeneRIF, " - newclause.append("""SELECT distinct %d, ProbeSet.Name as TNAME, 0 as thistable, - ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS, ProbeSetXRef.PVALUE as TPVALUE, - ProbeSet.Chr_num as TCHR_NUM, ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM FROM %s%s ProbeSetXRef, ProbeSet %s - WHERE %s and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %d - """ % (j, incGeneRIFTbl, incGenoTbl, incGoTbl, item, database.id)) - elif self.dbType == "Geno": - newclause.append("""SELECT %d, Geno.Name, GenoFreeze.createtime as thistable, - Geno.Name as Geno_Name, Geno.Source2 as Geno_Source2, - Geno.chr_num as Geno_chr_num, Geno.Mb as Geno_Mb FROM - GenoXRef, GenoFreeze, Geno WHERE %s and Geno.Id - = GenoXRef.GenoId and GenoXRef.GenoFreezeId = - GenoFreeze.Id and GenoFreeze.Id = %d""" % ( - j, item, database.id)) - else: - pass - - searchQuery = map(lambda X:'(%s)' % X, newclause) - searchQuery = string.join(searchQuery, ' UNION ') - self.query.append(searchQuery) - return 1 - else: - heading = "Search Result" - detail = ["No keyword was entered for this search, please go back and enter your keyword."] - self.error(heading=heading,detail=detail,error="No Keyword") - return 0 + + if self.dataset.type == "ProbeSet": + tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) + elif self.dataset.type == "Publish": + tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + elif self.dataset.type == "Geno": + tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) def search(self): @@ -641,165 +258,20 @@ class SearchResultPage(templatePage): self.results = [] for a_search in self.search_terms: print("[kodak] item is:", pf(a_search)) - search_term = None - search_type = None - if "search_term" in a_search: - search_term = a_search['search_term'] - elif key in a_search: - search_type = a_search['key'] + search_term = a_search['search_term'] + search_type = a_search['key'] + if not search_type: + # We fall back to the dataset type as the key to get the right object + search_type = self.dataset.type + + search_ob = do_search.DoSearch.get_search(search_type) + search_class = getattr(do_search, search_ob) + self.results.extend(search_class(search_term, + self.dataset, + self.cursor, + self.db_conn).run()) - - if search_term: - searches = dict( - ProbeSet = "ProbeSetSearch", - Publish = "PhenotypeSearch", - Geno = "GenotypeSearch", - ) - if self.dataset.type in searches: - search_ob = searches[self.dataset.type] - #if self.dataset.type == "ProbeSet": - # search_ob = "ProbeSetSearch" - #elif self.dataset.type == "Publish": - # search_ob = "PhenotypeSearch" - #elif self.dataset.type == "Geno": - # search_ob = "GenotypeSearch" - else: - SearchTermNeedsToBeDefined # Cause an error on purpose - search_class = getattr(do_search, search_ob) - results = search_class(search_term, - self.dataset, - self.cursor, - self.db_conn).run() - - print("in the search results are:", results) - -## clause_item = ( -##""" MATCH (ProbeSet.Name, -## ProbeSet.description, -## ProbeSet.symbol, -## alias, -## GenbankId, -## UniGeneId, -## Probe_Target_Description) -## AGAINST ('%s' IN BOOLEAN MODE) """ % self.db_conn.escape_string(search_term)) -# if self.dataset.type == "ProbeSet": -# -# query = ( -#"""SELECT distinct 0, -# ProbeSet.Name as TNAME, -# 0 as thistable, -# ProbeSetXRef.Mean as TMEAN, -# ProbeSetXRef.LRS as TLRS, -# ProbeSetXRef.PVALUE as TPVALUE, -# ProbeSet.Chr_num as TCHR_NUM, -# ProbeSet.Mb as TMB, -# ProbeSet.Symbol as TSYMBOL, -# ProbeSet.name_num as TNAME_NUM -# FROM ProbeSetXRef, ProbeSet -# WHERE (MATCH (ProbeSet.Name, -# ProbeSet.description, -# ProbeSet.symbol, -# alias, -# GenbankId, -# UniGeneId, -# Probe_Target_Description) -# AGAINST ('%s' IN BOOLEAN MODE)) -# and ProbeSet.Id = ProbeSetXRef.ProbeSetId -# and ProbeSetXRef.ProbeSetFreezeId = %s -# """ % (self.db_conn.escape_string(search_term), -# self.db_conn.escape_string(str(self.dataset.id)))) -# -# elif self.dataset.type == "Publish": -# include_geno = "" -# if search_term.find("Geno.name") >= 0: -# include_geno = " Geno, " -# -# if self.matchwhole and item.find("'") < 0: -# item = "[[:<:]]"+ item+"[[:>:]]" -# clause2 = [] -# for field in self.searchField: -# if self.dbType == "Publish": -# clause2.append("%s REGEXP \"%s\"" % (field,item)) -# else: -# clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dbType,field),item)) -# -# -# query = ( -#"""SELECT 0, PublishXRef.Id, PublishFreeze.createtime as thistable, -# Publication.PubMed_ID as Publication_PubMed_ID, -# Phenotype.Post_publication_description as Phenotype_Name -# FROM %s PublishFreeze, Publication, PublishXRef, Phenotype -# WHERE (MATCH (ProbeSet.Name, -# ProbeSet.description, -# ProbeSet.symbol, -# alias, -# GenbankId, -# UniGeneId, -# Probe_Target_Description) -# AGAINST ('%s' IN BOOLEAN MODE)) and -# PublishXRef.InbredSetId = %s and -# PublishXRef.PhenotypeId = Phenotype.Id and -# PublishXRef.PublicationId = Publication.Id and -# PublishFreeze.Id = %s -# """ % (include_geno, -# self.db_conn.escape_string(search_term), -# self.db_conn.escape_string(str(self.dataset.group_id)), -# self.db_conn.escape_string(str(self.dataset.id)))) -# -# elif self.dataset.type == "Geno": -# query = ( -#"""SELECT 0, Geno.Name, GenoFreeze.createtime as thistable, -# Geno.Name as Geno_Name, -# Geno.Source2 as Geno_Source2, -# Geno.chr_num as Geno_chr_num, -# Geno.Mb as Geno_Mb -# FROM GenoXRef, GenoFreeze, Geno -# WHERE (MATCH (ProbeSet.Name, -# ProbeSet.description, -# ProbeSet.symbol, -# alias, -# GenbankId, -# UniGeneId, -# Probe_Target_Description) -# AGAINST ('%s' IN BOOLEAN MODE)) and -# and Geno.Id = GenoXRef.GenoId and -# GenoXRef.GenoFreezeId = GenoFreeze.Id and -# GenoFreeze.Id = %d -# """% (self.db_conn.escape_string(search_term), -# self.db_conn.escape_string(str(self.dataset.id)))) -# -# -# self.cursor.execute(query) -# self.results.append(self.cursor.fetchall()) -# -# print("self.results is:", pf(self.results)) -# -# -# -# -# #if self.dataset.type == "ProbeSet" and search_term.find('.') < 0 and search_term.find('\'') < 0: -# # full_text.append(search_term) -# #else: -# # if self.matchwhole and search_term.find("'") < 0: -# # search_term = "[[:<:]]"+ search_term+"[[:>:]]" -# # clause2 = [] -# # for field in self.search_fields: -# # if self.dataset.type == "Publish": -# # clause2.append("%s REGEXP \"%s\"" % (field,search_term)) -# # else: -# # clause2.append("%s REGEXP \"%s\"" % ("%s.%s" % (self.dataset.type,field),search_term)) -# # clause_item = "(%s)" % string.join(clause2, clausejoin) -# # query.append(" (%s) " % clause_item) -# #if ANDFulltext: -# # clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol, -# # alias,GenbankId, UniGeneId, Probe_Target_Description) -# # AGAINST ('+%s' IN BOOLEAN MODE) """ % string.join(ANDFulltext, " +") -# # self.ANDQuery.append(" (%s) " % clauseItem) -# #if ORFulltext: -# #clauseItem = """ MATCH (ProbeSet.Name,ProbeSet.description,ProbeSet.symbol,alias, -# #GenbankId, UniGeneId, Probe_Target_Description) AGAINST ('%s' IN BOOLEAN MODE) -# #""" % string.join(full_text, " ") -# #self.query.append(" (%s) " % clauseItem) + print("in the search results are:", self.results) def encregexp(self,str): @@ -819,239 +291,6 @@ class SearchResultPage(templatePage): return wildcardkeyword - - def patternSearch(self): - # Lei Yan - ##Process Inputs - m1_AND = self._1mPattern.findall(self.ANDkeyword) - m2_AND = self._2mPattern.findall(self.ANDkeyword) - m3_AND = self._3mPattern.findall(self.ANDkeyword) - m5_AND = self._5mPattern.findall(self.ANDkeyword) - m1_OR = self._1mPattern.findall(self.ORkeyword) - m2_OR = self._2mPattern.findall(self.ORkeyword) - m3_OR = self._3mPattern.findall(self.ORkeyword) - m5_OR = self._5mPattern.findall(self.ORkeyword) - - #pattern search - if m1_AND or m1_OR or m2_AND or m2_OR or m3_AND or m3_OR or m5_AND or m5_OR: - - self.orderByDefalut = 'PROBESETID' - - _1Cmds = map(string.upper, map(lambda x:x[0], m1_AND + m1_OR)) - _2Cmds = map(string.upper, map(lambda x:x[0], m2_AND + m2_OR)) - _3Cmds = map(string.upper, map(lambda x:x[0], m3_AND + m3_OR)) - _5Cmds = map(string.upper, map(lambda x:x[0], m5_AND + m5_OR)) - - self.nkeywords += len(_1Cmds) + len(_2Cmds) + len(_3Cmds) - - if self.dbType == "Publish" and \ - ( (_2Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _2Cmds, False))\ - or (_5Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _5Cmds, False)) ): - heading = "Search Result" - detail = ["Pattern search is not available for phenotype databases at this time."] - self.error(heading=heading,detail=detail,error="Error") - return 0 - elif (self.dbType == "ProbeSet" and - ((_2Cmds and reduce(lambda x, y: (y not in [ - "MEAN", "LRS", "PVALUE", "TRANSLRS", "CISLRS", "RANGE", "H2" - ]) or x, _2Cmds, False))\ - or (_3Cmds and reduce(lambda x, y: (y not in ["POS", "POSITION", "MB"]) or x, _3Cmds, False))\ - or (_5Cmds and reduce(lambda x, y: (y not in ["LRS"]) or x, _5Cmds, False))\ - or (_1Cmds and reduce(lambda x, y: ( - y not in ["FLAG", "STRAND_PROBE", "STRAND_GENE", "GO", "WIKI", "RIF", "GENEID"] - ) or x, _1Cmds, False)))): - heading = "Search Result" - detail = ["You entered at least one incorrect search command."] - self.error(heading=heading,detail=detail,error="Error") - return 0 - elif self.dbType == "Geno" and (_1Cmds or _2Cmds or _5Cmds or (_3Cmds and reduce( - lambda x, y: (y not in ["POS", "POSITION", "MB"]) or x, _3Cmds, False)) ): - heading = "Search Result" - detail = ["You entered at least one incorrect search command."] - self.error(heading=heading,detail=detail,error="Error") - return 0 - else: - for k, item in enumerate(m1_OR+m1_AND): - if k >=len(m1_OR): - query = self.ANDQuery - DescriptionText = self.ANDDescriptionText - else: - query = self.ORQuery - DescriptionText = self.ORDescriptionText - - if item[1] == '-': - strandName = 'minus' - elif item[1] == '+': - strandName = 'plus' - else: - strandName = item[1] - - if item[0].upper() in ("FLAG"): - clauseItem = " %s.%s = %s " % (self.dbType, item[0], item[1]) - DescriptionText.append(HT.Span(' with ', HT.U('FLAG'), ' equal to ', item[1])) - elif item[0].upper() in ("WIKI"): - clauseItem = " %s.symbol = GeneRIF.symbol and GeneRIF.versionId=0 and GeneRIF.display>0 and (GeneRIF.comment REGEXP \"%s\" or GeneRIF.initial = \"%s\") " % (self.dbType, "[[:<:]]"+ item[1]+"[[:>:]]", item[1]) - DescriptionText.append(HT.Span(' with GeneWiki contains ', HT.U(item[1]))) - elif item[0].upper() in ("RIF"): - clauseItem = " %s.symbol = GeneRIF_BASIC.symbol and MATCH (GeneRIF_BASIC.comment) AGAINST ('+%s' IN BOOLEAN MODE) " % (self.dbType, item[1]) - DescriptionText.append(HT.Span(' with GeneRIF contains ', HT.U(item[1]))) - elif item[0].upper() in ("GENEID"): - clauseItem = " %s.GeneId in ( %s ) " % (self.dbType, string.replace(item[1], '-', ', ')) - DescriptionText.append(HT.Span(' with Entrez Gene ID in ', HT.U(string.replace(item[1], '-', ', ')))) - elif item[0].upper() in ("GO"): - Field = 'GOterm.acc' - Id = 'GO:'+('0000000'+item[1])[-7:] - Statements = '%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id' % (self.dbType); - clauseItem = " %s = '%s' and %s " % (Field, Id, Statements) - #self.incGoTbl = " ,db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product " - DescriptionText.append(HT.Span(' with ', HT.U('GO'), ' ID equal to ', Id)) - else: - clauseItem = " %s.%s = '%s' " % (self.dbType, item[0], item[1]) - if item[0].upper() in ["STRAND_PROBE"]: - DescriptionText.append(' with probe on the %s strand' % strandName) - elif item[0].upper() in ["STRAND_GENE"]: - DescriptionText.append(' with gene on the %s strand' % strandName) - else: - pass - query.append(" (%s) " % clauseItem) - - for k, item in enumerate(m2_OR+m2_AND): - if k >=len(m2_OR): - query = self.ANDQuery - DescriptionText = self.ANDDescriptionText - else: - query = self.ORQuery - DescriptionText = self.ORDescriptionText - - itemCmd = item[0] - lower_limit = float(item[1]) - upper_limit = float(item[2]) - - if itemCmd.upper() in ("TRANSLRS", "CISLRS"): - if item[3]: - mthresh = float(item[3]) - clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ - (self.dbType, min(lower_limit, upper_limit), self.dbType, max(lower_limit, upper_limit)) - if itemCmd.upper() == "CISLRS": - clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %2.7f """ % (self.dbType, self.speciesId, self.dbType, self.dbType, mthresh) - DescriptionText.append(HT.Span(' with a ', HT.U('cis-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lower_limit, upper_limit), max(lower_limit, upper_limit), mthresh))) - else: - clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and (%s.Chr != Geno.Chr or (%s.Chr != Geno.Chr and ABS(%s.Mb-Geno.Mb) > %2.7f)) """ % (self.dbType, self.speciesId, self.dbType, self.dbType, self.dbType, mthresh) - DescriptionText.append(HT.Span(' with a ', HT.U('trans-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lower_limit, upper_limit), max(lower_limit, upper_limit), mthresh))) - query.append(" (%s) " % clauseItem) - self.orderByDefalut = "LRS" - else: - pass - elif itemCmd.upper() in ("RANGE"): - #XZ, 03/05/2009: Xiaodong changed Data to ProbeSetData - clauseItem = " (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) > %2.7f and (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) < %2.7f " % (min(lower_limit, upper_limit), max(lower_limit, upper_limit)) - query.append(" (%s) " % clauseItem) - DescriptionText.append(HT.Span(' with a range of expression that varied between %g and %g' % (min(lower_limit, upper_limit), max(lower_limit, upper_limit)), " (fold difference)")) - else: - clauseItem = " %sXRef.%s > %2.7f and %sXRef.%s < %2.7f " % \ - (self.dbType, itemCmd, min(lower_limit, upper_limit), self.dbType, itemCmd, max(lower_limit, upper_limit)) - query.append(" (%s) " % clauseItem) - self.orderByDefalut = itemCmd - DescriptionText.append(HT.Span(' with ', HT.U(itemCmd), ' between %g and %g' % (min(lower_limit, upper_limit), max(lower_limit, upper_limit)))) - - for k, item in enumerate(m3_OR+m3_AND): - print("enumerating m3_OR+m3_AND with k: %s - item %s" % (k, item)) - if self.dbType not in ("ProbeSet", "Geno"): - continue - if k >=len(m3_OR): - query = self.ANDQuery - DescriptionText = self.ANDDescriptionText - else: - query = self.ORQuery - DescriptionText = self.ORDescriptionText - itemCmd = item[0] - - - chr_number = item[1] # chromosome number - lower_limit = float(item[2]) - upper_limit = float(item[3]) - - if self.dbType == "ProbeSet": - fname = 'target genes' - elif self.dbType == "Geno": - fname = 'loci' - - if lower_limit > upper_limit: - lower_limit, upper_limit = upper_limit, lower_limit - - - clauseItem = " %s.Chr = '%s' and %s.Mb > %2.7f and %s.Mb < %2.7f " % ( - self.dbType, chr_number, self.dbType, lower_limit, self.dbType, upper_limit) - - - query.append(" (%s) " % clauseItem) - self.orderByDefalut = itemCmd - - self.results_desc = dict() - #DescriptionText.append(HT.Span(' with ', HT.U('target genes'), ' on chromosome %s between %g and %g Mb' % \ - # (chr_number, min(lower_limit, upper_limit), max(lower_limit, upper_limit)))) - - for k, item in enumerate(m5_OR+m5_AND): - if k >=len(m5_OR): - query = self.ANDQuery - DescriptionText = self.ANDDescriptionText - else: - query = self.ORQuery - DescriptionText = self.ORDescriptionText - itemCmd = item[0] - lower_limit = float(item[1]) - upper_limit = float(item[2]) - chr_number = item[3] - mb_lower_limit = float(item[4]) - mb_upper_limit = float(item[5]) - if self.dbType == "ProbeSet" or self.dbType == "Publish": - clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ - (self.dbType, min(lower_limit, upper_limit), self.dbType, max(lower_limit, upper_limit)) - clauseItem += " and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and Geno.Chr = '%s' and Geno.Mb > %2.7f and Geno.Mb < %2.7f" \ - % (self.dbType, self.speciesId, chr_number, min(mb_lower_limit, mb_upper_limit), max(mb_lower_limit, mb_upper_limit)) - query.append(" (%s) " % clauseItem) - self.orderByDefalut = "MB" - DescriptionText.append(HT.Span(' with ', HT.U('LRS'), ' between %g and %g' % \ - (min(lower_limit, upper_limit), max(lower_limit, upper_limit)), \ - ' on chromosome %s between %g and %g Mb' % \ - (chr_number, min(mb_lower_limit, mb_upper_limit), max(mb_lower_limit, mb_upper_limit)))) - pass - - return 1 - - def generateWarningLayer(self): - - layerString = """ - -
      - - - -
      - - - - - - - -
      - Sort Table -
      - - Resorting this table
      - -
      -
      - - - - """ - - return layerString - def getTableHeaderForGeno(self, worksheet=None, newrow=None, headingStyle=None): tblobj_header = [] @@ -1112,26 +351,7 @@ class SearchResultPage(templatePage): newrow += 1 return tblobj_body - - def getTableHeaderForPublish(self, worksheet=None, newrow=None, headingStyle=None): - - tblobj_header = [] - - className = "fs13 fwb ffl b1 cw cbrb" - - tblobj_header = [[THCell(HT.TD(' ', Class=className, nowrap="on"), sort=0), - THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class=className, nowrap="on"), text="recond_id", idx=1), - THCell(HT.TD('Phenotype',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="pheno", idx=2), - THCell(HT.TD('Authors',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="auth", idx=3), - THCell(HT.TD('Year',HT.BR(),HT.BR(), Class=className, nowrap="on"), text="year", idx=4), - THCell(HT.TD('Max',HT.BR(), 'LRS', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="lrs", idx=5), - THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap="on"), text="lrs_location", idx=6)]] - - for ncol, item in enumerate(["Record", "Phenotype", "Authors", "Year", "Pubmed Id", "Max LRS", "Max LRS Location (Chr: Mb)"]): - worksheet.write([newrow, ncol], item, headingStyle) - worksheet.set_column([ncol, ncol], 2*len(item)) - - return tblobj_header + def getTableBodyForPublish(self, trait_list, formName=None, worksheet=None, newrow=None, species=''): @@ -1225,32 +445,13 @@ class SearchResultPage(templatePage): return tblobj_body - def getTableHeaderForProbeSet(self, worksheet=None, newrow=None, headingStyle=None): - - tblobj_header = [] - - className = "fs13 fwb ffl b1 cw cbrb" - - #tblobj_header = [[THCell(HT.TD(' ', Class="fs13 fwb ffl b1 cw cbrb",nowrap='ON'), sort=0), - # THCell(HT.TD('Record',HT.BR(), 'ID',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="record_id", idx=1), - # THCell(HT.TD('Symbol',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="symbol", idx=2), - # THCell(HT.TD('Description',HT.BR(),HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="desc", idx=3), - # THCell(HT.TD('Location',HT.BR(), 'Chr and Mb', HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="location", idx=4), - # THCell(HT.TD('Mean',HT.BR(),'Expr',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb"), text="mean", idx=5), - # THCell(HT.TD('Max',HT.BR(),'LRS',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lrs", idx=6), - # THCell(HT.TD('Max LRS Location',HT.BR(),'Chr and Mb',HT.BR(), Class="fs13 fwb ffl b1 cw cbrb", nowrap='ON'), text="lrs_location", idx=7)]] - # - #for ncol, item in enumerate(['Record', 'Gene ID', 'Homologene ID', 'Symbol', 'Description', 'Location (Chr, Mb)', 'Mean Expr', 'Max LRS', 'Max LRS Location (Chr: Mb)']): - # worksheet.write([newrow, ncol], item, headingStyle) - # worksheet.set_column([ncol, ncol], 2*len(item)) - return tblobj_header - - def getTableBodyForProbeSet(self, trait_list=[], primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): + def getTableBodyForProbeSet(self, trait_list=None, primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): # Note: setting trait_list to [] is probably not a great idea. tblobj_body = [] - className = "fs12 fwn b1 c222" + if not trait_list: + trait_list = [] for this_trait in trait_list: @@ -1298,8 +499,6 @@ class SearchResultPage(templatePage): if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': description_display = description_display + '; ' + target_string.strip() - #tr.append(TDCell(HT.TD(description_display, Class=className), description_display, description_display)) - # Save it for the jinja2 tablet this_trait.description_display = description_display @@ -1319,7 +518,6 @@ class SearchResultPage(templatePage): trait_location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) this_trait.trait_location_repr = trait_location_repr #this_trait.trait_location_value = trait_location_value - tr.append(TDCell(HT.TD(trait_location_repr, Class=className, nowrap="on"), trait_location_repr, trait_location_value)) #XZ, 01/12/08: This SQL query is much faster. query = ( @@ -1397,34 +595,10 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - #for ncol, item in enumerate([this_trait.name, this_trait.geneid, this_trait.homologeneid, this_trait.symbol, description_display, trait_location_repr, mean, LRS_score_repr, LRS_location_repr]): - # worksheet.write([newrow, ncol], item) - - newrow += 1 return tblobj_body - def createExcelFileWithTitleAndFooter(self, workbook=None, identification=None, db=None, returnNumber=None): - - worksheet = workbook.add_worksheet() - - titleStyle = workbook.add_format(align = 'left', bold = 0, size=14, border = 1, border_color="gray") - - ##Write title Info - # Modified by Hongqiang Li - worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) - worksheet.write([1, 0], "Citations: Please see %s/reference.html" % webqtlConfig.PORTADDR, titleStyle) - worksheet.write([2, 0], "Trait : %s" % identification, titleStyle) - worksheet.write([3, 0], "Database : %s" % db.fullname, titleStyle) - worksheet.write([4, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime()), titleStyle) - worksheet.write([5, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime()), titleStyle) - worksheet.write([6, 0], "Status of data ownership: Possibly unpublished data; please see %s/statusandContact.html for details on sources, ownership, and usage of these data." % webqtlConfig.PORTADDR, titleStyle) - #Write footer info - worksheet.write([9 + returnNumber, 0], "Funding for The GeneNetwork: NIAAA (U01AA13499, U24AA13513), NIDA, NIMH, and NIAAA (P20-DA21131), NCI MMHCC (U01CA105417), and NCRR (U01NR 105417)", titleStyle) - worksheet.write([10 + returnNumber, 0], "PLEASE RETAIN DATA SOURCE INFORMATION WHENEVER POSSIBLE", titleStyle) - - return worksheet def getSortByValue(self, datasetType=''): diff --git a/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json new file mode 100644 index 00000000..898ffa02 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/dataset_menu_structure.json @@ -0,0 +1,2904 @@ +{ + "datasets": { + "All Species": { + "All Groups": { + "Phenotypes": [ + [ + "All Phenotypes", + "All Phenotypes" + ] + ] + } + }, + "arabidopsis": { + "BayXSha": { + "Genotypes": [ + [ + "BayXShaGeno", + "BayXSha Genotypes" + ] + ], + "Phenotypes": [ + [ + "BayXShaPublish", + "BayXSha Published Phenotypes" + ] + ] + }, + "ColXBur": { + "Genotypes": [ + [ + "ColXBurGeno", + "ColXBur Genotypes" + ] + ], + "Phenotypes": [ + [ + "ColXBurPublish", + "ColXBur Published Phenotypes" + ] + ] + }, + "ColXCvi": { + "Genotypes": [ + [ + "ColXCviGeno", + "ColXCvi Genotypes" + ] + ], + "Phenotypes": [ + [ + "ColXCviPublish", + "ColXCvi Published Phenotypes" + ] + ] + } + }, + "barley": { + "QSM": { + "Genotypes": [ + [ + "QSMGeno", + "QSM Genotypes" + ] + ], + "Leaf": [ + [ + "B1LI0809R", + "Barley1 Leaf INOC TTKS (Aug09) RMA" + ], + [ + "B1LI0809M5", + "Barley1 Leaf INOC TTKS (Aug09) MAS5" + ], + [ + "B1MI0809M5", + "Barley1 Leaf MOCK TTKS (Aug09) MAS5" + ], + [ + "B1MI0809R", + "Barley1 Leaf MOCK TTKS (Aug09) RMA" + ] + ], + "Phenotypes": [ + [ + "QSMPublish", + "QSM Published Phenotypes" + ] + ] + }, + "SXM": { + "Embryo": [ + [ + "B139_K_1206_R", + "Barley1 Embryo gcRMA SCRI (Dec06)" + ], + [ + "B139_K_1206_M", + "Barley1 Embryo MAS 5.0 SCRI (Dec06)" + ], + [ + "B150_K_0406_R", + "Barley1 Embryo0 gcRMA SCRI (Apr06)" + ] + ], + "Genotypes": [ + [ + "SXMGeno", + "SXM Genotypes" + ] + ], + "Leaf": [ + [ + "B30_K_1206_M", + "Barley1 Leaf MAS 5.0 SCRI (Dec06)" + ], + [ + "B30_K_1206_Rn", + "Barley1 Leaf gcRMAn SCRI (Dec06)" + ], + [ + "B30_K_1206_R", + "Barley1 Leaf gcRMA SCRI (Dec06)" + ] + ], + "Phenotypes": [ + [ + "SXMPublish", + "SXM Published Phenotypes" + ] + ] + } + }, + "drosophila": { + "DGRP": { + "Genotypes": [ + [ + "DGRPGeno", + "DGRP Genotypes" + ] + ], + "Phenotypes": [ + [ + "DGRPPublish", + "DGRP Published Phenotypes" + ] + ], + "Whole Body": [ + [ + "NCSU_DrosWB_LC_RMA_0111", + "NCSU Drosophila Whole Body (Jan11) RMA" + ] + ] + }, + "Oregon-R_x_2b3": { + "Genotypes": [ + [ + "Oregon-R_x_2b3Geno", + "Oregon-R_x_2b3 Genotypes" + ] + ], + "Phenotypes": [ + [ + "Oregon-R_x_2b3Publish", + "Oregon-R_x_2b3 Published Phenotypes" + ] + ], + "Whole Body": [ + [ + "UAB_DrosWB_LC_RMA_1009", + "UAB Whole body D.m. mRNA control (Oct09) RMA" + ], + [ + "UAB_DrosWB_LE_RMA_1009", + "UAB Whole body D.m. mRNA lead (pbAc) (Oct09) RMA" + ] + ] + } + }, + "human": { + "AD-cases-controls": { + "Brain": [ + [ + "GSE5281_F_RMA_N_0709", + "GSE5281 Human Brain Normal Full Liang (Jul09) RMA" + ], + [ + "GSE5281_F_RMA_Alzh_0709", + "GSE5281 Human Brain Alzheimer Full Liang (Jul09) RMA" + ], + [ + "GSE5281_F_RMA0709", + "GSE5281 Human Brain Full Liang (Jul09) RMA" + ], + [ + "GSE5281_RMA0709", + "GSE5281 Human Brain Best 102 Liang (Jul09) RMA" + ] + ], + "Genotypes": [ + [ + "AD-cases-controlsGeno", + "AD-cases-controls Genotypes" + ] + ], + "Phenotypes": [ + [ + "AD-cases-controlsPublish", + "AD-cases-controls Published Phenotypes" + ] + ] + }, + "AD-cases-controls-Myers": { + "Brain": [ + [ + "GSE15222_F_A_RI_0409", + "GSE15222 Human Brain Alzheimer Myers (Apr09) RankInv" + ], + [ + "GSE15222_F_N_RI_0409", + "GSE15222 Human Brain Normal Myers (Apr09) RankInv" + ], + [ + "GSE15222_F_RI_0409", + "GSE15222 Human Brain Myers (Apr09) RankInv" + ] + ], + "Genotypes": [ + [ + "AD-cases-controls-MyersGeno", + "AD-cases-controls-Myers Genotypes" + ] + ], + "Phenotypes": [ + [ + "AD-cases-controls-MyersPublish", + "AD-cases-controls-Myers Published Phenotypes" + ] + ] + }, + "CANDLE": { + "Genotypes": [ + [ + "CANDLEGeno", + "CANDLE Genotypes" + ] + ], + "Newborn Cord Blood": [ + [ + "CANDLE_NB_0711", + "CANDLE Newborn Cord ILMv6.3 (Jun11) QUANT **" + ] + ], + "Phenotypes": [ + [ + "CANDLEPublish", + "CANDLE Published Phenotypes" + ] + ] + }, + "CEPH-2004": { + "Genotypes": [ + [ + "CEPH-2004Geno", + "CEPH-2004 Genotypes" + ] + ], + "Lymphoblast B-cell": [ + [ + "UT_CEPH_RankInv0909", + "UTHSC CEPH B-cells Illumina (Sep09) RankInv" + ], + [ + "Human_1008", + "Monks CEPH B-cells Agilent (Dec04) Log10Ratio" + ] + ], + "Phenotypes": [ + [ + "CEPH-2004Publish", + "CEPH-2004 Published Phenotypes" + ] + ] + }, + "HB": { + "Cerebellum": [ + [ + "HBTRC-MLC_0611", + "HBTRC-MLC Human Cerebellum Agilent (Jun11) mlratio" + ], + [ + "HBTRC-MLC_N_0611", + "HBTRC-MLC Human Cerebellum Agilent Normal (Jun11) mlratio" + ], + [ + "HBTRC-MLC_AD_0611", + "HBTRC-MLC Human Cerebellum Agilent AD (Jun11) mlratio" + ], + [ + "HBTRC-MLC_HD_0611", + "HBTRC-MLC Human Cerebellum Agilent HD (Jun11) mlratio" + ] + ], + "Genotypes": [ + [ + "HBGeno", + "HB Genotypes" + ] + ], + "Phenotypes": [ + [ + "HBPublish", + "HB Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ + [ + "HBTRC-MLPFC_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent (Jun11) mlratio" + ], + [ + "HBTRC-MLPFC_N_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent Normal (Jun11) mlratio" + ], + [ + "HBTRC-MLPFC_AD_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent AD (Jun11) mlratio" + ], + [ + "HBTRC-MLPFC_HD_0611", + "HBTRC-MLC Human Prefrontal Cortex Agilent HD (Jun11) mlratio" + ] + ], + "Primary Visual Cortex": [ + [ + "HBTRC-MLVC_0611", + "HBTRC-MLC Human Visual Cortex Agilent (Jun11) mlratio" + ], + [ + "HBTRC-MLVC_N_0611", + "HBTRC-MLC Human Visual Cortex Agilent Normal (Jun11) mlratio" + ], + [ + "HBTRC-MLVC_AD_0611", + "HBTRC-MLC Human Visual Cortex Agilent AD (Jun11) mlratio" + ], + [ + "HBTRC-MLVC_HD_0611", + "HBTRC-MLC Human Visual Cortex Agilent HD (Jun11) mlratio" + ] + ] + }, + "HLC": { + "Genotypes": [ + [ + "HLCGeno", + "HLC Genotypes" + ] + ], + "Liver": [ + [ + "HLC_0311", + "GSE9588 Human Liver Normal (Mar11) Both Sexes" + ], + [ + "HLCM_0311", + "GSE9588 Human Liver Normal (Mar11) Males" + ], + [ + "HLCF_0311", + "GSE9588 Human Liver Normal (Mar11) Females" + ] + ], + "Phenotypes": [ + [ + "HLCPublish", + "HLC Published Phenotypes" + ] + ] + }, + "HSB": { + "Amygdala": [ + [ + "KIN_YSM_AMY_0711", + "KIN/YSM Human AMY Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Caudal Ganglionic Eminence": [ + [ + "KIN_YSM_CGE_0711", + "KIN/YSM Human CGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Cerebellar Cortex": [ + [ + "KIN_YSM_CBC_0711", + "KIN/YSM Human CBC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Diencephalon": [ + [ + "KIN_YSM_DIE_0711", + "KIN/YSM Human DIE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Dorsal Thalamus": [ + [ + "KIN_YSM_DTH_0711", + "KIN/YSM Human DTH Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Dorsolateral Prefrontal Cortex": [ + [ + "KIN_YSM_DFC_0711", + "KIN/YSM Human DFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Frontal Cerebral Wall": [ + [ + "KIN_YSM_FC_0711", + "KIN/YSM Human FC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Genotypes": [ + [ + "HSBGeno", + "HSB Genotypes" + ] + ], + "Hippocampus": [ + [ + "KIN_YSM_HIP_0711", + "KIN/YSM Human HIP Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Inferior Temporal Cortex": [ + [ + "KIN_YSM_ITC_0711", + "KIN/YSM Human ITC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Lateral Ganglionic Eminence": [ + [ + "KIN_YSM_LGE_0711", + "KIN/YSM Human LGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Medial Ganglionic Eminence": [ + [ + "KIN_YSM_MGE_0711", + "KIN/YSM Human MGE Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Medial Prefrontal Cortex": [ + [ + "KIN_YSM_MFC_0711", + "KIN/YSM Human MFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Mediodorsal Nucleus of Thalamus": [ + [ + "KIN_YSM_MD_0711", + "KIN/YSM Human MD Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Occipital Cerebral Wall": [ + [ + "KIN_YSM_OC_0711", + "KIN/YSM Human OC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Orbital Prefrontal Cortex": [ + [ + "KIN_YSM_OFC_0711", + "KIN/YSM Human OFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Parietal Cerebral Wall": [ + [ + "KIN_YSM_PC_0711", + "KIN/YSM Human PC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Phenotypes": [ + [ + "HSBPublish", + "HSB Published Phenotypes" + ] + ], + "Posterior Inferior Parietal Cortex": [ + [ + "KIN_YSM_IPC_0711", + "KIN/YSM Human IPC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Posterior Superior Temporal Cortex": [ + [ + "KIN_YSM_STC_0711", + "KIN/YSM Human STC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Primary Auditory (A1) Cortex": [ + [ + "KIN_YSM_A1C_0711", + "KIN/YSM Human A1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Primary Motor (M1) Cortex": [ + [ + "KIN_YSM_M1C_0711", + "KIN/YSM Human M1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Primary Somatosensory (S1) Cortex": [ + [ + "KIN_YSM_S1C_0711", + "KIN/YSM Human S1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Primary Visual Cortex": [ + [ + "KIN_YSM_V1C_0711", + "KIN/YSM Human V1C Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Striatum": [ + [ + "KIN_YSM_STR_0711", + "KIN/YSM Human STR Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Temporal Cerebral Wall": [ + [ + "KIN_YSM_TC_0711", + "KIN/YSM Human TC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Upper (Rostral) Rhombic Lip": [ + [ + "KIN_YSM_URL_0711", + "KIN/YSM Human URL Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Ventral Forebrain": [ + [ + "KIN_YSM_VF_0711", + "KIN/YSM Human VF Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ], + "Ventrolateral Prefrontal Cortex": [ + [ + "KIN_YSM_VFC_0711", + "KIN/YSM Human VFC Affy Hu-Exon 1.0 ST (Jul11) Quantile **" + ] + ] + } + }, + "macaque monkey": { + "Macaca-fasicularis": { + "Amygdala": [ + [ + "INIA_MacFas_AMGc_RMA_0110", + "INIA Macaca fasicularis Amygdala control (Jan10) RMA **" + ], + [ + "INIA_MacFas_AMGe_RMA_0110", + "INIA Macaca fasicularis Amygdala ethanol (Jan10) RMA **" + ] + ], + "Brain": [ + [ + "INIA_MacFas_brain_RMA_0110", + "INIA Macaca fasicularis Brain (Jan10) RMA **" + ] + ], + "Genotypes": [ + [ + "Macaca-fasicularisGeno", + "Macaca-fasicularis Genotypes" + ] + ], + "Hippocampus": [ + [ + "INIA_MacFas_Hc_RMA_0110", + "INIA Macaca fasicularis Hippocampus control (Jan10) RMA **" + ], + [ + "INIA_MacFas_He_RMA_0110", + "INIA Macaca fasicularis Hippocampus ethanol (Jan10) RMA **" + ] + ], + "Nucleus Accumbens": [ + [ + "INIA_MacFas_Ac_RMA_0110", + "INIA Macaca fasicularis Nucleus Accumbens control (Jan10) RMA **" + ], + [ + "INIA_MacFas_Ae_RMA_0110", + "INIA Macaca fasicularis Nucleus Accumbens ethanol (Jan10) RMA **" + ] + ], + "Phenotypes": [ + [ + "Macaca-fasicularisPublish", + "Macaca-fasicularis Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ + [ + "INIA_MacFas_Pf_RMA_0110", + "INIA Macaca fasicularis Prefrontal Cortex control (Jan10) RMA **" + ], + [ + "INIA_MacFas_PfE_RMA_0110", + "INIA Macaca fasicularis Prefrontal Cortex ethanol (Jan10) RMA **" + ] + ] + } + }, + "mouse": { + "AKXD": { + "Genotypes": [ + [ + "AKXDGeno", + "AKXD Genotypes" + ] + ], + "Mammary Tumors": [ + [ + "NCI_Agil_Mam_Tum_RMA_0409", + "NCI Mammary LMT miRNA v2 (Apr09) RMA" + ], + [ + "MA_M_0704_R", + "NCI Mammary mRNA M430 (July04) RMA" + ], + [ + "MA_M_0704_M", + "NCI Mammary mRNA M430 (July04) MAS5" + ] + ], + "Phenotypes": [ + [ + "AKXDPublish", + "AKXD Published Phenotypes" + ] + ] + }, + "AXBXA": { + "Eye": [ + [ + "Eye_AXBXA_1008_RankInv", + "Eye AXBXA Illumina V6.2(Oct08) RankInv Beta" + ] + ], + "Genotypes": [ + [ + "AXBXAGeno", + "AXBXA Genotypes" + ] + ], + "Phenotypes": [ + [ + "AXBXAPublish", + "AXBXA Published Phenotypes" + ] + ] + }, + "B6BTBRF2": { + "Genotypes": [ + [ + "B6BTBRF2Geno", + "B6BTBRF2 Genotypes" + ] + ], + "Liver": [ + [ + "LVF2_M_0704_R", + "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) RMA" + ], + [ + "LVF2_M_0704_M", + "(B6 x BTBR)F2-ob/ob Liver mRNA M430 (Jul04) MAS5" + ] + ], + "Phenotypes": [ + [ + "B6BTBRF2Publish", + "B6BTBRF2 Published Phenotypes" + ] + ] + }, + "B6D2F2": { + "Brain": [ + [ + "BRF2_M_0805_M", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) MAS5" + ], + [ + "BRF2_M_0805_P", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) PDNN" + ], + [ + "BRF2_M_0805_R", + "OHSU/VA B6D2F2 Brain mRNA M430 (Aug05) RMA" + ], + [ + "BRF2_M_0304_P", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) PDNN" + ], + [ + "BRF2_M_0304_R", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) RMA" + ], + [ + "BRF2_M_0304_M", + "OHSU/VA B6D2F2 Brain mRNA M430A (Mar04) MAS5" + ] + ], + "Genotypes": [ + [ + "B6D2F2Geno", + "B6D2F2 Genotypes" + ] + ], + "Phenotypes": [ + [ + "B6D2F2Publish", + "B6D2F2 Published Phenotypes" + ] + ] + }, + "BDF2-1999": { + "Genotypes": [ + [ + "BDF2-1999Geno", + "BDF2-1999 Genotypes" + ] + ], + "Liver": [ + [ + "UCLA_BDF2_LIVER_1999", + "UCLA BDF2 Liver (1999) mlratio" + ] + ], + "Phenotypes": [ + [ + "BDF2-1999Publish", + "BDF2-1999 Published Phenotypes" + ] + ] + }, + "BDF2-2005": { + "Genotypes": [ + [ + "BDF2-2005Geno", + "BDF2-2005 Genotypes" + ] + ], + "Phenotypes": [ + [ + "BDF2-2005Publish", + "BDF2-2005 Published Phenotypes" + ] + ], + "Striatum": [ + [ + "SA_M2_0905_R", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) RMA" + ], + [ + "SA_M2_0905_M", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) MAS5" + ], + [ + "SA_M2_0905_P", + "OHSU/VA B6D2F2 Striatum M430v2 (Sep05) PDNN" + ] + ] + }, + "BHF2": { + "Adipose": [ + [ + "UCLA_BHF2_ADIPOSE_MALE", + "UCLA BHF2 Adipose Male mlratio" + ], + [ + "UCLA_BHF2_ADIPOSE_FEMALE", + "UCLA BHF2 Adipose Female mlratio" + ], + [ + "UCLA_BHF2_ADIPOSE_0605", + "UCLA BHF2 Adipose (June05) mlratio" + ] + ], + "Brain": [ + [ + "UCLA_BHF2_BRAIN_MALE", + "UCLA BHF2 Brain Male mlratio" + ], + [ + "UCLA_BHF2_BRAIN_FEMALE", + "UCLA BHF2 Brain Female mlratio" + ], + [ + "UCLA_BHF2_BRAIN_0605", + "UCLA BHF2 Brain (June05) mlratio" + ] + ], + "Genotypes": [ + [ + "BHF2Geno", + "BHF2 Genotypes" + ] + ], + "Liver": [ + [ + "UCLA_BHF2_LIVER_MALE", + "UCLA BHF2 Liver Male mlratio" + ], + [ + "UCLA_BHF2_LIVER_FEMALE", + "UCLA BHF2 Liver Female mlratio" + ], + [ + "UCLA_BHF2_LIVER_0605", + "UCLA BHF2 Liver (June05) mlratio" + ] + ], + "Muscle": [ + [ + "UCLA_BHF2_MUSCLE_MALE", + "UCLA BHF2 Muscle Male mlratio **" + ], + [ + "UCLA_BHF2_MUSCLE_FEMALE", + "UCLA BHF2 Muscle Female mlratio **" + ], + [ + "UCLA_BHF2_MUSCLE_0605", + "UCLA BHF2 Muscle (June05) mlratio **" + ] + ], + "Phenotypes": [ + [ + "BHF2Publish", + "BHF2 Published Phenotypes" + ] + ] + }, + "BHHBF2": { + "Adipose": [ + [ + "UCLA_BHHBF2_ADIPOSE_MALE", + "UCLA BHHBF2 Adipose Male Only" + ], + [ + "UCLA_BHHBF2_ADIPOSE_FEMALE", + "UCLA BHHBF2 Adipose Female Only" + ], + [ + "UCLA_BHHBF2_ADIPOSE_2005", + "UCLA BHHBF2 Adipose (2005) mlratio **" + ] + ], + "Brain": [ + [ + "UCLA_BHHBF2_BRAIN_MALE", + "UCLA BHHBF2 Brain Male Only" + ], + [ + "UCLA_BHHBF2_BRAIN_FEMALE", + "UCLA BHHBF2 Brain Female Only" + ], + [ + "UCLA_BHHBF2_BRAIN_2005", + "UCLA BHHBF2 Brain (2005) mlratio **" + ] + ], + "Genotypes": [ + [ + "BHHBF2Geno", + "BHHBF2 Genotypes" + ] + ], + "Liver": [ + [ + "UCLA_BHHBF2_LIVER_MALE", + "UCLA BHHBF2 Liver Male Only" + ], + [ + "UCLA_BHHBF2_LIVER_FEMALE", + "UCLA BHHBF2 Liver Female Only" + ], + [ + "UCLA_BHHBF2_LIVER_2005", + "UCLA BHHBF2 Liver (2005) mlratio **" + ] + ], + "Muscle": [ + [ + "UCLA_BHHBF2_MUSCLE_MALE", + "UCLA BHHBF2 Muscle Male Only" + ], + [ + "UCLA_BHHBF2_MUSCLE_FEMALE", + "UCLA BHHBF2 Muscle Female Only" + ], + [ + "UCLA_BHHBF2_MUSCLE_2005", + "UCLA BHHBF2 Muscle (2005) mlratio **" + ] + ], + "Phenotypes": [ + [ + "BHHBF2Publish", + "BHHBF2 Published Phenotypes" + ] + ] + }, + "BXD": { + "Amygdala": [ + [ + "INIA_AmgCoh_0311", + "INIA Amygdala Cohort Affy MoGene 1.0 ST (Mar11) RMA" + ], + [ + "INIA_Amg_BLA_RMA_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA" + ], + [ + "INIA_Amg_BLA_RMA_M_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Male" + ], + [ + "INIA_Amg_BLA_RMA_F_1110", + "INIA Amygdala Affy MoGene 1.0 ST (Nov10) RMA Female" + ] + ], + "Brain": [ + [ + "BR_M2_1106_R", + "UCHSC BXD Whole Brain M430 2.0 (Nov06) RMA" + ], + [ + "BR_U_1105_P", + "UTHSC Brain mRNA U74Av2 (Nov05) PDNN" + ], + [ + "BR_U_0805_M", + "UTHSC Brain mRNA U74Av2 (Aug05) MAS5" + ], + [ + "BR_U_0805_R", + "UTHSC Brain mRNA U74Av2 (Aug05) RMA" + ], + [ + "BR_U_0805_P", + "UTHSC Brain mRNA U74Av2 (Aug05) PDNN" + ], + [ + "CB_M_0204_P", + "INIA Brain mRNA M430 (Feb04) PDNN" + ] + ], + "Cartilage": [ + [ + "UCLA_BXDBXH_CARTILAGE_V2", + "UCLA BXD and BXH Cartilage v2" + ], + [ + "UCLA_BXDBXH_CARTILAGE", + "UCLA BXD and BXH Cartilage" + ], + [ + "UCLA_BXD_CARTILAGE", + "UCLA BXD Cartilage" + ] + ], + "Cerebellum": [ + [ + "CB_M_1004_M", + "SJUT Cerebellum mRNA M430 (Oct04) MAS5" + ], + [ + "CB_M_1004_R", + "SJUT Cerebellum mRNA M430 (Oct04) RMA" + ], + [ + "CB_M_1004_P", + "SJUT Cerebellum mRNA M430 (Oct04) PDNN" + ], + [ + "CB_M_1003_M", + "SJUT Cerebellum mRNA M430 (Oct03) MAS5" + ] + ], + "Eye": [ + [ + "Eye_M2_0908_R", + "Eye M430v2 (Sep08) RMA" + ], + [ + "Eye_M2_0908_R_NB", + "Eye M430v2 Mutant Gpnmb (Sep08) RMA **" + ], + [ + "Eye_M2_0908_R_ND", + "Eye M430v2 WT Gpnmb (Sep08) RMA **" + ], + [ + "Eye_M2_0908_WTWT", + "Eye M430v2 WT WT (Sep08) RMA **" + ], + [ + "Eye_M2_0908_R_MT", + "Eye M430v2 Mutant Tyrp1 (Sep08) RMA **" + ], + [ + "Eye_M2_0908_R_WT", + "Eye M430v2 WT Tyrp1 (Sep08) RMA **" + ], + [ + "BXD_GLA_0911", + "BXD Glaucoma Affy M430 2.0 Trial (Sep11) RMA **" + ] + ], + "Genotypes": [ + [ + "BXDGeno", + "BXD Genotypes" + ] + ], + "Hematopoietic Cells": [ + [ + "UMCG_0907_HemaStem_ori", + "UMCG Stem Cells ILM6v1.1 (Apr09) original" + ], + [ + "UMCG_0907_HemaStem", + "UMCG Stem Cells ILM6v1.1 (Apr09) transformed" + ], + [ + "UMCG_0907_Pro_ori", + "UMCG Progenitor Cells ILM6v1.1 (Apr09) original" + ], + [ + "UMCG_0907_Pro", + "UMCG Progenitor Cells ILM6v1.1 (Apr09) transformed" + ], + [ + "UMCG_0907_Eryth_ori", + "UMCG Erythroid Cells ILM6v1.1 (Apr09) original" + ], + [ + "UMCG_0907_Eryth", + "UMCG Erythroid Cells ILM6v1.1 (Apr09) transformed" + ], + [ + "UMCG_0907_Myeloid_ori", + "UMCG Myeloid Cells ILM6v1.1 (Apr09) original" + ], + [ + "UMCG_0907_Myeloid", + "UMCG Myeloid Cells ILM6v1.1 (Apr09) transformed" + ], + [ + "HC_U_0304_R", + "GNF Stem Cells U74Av2 (Mar04) RMA" + ] + ], + "Hippocampus": [ + [ + "HC_M2_0606_P", + "Hippocampus Consortium M430v2 (Jun06) PDNN" + ], + [ + "HC_M2_0606_M", + "Hippocampus Consortium M430v2 (Jun06) MAS5" + ], + [ + "HC_M2_0606_R", + "Hippocampus Consortium M430v2 (Jun06) RMA" + ], + [ + "UMUTAffyExon_0209_RMA", + "UMUTAffy Hippocampus Exon (Feb09) RMA" + ], + [ + "UT_ILM_BXD_hipp_NON_0909", + "UTHSC Hippocampus Illumina v6.1 NON (Sep09) RankInv" + ], + [ + "UT_ILM_BXD_hipp_NOS_0909", + "UTHSC Hippocampus Illumina v6.1 NOS (Sep09) RankInv" + ], + [ + "UT_ILM_BXD_hipp_NOE_0909", + "UTHSC Hippocampus Illumina v6.1 NOE (Sep09) RankInv" + ], + [ + "UT_ILM_BXD_hipp_RSS_0909", + "UTHSC Hippocampus Illumina v6.1 RSS (Sep09) RankInv" + ], + [ + "UT_ILM_BXD_hipp_RSE_0909", + "UTHSC Hippocampus Illumina v6.1 RSE (Sep09) RankInv" + ] + ], + "Hypothalamus": [ + [ + "INIA_Hyp_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10)" + ], + [ + "INIA_Hyp_M_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Male" + ], + [ + "INIA_Hyp_F_RMA_1110", + "INIA Hypothalamus Affy MoGene 1.0 ST (Nov10) Female" + ] + ], + "Kidney": [ + [ + "MA_M2M_0706_R", + "Mouse kidney M430v2 Male (Aug06) RMA" + ], + [ + "MA_M2F_0706_R", + "Mouse kidney M430v2 Female (Aug06) RMA" + ], + [ + "MA_M2_0806_R", + "Mouse kidney M430v2 Sex Balanced (Aug06) RMA" + ], + [ + "MA_M2_0806_P", + "Mouse Kidney M430v2 Sex Balanced (Aug06) PDNN" + ], + [ + "MA_M2_0706_P", + "Mouse Kidney M430v2 (Jul06) PDNN" + ], + [ + "MA_M2_0706_R", + "Mouse Kidney M430v2 (Jul06) RMA" + ] + ], + "Leucocytes": [ + [ + "Illum_BXD_PBL_1108", + "UWA Illumina PBL (Nov08) RSN **" + ] + ], + "Liver": [ + [ + "GSE16780_UCLA_ML0911", + "GSE16780 UCLA Hybrid MDP Liver Affy HT M430A (Sep11) RMA" + ], + [ + "GenEx_BXD_liverSal_RMA_F_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Females **" + ], + [ + "GenEx_BXD_liverSal_RMA_M_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Males **" + ], + [ + "GenEx_BXD_liverSal_RMA_0211", + "GenEx BXD Sal Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + ], + [ + "GenEx_BXD_liverEt_RMA_F_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Females **" + ], + [ + "GenEx_BXD_liverEt_RMA_M_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Males **" + ], + [ + "GenEx_BXD_liverEt_RMA_0211", + "GenEx BXD EtOH Liver Affy M430 2.0 (Feb11) RMA Both Sexes **" + ], + [ + "SUH_Liv_RMA_0611", + "SUH BXD Liver Affy Mouse Gene 1.0 ST (Jun11) RMA **" + ] + ], + "Lung": [ + [ + "HZI_0408_R", + "HZI Lung M430v2 (Apr08) RMA" + ], + [ + "HZI_0408_M", + "HZI Lung M430v2 (Apr08) MAS5" + ] + ], + "Midbrain": [ + [ + "VUBXDMouseMidBrainQ0212", + "VU BXD Midbrain Agilent SurePrint G3 Mouse GE (Feb12) Quantile" + ] + ], + "Muscle": [ + [ + "EPFLMouseMuscleRMA1211", + "EPFL/LISP BXD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ], + [ + "EPFLMouseMuscleHFDRMA1211", + "EPFL/LISP BXD HFD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ], + [ + "EPFLMouseMuscleCDRMA1211", + "EPFL/LISP BXD CD Muscle Affy Mouse Gene 1.0 ST (Dec11) RMA **" + ] + ], + "Neocortex": [ + [ + "DevNeocortex_ILM6.2P14RInv_1111", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov11) RankInv **" + ], + [ + "DevNeocortex_ILM6.2P3RInv_1111", + "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov11) RankInv **" + ], + [ + "HQFNeoc_1210v2_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Dec10v2) RankInv" + ], + [ + "HQFNeoc_1210_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Dec10) RankInv" + ], + [ + "HQFNeoc_0208_RankInv", + "HQF BXD Neocortex ILM6v1.1 (Feb08) RankInv" + ], + [ + "DevNeocortex_ILM6.2P3RInv_1110", + "BIDMC/UTHSC Dev Neocortex P3 ILMv6.2 (Nov10) RankInv **" + ], + [ + "DevNeocortex_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Neocortex P14 ILMv6.2 (Nov10) RankInv **" + ] + ], + "Nucleus Accumbens": [ + [ + "VCUSalo_1007_R", + "VCU BXD NA Sal M430 2.0 (Oct07) RMA" + ], + [ + "VCUEtOH_1007_R", + "VCU BXD NA EtOH M430 2.0 (Oct07) RMA **" + ], + [ + "VCUSal_1007_R", + "VCU BXD NA Et vs Sal M430 2.0 (Oct07) Sscore **" + ] + ], + "Phenotypes": [ + [ + "BXDPublish", + "BXD Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ + [ + "VCUEtOH_1206_R", + "VCU BXD PFC EtOH M430 2.0 (Dec06) RMA" + ], + [ + "VCUSal_1206_R", + "VCU BXD PFC Sal M430 2.0 (Dec06) RMA" + ], + [ + "VCUSal_1006_R", + "VCU BXD PFC Et vs Sal M430 2.0 (Dec06) Sscore" + ], + [ + "VCU_PF_Air_0111_R", + "VCU BXD PFC CIE Air M430 2.0 (Jan11) RMA **" + ], + [ + "VCU_PF_Et_0111_R", + "VCU BXD PFC CIE EtOH M430 2.0 (Jan11) RMA **" + ], + [ + "VCU_PF_AvE_0111_Ss", + "VCU BXD PFC EtOH vs CIE Air M430 2.0 (Jan11) Sscore **" + ] + ], + "Retina": [ + [ + "Illum_Retina_BXD_RankInv0410", + "HEI Retina Illumina V6.2 (April 2010) RankInv" + ], + [ + "B6D2ONCILM_0412", + "B6D2 ONC Illumina v6.1 (Apr12) RankInv **" + ], + [ + "ONCRetILM6_0412", + "ONC Retina Illumina V6.2 (Apr12) RankInv **" + ], + [ + "HEIONCvsCRetILM6_0911", + "HEI ONC vs Control Retina Illumina V6.2 (Sep11) RankInv **" + ], + [ + "G2HEIONCRetILM6_0911", + "G2 HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" + ], + [ + "HEIONCRetILM6_0911", + "HEI ONC Retina Illumina V6.2 (Sep11) RankInv **" + ], + [ + "ILM_Retina_BXD_F_RankInv1210", + "HEI Retina Females Illumina V6.2 (Dec10) RankInv **" + ], + [ + "ILM_Retina_BXD_M_RankInv1210", + "HEI Retina Males Illumina V6.2 (Dec10) RankInv **" + ], + [ + "ILM_Retina_BXD_FM_RankInv1210", + "HEI Retina F-M Illumina V6.2 (Dec10) RankInv **" + ], + [ + "G2NEI_ILM_Retina_BXD_RI0410", + "G2NEI Retina Illumina V6.2 (April 2010) RankInv **" + ] + ], + "Spleen": [ + [ + "UTHSC_SPL_RMA_1210", + "UTHSC Affy MoGene 1.0 ST Spleen (Dec10) RMA" + ], + [ + "UTHSC_SPL_RMA_1010", + "UTHSC Affy MoGene 1.0 ST Spleen (Oct10) RMA" + ], + [ + "IoP_SPL_RMA_0509", + "IoP Affy MOE 430v2 Spleen (May09) RMA" + ], + [ + "Illum_BXD_Spl_1108", + "UWA Illumina Spleen (Nov08) RSN **" + ], + [ + "UTK_BXDSpl_VST_0110", + "UTK Spleen ILM6.1 (Jan10) VST" + ] + ], + "Striatum": [ + [ + "DevStriatum_ILM6.2P3RInv_1111", + "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov11) RankInv **" + ], + [ + "DevStriatum_ILM6.2P14RInv_1111", + "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov11) RankInv **" + ], + [ + "UTHSC_Striatum_RankInv_1210", + "HQF BXD Striatum ILM6.1 (Dec10v2) RankInv" + ], + [ + "UTHSC_Str_RankInv_1210", + "HQF BXD Striatum ILM6.1 (Dec10) RankInv" + ], + [ + "UTHSC_1107_RankInv", + "HQF BXD Striatum ILM6.1 (Nov07) RankInv" + ], + [ + "SA_M2_0405_MC", + "HBP Rosen Striatum M430V2 (Apr05) MAS5 Clean" + ], + [ + "SA_M2_0405_RC", + "HBP Rosen Striatum M430V2 (Apr05) RMA Clean" + ], + [ + "SA_M2_0405_PC", + "HBP Rosen Striatum M430V2 (Apr05) PDNN Clean" + ], + [ + "SA_M2_0405_SS", + "HBP Rosen Striatum M430V2 (Apr05) SScore" + ], + [ + "SA_M2_0405_RR", + "HBP Rosen Striatum M430V2 (Apr05) RMA Orig" + ], + [ + "Striatum_Exon_0209", + "HQF Striatum Exon (Feb09) RMA" + ], + [ + "DevStriatum_ILM6.2P14RInv_1110", + "BIDMC/UTHSC Dev Striatum P14 ILMv6.2 (Nov10) RankInv **" + ], + [ + "DevStriatum_ILM6.2P3RInv_1110", + "BIDMC/UTHSC Dev Striatum P3 ILMv6.2 (Nov10) RankInv **" + ] + ], + "T Cell (helper)": [ + [ + "RTHC_0211_R", + "HZI Thelp M430v2 (Feb11) RMA" + ] + ], + "T Cell (regulatory)": [ + [ + "RTC_1106_R", + "HZI Treg M430v2 (Feb11) RMA" + ] + ], + "Thymus": [ + [ + "Illum_BXD_Thy_1108", + "UWA Illumina Thymus (Nov08) RSN **" + ] + ], + "Ventral Tegmental Area": [ + [ + "VCUEtOH_0609_R", + "VCU BXD VTA EtOH M430 2.0 (Jun09) RMA **" + ], + [ + "VCUSal_0609_R", + "VCU BXD VTA Sal M430 2.0 (Jun09) RMA **" + ], + [ + "VCUEtvsSal_0609_R", + "VCU BXD VTA Et vs Sal M430 2.0 (Jun09) Sscore **" + ] + ] + }, + "BXH": { + "Cartilage": [ + [ + "UCLA_BXHBXD_CARTILAGE_V2", + "UCLA BXH and BXD Cartilage v2" + ], + [ + "UCLA_BXHBXD_CARTILAGE", + "UCLA BXH and BXD Cartilage" + ], + [ + "UCLA_BXH_CARTILAGE", + "UCLA BXH Cartilage" + ] + ], + "Genotypes": [ + [ + "BXHGeno", + "BXH Genotypes" + ] + ], + "Phenotypes": [ + [ + "BXHPublish", + "BXH Published Phenotypes" + ] + ] + }, + "CTB6F2": { + "Adipose": [ + [ + "UCLA_CTB6B6CTF2_ADIPOSE_MALE", + "UCLA CTB6B6CTF2 Adipose Male mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_ADIPOSE_FEMALE", + "UCLA CTB6B6CTF2 Adipose Female mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_ADIPOSE_2005", + "UCLA CTB6/B6CTF2 Adipose (2005) mlratio **" + ] + ], + "Brain": [ + [ + "UCLA_CTB6B6CTF2_BRAIN_MALE", + "UCLA CTB6B6CTF2 Brain Male mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_BRAIN_FEMALE", + "UCLA CTB6B6CTF2 Brain Female mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_BRAIN_2005", + "UCLA CTB6/B6CTF2 Brain (2005) mlratio **" + ] + ], + "Genotypes": [ + [ + "CTB6F2Geno", + "CTB6F2 Genotypes" + ] + ], + "Liver": [ + [ + "UCLA_CTB6B6CTF2_LIVER_MALE", + "UCLA CTB6B6CTF2 Liver Male mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_LIVER_FEMALE", + "UCLA CTB6B6CTF2 Liver Female mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_LIVER_2005", + "UCLA CTB6/B6CTF2 Liver (2005) mlratio **" + ] + ], + "Muscle": [ + [ + "UCLA_CTB6B6CTF2_MUSCLE_MALE", + "UCLA CTB6B6CTF2 Muscle Male mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_MUSCLE_FEMALE", + "UCLA CTB6B6CTF2 Muscle Female mlratio **" + ], + [ + "UCLA_CTB6B6CTF2_MUSCLE_2005", + "UCLA CTB6/B6CTF2 Muscle (2005) mlratio **" + ] + ], + "Phenotypes": [ + [ + "CTB6F2Publish", + "CTB6F2 Published Phenotypes" + ] + ] + }, + "CXB": { + "Genotypes": [ + [ + "CXBGeno", + "CXB Genotypes" + ] + ], + "Hippocampus": [ + [ + "HC_M2CB_1205_R", + "Hippocampus Consortium M430v2 CXB (Dec05) RMA" + ], + [ + "HC_M2CB_1205_P", + "Hippocampus Consortium M430v2 CXB (Dec05) PDNN" + ] + ], + "Phenotypes": [ + [ + "CXBPublish", + "CXB Published Phenotypes" + ] + ], + "Spleen": [ + [ + "STSPL_1107_R", + "Stuart Spleen M430v2 (Nov07) RMA" + ] + ] + }, + "HS": { + "Genotypes": [ + [ + "HSGeno", + "HS Genotypes" + ] + ], + "Hippocampus": [ + [ + "OXUKHS_ILMHipp_RI0510", + "OX UK HS ILM6v1.1 Hippocampus (May 2010) RankInv" + ] + ], + "Liver": [ + [ + "OXUKHS_ILMLiver_RI0510", + "OX UK HS ILM6v1.1 Liver (May 2010) RankInv" + ] + ], + "Lung": [ + [ + "OXUKHS_ILMLung_RI0510", + "OX UK HS ILM6v1.1 Lung (May 2010) RankInv" + ] + ], + "Phenotypes": [ + [ + "HSPublish", + "HS Published Phenotypes" + ] + ] + }, + "HS-CC": { + "Genotypes": [ + [ + "HS-CCGeno", + "HS-CC Genotypes" + ] + ], + "Phenotypes": [ + [ + "HS-CCPublish", + "HS-CC Published Phenotypes" + ] + ], + "Striatum": [ + [ + "OHSU_HS-CC_ILMStr_0211", + "OHSU HS-CC Striatum ILM6v1 (Feb11) RankInv" + ] + ] + }, + "LXS": { + "Genotypes": [ + [ + "LXSGeno", + "LXS Genotypes" + ] + ], + "Hippocampus": [ + [ + "Illum_LXS_Hipp_loess0807", + "Hippocampus Illumina (Aug07) LOESS" + ], + [ + "Illum_LXS_Hipp_loess_nb0807", + "Hippocampus Illumina (Aug07) LOESS_NB" + ], + [ + "Illum_LXS_Hipp_quant0807", + "Hippocampus Illumina (Aug07) QUANT" + ], + [ + "Illum_LXS_Hipp_quant_nb0807", + "Hippocampus Illumina (Aug07) QUANT_NB" + ], + [ + "Illum_LXS_Hipp_rsn0807", + "Hippocampus Illumina (Aug07) RSN" + ], + [ + "Illum_LXS_Hipp_rsn_nb0807", + "Hippocampus Illumina (Aug07) RSN_NB" + ], + [ + "Hipp_Illumina_RankInv_0507", + "Hippocampus Illumina (May07) RankInv" + ], + [ + "Illum_LXS_Hipp_NON_1008", + "Hippocampus Illumina NON (Oct08) RankInv beta" + ], + [ + "Illum_LXS_Hipp_RSE_1008", + "Hippocampus Illumina RSE (Oct08) RankInv beta" + ], + [ + "Illum_LXS_Hipp_NOE_1008", + "Hippocampus Illumina NOE (Oct08) RankInv beta" + ], + [ + "Illum_LXS_Hipp_RSS_1008", + "Hippocampus Illumina RSS (Oct08) RankInv beta" + ], + [ + "Illum_LXS_Hipp_NOS_1008", + "Hippocampus Illumina NOS (Oct08) RankInv beta" + ] + ], + "Phenotypes": [ + [ + "LXSPublish", + "LXS Published Phenotypes" + ] + ], + "Prefrontal Cortex": [ + [ + "VCUEtOH_0806_R", + "VCU LXS PFC EtOH M430A 2.0 (Aug06) RMA **" + ], + [ + "VCUSal_0806_R", + "VCU LXS PFC Sal M430A 2.0 (Aug06) RMA" + ], + [ + "VCUEt_vs_Sal_0806_R", + "VCU LXS PFC Et vs Sal M430A 2.0 (Aug06) Sscore **" + ] + ] + }, + "MDP": { + "Genotypes": [ + [ + "MDPGeno", + "MDP Genotypes" + ] + ], + "Hippocampus": [ + [ + "UMUTAffyExon_0209_RMA_MDP", + "UMUTAffy Hippocampus Exon (Feb09) RMA MDP" + ], + [ + "HC_M2_0606_MDP", + "Hippocampus Consortium M430v2 (Jun06) RMA MDP" + ] + ], + "Liver": [ + [ + "JAX_CSB_L_0711", + "JAX Liver Affy M430 2.0 (Jul11) MDP" + ], + [ + "JAX_CSB_L_HF_0711", + "JAX Liver HF Affy M430 2.0 (Jul11) MDP" + ], + [ + "JAX_CSB_L_6C_0711", + "JAX Liver 6C Affy M430 2.0 (Jul11) MDP" + ] + ], + "Phenotypes": [ + [ + "MDPPublish", + "Mouse Phenome Database" + ] + ] + }, + "NZBXFVB-N2": { + "Genotypes": [ + [ + "NZBXFVB-N2Geno", + "NZBXFVB-N2 Genotypes" + ] + ], + "Mammary Tumors": [ + [ + "NCI_Mam_Tum_RMA_0409", + "NCI Mammary M430v2 (Apr09) RMA" + ] + ], + "Phenotypes": [ + [ + "NZBXFVB-N2Publish", + "NZBXFVB-N2 Published Phenotypes" + ] + ] + } + }, + "rat": { + "HXBBXH": { + "Adrenal Gland": [ + [ + "HXB_Adrenal_1208", + "MDC/CAS/UCL Adrenal 230A (Dec08) RMA" + ] + ], + "Genotypes": [ + [ + "HXBBXHGeno", + "HXBBXH Genotypes" + ] + ], + "Heart": [ + [ + "HXB_Heart_1208", + "MDC/CAS/UCL Heart 230_V2 (Dec08) RMA" + ] + ], + "Hippocampus": [ + [ + "UT_HippRatEx_RMA_0709", + "UT Hippocampus Affy RaEx 1.0 Exon (Jul09) RMA" + ] + ], + "Kidney": [ + [ + "KI_2A_0405_M", + "MDC/CAS/ICL Kidney 230A (Apr05) MAS5" + ], + [ + "KI_2A_0405_Rz", + "MDC/CAS/ICL Kidney 230A (Apr05) RMA 2z+8" + ], + [ + "KI_2A_0405_R", + "MDC/CAS/ICL Kidney 230A (Apr05) RMA" + ] + ], + "Liver": [ + [ + "HXB_Liver_1208", + "MDC/CAS/UCL Liver 230v2 (Dec08) RMA" + ] + ], + "Peritoneal Fat": [ + [ + "FT_2A_0805_M", + "MDC/CAS/ICL Peritoneal Fat 230A (Aug05) MAS5" + ], + [ + "FT_2A_0605_Rz", + "MDC/CAS/ICL Peritoneal Fat 230A (Jun05) RMA 2z+8" + ] + ], + "Phenotypes": [ + [ + "HXBBXHPublish", + "HXBBXH Published Phenotypes" + ] + ] + }, + "SRxSHRSPF2": { + "Eye": [ + [ + "UIOWA_Eye_RMA_0906", + "UIOWA Eye mRNA RAE230v2 (Sep06) RMA" + ] + ], + "Genotypes": [ + [ + "SRxSHRSPF2Geno", + "SRxSHRSPF2 Genotypes" + ] + ], + "Phenotypes": [ + [ + "SRxSHRSPF2Publish", + "SRxSHRSPF2 Published Phenotypes" + ] + ] + } + }, + "soybean": { + "J12XJ58F2": { + "Genotypes": [ + [ + "J12XJ58F2Geno", + "J12XJ58F2 Genotypes" + ] + ], + "Phenotypes": [ + [ + "J12XJ58F2Publish", + "J12XJ58F2 Published Phenotypes" + ] + ] + } + }, + "tomato": { + "LXP": { + "Genotypes": [ + [ + "LXPGeno", + "LXP Genotypes" + ] + ], + "Phenotypes": [ + [ + "LXPPublish", + "LXP Published Phenotypes" + ] + ] + } + } + }, + "groups": { + "All Species": [ + [ + "All Groups", + "All Groups" + ] + ], + "arabidopsis": [ + [ + "BayXSha", + "BayXSha" + ], + [ + "ColXBur", + "ColXBur" + ], + [ + "ColXCvi", + "ColXCvi" + ] + ], + "barley": [ + [ + "QSM", + "QSM" + ], + [ + "SXM", + "SXM" + ] + ], + "drosophila": [ + [ + "DGRP", + "Drosophila Genetic Reference Panel" + ], + [ + "Oregon-R_x_2b3", + "Oregon-R x 2b3" + ] + ], + "human": [ + [ + "AD-cases-controls", + "AD Cases & Controls (Liang)" + ], + [ + "AD-cases-controls-Myers", + "AD Cases & Controls (Myers)" + ], + [ + "CANDLE", + "CANDLE" + ], + [ + "CEPH-2004", + "CEPH Families" + ], + [ + "HB", + "Harvard Brain Tissue Resource Center" + ], + [ + "HLC", + "Human Liver Cohort" + ], + [ + "HSB", + "KIN/YSM" + ] + ], + "macaque monkey": [ + [ + "Macaca-fasicularis", + "Macaca fasicularis (Cynomolgus monkey)" + ] + ], + "mouse": [ + [ + "AKXD", + "AKXD" + ], + [ + "AXBXA", + "AXB/BXA" + ], + [ + "B6BTBRF2", + "B6BTBRF2" + ], + [ + "B6D2F2", + "B6D2F2" + ], + [ + "BDF2-1999", + "BDF2 UCLA" + ], + [ + "BDF2-2005", + "BDF2-2005" + ], + [ + "BHF2", + "BHF2 (Apoe Null) UCLA" + ], + [ + "BHHBF2", + "BH/HB F2 UCLA" + ], + [ + "BXD", + "BXD" + ], + [ + "BXH", + "BXH" + ], + [ + "CTB6F2", + "CastB6/B6Cast F2 UCLA" + ], + [ + "CXB", + "CXB" + ], + [ + "HS", + "Heterogeneous Stock" + ], + [ + "HS-CC", + "Heterogeneous Stock Collaborative Cross" + ], + [ + "LXS", + "LXS" + ], + [ + "MDP", + "Mouse Diversity Panel" + ], + [ + "NZBXFVB-N2", + "NZB/FVB N2 NCI" + ] + ], + "rat": [ + [ + "HXBBXH", + "HXB/BXH" + ], + [ + "SRxSHRSPF2", + "UIOWA SRxSHRSP F2" + ] + ], + "soybean": [ + [ + "J12XJ58F2", + "J12XJ58F2" + ] + ], + "tomato": [ + [ + "LXP", + "LXP" + ] + ] + }, + "species": [ + [ + "human", + "Human" + ], + [ + "macaque monkey", + "Macaque monkey" + ], + [ + "mouse", + "Mouse" + ], + [ + "rat", + "Rat" + ], + [ + "drosophila", + "Drosophila" + ], + [ + "arabidopsis", + "Arabidopsis thaliana" + ], + [ + "barley", + "Barley" + ], + [ + "soybean", + "Soybean" + ], + [ + "tomato", + "Tomato" + ], + [ + "All Species", + "All Species" + ] + ], + "types": { + "All Species": { + "All Groups": [ + [ + "Phenotypes", + "Phenotypes" + ] + ] + }, + "arabidopsis": { + "BayXSha": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ] + ], + "ColXBur": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ] + ], + "ColXCvi": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ] + ] + }, + "barley": { + "QSM": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Leaf", + "Leaf mRNA" + ] + ], + "SXM": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Embryo", + "Embryo mRNA" + ], + [ + "Leaf", + "Leaf mRNA" + ] + ] + }, + "drosophila": { + "DGRP": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Whole Body", + "Whole Body mRNA" + ] + ], + "Oregon-R_x_2b3": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Whole Body", + "Whole Body mRNA" + ] + ] + }, + "human": { + "AD-cases-controls": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Brain", + "Brain mRNA" + ] + ], + "AD-cases-controls-Myers": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Brain", + "Brain mRNA" + ] + ], + "CANDLE": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Newborn Cord Blood", + "Newborn Cord Blood mRNA" + ] + ], + "CEPH-2004": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Lymphoblast B-cell", + "Lymphoblast B-cell mRNA" + ] + ], + "HB": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Cerebellum", + "Cerebellum mRNA" + ], + [ + "Prefrontal Cortex", + "Prefrontal Cortex mRNA" + ], + [ + "Primary Visual Cortex", + "Primary Visual Cortex mRNA" + ] + ], + "HLC": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Liver", + "Liver mRNA" + ] + ], + "HSB": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Amygdala", + "Amygdala mRNA" + ], + [ + "Caudal Ganglionic Eminence", + "Caudal Ganglionic Eminence mRNA" + ], + [ + "Cerebellar Cortex", + "Cerebellar Cortex mRNA" + ], + [ + "Diencephalon", + "Diencephalon mRNA" + ], + [ + "Dorsal Thalamus", + "Dorsal Thalamus mRNA" + ], + [ + "Dorsolateral Prefrontal Cortex", + "Dorsolateral Prefrontal Cortex mRNA" + ], + [ + "Frontal Cerebral Wall", + "Frontal Cerebral Wall mRNA" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Inferior Temporal Cortex", + "Inferior Temporal Cortex mRNA" + ], + [ + "Lateral Ganglionic Eminence", + "Lateral Ganglionic Eminence mRNA" + ], + [ + "Medial Ganglionic Eminence", + "Medial Ganglionic Eminence mRNA" + ], + [ + "Medial Prefrontal Cortex", + "Medial Prefrontal Cortex mRNA" + ], + [ + "Mediodorsal Nucleus of Thalamus", + "Mediodorsal Nucleus of Thalamus mRNA" + ], + [ + "Occipital Cerebral Wall", + "Occipital Cerebral Wall mRNA" + ], + [ + "Orbital Prefrontal Cortex", + "Orbital Prefrontal Cortex mRNA" + ], + [ + "Parietal Cerebral Wall", + "Parietal Cerebral Wall mRNA" + ], + [ + "Posterior Inferior Parietal Cortex", + "Posterior Inferior Parietal Cortex mRNA" + ], + [ + "Posterior Superior Temporal Cortex", + "Posterior Superior Temporal Cortex mRNA" + ], + [ + "Primary Auditory (A1) Cortex", + "Primary Auditory (A1) Cortex mRNA" + ], + [ + "Primary Motor (M1) Cortex", + "Primary Motor (M1) Cortex mRNA" + ], + [ + "Primary Somatosensory (S1) Cortex", + "Primary Somatosensory (S1) Cortex mRNA" + ], + [ + "Primary Visual Cortex", + "Primary Visual Cortex mRNA" + ], + [ + "Striatum", + "Striatum mRNA" + ], + [ + "Temporal Cerebral Wall", + "Temporal Cerebral Wall mRNA" + ], + [ + "Upper (Rostral) Rhombic Lip", + "Upper (Rostral) Rhombic Lip mRNA" + ], + [ + "Ventral Forebrain", + "Ventral Forebrain mRNA" + ], + [ + "Ventrolateral Prefrontal Cortex", + "Ventrolateral Prefrontal Cortex mRNA" + ] + ] + }, + "macaque monkey": { + "Macaca-fasicularis": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Amygdala", + "Amygdala mRNA" + ], + [ + "Brain", + "Brain mRNA" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Nucleus Accumbens", + "Nucleus Accumbens mRNA" + ], + [ + "Prefrontal Cortex", + "Prefrontal Cortex mRNA" + ] + ] + }, + "mouse": { + "AKXD": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Mammary Tumors", + "Mammary Tumors mRNA" + ] + ], + "AXBXA": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Eye", + "Eye mRNA" + ] + ], + "B6BTBRF2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Liver", + "Liver mRNA" + ] + ], + "B6D2F2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Brain", + "Brain mRNA" + ] + ], + "BDF2-1999": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Liver", + "Liver mRNA" + ] + ], + "BDF2-2005": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Striatum", + "Striatum mRNA" + ] + ], + "BHF2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Adipose", + "Adipose mRNA" + ], + [ + "Brain", + "Brain mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Muscle", + "Muscle mRNA" + ] + ], + "BHHBF2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Adipose", + "Adipose mRNA" + ], + [ + "Brain", + "Brain mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Muscle", + "Muscle mRNA" + ] + ], + "BXD": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Amygdala", + "Amygdala mRNA" + ], + [ + "Brain", + "Brain mRNA" + ], + [ + "Cartilage", + "Cartilage mRNA" + ], + [ + "Cerebellum", + "Cerebellum mRNA" + ], + [ + "Eye", + "Eye mRNA" + ], + [ + "Hematopoietic Cells", + "Hematopoietic Cells mRNA" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Hypothalamus", + "Hypothalamus mRNA" + ], + [ + "Kidney", + "Kidney mRNA" + ], + [ + "Leucocytes", + "Leucocytes mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Lung", + "Lung mRNA" + ], + [ + "Midbrain", + "Midbrain mRNA" + ], + [ + "Muscle", + "Muscle mRNA" + ], + [ + "Neocortex", + "Neocortex mRNA" + ], + [ + "Nucleus Accumbens", + "Nucleus Accumbens mRNA" + ], + [ + "Prefrontal Cortex", + "Prefrontal Cortex mRNA" + ], + [ + "Retina", + "Retina mRNA" + ], + [ + "Spleen", + "Spleen mRNA" + ], + [ + "Striatum", + "Striatum mRNA" + ], + [ + "T Cell (helper)", + "T Cell (helper) mRNA" + ], + [ + "T Cell (regulatory)", + "T Cell (regulatory) mRNA" + ], + [ + "Thymus", + "Thymus mRNA" + ], + [ + "Ventral Tegmental Area", + "Ventral Tegmental Area mRNA" + ] + ], + "BXH": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Cartilage", + "Cartilage mRNA" + ] + ], + "CTB6F2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Adipose", + "Adipose mRNA" + ], + [ + "Brain", + "Brain mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Muscle", + "Muscle mRNA" + ] + ], + "CXB": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Spleen", + "Spleen mRNA" + ] + ], + "HS": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Lung", + "Lung mRNA" + ] + ], + "HS-CC": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Striatum", + "Striatum mRNA" + ] + ], + "LXS": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Prefrontal Cortex", + "Prefrontal Cortex mRNA" + ] + ], + "MDP": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Liver", + "Liver mRNA" + ] + ], + "NZBXFVB-N2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Mammary Tumors", + "Mammary Tumors mRNA" + ] + ] + }, + "rat": { + "HXBBXH": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Adrenal Gland", + "Adrenal Gland mRNA" + ], + [ + "Heart", + "Heart mRNA" + ], + [ + "Hippocampus", + "Hippocampus mRNA" + ], + [ + "Kidney", + "Kidney mRNA" + ], + [ + "Liver", + "Liver mRNA" + ], + [ + "Peritoneal Fat", + "Peritoneal Fat mRNA" + ] + ], + "SRxSHRSPF2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ], + [ + "Eye", + "Eye mRNA" + ] + ] + }, + "soybean": { + "J12XJ58F2": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ] + ] + }, + "tomato": { + "LXP": [ + [ + "Phenotypes", + "Phenotypes" + ], + [ + "Genotypes", + "Genotypes" + ] + ] + } + } +} \ No newline at end of file diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 79f6e78e..b5c1d6ac 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -11,1211 +11,27 @@ + + {% for key in hddn %} + + {% endfor %} - -
      - - -
      -
      Aliases
      -
      {{ this_trait.alias_fmt }}
      - -
      Location
      -
      {{ this_trait.location_fmt }}
      - -
      Database
      -
      - - {{ this_trait.database.name }} - -
      - -
      - - BLAT Specifity - -
      -
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      - -
      BLAT Score
      -
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      -
      - - - {% for key in hddn %} - - {% endfor %} - -
      -
      - - - - - -
      - -
      - - - - - - - - - +
      + + + {% include 'show_trait_details.html' %} + {% include 'show_trait_statistics.html' %} + {% include 'show_trait_calculate_correlations.html' %} + {% include 'show_trait_mapping_tools.html' %} + {% include 'show_trait_edit_data.html' %}
      - - - -

        Basic Statistics

      - - -

      Include: -
      -
      -
      -
      - -
      - - - - - -
      - {% for sd in stats_data %} -
      - - -
      - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      StatisticValue
      N of Samples{{ sd.N }}
      Mean{{ "%2.3f" % sd.traitmean }}
      Median{{ "%2.3f" % sd.traitmedian }}
      Standard Error (SE){{ "%2.3f" % sd.traitsem }}
      Standard Deviation (SD){{ "%2.3f" % sd.traitstdev }}
      Minimum{{ "%2.3f" % sd.min }}
      Maximum{{ "%2.3f" % sd.max }}
      Range (log2){{ "%2.3f" % sd.range_log2 }}
      Range (fold){{ "%2.3f" % sd.range_fold }}
      Interquartile Range{{ "%2.3f" % sd.interquartile }}
      -
      -
      - -
      - - - - - - - - -
      nP_OE9u7BSx.gif

      -
      - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      -
      - More about Normal Probability Plots and more - about interpreting these plots from the glossary
      -
      - -
      - - - - -
      - Box_gUFtEOVI.gif - -

      More about Box Plots

      -
      -
      - -
      - - - - -
      Bar_y7L2rYlL.gif
      -
      - -
      - - - - -
      Bar_1Z4GjYFq.gif
      -
      -
      - {% endfor %} - {# Not used now - Todo: Delete after we're sure this is right. -
      - - -
      - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      StatisticValue
      N of Samples71
      Mean6.109
      Median6.084
      Standard Error (SE)0.022
      Standard Deviation (SD)0.187
      Minimum5.782
      Maximum6.579
      Range (log2)0.797
      Range (fold)1.74
      Interquartile Range1.13
      -
      -
      - -
      - - - - - - - - -
      nP_eSYO7ZQg.gif

      -
      - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      -
      - More about Normal Probability Plots and more - about interpreting these plots from the glossary
      -
      - -
      - - - - -
      - Box_PWNWQMfj.gif - -

      More about Box Plots

      -
      -
      - -
      - - - - -
      Bar_VuPqYbR6.gif
      -
      - -
      - - - - -
      Bar_9PbdvXZ9.gif
      -
      -
      - -
      - - - - -
      - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      StatisticValue
      N of Samples32
      Mean6.176
      Median6.170
      Standard Error (SE)0.027
      Standard Deviation (SD)0.150
      Minimum5.906
      Maximum6.485
      Range (log2)0.579
      Range (fold)1.49
      Interquartile Range1.15
      -
      -
      - -
      - - - - - - - - -
      nP_swDAFlJy.gif

      -
      - This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      -
      - More about Normal Probability Plots and more - about interpreting these plots from the glossary
      -
      - -
      - - - - -
      - Box_6sQJ8xhK.gif - -

      More about Box Plots

      -
      -
      - -
      - - - - -
      Bar_QMWE2VEp.gif
      -
      - -
      - - - - -
      Bar_X07QmgsX.gif
      -
      -
      -
      - #} - -

        Calculate Correlations

      - -

      - - - - - -
      -
      -
      - - - - -
      - - - - - - - - - - - - - - - - - - - - - - - - - -
      Method: - -
      Database: - -
      Return:
      Samples: - -
      -
      -
      - Pearson -     - Spearman Rank -
      -
      - -

      - - - The Sample Correlation - is computed - between trait data and any
      - other traits in the sample database selected above. Use - Spearman - Rank
      - when the sample size is small (<20) or when there are influential outliers. -
      - - - -
      -
      -
      -
      -
      - -

        Mapping Tools

      - -

      - - - - - -
      -
      - - -
      - - - - - - - - -
      - - - - - - - - - - - - -
      Chromosome:
      Mapping Scale:

      - Permutation Test (n=2000)
      - Bootstrap Test (n=2000)
      - Use Parents
      - Use Weighted
      -
      -
      -
      -
      Interval Mapping computes linkage maps - for the entire genome or single
      - chromosomes. The Permutation Test estimates suggestive and - significant
      - linkage scores. The Bootstrap Test estimates the precision of the QTL - location.

      -
      - -
      - - - - - - - - -
      - - - - - - - - - - - - - - - - - - -
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      -
      -
      -
      Marker regression computes and displays LRS - values for individual markers.
      - This function also lists additive effects (phenotype units per allele) and
      - dominance deviations for some datasets.

      -
      - -
      - - - - - - - - -
      - - - - - - - - - - - - - - - - - - -
      Chromosome:
      Mapping Scale:
      Control Locus:

      - Permutation Test (n=2000)
      - Bootstrap Test (n=2000)
      - Use Parents
      -
      -
      -
      -
      Composite Interval Mapping allows you to control - for a single marker as
      - a cofactor. To find a control marker, run the Marker Regression function.

      -
      - -
      - - - - - - - - -
      - - - - - - - - - - - - -
      Sort by:
      Return:

      - Permutation Test - (n=500)
      -
      -
      -
      -
      Pair-Scan searches for pairs of chromosomal regions - that are
      - involved in two-locus epistatic interactions.

      -
      -
      -
      - -

        Review and Edit Data

      - - - -

      - -
      - - - -
      -
      -
      -
      - Block samples -

      Edit or delete values in the Trait Data boxes, and use the - Reset option as - needed. -

      - - -
      - - - - - - -
      - - -
      - - {% if sample_groups[0].attributes %} -
      - - - - -
      - {% endif %} -
      -
      - - - - - - - -
      -
      -
      -
      -

      Outliers highlighted in - yellow - can be hidden using - the Hide Outliers button. -

      - -

      Samples with no value (x) can be hidden by clicking - Hide No Value button. -

      -
      -
      -
      - - - -
      - {% for sample_type in sample_groups %} -
      -

      {{ sample_type.header }}

      - -
      - - - - - - - - {% if sample_type.se_exists() %} - - - - {% endif %} - - {% for attribute in sample_type.attributes|sort() %} - - {% endfor %} - - - {% for sample in sample_type.sample_list %} - - - - - - {# Todo: Add IDs #} - - - {% if sample_type.se_exists() %} - - - {# Todo: Add IDs #} - - {% endif %} - - {# Loop through each attribute type and input value #} - {% for attribute in sample_type.attributes|sort() %} - - {% endfor %} - - {% endfor %} - -
      IndexSampleValue SE - {{ sample_type.attributes[attribute].name }} -
      - {{ loop.index }} - - - - {{ sample.name }} - - - - - ± - - - - {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} -
      -
      -
      - {% endfor %} -
      -
      -
      - - -
      - - - + diff --git a/wqflask/wqflask/templates/show_trait_calculate_correlations.html b/wqflask/wqflask/templates/show_trait_calculate_correlations.html new file mode 100644 index 00000000..543afadd --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_calculate_correlations.html @@ -0,0 +1,130 @@ +

        Calculate Correlations

      + +

      + + + + + +
      +
      +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      Method: + +
      Database: + +
      Return:
      Samples: + +
      +
      +
      + Pearson +     + Spearman Rank +
      +
      + +

      + + + The Sample Correlation + is computed + between trait data and any
      + other traits in the sample database selected above. Use + Spearman + Rank
      + when the sample size is small (<20) or when there are influential outliers. +
      + + + +
      +
      +
      +
      +
      diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html new file mode 100644 index 00000000..e45886b4 --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -0,0 +1,63 @@ +
      +
      Aliases
      +
      {{ this_trait.alias_fmt }}
      + +
      Location
      +
      {{ this_trait.location_fmt }}
      + +
      Database
      +
      + + {{ this_trait.database.name }} + +
      + +
      + + BLAT Specifity + +
      +
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      + +
      BLAT Score
      +
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      +
      + + + +
      +
      + + + + + +
      + +
      + + + + + + + + + +
      +
      diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html new file mode 100644 index 00000000..ce1642d3 --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -0,0 +1,163 @@ +
      +

      Review and Edit Data

      + +
      +
      + Block samples +

      Edit or delete values in the Trait Data boxes, and use the + Reset option as + needed. +

      + +
      + + + + +
      + + +
      + + {% if sample_groups[0].attributes %} +
      + + + + +
      + {% endif %} +
      +
      + + + + + + + +
      +
      +
      + +
      +

      Outliers highlighted in + yellow + can be hidden using + the Hide Outliers button. +

      + +

      Samples with no value (x) can be hidden by clicking + Hide No Value button. +

      +
      +
      +
      + +
      +

      Stats

      +
      +
      + +
      + {% for sample_type in sample_groups %} +
      +

      {{ sample_type.header }}

      + +
      + + + + + + + + {% if sample_type.se_exists() %} + + + + {% endif %} + + {% for attribute in sample_type.attributes|sort() %} + + {% endfor %} + + + {% for sample in sample_type.sample_list %} + + + + + + {# Todo: Add IDs #} + + + {% if sample_type.se_exists() %} + + + {# Todo: Add IDs #} + + {% endif %} + + {# Loop through each attribute type and input value #} + {% for attribute in sample_type.attributes|sort() %} + + {% endfor %} + + {% endfor %} + +
      IndexSampleValue SE + {{ sample_type.attributes[attribute].name }} +
      + {{ loop.index }} + + + + {{ sample.name }} + + + + + ± + + + + {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} +
      +
      +
      + {% endfor %} +
      + + + +
      diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html new file mode 100644 index 00000000..90498e9a --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -0,0 +1,382 @@ +

        Mapping Tools

      + +

      + + + + + +
      +
      + + +
      + + + + + + + + +
      + + + + + + + + + + + + +
      Chromosome:
      Mapping Scale:

      + Permutation Test (n=2000)
      + Bootstrap Test (n=2000)
      + Use Parents
      + Use Weighted
      +
      +
      +
      +
      Interval Mapping computes linkage maps + for the entire genome or single
      + chromosomes. The Permutation Test estimates suggestive and + significant
      + linkage scores. The Bootstrap Test estimates the precision of the QTL + location.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + + + + + + + +
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      +
      +
      +
      Marker regression computes and displays LRS + values for individual markers.
      + This function also lists additive effects (phenotype units per allele) and
      + dominance deviations for some datasets.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + + + + + + + +
      Chromosome:
      Mapping Scale:
      Control Locus:

      + Permutation Test (n=2000)
      + Bootstrap Test (n=2000)
      + Use Parents
      +
      +
      +
      +
      Composite Interval Mapping allows you to control + for a single marker as
      + a cofactor. To find a control marker, run the Marker Regression function.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + +
      Sort by:
      Return:

      + Permutation Test + (n=500)
      +
      +
      +
      +
      Pair-Scan searches for pairs of chromosomal regions + that are
      + involved in two-locus epistatic interactions.

      +
      +
      +
      + + + diff --git a/wqflask/wqflask/templates/show_trait_statistics.html b/wqflask/wqflask/templates/show_trait_statistics.html new file mode 100644 index 00000000..eda5466e --- /dev/null +++ b/wqflask/wqflask/templates/show_trait_statistics.html @@ -0,0 +1,433 @@ +
      + +
      +

      Basic Statistics

      + + +

      Include: +
      +
      +
      +
      + + {% for sd in stats_data %} +
      + + +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      StatisticValue
      N of Samples{{ sd.N }}
      Mean{{ "%2.3f" % sd.traitmean }}
      Median{{ "%2.3f" % sd.traitmedian }}
      Standard Error (SE){{ "%2.3f" % sd.traitsem }}
      Standard Deviation (SD){{ "%2.3f" % sd.traitstdev }}
      Minimum{{ "%2.3f" % sd.min }}
      Maximum{{ "%2.3f" % sd.max }}
      Range (log2){{ "%2.3f" % sd.range_log2 }}
      Range (fold){{ "%2.3f" % sd.range_fold }}
      Interquartile Range{{ "%2.3f" % sd.interquartile }}
      +
      +
      + +
      + + + + + + + + +
      nP_OE9u7BSx.gif

      +
      + This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      +
      + More about Normal Probability Plots and more + about interpreting these plots from the glossary
      +
      + +
      + + + + +
      + Box_gUFtEOVI.gif + +

      More about Box Plots

      +
      +
      + +
      + + + + +
      Bar_y7L2rYlL.gif
      +
      + +
      + + + + +
      Bar_1Z4GjYFq.gif
      +
      +
      + {% endfor %} + {# Not used now - Todo: Delete after we're sure this is right. +
      + + +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      StatisticValue
      N of Samples71
      Mean6.109
      Median6.084
      Standard Error (SE)0.022
      Standard Deviation (SD)0.187
      Minimum5.782
      Maximum6.579
      Range (log2)0.797
      Range (fold)1.74
      Interquartile Range1.13
      +
      +
      + +
      + + + + + + + + +
      nP_eSYO7ZQg.gif

      +
      + This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      +
      + More about Normal Probability Plots and more + about interpreting these plots from the glossary
      +
      + +
      + + + + +
      + Box_PWNWQMfj.gif + +

      More about Box Plots

      +
      +
      + +
      + + + + +
      Bar_VuPqYbR6.gif
      +
      + +
      + + + + +
      Bar_9PbdvXZ9.gif
      +
      +
      + +
      + + + + +
      + + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      StatisticValue
      N of Samples32
      Mean6.176
      Median6.170
      Standard Error (SE)0.027
      Standard Deviation (SD)0.150
      Minimum5.906
      Maximum6.485
      Range (log2)0.579
      Range (fold)1.49
      Interquartile Range1.15
      +
      +
      + +
      + + + + + + + + +
      nP_swDAFlJy.gif

      +
      + This plot evaluates whether data are normally distributed. Different symbols represent different groups.
      +
      + More about Normal Probability Plots and more + about interpreting these plots from the glossary
      +
      + +
      + + + + +
      + Box_6sQJ8xhK.gif + +

      More about Box Plots

      +
      +
      + +
      + + + + +
      Bar_QMWE2VEp.gif
      +
      + +
      + + + + +
      Bar_X07QmgsX.gif
      +
      +
      + + + + #} -- cgit v1.2.3 From 8fdd8a9e11ebe63bb421252d7a143bc9e2280d6e Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 9 Nov 2012 18:04:13 -0600 Subject: Did some work with adding code for LRS-related searches --- wqflask/wqflask/do_search.py | 114 +++++++++++++++++++++++++++++++++++++- wqflask/wqflask/search_results.py | 19 +++---- 2 files changed, 119 insertions(+), 14 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 2641431c..4517d9f5 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -5,6 +5,8 @@ from __future__ import print_function, division from pprint import pformat as pf +from dbFunction import webqtlDatabaseFunction + class DoSearch(object): """Parent class containing parameters/functions used for all searches""" @@ -45,6 +47,10 @@ class ProbeSetSearch(DoSearch): DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" + #Get group information for dataset and the species id + self.dataset.get_group() + self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) + base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -224,7 +230,9 @@ class WikiSearch(ProbeSetSearch): where_clause = """%s.symbol = GeneRIF.symbol and GeneRIF.versionId=0 and GeneRIF.display>0 and (GeneRIF.comment REGEXP '%s' or GeneRIF.initial = '%s') - """ % (self.dataset.type, "[[:<:]]"+self.search_term+"[[:>:]]", self.search_term) + """ % (self.dataset.type, + "[[:<:]]"+self.search_term+"[[:>:]]", + self.search_term) from_clause = ", GeneRIF " query = self.compile_final_query(from_clause, where_clause) @@ -255,6 +263,107 @@ class GoSearch(ProbeSetSearch): return self.execute(query) +class LrsSearch(ProbeSetSearch): + """Searches for genes with a QTL within the given LRS values + + LRS searches can take 2 different forms: + - LRS=(min_LRS max_LRS) + - LRS=(mine_LRS max_LRS chromosome start_Mb end_Mb) + where min/max_LRS represent the range of LRS scores and start/end_Mb represent + the range in megabases on the given chromosome + + """ + + DoSearch.search_types['LRS'] = 'LrsSearch' + + self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, + self.dataset.group) + +class CisLrsSearch(LrsSearch): + """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values + + A cisLRS search can take 2 forms: + - cisLRS=(min_LRS max_LRS) + - cisLRS=(min_LRS max_LRS mb_buffer) + where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around + a particular QTL where its eQTL would be considered "cis". If there is no third parameter, + mb_buffer will default to 5 megabases. + + A QTL is a cis-eQTL if a gene's expression is regulated by a QTL in roughly the same area + (where the area is determined by the mb_buffer that the user can choose. + """ + # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps + # between this and the LrsSearch code. In the original code, commands are divided by + # the number of inputs they take, so these commands are completely separate + + DoSearch.search_types['CISLRS'] = "CisLrsSearch" + + def run(self): + if len(self.search_term) == 3: + lower_limit, upper_limit, min_threshold = int(value) for value in self.search_term + + where_clause = """ %sXRef.LRS > %s and + %sXRef.LRS < %s and + %sXRef.Locus = Geno.name and + Geno.SpeciesId = %s and + %s.Chr = Geno.Chr and + ABS(%s.Mb-Geno.Mb) < %s """ % ( + self.dataset.type, + min(lower_limit, upper_limit) + self.dataset.type, + max(lower_limit, upper_limit, + self.dataset.type, + + ) + + else: + NeedSomeErrorHere + + + return None + + +#itemCmd = item[0] +#lowerLimit = float(item[1]) +#upperLimit = float(item[2]) +# +#if itemCmd.upper() in ("TRANSLRS", "CISLRS"): +# if item[3]: +# mthresh = float(item[3]) +# clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ +# (self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) +# if itemCmd.upper() == "CISLRS": +# clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %2.7f """ % (self.dbType, self.speciesId, self.dbType, self.dbType, mthresh) +# DescriptionText.append(HT.Span(' with a ', HT.U('cis-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) +# else: +# clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and (%s.Chr != Geno.Chr or (%s.Chr != Geno.Chr and ABS(%s.Mb-Geno.Mb) > %2.7f)) """ % (self.dbType, self.speciesId, self.dbType, self.dbType, self.dbType, mthresh) +# DescriptionText.append(HT.Span(' with a ', HT.U('trans-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) +# query.append(" (%s) " % clauseItem) +# self.orderByDefalut = "LRS" +# else: +# pass +#elif itemCmd.upper() in ("RANGE"): +# #XZ, 03/05/2009: Xiaodong changed Data to ProbeSetData +# clauseItem = " (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) > %2.7f and (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) < %2.7f " % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)) +# query.append(" (%s) " % clauseItem) +# DescriptionText.append(HT.Span(' with a range of expression that varied between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)), " (fold difference)")) +#else: +# clauseItem = " %sXRef.%s > %2.7f and %sXRef.%s < %2.7f " % \ +# (self.dbType, itemCmd, min(lowerLimit, upperLimit), self.dbType, itemCmd, max(lowerLimit, upperLimit)) +# query.append(" (%s) " % clauseItem) +# self.orderByDefalut = itemCmd +# DescriptionText.append(HT.Span(' with ', HT.U(itemCmd), ' between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)))) + + +class MeanSearch(ProbeSetSearch): + """Searches for genes expressed within an interval (log2 units) determined by the user""" + + DoSearch.search_types['MEAN'] = "MeanSearch" + + def run(self): + + return None + if __name__ == "__main__": ### Usually this will be used as a library, but call it from the command line for testing @@ -283,7 +392,8 @@ if __name__ == "__main__": #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() - results = WikiSearch("nicotine", dataset, cursor, db_conn).run() + #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() + results = CisLrsSearch(['9','99','10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index a97ea8fd..6ba4d94a 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -259,7 +259,7 @@ class SearchResultPage(templatePage): for a_search in self.search_terms: print("[kodak] item is:", pf(a_search)) search_term = a_search['search_term'] - search_type = a_search['key'] + search_type = string.upper(a_search['key']) if not search_type: # We fall back to the dataset type as the key to get the right object search_type = self.dataset.type @@ -543,7 +543,6 @@ class SearchResultPage(templatePage): #XZ, 06/05/2009: It is neccessary to turn on nowrap this_trait.mean = repr = "%2.3f" % mean - tr.append(TDCell(HT.TD(repr, Class=className, align='right', nowrap='ON'),repr, mean)) #LRS and its location LRS_score_repr = 'N/A' @@ -581,17 +580,13 @@ class SearchResultPage(templatePage): this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) LRS_flag = 0 - #tr.append(TDCell(HT.TD(HT.Href(text=LRS_score_repr,url="javascript:showIntervalMapping('%s', '%s : %s')" % (formName, this_trait.db.shortname, this_trait.name), Class="fs12 fwn"), Class=className, align='right', nowrap="on"),LRS_score_repr, LRS_score_value)) - tr.append(TDCell(HT.TD(LRS_score_repr, Class=className, align='right', nowrap="on"), LRS_score_repr, LRS_score_value)) - tr.append(TDCell(HT.TD(LRS_location_repr, Class=className, nowrap="on"), LRS_location_repr, LRS_location_value)) + #if LRS_flag: + #tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) + #tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value)) - if LRS_flag: - tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) - tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value)) - - else: - tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) - tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + #else: + #tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) + #tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) tblobj_body.append(tr) -- cgit v1.2.3 From 8aa848b0c1bddab3080f7a5abbd7ba199e786262 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 16 Nov 2012 10:15:14 -0600 Subject: Made small change to parser to have it detect square brackets '[' along with round ones '('; need to ask Sam about rewriting the regular expression stuff Trimmed a lot of code from search_results.py --- wqflask/wqflask/do_search.py | 79 ++++++++++++++++++++++++++++------- wqflask/wqflask/parser.py | 7 ++++ wqflask/wqflask/search_results.py | 86 +++++++++++++-------------------------- 3 files changed, 99 insertions(+), 73 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 4517d9f5..ac6014e7 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -19,6 +19,10 @@ class DoSearch(object): self.dataset = dataset self.db_conn = db_conn self.cursor = cursor + + #Get group information for dataset and the species id + self.dataset.get_group() + self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) def execute(self, query): """Executes query and returns results""" @@ -47,10 +51,6 @@ class ProbeSetSearch(DoSearch): DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" - #Get group information for dataset and the species id - self.dataset.get_group() - self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) - base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -62,6 +62,7 @@ class ProbeSetSearch(DoSearch): ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, ProbeSet """ + def compile_final_query(self, from_clause, where_clause): """Generates the final query string""" @@ -268,7 +269,7 @@ class LrsSearch(ProbeSetSearch): LRS searches can take 2 different forms: - LRS=(min_LRS max_LRS) - - LRS=(mine_LRS max_LRS chromosome start_Mb end_Mb) + - LRS=(min_LRS max_LRS chromosome start_Mb end_Mb) where min/max_LRS represent the range of LRS scores and start/end_Mb represent the range in megabases on the given chromosome @@ -276,9 +277,6 @@ class LrsSearch(ProbeSetSearch): DoSearch.search_types['LRS'] = 'LrsSearch' - self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, - self.dataset.group) - class CisLrsSearch(LrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values @@ -290,8 +288,10 @@ class CisLrsSearch(LrsSearch): mb_buffer will default to 5 megabases. A QTL is a cis-eQTL if a gene's expression is regulated by a QTL in roughly the same area - (where the area is determined by the mb_buffer that the user can choose. + (where the area is determined by the mb_buffer that the user can choose). + """ + # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps # between this and the LrsSearch code. In the original code, commands are divided by # the number of inputs they take, so these commands are completely separate @@ -300,7 +300,7 @@ class CisLrsSearch(LrsSearch): def run(self): if len(self.search_term) == 3: - lower_limit, upper_limit, min_threshold = int(value) for value in self.search_term + lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] where_clause = """ %sXRef.LRS > %s and %sXRef.LRS < %s and @@ -309,16 +309,65 @@ class CisLrsSearch(LrsSearch): %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %s """ % ( self.dataset.type, - min(lower_limit, upper_limit) + min(lower_limit, upper_limit), + self.dataset.type, + max(lower_limit, upper_limit), + self.dataset.type, + self.species_id, self.dataset.type, - max(lower_limit, upper_limit, self.dataset.type, - + min_threshold ) else: - NeedSomeErrorHere - + NeedSomeErrorHere + + return None + +class TransLrsSearch(LrsSearch): + """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values + + A transLRS search can take 2 forms: + - transLRS=(min_LRS max_LRS) + - transLRS=(min_LRS max_LRS mb_buffer) + where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around + a particular QTL where its eQTL would be considered "cis". If there is no third parameter, + mb_buffer will default to 5 megabases. + + A QTL is a trans-eQTL if a gene's expression is regulated by a QTL in a different location/area + (where the area is determined by the mb_buffer that the user can choose). Opposite of cis-eQTL. + + """ + + # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps + # between this and the LrsSearch code. In the original code, commands are divided by + # the number of inputs they take, so these commands are completely separate + + DoSearch.search_types['TRANSLRS'] = "TransLrsSearch" + + def run(self): + if len(self.search_term) == 3: + lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] + + where_clause = """ %sXRef.LRS > %s and + %sXRef.LRS < %s and + %sXRef.Locus = Geno.name and + Geno.SpeciesId = %s and + (%s.Chr != Geno.Chr or + ABS(%s.Mb-Geno.Mb) > %s) """ % ( + self.dataset.type, + min(lower_limit, upper_limit), + self.dataset.type, + max(lower_limit, upper_limit), + self.dataset.type, + self.species_id, + self.dataset.type, + self.dataset.type, + min_threshold + ) + + else: + NeedSomeErrorHere return None diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index e693b2b8..b220f837 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -27,6 +27,13 @@ def parse(pstring): value = value[1:-1] # Get rid of the parenthesis values = re.split(r"""\s+|,""", value) value = [value.strip() for value in values if value.strip()] + # Brackets can also be used to encapsulate values + elif '[' in value: + assert value.startswith("["), "Invalid token" + assert value.endswith("]"), "Invalid token" + value = value[1:-1] # Get rid of the brackets + values = re.split(r"""\s+|,""", value) + value = [value.strip() for value in values if value.strip()] term = dict(key=key, seperator=seperator, search_term=value) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 6ba4d94a..4aa1f2bc 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -213,56 +213,49 @@ class SearchResultPage(templatePage): #### Excel file stuff stops if self.dataset.type == "ProbeSet": - #for item in result: print("foo locals are:", locals()) probe_set_id = result[0] - print("probe_set_id is:", pf(probe_set_id)) this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) this_trait.retrieveInfo(QTL=True) print("this_trait is:", pf(this_trait)) self.trait_list.append(this_trait) - elif self.dataset.type == "Publish": - newrow += 1 - tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) - elif self.dataset.type == "Geno": - newrow += 1 - tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) + #elif self.dataset.type == "Publish": + # tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, species=species) + #elif self.dataset.type == "Geno": + # tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet) #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} hddn['incparentsf1']='ON' - # for key in hddn.keys(): - # traitForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) - # - # traitForm.append(HT.P(),pageTable) - # - # TD_LR.append(traitForm) - # if len(self.results) > 1 and i < len(self.results) - 1: - # last_result = True - #if last_result: - # TD_LR.contents.pop() - + if self.dataset.type == "ProbeSet": - tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, newrow=newrow, species=species) + tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, species=species) elif self.dataset.type == "Publish": - tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, newrow=newrow, species=species) + tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=self.form_name, species=species) elif self.dataset.type == "Geno": - tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet, newrow=newrow) + tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=self.form_name) def search(self): print("fd.search_terms:", self.fd['search_terms']) self.search_terms = parser.parse(self.fd['search_terms']) print("After parsing:", self.search_terms) - + self.results = [] for a_search in self.search_terms: print("[kodak] item is:", pf(a_search)) search_term = a_search['search_term'] - search_type = string.upper(a_search['key']) - if not search_type: + if a_search['key']: + search_type = string.upper(a_search['key']) + else: # We fall back to the dataset type as the key to get the right object - search_type = self.dataset.type + search_type = self.dataset.type + + # This is throwing an error when a_search['key'] is None, so I changed above + #search_type = string.upper(a_search['key']) + #if not search_type: + # # We fall back to the dataset type as the key to get the right object + # search_type = self.dataset.type search_ob = do_search.DoSearch.get_search(search_type) search_class = getattr(do_search, search_ob) @@ -289,26 +282,9 @@ class SearchResultPage(templatePage): keyword = string.replace(keyword,"?",".") wildcardkeyword[i] = keyword#'[[:<:]]'+ keyword+'[[:>:]]' return wildcardkeyword + - - def getTableHeaderForGeno(self, worksheet=None, newrow=None, headingStyle=None): - - tblobj_header = [] - - className = "fs13 fwb ffl b1 cw cbrb" - - tblobj_header = [[THCell(HT.TD(' ', Class=className), sort=0), - THCell(HT.TD('Record', HT.BR(), 'ID', HT.BR(), Class=className), text='record_id', idx=1), - THCell(HT.TD('Location', HT.BR(), 'Chr and Mb', HT.BR(), Class=className), text='location', idx=2)]] - - for ncol, item in enumerate(['Record ID', 'Location (Chr, Mb)']): - worksheet.write([newrow, ncol], item, headingStyle) - worksheet.set_column([ncol, ncol], 2*len(item)) - - return tblobj_header - - - def getTableBodyForGeno(self, trait_list, formName=None, worksheet=None, newrow=None): + def getTableBodyForGeno(self, trait_list, formName=None): tblobj_body = [] @@ -345,15 +321,13 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - for ncol, item in enumerate([this_trait.name, trait_location_repr]): - worksheet.write([newrow, ncol], item) - - newrow += 1 + #for ncol, item in enumerate([this_trait.name, trait_location_repr]): + # worksheet.write([newrow, ncol], item) return tblobj_body - - def getTableBodyForPublish(self, trait_list, formName=None, worksheet=None, newrow=None, species=''): + + def getTableBodyForPublish(self, trait_list, formName=None, species=''): tblobj_body = [] @@ -438,15 +412,13 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - for ncol, item in enumerate([this_trait.name, PhenotypeString, this_trait.authors, this_trait.year, this_trait.pubmed_id, LRS_score_repr, LRS_location_repr]): - worksheet.write([newrow, ncol], item) - - newrow += 1 + #for ncol, item in enumerate([this_trait.name, PhenotypeString, this_trait.authors, this_trait.year, this_trait.pubmed_id, LRS_score_repr, LRS_location_repr]): + # worksheet.write([newrow, ncol], item) return tblobj_body - def getTableBodyForProbeSet(self, trait_list=None, primaryTrait=None, formName=None, worksheet=None, newrow=None, species=''): + def getTableBodyForProbeSet(self, trait_list=None, primaryTrait=None, formName=None, species=''): # Note: setting trait_list to [] is probably not a great idea. tblobj_body = [] @@ -590,8 +562,6 @@ class SearchResultPage(templatePage): tblobj_body.append(tr) - newrow += 1 - return tblobj_body -- cgit v1.2.3 From 7444dd226335fe859d2c51a44c67820a5dd024d8 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 21 Nov 2012 14:29:49 -0600 Subject: Trimmed a large amount of code from search_results.py Removed everything related to drawing html; finished code for getting info for Phenotype and Genotype result tables Did some more with CisLRS and TransLRS searches Put something in parser about using square brackets as well as parentheses Edited template for other table types (Geno and Pheno) --- wqflask/wqflask/do_search.py | 90 ++++----- wqflask/wqflask/parser.py | 10 +- wqflask/wqflask/search_results.py | 217 +++++----------------- wqflask/wqflask/templates/search_result_page.html | 34 +++- 4 files changed, 126 insertions(+), 225 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index ac6014e7..61bfbaba 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -7,19 +7,18 @@ from pprint import pformat as pf from dbFunction import webqtlDatabaseFunction - class DoSearch(object): """Parent class containing parameters/functions used for all searches""" - + # Used to translate search phrases into classes search_types = dict() - + def __init__(self, search_term, dataset, cursor, db_conn): self.search_term = search_term self.dataset = dataset self.db_conn = db_conn self.cursor = cursor - + #Get group information for dataset and the species id self.dataset.get_group() self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) @@ -40,7 +39,7 @@ class DoSearch(object): """Strips out newlines/extra spaces and replaces them with just spaces""" step_one = " ".join(stringy.split()) return step_one - + @classmethod def get_search(cls, search_type): return cls.search_types[search_type] @@ -48,9 +47,9 @@ class DoSearch(object): class ProbeSetSearch(DoSearch): """A search within an mRNA expression dataset""" - + DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" - + base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, ProbeSetXRef.Mean as TMEAN, @@ -63,9 +62,10 @@ class ProbeSetSearch(DoSearch): FROM ProbeSetXRef, ProbeSet """ - def compile_final_query(self, from_clause, where_clause): + def compile_final_query(self, from_clause = '', where_clause = ''): """Generates the final query string""" + from_clause = '' from_clause = self.normalize_spaces(from_clause) query = (self.base_query + @@ -78,12 +78,12 @@ class ProbeSetSearch(DoSearch): self.escape(self.dataset.id))) print("query is:", pf(query)) - + return query def run(self): """Generates and runs a simple search of an mRNA expression dataset""" - + print("Running ProbeSetSearch") query = (self.base_query + """WHERE (MATCH (ProbeSet.Name, @@ -106,9 +106,9 @@ class ProbeSetSearch(DoSearch): class PhenotypeSearch(DoSearch): """A search within a phenotype dataset""" - + DoSearch.search_types['Publish'] = "PhenotypeSearch" - + base_query = """SELECT PublishXRef.Id, PublishFreeze.createtime as thistable, Publication.PubMed_ID as Publication_PubMed_ID, @@ -125,7 +125,7 @@ class PhenotypeSearch(DoSearch): 'Publication.Title', 'Publication.Authors', 'PublishXRef.Id') - + def get_where_clause(self): """Generate clause for WHERE portion of query""" @@ -140,7 +140,7 @@ class PhenotypeSearch(DoSearch): for field in self.search_fields: where_clause.append('''%s REGEXP "%s"''' % (field, search_term)) where_clause = "(%s)" % ' OR '.join(where_clause) - + return where_clause def run(self): @@ -164,7 +164,7 @@ class PhenotypeSearch(DoSearch): class GenotypeSearch(DoSearch): """A search within a genotype dataset""" - + DoSearch.search_types['Geno'] = "GenotypeSearch" base_query = """SELECT Geno.Name, @@ -185,7 +185,8 @@ class GenotypeSearch(DoSearch): where_clause = [] for field in self.search_fields: where_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % (self.dataset.type, field), - self.search_term)) + self.escape(self.search_term))) + print("where_clause is:", pf(where_clause)) where_clause = "(%s)" % ' OR '.join(where_clause) return where_clause @@ -209,7 +210,7 @@ class GenotypeSearch(DoSearch): class RifSearch(ProbeSetSearch): """Searches for traits with a Gene RIF entry including the search term.""" - + DoSearch.search_types['RIF'] = "RifSearch" def run(self): @@ -224,9 +225,9 @@ class RifSearch(ProbeSetSearch): class WikiSearch(ProbeSetSearch): """Searches GeneWiki for traits other people have annotated""" - + DoSearch.search_types['WIKI'] = "WikiSearch" - + def run(self): where_clause = """%s.symbol = GeneRIF.symbol and GeneRIF.versionId=0 and GeneRIF.display>0 @@ -259,43 +260,44 @@ class GoSearch(ProbeSetSearch): from_clause = """ , db_GeneOntology.term as GOterm, db_GeneOntology.association as GOassociation, db_GeneOntology.gene_product as GOgene_product """ - + query = self.compile_final_query(from_clause, where_clause) return self.execute(query) +#ZS: Not sure what the best way to deal with LRS searches is class LrsSearch(ProbeSetSearch): """Searches for genes with a QTL within the given LRS values - + LRS searches can take 2 different forms: - LRS=(min_LRS max_LRS) - LRS=(min_LRS max_LRS chromosome start_Mb end_Mb) where min/max_LRS represent the range of LRS scores and start/end_Mb represent the range in megabases on the given chromosome - + """ - + DoSearch.search_types['LRS'] = 'LrsSearch' class CisLrsSearch(LrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values - + A cisLRS search can take 2 forms: - cisLRS=(min_LRS max_LRS) - cisLRS=(min_LRS max_LRS mb_buffer) where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around a particular QTL where its eQTL would be considered "cis". If there is no third parameter, mb_buffer will default to 5 megabases. - + A QTL is a cis-eQTL if a gene's expression is regulated by a QTL in roughly the same area (where the area is determined by the mb_buffer that the user can choose). - + """ - + # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps # between this and the LrsSearch code. In the original code, commands are divided by # the number of inputs they take, so these commands are completely separate - + DoSearch.search_types['CISLRS'] = "CisLrsSearch" def run(self): @@ -318,27 +320,28 @@ class CisLrsSearch(LrsSearch): self.dataset.type, min_threshold ) - else: - NeedSomeErrorHere + NeedSomeErrorHere - return None + query = self.compile_final_query(where_clause) + + return self.execute(query) class TransLrsSearch(LrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values - + A transLRS search can take 2 forms: - transLRS=(min_LRS max_LRS) - transLRS=(min_LRS max_LRS mb_buffer) where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around a particular QTL where its eQTL would be considered "cis". If there is no third parameter, mb_buffer will default to 5 megabases. - + A QTL is a trans-eQTL if a gene's expression is regulated by a QTL in a different location/area (where the area is determined by the mb_buffer that the user can choose). Opposite of cis-eQTL. - + """ - + # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps # between this and the LrsSearch code. In the original code, commands are divided by # the number of inputs they take, so these commands are completely separate @@ -370,8 +373,8 @@ class TransLrsSearch(LrsSearch): NeedSomeErrorHere return None - - + + #itemCmd = item[0] #lowerLimit = float(item[1]) #upperLimit = float(item[2]) @@ -402,15 +405,15 @@ class TransLrsSearch(LrsSearch): # query.append(" (%s) " % clauseItem) # self.orderByDefalut = itemCmd # DescriptionText.append(HT.Span(' with ', HT.U(itemCmd), ' between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)))) - - + + class MeanSearch(ProbeSetSearch): """Searches for genes expressed within an interval (log2 units) determined by the user""" - + DoSearch.search_types['MEAN'] = "MeanSearch" - + def run(self): - + return None @@ -443,8 +446,9 @@ if __name__ == "__main__": #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() results = CisLrsSearch(['9','99','10'], dataset, cursor, db_conn).run() + #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() - + print("results are:", pf(results)) \ No newline at end of file diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index b220f837..74343b8a 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -9,9 +9,9 @@ def parse(pstring): pstring = re.split(r"""(?:(\w+\s*=\s*\([^)]*\))|(\w+\s*[=:]\w+)|(\w+))""", pstring) pstring = [item.strip() for item in pstring if item and item.strip()] print(pstring) - + items = [] - + for item in pstring: if ":" in item: key, seperator, value = item.partition(':') @@ -19,7 +19,7 @@ def parse(pstring): key, seperator, value = item.partition('=') else: seperator = None - + if seperator: if '(' in value: assert value.startswith("("), "Invalid token" @@ -41,11 +41,11 @@ def parse(pstring): term = dict(key=None, seperator=None, search_term = item) - + items.append(term) print(pf(items)) return(items) - + if __name__ == '__main__': parse("foo=(3 2 1)") parse("shh") diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 4aa1f2bc..dc3c72fc 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -45,7 +45,6 @@ from utility import formatting class SearchResultPage(templatePage): maxReturn = 3000 - #NPerPage = 100 nkeywords = 0 def __init__(self, fd): @@ -155,6 +154,13 @@ class SearchResultPage(templatePage): 'Publication.Title', 'Publication.Authors', 'PublishXRef.Id'] + self.header_fields = ['', + 'ID', + 'Description', + 'Authors', + 'Year', + 'Max LRS', + 'Max LRS Location'] elif self.dataset.type == "ProbeSet": self.search_fields = ['Name', @@ -175,13 +181,19 @@ class SearchResultPage(templatePage): 'Max LRS Location'] elif self.dataset.type == "Geno": self.search_fields = ['Name','Chr'] + self.header_fields = ['', + 'ID', + 'Location'] self.search() self.gen_search_result() def gen_search_result(self): - + """Get the info displayed in the search result table from the set of results computed in + the "search" function + + """ self.trait_list = [] # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term @@ -192,52 +204,27 @@ class SearchResultPage(templatePage): seq = 1 group = self.dataset.group - self.form_name = form_name = 'show_dataset_'+group - tblobj = {} species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) - #### Excel file - - # Todo: Replace this with official Python temp file naming functions? - filename= webqtlUtil.genRandStr("Search_") - #xlsUrl = HT.Input(type='button', value = 'Download Table', onClick= "location.href='/tmp/%s.xls'" % filename, Class='button') - # Create a new Excel workbook - #workbook = xl.Writer('%s.xls' % (webqtlConfig.TMPDIR+filename)) - #headingStyle = workbook.add_format(align = 'center', bold = 1, border = 1, size=13, fg_color = 0x1E, color="white") - - #XZ, 3/18/2010: pay attention to the line number of header in this file. As of today, there are 7 lines. - #worksheet = self.createExcelFileWithTitleAndFooter(workbook=workbook, db=this_trait.db, returnNumber=len(self.trait_list)) - newrow = 7 - - #### Excel file stuff stops - - if self.dataset.type == "ProbeSet": - print("foo locals are:", locals()) - probe_set_id = result[0] - this_trait = webqtlTrait(db=self.dataset, name=probe_set_id, cursor=self.cursor) - this_trait.retrieveInfo(QTL=True) - print("this_trait is:", pf(this_trait)) - self.trait_list.append(this_trait) - #elif self.dataset.type == "Publish": - # tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=mainfmName, worksheet=worksheet, species=species) - #elif self.dataset.type == "Geno": - # tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=form_name, worksheet=worksheet) - - #traitForm = HT.Form(cgi= os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), enctype='multipart/form-data', name=thisFormName, submit=HT.Input(type='hidden')) - hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':'_','CellID':'_','group':group} - hddn['incparentsf1']='ON' + #### Excel file needs to be generated #### + + print("foo locals are:", locals()) + trait_id = result[0] + this_trait = webqtlTrait(db=self.dataset, name=trait_id, cursor=self.cursor) + this_trait.retrieveInfo(QTL=True) + print("this_trait is:", pf(this_trait)) + self.trait_list.append(this_trait) if self.dataset.type == "ProbeSet": - tblobj['body'] = self.getTableBodyForProbeSet(trait_list=self.trait_list, formName=self.form_name, species=species) + self.getTraitInfoForProbeSet(trait_list=self.trait_list, species=species) elif self.dataset.type == "Publish": - tblobj['body'] = self.getTableBodyForPublish(trait_list=self.trait_list, formName=self.form_name, species=species) + self.getTraitInfoForPublish(trait_list=self.trait_list, species=species) elif self.dataset.type == "Geno": - tblobj['body'] = self.getTableBodyForGeno(trait_list=self.trait_list, form_name=self.form_name) + self.getTraitInfoForGeno(trait_list=self.trait_list) def search(self): - print("fd.search_terms:", self.fd['search_terms']) self.search_terms = parser.parse(self.fd['search_terms']) print("After parsing:", self.search_terms) @@ -267,6 +254,7 @@ class SearchResultPage(templatePage): print("in the search results are:", self.results) + #ZS: This should be handled in the parser def encregexp(self,str): if not str: return [] @@ -284,24 +272,12 @@ class SearchResultPage(templatePage): return wildcardkeyword - def getTableBodyForGeno(self, trait_list, formName=None): - - tblobj_body = [] - - className = "fs12 fwn ffl b1 c222" + def getTraitInfoForGeno(self, trait_list): for this_trait in trait_list: - tr = [] - if not this_trait.haveinfo: this_trait.retrieveInfo() - trId = str(this_trait) - - tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) - - tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name, this_trait.name), Class="fs12 fwn ffl"),align="left", Class=className), text=this_trait.name, val=this_trait.name.upper())) - #XZ: trait_location_value is used for sorting trait_location_repr = 'N/A' trait_location_value = 1000000 @@ -315,70 +291,37 @@ class SearchResultPage(templatePage): else: trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - trait_location_repr = 'Chr%s: %.6f' % (this_trait.chr, float(this_trait.mb) ) + this_trait.location_repr = 'Chr%s: %.4f' % (this_trait.chr, float(this_trait.mb) ) + this_trait.location_value = trait_location_value - tr.append(TDCell(HT.TD(trait_location_repr, Class="fs12 fwn b1 c222", nowrap="on"), trait_location_repr, trait_location_value)) - tblobj_body.append(tr) - - #for ncol, item in enumerate([this_trait.name, trait_location_repr]): - # worksheet.write([newrow, ncol], item) - - return tblobj_body - - - def getTableBodyForPublish(self, trait_list, formName=None, species=''): - - tblobj_body = [] - - className = "fs12 fwn b1 c222" + def getTraitInfoForPublish(self, trait_list, species=''): for this_trait in trait_list: - tr = [] - if not this_trait.haveinfo: this_trait.retrieveInfo(QTL=1) - trId = str(this_trait) - - tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class=className), text=trId)) - - tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name,url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name, this_trait.name), Class="fs12 fwn"), nowrap="yes",align="center", Class=className),str(this_trait.name), this_trait.name)) - - PhenotypeString = this_trait.post_publication_description + description = this_trait.post_publication_description if this_trait.confidential: if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): - PhenotypeString = this_trait.pre_publication_description - tr.append(TDCell(HT.TD(PhenotypeString, Class=className), PhenotypeString, PhenotypeString.upper())) - - tr.append(TDCell(HT.TD(this_trait.authors, Class="fs12 fwn b1 c222 fsI"),this_trait.authors, this_trait.authors.strip().upper())) + description = this_trait.pre_publication_description + this_trait.description_display = description try: - PubMedLinkText = myear = repr = int(this_trait.year) + this_trait.pubmed_text = int(this_trait.year) except: - PubMedLinkText = repr = "N/A" - myear = 0 + this_trait.pubmed_text = "N/A" if this_trait.pubmed_id: - PubMedLink = HT.Href(text= repr,url= webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id,target='_blank', Class="fs12 fwn") - else: - PubMedLink = repr - - tr.append(TDCell(HT.TD(PubMedLink, Class=className, align='center'), repr, myear)) + this_trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id #LRS and its location - LRS_score_repr = 'N/A' - LRS_score_value = 0 - LRS_location_repr = 'N/A' - LRS_location_value = 1000000 - LRS_flag = 1 - + this_trait.LRS_score_repr = 'N/A' + this_trait.LRS_score_value = 0 + this_trait.LRS_location_repr = 'N/A' + this_trait.LRS_location_value = 1000000 if this_trait.lrs: - LRS_score_repr = '%3.1f' % this_trait.lrs - LRS_score_value = this_trait.lrs - tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) - self.cursor.execute(""" select Geno.Chr, Geno.Mb from Geno, Species where Species.Name = '%s' and @@ -401,27 +344,14 @@ class SearchResultPage(templatePage): else: LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) - LRS_location_repr = 'Chr%s: %.6f' % (LRS_Chr, float(LRS_Mb) ) - LRS_flag = 0 - - tr.append(TDCell(HT.TD(LRS_location_repr, Class=className, nowrap="on"), LRS_location_repr, LRS_location_value)) - - else: - tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) - tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) - - tblobj_body.append(tr) - - #for ncol, item in enumerate([this_trait.name, PhenotypeString, this_trait.authors, this_trait.year, this_trait.pubmed_id, LRS_score_repr, LRS_location_repr]): - # worksheet.write([newrow, ncol], item) + this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs + this_trait.LRS_score_value = LRS_score_value = this_trait.lrs + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) - return tblobj_body + def getTraitInfoForProbeSet(self, trait_list=None, species=''): - def getTableBodyForProbeSet(self, trait_list=None, primaryTrait=None, formName=None, species=''): # Note: setting trait_list to [] is probably not a great idea. - tblobj_body = [] - if not trait_list: trait_list = [] @@ -435,27 +365,6 @@ class SearchResultPage(templatePage): else: this_trait.symbol = "N/A" - tr = [] - - trId = str(this_trait) - - #XZ, 12/08/2008: checkbox - #tr.append(TDCell(HT.TD(HT.Input(type="checkbox", Class="checkbox", name="searchResult",value=trId, onClick="highlight(this)"), nowrap="on", Class="fs12 fwn ffl b1 c222"), text=trId)) - - #XZ, 12/08/2008: probeset name - #if this_trait.cellid: - # tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name, url="javascript:showDatabase3('%s','%s','%s','%s')" % (formName, this_trait.db.name,this_trait.name,this_trait.cellid), Class="fs12 fwn"), Class=className), this_trait.name, this_trait.name.upper())) - #else: - # tr.append(TDCell(HT.TD(HT.Href(text=this_trait.name, url="javascript:showDatabase3('%s','%s','%s','')" % (formName, this_trait.db.name,this_trait.name), Class="fs12 fwn"), Class=className), this_trait.name, this_trait.name.upper())) - # - #if this_trait.geneid: - # symbolurl = HT.Href(text=this_trait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?db=gene&cmd=Retrieve&dopt=Graphics&list_uids=%s" % this_trait.geneid, Class="font_black fs12 fwn") - #else: - # symbolurl = HT.Href(text=this_trait.symbol,target='_blank',url="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?CMD=search&DB=gene&term=%s" % this_trait.symbol, Class="font_black fs12 fwn") - # - ##XZ, 12/08/2008: gene symbol - #tr.append(TDCell(HT.TD(symbolurl, Class="fs12 fwn b1 c222 fsI"),this_trait.symbol, this_trait.symbol.upper())) - #XZ, 12/08/2008: description #XZ, 06/05/2009: Rob asked to add probe target description description_string = str(this_trait.description).strip() @@ -487,8 +396,8 @@ class SearchResultPage(templatePage): else: trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - trait_location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) - this_trait.trait_location_repr = trait_location_repr + this_trait.location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) + this_trait.location_value = trait_location_value #this_trait.trait_location_value = trait_location_value #XZ, 01/12/08: This SQL query is much faster. @@ -517,11 +426,10 @@ class SearchResultPage(templatePage): this_trait.mean = repr = "%2.3f" % mean #LRS and its location - LRS_score_repr = 'N/A' - LRS_score_value = 0 - LRS_location_repr = 'N/A' - LRS_location_value = 1000000 - LRS_flag = 1 + this_trait.LRS_score_repr = 'N/A' + this_trait.LRS_score_value = 0 + this_trait.LRS_location_repr = 'N/A' + this_trait.LRS_location_value = 1000000 #Max LRS and its Locus location if this_trait.lrs and this_trait.locus: @@ -550,28 +458,3 @@ class SearchResultPage(templatePage): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) - LRS_flag = 0 - - #if LRS_flag: - #tr.append(TDCell(HT.TD(LRS_score_repr, Class=className), LRS_score_repr, LRS_score_value)) - #tr.append(TDCell(HT.TD(LRS_location_repr, Class=className), LRS_location_repr, LRS_location_value)) - - #else: - #tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) - #tr.append(TDCell(HT.TD("N/A", Class=className), "N/A", "N/A")) - - tblobj_body.append(tr) - - return tblobj_body - - - def getSortByValue(self, datasetType=''): - - if datasetType == 'Geno': - sortby = ("location", "up") - elif datasetType == 'ProbeSet': - sortby = ("symbol", "up") - else: #Phenotype - sortby = ("record_id", "down") - - return sortby diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 65182e1f..e393ced6 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -50,18 +50,32 @@ - {{ this_trait.name.upper() }} + dataset = dataset.name, + trait_id = this_trait.name, + group = dataset.group)}}"> + {{ this_trait.name }} - {{ this_trait.symbol }} - {{ this_trait.description_display }} - {{ this_trait.trait_location_repr }} - {{ this_trait.mean }} - {{ this_trait.LRS_score_repr }} - {{ this_trait.LRS_location_repr }} + {% if dataset.type == 'ProbeSet' %} + {{ this_trait.symbol }} + {{ this_trait.description_display }} + {{ this_trait.location_repr }} + {{ this_trait.mean }} + {{ this_trait.LRS_score_repr }} + {{ this_trait.LRS_location_repr }} + {% elif dataset.type == 'Publish' %} + {{ this_trait.description_display }} + {{ this_trait.authors }} + + + {{ this_trait.pubmed_text }} + + + {{ this_trait.LRS_score_repr }} + {{ this_trait.LRS_location_repr }} + {% elif dataset.type == 'Geno' %} + {{ this_trait.location_repr }} + {% endif %} {% endfor %} -- cgit v1.2.3 From 1749c660a7e71f10bbdec04f8bf7bb77df3f3eef Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 21 Nov 2012 17:54:13 -0600 Subject: Changed parser to allow for bother square brackets and parentheses Changed show_trait.coffee to get the stats table working again Still need to get stats table to work with changed values --- misc/notes.txt | 2 + wqflask/wqflask/do_search.py | 6 +- wqflask/wqflask/parser.py | 40 +++++-- wqflask/wqflask/show_trait/show_trait.py | 16 +-- .../static/new/javascript/show_trait.coffee | 57 +++++---- .../wqflask/static/new/javascript/show_trait.js | 46 ++++---- .../wqflask/templates/show_trait_edit_data.html | 130 ++++++++++----------- 7 files changed, 169 insertions(+), 128 deletions(-) diff --git a/misc/notes.txt b/misc/notes.txt index b3678a04..59ab79cb 100644 --- a/misc/notes.txt +++ b/misc/notes.txt @@ -1,5 +1,7 @@ To get server running: +!If having seemingly inexplicable problems with imports, make sure I've started the environment! + Start up virtual environment: source ~/ve27/bin/activate diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 61bfbaba..fd03f359 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -5,8 +5,12 @@ from __future__ import print_function, division from pprint import pformat as pf +import sys +sys.path.append("..") + from dbFunction import webqtlDatabaseFunction + class DoSearch(object): """Parent class containing parameters/functions used for all searches""" @@ -423,8 +427,6 @@ if __name__ == "__main__": import MySQLdb import sys - sys.path.append("/home/zas1024/gene/wqflask") - print("Path is:", sys.path) from base import webqtlConfig diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 74343b8a..dc33fc52 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -1,12 +1,33 @@ +""" +Parses search terms input by user + +Searches take two primary forms: +- search term by itself (ex. "shh" or "brain") +- key / separator / value(s) (ex. "LRS=(9 99 Chr4 122 155)" or "GO:342533") + +In the example of "LRS=(9 99 Chr4 122 155)", the key is "LRS", the separator is "=" and the value +is everything within the parentheses. + +Both "=" and ":" can be used as separators; in the future, it would also be good to allow no +separator at all (ex. "cisLRS(9 999 10)") + +Both square brackets and parentheses can be used interchangeably. Both can also be used to +encapsulate a single value; "cisLRS=[9 999 10)" would +be acceptable.] + +""" + from __future__ import print_function, division import re from pprint import pformat as pf - def parse(pstring): - pstring = re.split(r"""(?:(\w+\s*=\s*\([^)]*\))|(\w+\s*[=:]\w+)|(\w+))""", pstring) + pstring = re.split(r"""(?:(\w+\s*=\s*[\(\[][^)]*[\)\]]) | # LRS=(1 2 3), cisLRS=[4 5 6], etc + (\w+\s*[=:]\w+) | # wiki=bar, GO:foobar, etc + (\w+)) # shh, brain, etc """, pstring, + flags=re.VERBOSE) pstring = [item.strip() for item in pstring if item and item.strip()] print(pstring) @@ -21,19 +42,12 @@ def parse(pstring): seperator = None if seperator: - if '(' in value: - assert value.startswith("("), "Invalid token" - assert value.endswith(")"), "Invalid token" + if '(' in value or '[' in value: + assert value.startswith(("(", "[")), "Invalid token" + assert value.endswith((")", "]")), "Invalid token" value = value[1:-1] # Get rid of the parenthesis values = re.split(r"""\s+|,""", value) value = [value.strip() for value in values if value.strip()] - # Brackets can also be used to encapsulate values - elif '[' in value: - assert value.startswith("["), "Invalid token" - assert value.endswith("]"), "Invalid token" - value = value[1:-1] # Get rid of the brackets - values = re.split(r"""\s+|,""", value) - value = [value.strip() for value in values if value.strip()] term = dict(key=key, seperator=seperator, search_term=value) @@ -47,6 +61,8 @@ def parse(pstring): return(items) if __name__ == '__main__': + parse("foo=[3 2 1]") + parse("foo=[3 2 1)") parse("foo=(3 2 1)") parse("shh") parse("shh grep") diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 86a0a992..19e67c43 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -159,9 +159,9 @@ class ShowTrait(templatePage): self.hddn = hddn self.sample_group_types = OrderedDict() - self.sample_group_types['primary_only'] = fd.RISet + " Only" - self.sample_group_types['other_only'] = "Non-" + fd.RISet - self.sample_group_types['all_cases'] = "All Cases" + self.sample_group_types['samples_primary'] = fd.RISet + " Only" + self.sample_group_types['samples_other'] = "Non-" + fd.RISet + self.sample_group_types['samples_all'] = "All Cases" sample_lists = [group.sample_list for group in self.sample_groups] print("sample_lists is:", pf(sample_lists)) js_data = dict(sample_group_types = self.sample_group_types, @@ -176,16 +176,16 @@ class ShowTrait(templatePage): #if traitInfos: # database, ProbeSetID, CellID = traitInfos #else: - database = self.fd['database'] - probe_set_id = self.fd['ProbeSetID'] + dataset = self.fd['dataset'] + trait_id = self.fd['trait_id'] cell_id = self.fd.get('CellID') - this_trait = webqtlTrait(db=database, name=probe_set_id, cellid=cell_id, cursor=self.cursor) + this_trait = webqtlTrait(db=dataset, name=trait_id, cellid=cell_id, cursor=self.cursor) ##identification, etc. - self.fd.identification = '%s : %s' % (this_trait.db.shortname, probe_set_id) + self.fd.identification = '%s : %s' % (this_trait.db.shortname, trait_id) this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&RISet=%s&parentsf1=on' %(database, probe_set_id, self.fd['RISet']) + &ProbeSetID=%s&RISet=%s&parentsf1=on' %(dataset, trait_id, self.fd['RISet']) if cell_id: self.fd.identification = '%s/%s'%(self.fd.identification, cell_id) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 10671e78..6e22119f 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -26,45 +26,62 @@ $ -> current_value = parseFloat($(in_box)).toFixed(decimal_places) + console.log("urgh:", category, value_type) the_value = sample_sets[category][value_type]() + console.log("After running sample_sets, the_value is:", the_value) if decimal_places > 0 the_value = the_value.toFixed(decimal_places) + console.log("*-* the_value:", the_value) + console.log("*-* current_value:", current_value) if the_value != current_value $(id).html(the_value).effect("highlight") update_stat_values = (sample_sets)-> - for category in ['primary_only', 'other_only', 'all_cases'] + for category in ['samples_primary', 'samples_other', 'samples_all'] change_stats_value(sample_sets, category, "n_of_samples", 0) for stat in ["mean", "median", "std_dev", "std_error"] + console.log("Calling change_stats_value") change_stats_value(sample_sets, category, stat, 2) edit_data_change = -> sample_sets = - primary_only: new Stats([]) - other_only: new Stats([]) - all_cases: new Stats([]) + samples_primary: new Stats([]) + samples_other: new Stats([]) + samples_all: new Stats([]) console.log("at beginning:", sample_sets) - values = $('#value_table').find(".edit_sample_value") - for value in values - real_value = $(value).val() - row = $(value).closest("tr") - category = row[0].id - checkbox = $(row).find(".edit_sample_checkbox") - checked = $(checkbox).attr('checked') - - if checked and is_number(real_value) and real_value != "" - real_value = parseFloat(real_value) - if _(category).startsWith("Primary") - sample_sets.primary_only.add_value(real_value) - else if _(category).startsWith("Other") - sample_sets.other_only.add_value(real_value) - sample_sets.all_cases.add_value(real_value) + # ########## + # Bug here #value_table doesn't exist and why is it a class? + # ########## + + #values = $('.value_table').find(".edit_sample_value") + + + tables = ['samples_primary', 'samples_other'] + for table in tables + rows = $("#" + table).find('tr') + console.log("[fuji3] rows:", rows) + for row in rows + real_value = $(row).find('.edit_sample_value').val() + #row = $(value).closest("tr") + #category = row[0].id + console.log("real_value:", real_value) + checkbox = $(row).find(".edit_sample_checkbox") + checked = $(checkbox).attr('checked') + + if checked and is_number(real_value) and real_value != "" + console.log("in the iffy if") + real_value = parseFloat(real_value) + #if _(category).startsWith("Primary") + sample_sets[table].add_value(real_value) + #else if _(category).startsWith("Other") + # sample_sets.other_only.add_value(real_value) + sample_sets['samples_all'].add_value(real_value) console.log("towards end:", sample_sets) update_stat_values(sample_sets) - + make_table = -> header = " " diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index db40b547..919bc766 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -32,17 +32,21 @@ console.log("the_id:", id); in_box = $(id).html; current_value = parseFloat($(in_box)).toFixed(decimal_places); + console.log("urgh:", category, value_type); the_value = sample_sets[category][value_type](); + console.log("After running sample_sets, the_value is:", the_value); if (decimal_places > 0) { the_value = the_value.toFixed(decimal_places); } + console.log("*-* the_value:", the_value); + console.log("*-* current_value:", current_value); if (the_value !== current_value) { return $(id).html(the_value).effect("highlight"); } }; update_stat_values = function(sample_sets) { var category, stat, _i, _len, _ref, _results; - _ref = ['primary_only', 'other_only', 'all_cases']; + _ref = ['samples_primary', 'samples_other', 'samples_all']; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { category = _ref[_i]; @@ -53,6 +57,7 @@ _results1 = []; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { stat = _ref1[_j]; + console.log("Calling change_stats_value"); _results1.push(change_stats_value(sample_sets, category, stat, 2)); } return _results1; @@ -61,29 +66,30 @@ return _results; }; edit_data_change = function() { - var category, checkbox, checked, real_value, row, sample_sets, value, values, _i, _len; + var checkbox, checked, real_value, row, rows, sample_sets, table, tables, _i, _j, _len, _len1; sample_sets = { - primary_only: new Stats([]), - other_only: new Stats([]), - all_cases: new Stats([]) + samples_primary: new Stats([]), + samples_other: new Stats([]), + samples_all: new Stats([]) }; console.log("at beginning:", sample_sets); - values = $('#value_table').find(".edit_sample_value"); - for (_i = 0, _len = values.length; _i < _len; _i++) { - value = values[_i]; - real_value = $(value).val(); - row = $(value).closest("tr"); - category = row[0].id; - checkbox = $(row).find(".edit_sample_checkbox"); - checked = $(checkbox).attr('checked'); - if (checked && is_number(real_value) && real_value !== "") { - real_value = parseFloat(real_value); - if (_(category).startsWith("Primary")) { - sample_sets.primary_only.add_value(real_value); - } else if (_(category).startsWith("Other")) { - sample_sets.other_only.add_value(real_value); + tables = ['samples_primary', 'samples_other']; + for (_i = 0, _len = tables.length; _i < _len; _i++) { + table = tables[_i]; + rows = $("#" + table).find('tr'); + console.log("[fuji3] rows:", rows); + for (_j = 0, _len1 = rows.length; _j < _len1; _j++) { + row = rows[_j]; + real_value = $(row).find('.edit_sample_value').val(); + console.log("real_value:", real_value); + checkbox = $(row).find(".edit_sample_checkbox"); + checked = $(checkbox).attr('checked'); + if (checked && is_number(real_value) && real_value !== "") { + console.log("in the iffy if"); + real_value = parseFloat(real_value); + sample_sets[table].add_value(real_value); + sample_sets['samples_all'].add_value(real_value); } - sample_sets.all_cases.add_value(real_value); } } console.log("towards end:", sample_sets); diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html index ce1642d3..6c9b1073 100644 --- a/wqflask/wqflask/templates/show_trait_edit_data.html +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -82,78 +82,76 @@

      {{ sample_type.header }}

      -
      - - - - - - - - {% if sample_type.se_exists() %} - - - - {% endif %} - - {% for attribute in sample_type.attributes|sort() %} - - {% endfor %} - - - {% for sample in sample_type.sample_list %} - - - - - - {# Todo: Add IDs #} - +
      IndexSampleValue SE - {{ sample_type.attributes[attribute].name }} -
      - {{ loop.index }} - - - - {{ sample.name }} - - - -
      + + + + + {% if sample_type.se_exists() %} - - - {# Todo: Add IDs #} - + + + {% endif %} - {# Loop through each attribute type and input value #} {% for attribute in sample_type.attributes|sort() %} - + {% endfor %} - - {% endfor %} - -
      IndexSampleValue - ± - - -  SE - {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} - + {{ sample_type.attributes[attribute].name }} +
      -
      + + + {% for sample in sample_type.sample_list %} + + + {{ loop.index }} + + + + + + {{ sample.name }} + + + + {# Todo: Add IDs #} + + + + + {% if sample_type.se_exists() %} + + ± + + + {# Todo: Add IDs #} + + + + {% endif %} + + {# Loop through each attribute type and input value #} + {% for attribute in sample_type.attributes|sort() %} + + {{ sample.extra_attributes[sample_type.attributes[attribute].name] }} + + {% endfor %} + + {% endfor %} + +
      {% endfor %}
      -- cgit v1.2.3 From 0931212bc692177cfc0ebcf016bc869dd4f88fd8 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 27 Nov 2012 14:44:14 -0600 Subject: Renamed webqtlDataSet.py to data_set.py Renamed the class webqtlDataset to DataSet Finished cisLRS and transLRS search types in d_search.py Fixed parent/f1 issue in show_trait.py --- wqflask/base/data_set.py | 162 +++++++++++++++++++++++++++++++ wqflask/base/webqtlDataset.py | 157 ------------------------------ wqflask/wqflask/do_search.py | 137 +++++++++++++------------- wqflask/wqflask/search_results.py | 34 ++----- wqflask/wqflask/show_trait/show_trait.py | 11 +-- 5 files changed, 247 insertions(+), 254 deletions(-) create mode 100755 wqflask/base/data_set.py delete mode 100755 wqflask/base/webqtlDataset.py diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py new file mode 100755 index 00000000..992c673e --- /dev/null +++ b/wqflask/base/data_set.py @@ -0,0 +1,162 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from htmlgen import HTMLgen2 as HT + +import webqtlConfig + + + +class DataSet(object): + """ + Dataset class defines a dataset in webqtl, can be either Microarray, + Published phenotype, genotype, or user input dataset(temp) + + """ + + def __init__(self, dbName, cursor=None): + + assert dbName + self.id = 0 + self.name = '' + self.type = '' + self.group = '' + self.cursor = cursor + + #temporary storage + if dbName.find('Temp') >= 0: + self.searchfield = ['name','description'] + self.disfield = ['name','description'] + self.type = 'Temp' + self.id = 1 + self.fullname = 'Temporary Storage' + self.shortname = 'Temp' + elif dbName.find('Publish') >= 0: + pass + elif dbName.find('Geno') >= 0: + self.searchfield = ['name','chr'] + self.disfield = ['name','chr','mb', 'source2', 'sequence'] + self.type = 'Geno' + else: #ProbeSet + self.searchfield = ['name','description','probe_target_description', + 'symbol','alias','genbankid','unigeneid','omim', + 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] + self.disfield = ['name','symbol','description','probe_target_description', + 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', + 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', + 'strand_probe','strand_gene','probe_set_target_region', + 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', + 'probe_set_blat_mb_end', 'probe_set_strand', + 'probe_set_note_by_rw', 'flag'] + self.type = 'ProbeSet' + self.name = dbName + if self.cursor and self.id == 0: + self.retrieveName() + + + # Delete this eventually + @property + def riset(): + Weve_Renamed_This_As_Group + + + def get_group(self): + assert self.cursor + if self.type == 'Publish': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, PublishFreeze + WHERE + PublishFreeze.InbredSetId = InbredSet.Id AND + PublishFreeze.Name = "%s" + ''' % self.name + elif self.type == 'Geno': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, GenoFreeze + WHERE + GenoFreeze.InbredSetId = InbredSet.Id AND + GenoFreeze.Name = "%s" + ''' % self.name + elif self.type == 'ProbeSet': + query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, ProbeSetFreeze, ProbeFreeze + WHERE + ProbeFreeze.InbredSetId = InbredSet.Id AND + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % self.name + else: + return "" + self.cursor.execute(query) + group, RIID = self.cursor.fetchone() + if group == 'BXD300': + group = "BXD" + self.group = group + self.group_id = RIID + return group + + + def retrieveName(self): + assert self.id == 0 and self.cursor + query = ''' + SELECT + Id, Name, FullName, ShortName + FROM + %sFreeze + WHERE + public > %d AND + (Name = "%s" OR FullName = "%s" OR ShortName = "%s") + '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) + try: + self.cursor.execute(query) + self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() + except: + raise KeyError, `self.name`+' doesn\'t exist.' + + + def genHTML(self, Class='c0dd'): + return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), + url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") + +class PhenotypeDataSet(DataSet): + + def __init__(self): + self.searchfield = ['name','post_publication_description','abstract','title','authors'] + self.disfield = ['name','pubmed_id', + 'pre_publication_description', 'post_publication_description', 'original_description', + 'pre_publication_abbreviation', 'post_publication_abbreviation', + 'lab_code', 'submitter', 'owner', 'authorized_users', + 'authors','title','abstract', 'journal','volume','pages','month', + 'year','sequence', 'units', 'comments'] + self.type = 'Publish' \ No newline at end of file diff --git a/wqflask/base/webqtlDataset.py b/wqflask/base/webqtlDataset.py deleted file mode 100755 index 933077fd..00000000 --- a/wqflask/base/webqtlDataset.py +++ /dev/null @@ -1,157 +0,0 @@ -# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. -# -# This program is free software: you can redistribute it and/or modify it -# under the terms of the GNU Affero General Public License -# as published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the GNU Affero General Public License for more details. -# -# This program is available from Source Forge: at GeneNetwork Project -# (sourceforge.net/projects/genenetwork/). -# -# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) -# at rwilliams@uthsc.edu and xzhou15@uthsc.edu -# -# -# -# This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 - -from htmlgen import HTMLgen2 as HT - -import webqtlConfig - - - -class webqtlDataset: - """ - Dataset class defines a dataset in webqtl, can be either Microarray, - Published phenotype, genotype, or user input dataset(temp) - - """ - - def __init__(self, dbName, cursor=None): - - assert dbName - self.id = 0 - self.name = '' - self.type = '' - self.group = '' - self.cursor = cursor - - #temporary storage - if dbName.find('Temp') >= 0: - self.searchfield = ['name','description'] - self.disfield = ['name','description'] - self.type = 'Temp' - self.id = 1 - self.fullname = 'Temporary Storage' - self.shortname = 'Temp' - elif dbName.find('Publish') >= 0: - self.searchfield = ['name','post_publication_description','abstract','title','authors'] - self.disfield = ['name','pubmed_id', - 'pre_publication_description', 'post_publication_description', 'original_description', - 'pre_publication_abbreviation', 'post_publication_abbreviation', - 'lab_code', 'submitter', 'owner', 'authorized_users', - 'authors','title','abstract', 'journal','volume','pages','month', - 'year','sequence', 'units', 'comments'] - self.type = 'Publish' - elif dbName.find('Geno') >= 0: - self.searchfield = ['name','chr'] - self.disfield = ['name','chr','mb', 'source2', 'sequence'] - self.type = 'Geno' - else: #ProbeSet - self.searchfield = ['name','description','probe_target_description', - 'symbol','alias','genbankid','unigeneid','omim', - 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] - self.disfield = ['name','symbol','description','probe_target_description', - 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', - 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', - 'strand_probe','strand_gene','probe_set_target_region', - 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', - 'probe_set_blat_mb_end', 'probe_set_strand', - 'probe_set_note_by_rw', 'flag'] - self.type = 'ProbeSet' - self.name = dbName - if self.cursor and self.id == 0: - self.retrieveName() - - - # Delete this eventually - @property - def riset(): - Weve_Renamed_This_As_Group - - - def get_group(self): - assert self.cursor - if self.type == 'Publish': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, PublishFreeze - WHERE - PublishFreeze.InbredSetId = InbredSet.Id AND - PublishFreeze.Name = "%s" - ''' % self.name - elif self.type == 'Geno': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, GenoFreeze - WHERE - GenoFreeze.InbredSetId = InbredSet.Id AND - GenoFreeze.Name = "%s" - ''' % self.name - elif self.type == 'ProbeSet': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, ProbeSetFreeze, ProbeFreeze - WHERE - ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % self.name - else: - return "" - self.cursor.execute(query) - group, RIID = self.cursor.fetchone() - if group == 'BXD300': - group = "BXD" - self.group = group - self.group_id = RIID - return group - - - def retrieveName(self): - assert self.id == 0 and self.cursor - query = ''' - SELECT - Id, Name, FullName, ShortName - FROM - %sFreeze - WHERE - public > %d AND - (Name = "%s" OR FullName = "%s" OR ShortName = "%s") - '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) - try: - self.cursor.execute(query) - self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() - except: - raise KeyError, `self.name`+' doesn\'t exist.' - - - def genHTML(self, Class='c0dd'): - return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), - url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index fd03f359..e2bafb3a 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -49,65 +49,6 @@ class DoSearch(object): return cls.search_types[search_type] -class ProbeSetSearch(DoSearch): - """A search within an mRNA expression dataset""" - - DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" - - base_query = """SELECT ProbeSet.Name as TNAME, - 0 as thistable, - ProbeSetXRef.Mean as TMEAN, - ProbeSetXRef.LRS as TLRS, - ProbeSetXRef.PVALUE as TPVALUE, - ProbeSet.Chr_num as TCHR_NUM, - ProbeSet.Mb as TMB, - ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM - FROM ProbeSetXRef, ProbeSet """ - - - def compile_final_query(self, from_clause = '', where_clause = ''): - """Generates the final query string""" - - from_clause = '' - from_clause = self.normalize_spaces(from_clause) - - query = (self.base_query + - """%s - WHERE %s - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(from_clause), - where_clause, - self.escape(self.dataset.id))) - - print("query is:", pf(query)) - - return query - - def run(self): - """Generates and runs a simple search of an mRNA expression dataset""" - - print("Running ProbeSetSearch") - query = (self.base_query + - """WHERE (MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(self.search_term), - self.escape(self.dataset.id))) - - print("final query is:", pf(query)) - - return self.execute(query) - - class PhenotypeSearch(DoSearch): """A search within a phenotype dataset""" @@ -212,6 +153,65 @@ class GenotypeSearch(DoSearch): return self.execute(query) + +class ProbeSetSearch(DoSearch): + """A search within an mRNA expression dataset""" + + DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" + + base_query = """SELECT ProbeSet.Name as TNAME, + 0 as thistable, + ProbeSetXRef.Mean as TMEAN, + ProbeSetXRef.LRS as TLRS, + ProbeSetXRef.PVALUE as TPVALUE, + ProbeSet.Chr_num as TCHR_NUM, + ProbeSet.Mb as TMB, + ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM + FROM ProbeSetXRef, ProbeSet """ + + + def compile_final_query(self, from_clause, where_clause): + """Generates the final query string""" + + from_clause = self.normalize_spaces(from_clause) + + query = (self.normalize_spaces(self.base_query) + + """%s + WHERE %s + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(from_clause), + where_clause, + self.escape(self.dataset.id))) + + print("query is:", pf(query)) + + return query + + def run(self): + """Generates and runs a simple search of an mRNA expression dataset""" + + print("Running ProbeSetSearch") + query = (self.base_query + + """WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(self.search_term), + self.escape(self.dataset.id))) + + print("final query is:", pf(query)) + + return self.execute(query) + + class RifSearch(ProbeSetSearch): """Searches for traits with a Gene RIF entry including the search term.""" @@ -283,7 +283,7 @@ class LrsSearch(ProbeSetSearch): DoSearch.search_types['LRS'] = 'LrsSearch' -class CisLrsSearch(LrsSearch): +class CisLrsSearch(ProbeSetSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values A cisLRS search can take 2 forms: @@ -305,9 +305,12 @@ class CisLrsSearch(LrsSearch): DoSearch.search_types['CISLRS'] = "CisLrsSearch" def run(self): + + from_clause = ", Geno " + if len(self.search_term) == 3: lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] - + where_clause = """ %sXRef.LRS > %s and %sXRef.LRS < %s and %sXRef.Locus = Geno.name and @@ -327,7 +330,7 @@ class CisLrsSearch(LrsSearch): else: NeedSomeErrorHere - query = self.compile_final_query(where_clause) + query = self.compile_final_query(from_clause, where_clause) return self.execute(query) @@ -353,6 +356,8 @@ class TransLrsSearch(LrsSearch): DoSearch.search_types['TRANSLRS'] = "TransLrsSearch" def run(self): + from_clause = ", Geno " + if len(self.search_term) == 3: lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] @@ -374,9 +379,11 @@ class TransLrsSearch(LrsSearch): ) else: - NeedSomeErrorHere + NeedSomeErrorHere - return None + query = self.compile_final_query(from_clause, where_clause) + + return self.execute(query) #itemCmd = item[0] @@ -447,7 +454,7 @@ if __name__ == "__main__": #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() - results = CisLrsSearch(['9','99','10'], dataset, cursor, db_conn).run() + results = TransLrsSearch(['25','99','10'], dataset, cursor, db_conn).run() #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index dc3c72fc..05f062fc 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -84,16 +84,7 @@ class SearchResultPage(templatePage): print("self.dataset is:", pf(self.dataset)) self.dataset = webqtlDataset(self.dataset, self.cursor) print("self.dataset is now:", pf(self.dataset)) - #self.dataset = map(lambda x: webqtlDataset(x, self.cursor), self.dataset) - #currently, webqtl won't allow multiple crosses - #for other than multiple publish db search - #so we can use the first dataset as example - #if self.dataset.type=="Publish": - # pass if self.dataset.type in ("Geno", "ProbeSet"): - - #userExist = None - # Can't use paramater substitution for table names apparently db_type = self.dataset.type + "Freeze" print("db_type [%s]: %s" % (type(db_type), db_type)) @@ -124,11 +115,8 @@ class SearchResultPage(templatePage): # access_to_confidential_dataset = 1 # #if not access_to_confidential_dataset: - # #Error, No dataset selected - # heading = "Search Result" - # detail = ["The %s dataset you selected is not open to the public at this time, please go back and SELECT other dataset." % indFullName] - # self.error(heading=heading,detail=detail,error="Confidential dataset") - # return + # Some error + #else: # heading = "Search Result" # detail = ['''The dataset has not been established yet, please @@ -180,7 +168,8 @@ class SearchResultPage(templatePage): 'Max LRS', 'Max LRS Location'] elif self.dataset.type == "Geno": - self.search_fields = ['Name','Chr'] + self.search_fields = ['Name', + 'Chr'] self.header_fields = ['', 'ID', 'Location'] @@ -241,7 +230,6 @@ class SearchResultPage(templatePage): # This is throwing an error when a_search['key'] is None, so I changed above #search_type = string.upper(a_search['key']) #if not search_type: - # # We fall back to the dataset type as the key to get the right object # search_type = self.dataset.type search_ob = do_search.DoSearch.get_search(search_type) @@ -273,7 +261,6 @@ class SearchResultPage(templatePage): def getTraitInfoForGeno(self, trait_list): - for this_trait in trait_list: if not this_trait.haveinfo: this_trait.retrieveInfo() @@ -295,8 +282,7 @@ class SearchResultPage(templatePage): this_trait.location_value = trait_location_value - def getTraitInfoForPublish(self, trait_list, species=''): - + def getTraitInfoForPublish(self, trait_list, species = ''): for this_trait in trait_list: if not this_trait.haveinfo: this_trait.retrieveInfo(QTL=1) @@ -307,18 +293,16 @@ class SearchResultPage(templatePage): description = this_trait.pre_publication_description this_trait.description_display = description - try: - this_trait.pubmed_text = int(this_trait.year) - except: + if not this_trait.year.isdigit(): this_trait.pubmed_text = "N/A" if this_trait.pubmed_id: this_trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id #LRS and its location - this_trait.LRS_score_repr = 'N/A' + this_trait.LRS_score_repr = "N/A" this_trait.LRS_score_value = 0 - this_trait.LRS_location_repr = 'N/A' + this_trait.LRS_location_repr = "N/A" this_trait.LRS_location_value = 1000000 if this_trait.lrs: @@ -408,7 +392,7 @@ class SearchResultPage(templatePage): ProbeSet.Name = '%s' """ % (self.db_conn.escape_string(str(this_trait.db.id)), self.db_conn.escape_string(this_trait.name))) - + print("query is:", pf(query)) self.cursor.execute(query) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 19e67c43..3dac5933 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -1509,10 +1509,10 @@ class ShowTrait(templatePage): def make_sample_lists(self, fd, variance_data_page, this_trait): - if fd.genotype.type == "riset": - all_samples_ordered = fd.f1list + fd.samplelist - else: + if fd.parlist: all_samples_ordered = fd.parlist + fd.f1list + fd.samplelist + else: + all_samples_ordered = fd.f1list + fd.samplelist this_trait_samples = set(this_trait.data.keys()) @@ -1527,8 +1527,6 @@ class ShowTrait(templatePage): this_trait=this_trait, sample_group_type='primary', header="%s Only" % (fd.RISet)) - - print("primary_samples.attributes:", pf(primary_samples.attributes)) other_sample_names = [] for sample in this_trait.data.keys(): @@ -1538,8 +1536,7 @@ class ShowTrait(templatePage): other_sample_names.append(sample) if other_sample_names: - unappended_par_f1 = fd.f1list + fd.parlist - par_f1_samples = ["_2nd_" + sample for sample in unappended_par_f1] + par_f1_samples = fd.parlist + fd.f1list other_sample_names.sort() #Sort other samples other_sample_names = par_f1_samples + other_sample_names -- cgit v1.2.3 From 94dd9844fb55f4576d3a079e9d5e59ebbf911b8c Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 27 Nov 2012 17:59:17 -0600 Subject: Created subclass for each main data set type and moved the code for getting trait info that was in search_results.py into its respective class Renamed webqtlDataset to DataSet/create_dataset in webqtlTrait.py, webqtlDatabaseFunction.py, and CorrelationPage.py Got search page running again for mRNA assay data sets with these changes --- web/webqtl/search/SearchResultPage.py | 6 +- wqflask/base/data_set.py | 556 ++++++++++++++++++++----- wqflask/base/webqtlTrait.py | 25 +- wqflask/dbFunction/webqtlDatabaseFunction.py | 23 +- wqflask/wqflask/correlation/CorrelationPage.py | 4 +- wqflask/wqflask/do_search.py | 22 +- wqflask/wqflask/search_results.py | 325 +-------------- 7 files changed, 514 insertions(+), 447 deletions(-) diff --git a/web/webqtl/search/SearchResultPage.py b/web/webqtl/search/SearchResultPage.py index 029a54c4..d62bb449 100755 --- a/web/webqtl/search/SearchResultPage.py +++ b/web/webqtl/search/SearchResultPage.py @@ -14,7 +14,7 @@ from htmlgen import HTMLgen2 as HT from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell -from base.webqtlDataset import webqtlDataset +from base.data_set import DataSet from base.webqtlTrait import webqtlTrait from base.templatePage import templatePage from utility import webqtlUtil @@ -65,12 +65,12 @@ class SearchResultPage(templatePage): InbredSet where PublishFreeze.Name not like 'BXD300%' and InbredSet.Id = PublishFreeze.InbredSetId""") results = self.cursor.fetchall() - self.database = map(lambda x: webqtlDataset(x[0], self.cursor), results) + self.database = map(lambda x: DataSet(x[0], self.cursor), results) self.databaseCrosses = map(lambda x: x[1], results) self.databaseCrossIds = map(lambda x: x[2], results) self.singleCross = False else: - self.database = map(lambda x: webqtlDataset(x, self.cursor), self.database) + self.database = map(lambda x: DataSet(x, self.cursor), self.database) #currently, webqtl wouldn't allow multiple crosses #for other than multiple publish db search #so we can use the first database as example diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 992c673e..9e3e6d81 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -19,64 +19,64 @@ # # # This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by GeneNetwork Core Team 2010/10/20 + +from __future__ import print_function, division from htmlgen import HTMLgen2 as HT import webqtlConfig +from pprint import pformat as pf +# Used by create_database to instantiate objects +DS_NAME_MAP = {} + +def create_dataset(db_conn, dataset_name): + cursor = db_conn.cursor() + cursor.execute(""" + SELECT DBType.Name + FROM DBList, DBType + WHERE DBList.Name = %s and + DBType.Id = DBList.DBTypeId + """, (dataset_name)) + print("dataset_name:", dataset_name) + dataset_type = cursor.fetchone()[0] + print("dataset_type:", pf(dataset_type)) + + dataset_ob = DS_NAME_MAP[dataset_type] + #dataset_class = getattr(data_set, dataset_ob) + + print("DS_NAME_MAP:", pf(DS_NAME_MAP)) + + dataset_class = globals()[dataset_ob] + return dataset_class(dataset_name, db_conn) class DataSet(object): """ - Dataset class defines a dataset in webqtl, can be either Microarray, + DataSet class defines a dataset in webqtl, can be either Microarray, Published phenotype, genotype, or user input dataset(temp) """ - def __init__(self, dbName, cursor=None): - - assert dbName - self.id = 0 - self.name = '' - self.type = '' - self.group = '' - self.cursor = cursor - - #temporary storage - if dbName.find('Temp') >= 0: - self.searchfield = ['name','description'] - self.disfield = ['name','description'] - self.type = 'Temp' - self.id = 1 - self.fullname = 'Temporary Storage' - self.shortname = 'Temp' - elif dbName.find('Publish') >= 0: - pass - elif dbName.find('Geno') >= 0: - self.searchfield = ['name','chr'] - self.disfield = ['name','chr','mb', 'source2', 'sequence'] - self.type = 'Geno' - else: #ProbeSet - self.searchfield = ['name','description','probe_target_description', - 'symbol','alias','genbankid','unigeneid','omim', - 'refseq_transcriptid','probe_set_specificity', 'probe_set_blat_score'] - self.disfield = ['name','symbol','description','probe_target_description', - 'chr','mb','alias','geneid','genbankid', 'unigeneid', 'omim', - 'refseq_transcriptid','blatseq','targetseq','chipid', 'comments', - 'strand_probe','strand_gene','probe_set_target_region', - 'probe_set_specificity', 'probe_set_blat_score','probe_set_blat_mb_start', - 'probe_set_blat_mb_end', 'probe_set_strand', - 'probe_set_note_by_rw', 'flag'] - self.type = 'ProbeSet' - self.name = dbName - if self.cursor and self.id == 0: - self.retrieveName() - - + def __init__(self, name, db_conn): + + assert name + self.name = name + self.db_conn = db_conn + self.cursor = self.db_conn.cursor() + self.id = None + self.type = None + self.group = None + + #if self.cursor and self.id == 0: + self.setup() + + self.check_confidentiality() + + self.retrieve_name() + self.get_group() + + # Delete this eventually @property def riset(): @@ -85,8 +85,93 @@ class DataSet(object): def get_group(self): assert self.cursor - if self.type == 'Publish': - query = ''' + self.cursor.execute(self.query) + self.group, self.group_id = self.cursor.fetchone() + if self.group == 'BXD300': + self.group = "BXD" + #return group + + + def retrieve_name(self): + """ + If the data set name parameter is not found in the 'Name' field of the data set table, + check if it is actually the FullName or ShortName instead. + + This is not meant to retrieve the data set info if no name at all is passed. + + """ + + query_args = tuple(self.db_conn.escape_string(x) for x in ( + (self.type + "Freeze"), + str(webqtlConfig.PUBLICTHRESH), + self.name, + self.name, + self.name)) + print("query_args are:", query_args) + + query = ''' + SELECT + Id, Name, FullName, ShortName + FROM + %s + WHERE + public > %s AND + (Name = "%s" OR FullName = "%s" OR ShortName = "%s") + ''' % (query_args) + + self.cursor.execute(query) + self.id, self.name, self.fullname, self.shortname = self.cursor.fetchone() + + + #def genHTML(self, Class='c0dd'): + # return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), + # url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") + +class PhenotypeDataSet(DataSet): + DS_NAME_MAP['Publish'] = 'PhenotypeDataSet' + + def setup(self): + # Fields in the database table + self.search_fields = ['Phenotype.Post_publication_description', + 'Phenotype.Pre_publication_description', + 'Phenotype.Pre_publication_abbreviation', + 'Phenotype.Post_publication_abbreviation', + 'Phenotype.Lab_code', + 'Publication.PubMed_ID', + 'Publication.Abstract', + 'Publication.Title', + 'Publication.Authors', + 'PublishXRef.Id'] + + # Figure out what display_fields is + self.display_fields = ['name', + 'pubmed_id', + 'pre_publication_description', + 'post_publication_description', + 'original_description', + 'pre_publication_abbreviation', + 'post_publication_abbreviation', + 'lab_code', + 'submitter', 'owner', + 'authorized_users', + 'authors', 'title', + 'abstract', 'journal', + 'volume', 'pages', + 'month', 'year', + 'sequence', 'units', 'comments'] + + # Fields displayed in the search results table header + self.header_fields = ['', + 'ID', + 'Description', + 'Authors', + 'Year', + 'Max LRS', + 'Max LRS Location'] + + self.type = 'Publish' + + self.query = ''' SELECT InbredSet.Name, InbredSet.Id FROM @@ -94,69 +179,336 @@ class DataSet(object): WHERE PublishFreeze.InbredSetId = InbredSet.Id AND PublishFreeze.Name = "%s" - ''' % self.name - elif self.type == 'Geno': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, GenoFreeze - WHERE - GenoFreeze.InbredSetId = InbredSet.Id AND - GenoFreeze.Name = "%s" - ''' % self.name - elif self.type == 'ProbeSet': - query = ''' - SELECT - InbredSet.Name, InbredSet.Id - FROM - InbredSet, ProbeSetFreeze, ProbeFreeze - WHERE - ProbeFreeze.InbredSetId = InbredSet.Id AND - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Name = "%s" - ''' % self.name - else: - return "" - self.cursor.execute(query) - group, RIID = self.cursor.fetchone() - if group == 'BXD300': - group = "BXD" - self.group = group - self.group_id = RIID - return group + ''' % self.db_conn.escape_string(self.name) + + def check_confidentiality(self): + # (Urgently?) Need to write this + pass + + def get_trait_info(self, trait_list, species = ''): + for this_trait in trait_list: + if not this_trait.haveinfo: + this_trait.retrieveInfo(QTL=1) + + description = this_trait.post_publication_description + if this_trait.confidential: + if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): + description = this_trait.pre_publication_description + this_trait.description_display = description + + if not this_trait.year.isdigit(): + this_trait.pubmed_text = "N/A" + + if this_trait.pubmed_id: + this_trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id + + #LRS and its location + this_trait.LRS_score_repr = "N/A" + this_trait.LRS_score_value = 0 + this_trait.LRS_location_repr = "N/A" + this_trait.LRS_location_value = 1000000 + + if this_trait.lrs: + self.cursor.execute(""" + select Geno.Chr, Geno.Mb from Geno, Species + where Species.Name = '%s' and + Geno.Name = '%s' and + Geno.SpeciesId = Species.Id + """ % (species, this_trait.locus)) + result = self.cursor.fetchone() + if result: + if result[0] and result[1]: + LRS_Chr = result[0] + LRS_Mb = result[1] - def retrieveName(self): - assert self.id == 0 and self.cursor + #XZ: LRS_location_value is used for sorting + try: + LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) + except: + if LRS_Chr.upper() == 'X': + LRS_location_value = 20*1000 + float(LRS_Mb) + else: + LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) + + this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs + this_trait.LRS_score_value = LRS_score_value = this_trait.lrs + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + +class GenotypeDataSet(DataSet): + DS_NAME_MAP['Geno'] = 'GenotypeDataSet' + + def setup(self): + # Fields in the database table + self.search_fields = ['Name', + 'Chr'] + + # Find out what display_fields is + self.display_fields = ['name', + 'chr', + 'mb', + 'source2', + 'sequence'] + + # Fields displayed in the search results table header + self.header_fields = ['', + 'ID', + 'Location'] + + # Todo: Obsolete or rename this field + self.type = 'Geno' + query = ''' SELECT - Id, Name, FullName, ShortName + InbredSet.Name, InbredSet.Id FROM - %sFreeze + InbredSet, GenoFreeze WHERE - public > %d AND - (Name = "%s" OR FullName = "%s" OR ShortName = "%s") - '''% (self.type, webqtlConfig.PUBLICTHRESH, self.name, self.name, self.name) - try: + GenoFreeze.InbredSetId = InbredSet.Id AND + GenoFreeze.Name = "%s" + ''' % self.db_conn.escape_string(self.name) + + def check_confidentiality(self): + return geno_mrna_confidentiality(self) + + def get_trait_info(self, trait_list): + for this_trait in trait_list: + if not this_trait.haveinfo: + this_trait.retrieveInfo() + + #XZ: trait_location_value is used for sorting + trait_location_repr = 'N/A' + trait_location_value = 1000000 + + if this_trait.chr and this_trait.mb: + try: + trait_location_value = int(this_trait.chr)*1000 + this_trait.mb + except: + if this_trait.chr.upper() == 'X': + trait_location_value = 20*1000 + this_trait.mb + else: + trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb + + this_trait.location_repr = 'Chr%s: %.4f' % (this_trait.chr, float(this_trait.mb) ) + this_trait.location_value = trait_location_value + + +class MrnaAssayDataSet(DataSet): + ''' + An mRNA Assay is a quantitative assessment (assay) associated with an mRNA trait + + This used to be called ProbeSet, but that term only refers specifically to the Affymetrix + platform and is far too specific. + + ''' + DS_NAME_MAP['ProbeSet'] = 'MrnaAssayDataSet' + + def setup(self): + # Fields in the database table + self.search_fields = ['Name', + 'Description', + 'Probe_Target_Description', + 'Symbol', + 'Alias', + 'GenbankId', + 'UniGeneId', + 'RefSeq_TranscriptId'] + + # Find out what display_fields is + self.display_fields = ['name', 'symbol', + 'description', 'probe_target_description', + 'chr', 'mb', + 'alias', 'geneid', + 'genbankid', 'unigeneid', + 'omim', 'refseq_transcriptid', + 'blatseq', 'targetseq', + 'chipid', 'comments', + 'strand_probe', 'strand_gene', + 'probe_set_target_region', + 'probe_set_specificity', + 'probe_set_blat_score', + 'probe_set_blat_mb_start', + 'probe_set_blat_mb_end', + 'probe_set_strand', + 'probe_set_note_by_rw', + 'flag'] + + # Fields displayed in the search results table header + self.header_fields = ['', + 'ID', + 'Symbol', + 'Description', + 'Location', + 'Mean Expr', + 'Max LRS', + 'Max LRS Location'] + + # Todo: Obsolete or rename this field + self.type = 'ProbeSet' + + self.query = ''' + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, ProbeSetFreeze, ProbeFreeze + WHERE + ProbeFreeze.InbredSetId = InbredSet.Id AND + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Name = "%s" + ''' % self.db_conn.escape_string(self.name) + + + def check_confidentiality(self): + return geno_mrna_confidentiality(self) + + def get_trait_info(self, trait_list=None, species=''): + + # Note: setting trait_list to [] is probably not a great idea. + if not trait_list: + trait_list = [] + + for this_trait in trait_list: + + if not this_trait.haveinfo: + this_trait.retrieveInfo(QTL=1) + + if this_trait.symbol: + pass + else: + this_trait.symbol = "N/A" + + #XZ, 12/08/2008: description + #XZ, 06/05/2009: Rob asked to add probe target description + description_string = str(this_trait.description).strip() + target_string = str(this_trait.probe_target_description).strip() + + description_display = '' + + if len(description_string) > 1 and description_string != 'None': + description_display = description_string + else: + description_display = this_trait.symbol + + if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': + description_display = description_display + '; ' + target_string.strip() + + # Save it for the jinja2 tablet + this_trait.description_display = description_display + + #XZ: trait_location_value is used for sorting + trait_location_repr = 'N/A' + trait_location_value = 1000000 + + if this_trait.chr and this_trait.mb: + try: + trait_location_value = int(this_trait.chr)*1000 + this_trait.mb + except: + if this_trait.chr.upper() == 'X': + trait_location_value = 20*1000 + this_trait.mb + else: + trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb + + this_trait.location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) + this_trait.location_value = trait_location_value + #this_trait.trait_location_value = trait_location_value + + #XZ, 01/12/08: This SQL query is much faster. + query = ( +"""select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet + where ProbeSetXRef.ProbeSetFreezeId = %s and + ProbeSet.Id = ProbeSetXRef.ProbeSetId and + ProbeSet.Name = '%s' + """ % (self.db_conn.escape_string(str(this_trait.db.id)), + self.db_conn.escape_string(this_trait.name))) + + print("query is:", pf(query)) + self.cursor.execute(query) - self.id,self.name,self.fullname,self.shortname=self.cursor.fetchone() - except: - raise KeyError, `self.name`+' doesn\'t exist.' + result = self.cursor.fetchone() + if result: + if result[0]: + mean = result[0] + else: + mean=0 + else: + mean = 0 - def genHTML(self, Class='c0dd'): - return HT.Href(text = HT.Span('%s Database' % self.fullname, Class= "fwb " + Class), - url= webqtlConfig.INFOPAGEHREF % self.name,target="_blank") + #XZ, 06/05/2009: It is neccessary to turn on nowrap + this_trait.mean = repr = "%2.3f" % mean -class PhenotypeDataSet(DataSet): + #LRS and its location + this_trait.LRS_score_repr = 'N/A' + this_trait.LRS_score_value = 0 + this_trait.LRS_location_repr = 'N/A' + this_trait.LRS_location_value = 1000000 + + #Max LRS and its Locus location + if this_trait.lrs and this_trait.locus: + self.cursor.execute(""" + select Geno.Chr, Geno.Mb from Geno, Species + where Species.Name = '%s' and + Geno.Name = '%s' and + Geno.SpeciesId = Species.Id + """ % (species, this_trait.locus)) + result = self.cursor.fetchone() + + if result: + if result[0] and result[1]: + LRS_Chr = result[0] + LRS_Mb = result[1] + + #XZ: LRS_location_value is used for sorting + try: + LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) + except: + if LRS_Chr.upper() == 'X': + LRS_location_value = 20*1000 + float(LRS_Mb) + else: + LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) + + this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs + this_trait.LRS_score_value = LRS_score_value = this_trait.lrs + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + + +class TempDataSet(DataSet): + '''Temporary user-generated data set''' - def __init__(self): - self.searchfield = ['name','post_publication_description','abstract','title','authors'] - self.disfield = ['name','pubmed_id', - 'pre_publication_description', 'post_publication_description', 'original_description', - 'pre_publication_abbreviation', 'post_publication_abbreviation', - 'lab_code', 'submitter', 'owner', 'authorized_users', - 'authors','title','abstract', 'journal','volume','pages','month', - 'year','sequence', 'units', 'comments'] - self.type = 'Publish' \ No newline at end of file + def setup(self): + self.search_fields = ['name', + 'description'] + + self.display_fields = ['name', + 'description'] + + self.header_fields = ['Name', + 'Description'] + + self.type = 'Temp' + + # Need to double check later how these are used + self.id = 1 + self.fullname = 'Temporary Storage' + self.shortname = 'Temp' + + +def geno_mrna_confidentiality(ob): + dataset_table = ob.type + "Freeze" + print("dataset_table [%s]: %s" % (type(dataset_table), dataset_table)) + + query = '''SELECT Id, Name, FullName, confidentiality, + AuthorisedUsers FROM %s WHERE Name = %%s''' % (dataset_table) + + ob.cursor.execute(query, ob.name) + + (dataset_id, + name, + full_name, + confidential, + authorized_users) = ob.cursor.fetchall()[0] + + if confidential: + # Allow confidential data later + NoConfindetialDataForYouTodaySorry + \ No newline at end of file diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 51d36ab2..29087721 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -6,7 +6,7 @@ from htmlgen import HTMLgen2 as HT import webqtlConfig from webqtlCaseData import webqtlCaseData -from webqtlDataset import webqtlDataset +from data_set import create_dataset from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil @@ -20,9 +20,10 @@ class webqtlTrait: """ - def __init__(self, cursor = None, **kw): + def __init__(self, db_conn, **kw): print("in webqtlTrait") - self.cursor = cursor + self.db_conn = db_conn + self.cursor = self.db_conn.cursor() self.db = None # database object self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. self.cellid = '' @@ -50,7 +51,7 @@ class webqtlTrait: if self.db and isinstance(self.db, basestring): assert self.cursor, "Don't have a cursor" - self.db = webqtlDataset(self.db, self.cursor) + self.db = create_dataset(self.db_conn, self.db) #if self.db == None, not from a database print("self.db is:", self.db, type(self.db)) @@ -396,8 +397,8 @@ class webqtlTrait: #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif self.db.type == 'ProbeSet': - disfieldString = string.join(self.db.disfield,',ProbeSet.') - disfieldString = 'ProbeSet.' + disfieldString + display_fields_string = ',ProbeSet.'.join(self.db.display_fields) + display_fields_string = 'ProbeSet.' + display_fields_string query = """ SELECT %s FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef @@ -406,12 +407,12 @@ class webqtlTrait: ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' - """ % (disfieldString, self.db.name, self.name) + """ % (display_fields_string, self.db.name, self.name) #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif self.db.type == 'Geno': - disfieldString = string.join(self.db.disfield,',Geno.') - disfieldString = 'Geno.' + disfieldString + display_fields_string = string.join(self.db.display_fields,',Geno.') + display_fields_string = 'Geno.' + display_fields_string query = """ SELECT %s FROM Geno, GenoFreeze, GenoXRef @@ -420,10 +421,10 @@ class webqtlTrait: GenoXRef.GenoId = Geno.Id AND GenoFreeze.Name = '%s' AND Geno.Name = '%s' - """ % (disfieldString, self.db.name, self.name) + """ % (display_fields_string, self.db.name, self.name) else: #Temp type query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ - (string.join(self.db.disfield,','), self.db.type, self.name) + (string.join(self.db.display_fields,','), self.db.type, self.name) self.cursor.execute(query) @@ -432,7 +433,7 @@ class webqtlTrait: self.haveinfo = 1 #XZ: assign SQL query result to trait attributes. - for i, field in enumerate(self.db.disfield): + for i, field in enumerate(self.db.display_fields): setattr(self, field, traitInfo[i]) if self.db.type == 'Publish': diff --git a/wqflask/dbFunction/webqtlDatabaseFunction.py b/wqflask/dbFunction/webqtlDatabaseFunction.py index 7e33da3f..8f923b8a 100755 --- a/wqflask/dbFunction/webqtlDatabaseFunction.py +++ b/wqflask/dbFunction/webqtlDatabaseFunction.py @@ -19,14 +19,7 @@ # # # This module is used by GeneNetwork project (www.genenetwork.org) -# -# Created by GeneNetwork Core Team 2010/08/10 -# -# Last updated by Xiaodong Zhou 2011/Jan/20 -#webqtlDatabaseFunction.py -# -#This file consists of various database related functions; the names are generally self-explanatory. import MySQLdb import string @@ -206,21 +199,21 @@ def getTissueCountByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=N ########################################################################### # input: cursor, TissueProbeSetFreezeId (int) -# output: DatasetName(string),DatasetFullName(string) -# function: retrieve DatasetName, DatasetFullName based on TissueProbeSetFreezeId +# output: DataSetName(string),DataSetFullName(string) +# function: retrieve DataSetName, DataSetFullName based on TissueProbeSetFreezeId ########################################################################### -def getDatasetNamesByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): +def getDataSetNamesByTissueProbeSetFreezeId(cursor=None, TissueProbeSetFreezeId=None): query ="select Name, FullName from TissueProbeSetFreeze where Id=%s" % TissueProbeSetFreezeId try: cursor.execute(query) result = cursor.fetchone() - DatasetName = result[0] - DatasetFullName =result[1] + DataSetName = result[0] + DataSetFullName =result[1] except: - DatasetName =None - DatasetFullName =None + DataSetName =None + DataSetFullName =None - return DatasetName, DatasetFullName + return DataSetName, DataSetFullName ########################################################################### # input: cursor, geneIdLst (list) diff --git a/wqflask/wqflask/correlation/CorrelationPage.py b/wqflask/wqflask/correlation/CorrelationPage.py index e48ea412..8af30d1e 100644 --- a/wqflask/wqflask/correlation/CorrelationPage.py +++ b/wqflask/wqflask/correlation/CorrelationPage.py @@ -47,7 +47,7 @@ from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell from base.webqtlTrait import webqtlTrait -from base.webqtlDataset import webqtlDataset +from base.data_set import create_dataset from base.templatePage import templatePage from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction @@ -310,7 +310,7 @@ class CorrelationPage(templatePage): #try: #print("target_db_name is:", target_db_name) - self.db = webqtlDataset(self.target_db_name, self.cursor) + self.db = create_dataset(self.db_conn, self.target_db_name) #except: # detail = ["The database you just requested has not been established yet."] # self.error(detail) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index e2bafb3a..73a72e00 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -147,7 +147,7 @@ class GenotypeSearch(DoSearch): """WHERE %s and Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and - GenoFreeze.Id = %s"""% ( + GenoFreeze.Id = %s""" % ( self.get_where_clause(), self.escape(self.dataset.id))) @@ -257,7 +257,7 @@ class GoSearch(ProbeSetSearch): statements = ("""%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id""" % ( - self.db_conn.escape_string(self.dataset.type))) + self.escape(self.dataset.type))) where_clause = " %s = '%s' and %s " % (field, go_id, statements) @@ -317,14 +317,14 @@ class CisLrsSearch(ProbeSetSearch): Geno.SpeciesId = %s and %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %s """ % ( - self.dataset.type, + self.escape(self.dataset.type), min(lower_limit, upper_limit), - self.dataset.type, + self.escape(self.dataset.type), max(lower_limit, upper_limit), - self.dataset.type, + self.escape(self.dataset.type), self.species_id, - self.dataset.type, - self.dataset.type, + self.escape(self.dataset.type), + self.escape(self.dataset.type), min_threshold ) else: @@ -437,7 +437,7 @@ if __name__ == "__main__": from base import webqtlConfig - from base.webqtlDataset import webqtlDataset + from base.data_set import create_dataset from base.templatePage import templatePage from utility import webqtlUtil from dbFunction import webqtlDatabaseFunction @@ -449,13 +449,13 @@ if __name__ == "__main__": cursor = db_conn.cursor() dataset_name = "HC_M2_0606_P" - dataset = webqtlDataset(dataset_name, cursor) + dataset = create_dataset(db_conn, dataset_name) #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() - results = TransLrsSearch(['25','99','10'], dataset, cursor, db_conn).run() - #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() + results = CisLrsSearch(['25','99','10'], dataset, cursor, db_conn).run() + #results = TransLrsSearch(['25', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 05f062fc..b50e45d5 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -10,7 +10,7 @@ from flask import render_template # # ################################################### -import string +#import string import os import cPickle import re @@ -29,7 +29,7 @@ from htmlgen import HTMLgen2 as HT from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell -from base.webqtlDataset import webqtlDataset +from base.data_set import create_dataset from base.webqtlTrait import webqtlTrait from base.templatePage import templatePage from wqflask import parser @@ -43,14 +43,13 @@ from utility import formatting class SearchResultPage(templatePage): + #maxReturn = 3000 - maxReturn = 3000 - nkeywords = 0 def __init__(self, fd): print("initing SearchResultPage") - import logging_tree - logging_tree.printout() + #import logging_tree + #logging_tree.printout() self.fd = fd templatePage.__init__(self, fd) assert self.openMysql(), "Couldn't open MySQL" @@ -59,127 +58,40 @@ class SearchResultPage(templatePage): self.dataset = fd['dataset'] # change back to self.dataset - if not self.dataset or self.dataset == 'spacer': - #Error, No dataset selected - heading = "Search Result" - detail = ['''No dataset was selected for this search, please - go back and SELECT at least one dataset.'''] - self.error(heading=heading,detail=detail,error="No dataset Selected") - return + #if not self.dataset or self.dataset == 'spacer': + # #Error, No dataset selected + # heading = "Search Result" + # detail = ['''No dataset was selected for this search, please + # go back and SELECT at least one dataset.'''] + # self.error(heading=heading,detail=detail,error="No dataset Selected") + # return ########################################### # Names and IDs of RISet / F2 set ########################################### + + # All Phenotypes is a special case we'll deal with later if self.dataset == "All Phenotypes": self.cursor.execute(""" select PublishFreeze.Name, InbredSet.Name, InbredSet.Id from PublishFreeze, InbredSet where PublishFreeze.Name not like 'BXD300%' and InbredSet.Id = PublishFreeze.InbredSetId""") results = self.cursor.fetchall() - self.dataset = map(lambda x: webqtlDataset(x[0], self.cursor), results) + self.dataset = map(lambda x: DataSet(x[0], self.cursor), results) self.dataset_groups = map(lambda x: x[1], results) self.dataset_group_ids = map(lambda x: x[2], results) - self.single_group = False else: print("self.dataset is:", pf(self.dataset)) - self.dataset = webqtlDataset(self.dataset, self.cursor) + self.dataset = create_dataset(self.db_conn, self.dataset) print("self.dataset is now:", pf(self.dataset)) - if self.dataset.type in ("Geno", "ProbeSet"): - db_type = self.dataset.type + "Freeze" - print("db_type [%s]: %s" % (type(db_type), db_type)) - - query = '''SELECT Id, Name, FullName, confidentiality, - AuthorisedUsers FROM %s WHERE Name = %%s''' % (db_type) - - self.cursor.execute(query, self.dataset.name) - - (indId, - indName, - indFullName, - confidential, - AuthorisedUsers) = self.cursor.fetchall()[0] - - if confidential: - # Allow confidential data later - NoConfindetialDataForYouTodaySorry - #access_to_confidential_dataset = 0 - # - ##for the dataset that confidentiality is 1 - ##1. 'admin' and 'root' can see all of the dataset - ##2. 'user' can see the dataset that AuthorisedUsers contains his id(stored in the Id field of User table) - #if webqtlConfig.USERDICT[self.privilege] > webqtlConfig.USERDICT['user']: - # access_to_confidential_dataset = 1 - #else: - # AuthorisedUsersList=AuthorisedUsers.split(',') - # if AuthorisedUsersList.__contains__(self.userName): - # access_to_confidential_dataset = 1 - # - #if not access_to_confidential_dataset: - # Some error - - #else: - # heading = "Search Result" - # detail = ['''The dataset has not been established yet, please - # go back and SELECT at least one dataset.'''] - # self.error(heading=heading,detail=detail,error="No dataset Selected") - # return - - self.dataset.get_group() - self.single_group = True - #XZ, August 24,2010: Since self.single_group = True, it's safe to assign one species Id. - self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, - self.dataset.group) - - #self.db_type = self.dataset.type - if self.dataset.type == "Publish": - self.search_fields = ['Phenotype.Post_publication_description', - 'Phenotype.Pre_publication_description', - 'Phenotype.Pre_publication_abbreviation', - 'Phenotype.Post_publication_abbreviation', - 'Phenotype.Lab_code', - 'Publication.PubMed_ID', - 'Publication.Abstract', - 'Publication.Title', - 'Publication.Authors', - 'PublishXRef.Id'] - self.header_fields = ['', - 'ID', - 'Description', - 'Authors', - 'Year', - 'Max LRS', - 'Max LRS Location'] - - elif self.dataset.type == "ProbeSet": - self.search_fields = ['Name', - 'Description', - 'Probe_Target_Description', - 'Symbol', - 'Alias', - 'GenbankId', - 'UniGeneId', - 'RefSeq_TranscriptId'] - self.header_fields = ['', - 'ID', - 'Symbol', - 'Description', - 'Location', - 'Mean Expr', - 'Max LRS', - 'Max LRS Location'] - elif self.dataset.type == "Geno": - self.search_fields = ['Name', - 'Chr'] - self.header_fields = ['', - 'ID', - 'Location'] - + self.search() self.gen_search_result() def gen_search_result(self): - """Get the info displayed in the search result table from the set of results computed in + """ + Get the info displayed in the search result table from the set of results computed in the "search" function """ @@ -191,26 +103,19 @@ class SearchResultPage(templatePage): if not result: continue - seq = 1 group = self.dataset.group - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) #### Excel file needs to be generated #### print("foo locals are:", locals()) trait_id = result[0] - this_trait = webqtlTrait(db=self.dataset, name=trait_id, cursor=self.cursor) + this_trait = webqtlTrait(self.db_conn, db=self.dataset, name=trait_id) this_trait.retrieveInfo(QTL=True) print("this_trait is:", pf(this_trait)) self.trait_list.append(this_trait) - - if self.dataset.type == "ProbeSet": - self.getTraitInfoForProbeSet(trait_list=self.trait_list, species=species) - elif self.dataset.type == "Publish": - self.getTraitInfoForPublish(trait_list=self.trait_list, species=species) - elif self.dataset.type == "Geno": - self.getTraitInfoForGeno(trait_list=self.trait_list) + + self.dataset.get_trait_info(self.trait_list, species) def search(self): @@ -222,7 +127,7 @@ class SearchResultPage(templatePage): print("[kodak] item is:", pf(a_search)) search_term = a_search['search_term'] if a_search['key']: - search_type = string.upper(a_search['key']) + search_type = a_search['key'].upper() else: # We fall back to the dataset type as the key to get the right object search_type = self.dataset.type @@ -258,187 +163,3 @@ class SearchResultPage(templatePage): keyword = string.replace(keyword,"?",".") wildcardkeyword[i] = keyword#'[[:<:]]'+ keyword+'[[:>:]]' return wildcardkeyword - - - def getTraitInfoForGeno(self, trait_list): - for this_trait in trait_list: - if not this_trait.haveinfo: - this_trait.retrieveInfo() - - #XZ: trait_location_value is used for sorting - trait_location_repr = 'N/A' - trait_location_value = 1000000 - - if this_trait.chr and this_trait.mb: - try: - trait_location_value = int(this_trait.chr)*1000 + this_trait.mb - except: - if this_trait.chr.upper() == 'X': - trait_location_value = 20*1000 + this_trait.mb - else: - trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - - this_trait.location_repr = 'Chr%s: %.4f' % (this_trait.chr, float(this_trait.mb) ) - this_trait.location_value = trait_location_value - - - def getTraitInfoForPublish(self, trait_list, species = ''): - for this_trait in trait_list: - if not this_trait.haveinfo: - this_trait.retrieveInfo(QTL=1) - - description = this_trait.post_publication_description - if this_trait.confidential: - if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): - description = this_trait.pre_publication_description - this_trait.description_display = description - - if not this_trait.year.isdigit(): - this_trait.pubmed_text = "N/A" - - if this_trait.pubmed_id: - this_trait.pubmed_link = webqtlConfig.PUBMEDLINK_URL % this_trait.pubmed_id - - #LRS and its location - this_trait.LRS_score_repr = "N/A" - this_trait.LRS_score_value = 0 - this_trait.LRS_location_repr = "N/A" - this_trait.LRS_location_value = 1000000 - - if this_trait.lrs: - self.cursor.execute(""" - select Geno.Chr, Geno.Mb from Geno, Species - where Species.Name = '%s' and - Geno.Name = '%s' and - Geno.SpeciesId = Species.Id - """ % (species, this_trait.locus)) - result = self.cursor.fetchone() - - if result: - if result[0] and result[1]: - LRS_Chr = result[0] - LRS_Mb = result[1] - - #XZ: LRS_location_value is used for sorting - try: - LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) - except: - if LRS_Chr.upper() == 'X': - LRS_location_value = 20*1000 + float(LRS_Mb) - else: - LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) - - this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs - this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) - - - def getTraitInfoForProbeSet(self, trait_list=None, species=''): - - # Note: setting trait_list to [] is probably not a great idea. - if not trait_list: - trait_list = [] - - for this_trait in trait_list: - - if not this_trait.haveinfo: - this_trait.retrieveInfo(QTL=1) - - if this_trait.symbol: - pass - else: - this_trait.symbol = "N/A" - - #XZ, 12/08/2008: description - #XZ, 06/05/2009: Rob asked to add probe target description - description_string = str(this_trait.description).strip() - target_string = str(this_trait.probe_target_description).strip() - - description_display = '' - - if len(description_string) > 1 and description_string != 'None': - description_display = description_string - else: - description_display = this_trait.symbol - - if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': - description_display = description_display + '; ' + target_string.strip() - - # Save it for the jinja2 tablet - this_trait.description_display = description_display - - #XZ: trait_location_value is used for sorting - trait_location_repr = 'N/A' - trait_location_value = 1000000 - - if this_trait.chr and this_trait.mb: - try: - trait_location_value = int(this_trait.chr)*1000 + this_trait.mb - except: - if this_trait.chr.upper() == 'X': - trait_location_value = 20*1000 + this_trait.mb - else: - trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb - - this_trait.location_repr = 'Chr %s: %.4f Mb' % (this_trait.chr, float(this_trait.mb) ) - this_trait.location_value = trait_location_value - #this_trait.trait_location_value = trait_location_value - - #XZ, 01/12/08: This SQL query is much faster. - query = ( -"""select ProbeSetXRef.mean from ProbeSetXRef, ProbeSet - where ProbeSetXRef.ProbeSetFreezeId = %s and - ProbeSet.Id = ProbeSetXRef.ProbeSetId and - ProbeSet.Name = '%s' - """ % (self.db_conn.escape_string(str(this_trait.db.id)), - self.db_conn.escape_string(this_trait.name))) - - print("query is:", pf(query)) - - self.cursor.execute(query) - result = self.cursor.fetchone() - - if result: - if result[0]: - mean = result[0] - else: - mean=0 - else: - mean = 0 - - #XZ, 06/05/2009: It is neccessary to turn on nowrap - this_trait.mean = repr = "%2.3f" % mean - - #LRS and its location - this_trait.LRS_score_repr = 'N/A' - this_trait.LRS_score_value = 0 - this_trait.LRS_location_repr = 'N/A' - this_trait.LRS_location_value = 1000000 - - #Max LRS and its Locus location - if this_trait.lrs and this_trait.locus: - self.cursor.execute(""" - select Geno.Chr, Geno.Mb from Geno, Species - where Species.Name = '%s' and - Geno.Name = '%s' and - Geno.SpeciesId = Species.Id - """ % (species, this_trait.locus)) - result = self.cursor.fetchone() - - if result: - if result[0] and result[1]: - LRS_Chr = result[0] - LRS_Mb = result[1] - - #XZ: LRS_location_value is used for sorting - try: - LRS_location_value = int(LRS_Chr)*1000 + float(LRS_Mb) - except: - if LRS_Chr.upper() == 'X': - LRS_location_value = 20*1000 + float(LRS_Mb) - else: - LRS_location_value = ord(str(LRS_chr).upper()[0])*1000 + float(LRS_Mb) - - this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs - this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) -- cgit v1.2.3 From d1f2863c15f62ae37833fa1311870d7b1aab3355 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 28 Nov 2012 14:30:04 -0600 Subject: Made some small changes to get code working for genotype searches --- wqflask/base/data_set.py | 2 +- wqflask/wqflask/parser.py | 2 ++ wqflask/wqflask/search_results.py | 5 +++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 9e3e6d81..d9d3a52b 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -258,7 +258,7 @@ class GenotypeDataSet(DataSet): # Todo: Obsolete or rename this field self.type = 'Geno' - query = ''' + self.query = ''' SELECT InbredSet.Name, InbredSet.Id FROM diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index dc33fc52..7711942a 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -15,6 +15,8 @@ Both square brackets and parentheses can be used interchangeably. Both can also encapsulate a single value; "cisLRS=[9 999 10)" would be acceptable.] +NEED TO DEAL WITH WILDCARD CHARACTER '*' + """ from __future__ import print_function, division diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index b50e45d5..96350f22 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -55,6 +55,7 @@ class SearchResultPage(templatePage): assert self.openMysql(), "Couldn't open MySQL" print("fd is:", pf(fd)) + print("fd.dict is:", pf(fd['dataset'])) self.dataset = fd['dataset'] # change back to self.dataset @@ -93,7 +94,7 @@ class SearchResultPage(templatePage): """ Get the info displayed in the search result table from the set of results computed in the "search" function - + """ self.trait_list = [] # result_set represents the results for each search term; a search of @@ -114,7 +115,7 @@ class SearchResultPage(templatePage): this_trait.retrieveInfo(QTL=True) print("this_trait is:", pf(this_trait)) self.trait_list.append(this_trait) - + self.dataset.get_trait_info(self.trait_list, species) -- cgit v1.2.3 From a47111b7fce834924285d7a89b544c47473ce724 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 28 Nov 2012 15:01:54 -0600 Subject: Changed parser.py to deal with the wild card character (*) and to split by ">" and "<" in addition to "=" and ":" --- wqflask/wqflask/parser.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 7711942a..a94a8842 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -27,23 +27,26 @@ from pprint import pformat as pf def parse(pstring): pstring = re.split(r"""(?:(\w+\s*=\s*[\(\[][^)]*[\)\]]) | # LRS=(1 2 3), cisLRS=[4 5 6], etc - (\w+\s*[=:]\w+) | # wiki=bar, GO:foobar, etc - (\w+)) # shh, brain, etc """, pstring, + (\w+\s*[=:\>\<][\w\*]+) | # wiki=bar, GO:foobar, etc + ([\w\*]+)) # shh, brain, etc """, pstring, flags=re.VERBOSE) pstring = [item.strip() for item in pstring if item and item.strip()] print(pstring) items = [] + separators = [re.escape(x) for x in (":", "=", "<", ">")] + separators = '([%s])' % ("".join(separators)) + + print("separators:", separators) + for item in pstring: - if ":" in item: - key, seperator, value = item.partition(':') - elif "=" in item: - key, seperator, value = item.partition('=') - else: - seperator = None + splat = re.split(separators, item) + print("splat is:", splat) - if seperator: + # splat is an array of 1 if no match, otherwise more than 1 + if len(splat) > 1: + key, separator, value = splat if '(' in value or '[' in value: assert value.startswith(("(", "[")), "Invalid token" assert value.endswith((")", "]")), "Invalid token" @@ -51,19 +54,21 @@ def parse(pstring): values = re.split(r"""\s+|,""", value) value = [value.strip() for value in values if value.strip()] term = dict(key=key, - seperator=seperator, + separator=separator, search_term=value) else: term = dict(key=None, - seperator=None, + separator=None, search_term = item) items.append(term) - print(pf(items)) + print(pf(items) + "\n") return(items) if __name__ == '__main__': parse("foo=[3 2 1]") + parse("WIKI=ho*") + parse("LRS>9") parse("foo=[3 2 1)") parse("foo=(3 2 1)") parse("shh") -- cgit v1.2.3 From 5278e4b66d3261c8ff114bf4cd0e69307d1ffd5f Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 28 Nov 2012 15:09:36 -0600 Subject: Changed parser to split by ">=" and "<=" --- wqflask/wqflask/parser.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index a94a8842..676efa1e 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -35,8 +35,8 @@ def parse(pstring): items = [] - separators = [re.escape(x) for x in (":", "=", "<", ">")] - separators = '([%s])' % ("".join(separators)) + separators = [re.escape(x) for x in ("<=", ">=", ":", "=", "<", ">")] + separators = '(%s)' % ("|".join(separators)) print("separators:", separators) @@ -69,6 +69,9 @@ if __name__ == '__main__': parse("foo=[3 2 1]") parse("WIKI=ho*") parse("LRS>9") + parse("LRS>=18") + parse("foo <= 2") + parse("cisLRS<20") parse("foo=[3 2 1)") parse("foo=(3 2 1)") parse("shh") -- cgit v1.2.3 From 9eab3fbce2cd2247dc571f9d1c19946f97fb33ce Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 28 Nov 2012 17:45:02 -0600 Subject: Got cisLRS search working (in web service) for searches with > or < (ex. LRS>99) search_term is always a list now ([99] in the example LRS>99) --- wqflask/wqflask/do_search.py | 217 ++++++++++++++++++++++---------------- wqflask/wqflask/parser.py | 16 ++- wqflask/wqflask/search_results.py | 2 + 3 files changed, 143 insertions(+), 92 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 73a72e00..49da4282 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -17,8 +17,11 @@ class DoSearch(object): # Used to translate search phrases into classes search_types = dict() - def __init__(self, search_term, dataset, cursor, db_conn): + def __init__(self, search_term, search_operator, dataset, cursor, db_conn): self.search_term = search_term + # Make sure search_operator is something we expect + assert search_operator in ("=", "<", ">", "<=", ">="), "Bad search operator" + self.search_operator = search_operator self.dataset = dataset self.db_conn = db_conn self.cursor = cursor @@ -49,6 +52,64 @@ class DoSearch(object): return cls.search_types[search_type] +class ProbeSetSearch(DoSearch): + """A search within an mRNA expression dataset""" + + DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" + + base_query = """SELECT ProbeSet.Name as TNAME, + 0 as thistable, + ProbeSetXRef.Mean as TMEAN, + ProbeSetXRef.LRS as TLRS, + ProbeSetXRef.PVALUE as TPVALUE, + ProbeSet.Chr_num as TCHR_NUM, + ProbeSet.Mb as TMB, + ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM + FROM ProbeSetXRef, ProbeSet """ + + + def compile_final_query(self, from_clause = '', where_clause = ''): + """Generates the final query string""" + + from_clause = self.normalize_spaces(from_clause) + + query = (self.base_query + + """%s + WHERE %s + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(from_clause), + where_clause, + self.escape(self.dataset.id))) + + print("query is:", pf(query)) + + return query + + def run(self): + """Generates and runs a simple search of an mRNA expression dataset""" + + print("Running ProbeSetSearch") + query = (self.base_query + + """WHERE (MATCH (ProbeSet.Name, + ProbeSet.description, + ProbeSet.symbol, + alias, + GenbankId, + UniGeneId, + Probe_Target_Description) + AGAINST ('%s' IN BOOLEAN MODE)) + and ProbeSet.Id = ProbeSetXRef.ProbeSetId + and ProbeSetXRef.ProbeSetFreezeId = %s + """ % (self.escape(self.search_term), + self.escape(self.dataset.id))) + + print("final query is:", pf(query)) + + return self.execute(query) + + class PhenotypeSearch(DoSearch): """A search within a phenotype dataset""" @@ -147,71 +208,12 @@ class GenotypeSearch(DoSearch): """WHERE %s and Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and - GenoFreeze.Id = %s""" % ( + GenoFreeze.Id = %s"""% ( self.get_where_clause(), self.escape(self.dataset.id))) return self.execute(query) - -class ProbeSetSearch(DoSearch): - """A search within an mRNA expression dataset""" - - DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" - - base_query = """SELECT ProbeSet.Name as TNAME, - 0 as thistable, - ProbeSetXRef.Mean as TMEAN, - ProbeSetXRef.LRS as TLRS, - ProbeSetXRef.PVALUE as TPVALUE, - ProbeSet.Chr_num as TCHR_NUM, - ProbeSet.Mb as TMB, - ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM - FROM ProbeSetXRef, ProbeSet """ - - - def compile_final_query(self, from_clause, where_clause): - """Generates the final query string""" - - from_clause = self.normalize_spaces(from_clause) - - query = (self.normalize_spaces(self.base_query) + - """%s - WHERE %s - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(from_clause), - where_clause, - self.escape(self.dataset.id))) - - print("query is:", pf(query)) - - return query - - def run(self): - """Generates and runs a simple search of an mRNA expression dataset""" - - print("Running ProbeSetSearch") - query = (self.base_query + - """WHERE (MATCH (ProbeSet.Name, - ProbeSet.description, - ProbeSet.symbol, - alias, - GenbankId, - UniGeneId, - Probe_Target_Description) - AGAINST ('%s' IN BOOLEAN MODE)) - and ProbeSet.Id = ProbeSetXRef.ProbeSetId - and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(self.search_term), - self.escape(self.dataset.id))) - - print("final query is:", pf(query)) - - return self.execute(query) - - class RifSearch(ProbeSetSearch): """Searches for traits with a Gene RIF entry including the search term.""" @@ -257,7 +259,7 @@ class GoSearch(ProbeSetSearch): statements = ("""%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id""" % ( - self.escape(self.dataset.type))) + self.db_conn.escape_string(self.dataset.type))) where_clause = " %s = '%s' and %s " % (field, go_id, statements) @@ -283,12 +285,13 @@ class LrsSearch(ProbeSetSearch): DoSearch.search_types['LRS'] = 'LrsSearch' -class CisLrsSearch(ProbeSetSearch): +class CisLrsSearch(LrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values - A cisLRS search can take 2 forms: + A cisLRS search can take 3 forms: - cisLRS=(min_LRS max_LRS) - cisLRS=(min_LRS max_LRS mb_buffer) + - cisLRS>min_LRS where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around a particular QTL where its eQTL would be considered "cis". If there is no third parameter, mb_buffer will default to 5 megabases. @@ -305,30 +308,56 @@ class CisLrsSearch(ProbeSetSearch): DoSearch.search_types['CISLRS'] = "CisLrsSearch" def run(self): + #if isinstance(self.search_term, basestring): + # self.search_term = [self.search_term] + print("self.search_term is:", self.search_term) + self.search_term = [float(value) for value in self.search_term] + mb_buffer = 5 # default from_clause = ", Geno " - if len(self.search_term) == 3: - lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] - - where_clause = """ %sXRef.LRS > %s and + + if self.search_operator == "=": + if len(self.search_term) == 2: + lower_limit, upper_limit = self.search_term + #[int(value) for value in self.search_term] + + elif len(self.search_term) == 3: + lower_limit, upper_limit, mb_buffer = self.search_term + + sub_clause = """ %sXRef.LRS > %s and %sXRef.LRS < %s and - %sXRef.Locus = Geno.name and - Geno.SpeciesId = %s and - %s.Chr = Geno.Chr and - ABS(%s.Mb-Geno.Mb) < %s """ % ( + ABS(%s.Mb-Geno.Mb) < %s """ % ( self.escape(self.dataset.type), - min(lower_limit, upper_limit), + self.escape(min(lower_limit, upper_limit)), self.escape(self.dataset.type), - max(lower_limit, upper_limit), + self.escape(max(lower_limit, upper_limit)), self.escape(self.dataset.type), - self.species_id, + self.escape(mb_buffer) + ) + + + + else: + # Deal with >, <, >=, and <= + sub_clause = """ %sXRef.LRS %s %s and + ABS(%s.Mb-Geno.Mb) < %s and """ % ( self.escape(self.dataset.type), + self.escape(self.search_operator), + self.escape(self.search_term[0]), self.escape(self.dataset.type), - min_threshold + self.escape(mb_buffer) + ) + + where_clause = sub_clause + """%sXRef.Locus = Geno.name and + Geno.SpeciesId = %s and + %s.Chr = Geno.Chr""" % ( + self.escape(self.dataset.type), + self.escape(self.species_id), + self.escape(self.dataset.type) ) - else: - NeedSomeErrorHere + + print("where_clause is:", pf(where_clause)) query = self.compile_final_query(from_clause, where_clause) @@ -356,8 +385,6 @@ class TransLrsSearch(LrsSearch): DoSearch.search_types['TRANSLRS'] = "TransLrsSearch" def run(self): - from_clause = ", Geno " - if len(self.search_term) == 3: lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] @@ -379,11 +406,9 @@ class TransLrsSearch(LrsSearch): ) else: - NeedSomeErrorHere - - query = self.compile_final_query(from_clause, where_clause) + NeedSomeErrorHere - return self.execute(query) + return None #itemCmd = item[0] @@ -450,14 +475,30 @@ if __name__ == "__main__": dataset_name = "HC_M2_0606_P" dataset = create_dataset(db_conn, dataset_name) - + + cursor.execute(""" + SELECT ProbeSet.Name as TNAME, 0 as thistable, + ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS, + ProbeSetXRef.PVALUE as TPVALUE, ProbeSet.Chr_num as TCHR_NUM, + ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, + ProbeSet.name_num as TNAME_NUM + FROM ProbeSetXRef, ProbeSet, Geno + WHERE ProbeSetXRef.LRS > 99.0 and + ABS(ProbeSet.Mb-Geno.Mb) < 5 and + ProbeSetXRef.Locus = Geno.name and + Geno.SpeciesId = 1 and + ProbeSet.Chr = Geno.Chr and + ProbeSet.Id = ProbeSetXRef.ProbeSetId and + ProbeSetXRef.ProbeSetFreezeId = 112""") + + #print(pf(cursor.fetchall())) #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() - results = CisLrsSearch(['25','99','10'], dataset, cursor, db_conn).run() - #results = TransLrsSearch(['25', '999', '10'], dataset, cursor, db_conn).run() + results = CisLrsSearch('99', '>', dataset, cursor, db_conn).run() # cisLRS > 99 + #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() - print("results are:", pf(results)) \ No newline at end of file + #print("results are:", pf(results)) \ No newline at end of file diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index 676efa1e..efe479e6 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -15,8 +15,6 @@ Both square brackets and parentheses can be used interchangeably. Both can also encapsulate a single value; "cisLRS=[9 999 10)" would be acceptable.] -NEED TO DEAL WITH WILDCARD CHARACTER '*' - """ from __future__ import print_function, division @@ -26,6 +24,10 @@ import re from pprint import pformat as pf def parse(pstring): + """ + + returned item serach_term is always a list, even if only one element + """ pstring = re.split(r"""(?:(\w+\s*=\s*[\(\[][^)]*[\)\]]) | # LRS=(1 2 3), cisLRS=[4 5 6], etc (\w+\s*[=:\>\<][\w\*]+) | # wiki=bar, GO:foobar, etc ([\w\*]+)) # shh, brain, etc """, pstring, @@ -53,16 +55,22 @@ def parse(pstring): value = value[1:-1] # Get rid of the parenthesis values = re.split(r"""\s+|,""", value) value = [value.strip() for value in values if value.strip()] + else: + value = [value] + # : is a synonym for = + if separator == ":": + separator = "=" + term = dict(key=key, separator=separator, search_term=value) else: term = dict(key=None, separator=None, - search_term = item) + search_term=[item]) items.append(term) - print(pf(items) + "\n") + print("* items are:", pf(items) + "\n") return(items) if __name__ == '__main__': diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 96350f22..fe091f97 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -127,6 +127,7 @@ class SearchResultPage(templatePage): for a_search in self.search_terms: print("[kodak] item is:", pf(a_search)) search_term = a_search['search_term'] + search_operator = a_search['separator'] if a_search['key']: search_type = a_search['key'].upper() else: @@ -141,6 +142,7 @@ class SearchResultPage(templatePage): search_ob = do_search.DoSearch.get_search(search_type) search_class = getattr(do_search, search_ob) self.results.extend(search_class(search_term, + search_operator, self.dataset, self.cursor, self.db_conn).run()) -- cgit v1.2.3 From 8540859f868a5fa6827f35d7fa5cc14e97360850 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 29 Nov 2012 14:26:54 -0600 Subject: Got LRS searches working with 5 parameters --- wqflask/wqflask/do_search.py | 59 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 49da4282..2b8efd68 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -285,6 +285,53 @@ class LrsSearch(ProbeSetSearch): DoSearch.search_types['LRS'] = 'LrsSearch' + def run(self): + + self.search_term = [float(value) for value in self.search_term] + + from_clause = ", Geno" + + if self.search_operator == "=": + if len(self.search_term) >= 2: + if len(self.search_term) == 2: + lrs_min, lrs_max = self.search_term + elif len(self.search_term) == 5: + lrs_min, lrs_max, chr_num, mb_low, mb_high = self.search_term + else: + SomeError + + sub_clause = """ %sXRef.LRS > %s and + %sXRef.LRS < %s and """ % (self.escape(self.dataset.type), + self.escape(min(lrs_min, lrs_max)), + self.escape(self.dataset.type), + self.escape(max(lrs_min, lrs_max))) + + if len(self.search_term) == 5: + sub_clause = sub_clause + """ Geno.Mb > %s and + Geno.Mb < %s and + Geno.Chr = %s and + """ % (self.escape(min(mb_low, mb_high)), + self.escape(max(mb_low, mb_high)), + self.escape(chr_num)) + else: + # Deal with >, <, >=, and <= + sub_clause = """ %sXRef.LRS %s %s and """ % (self.escape(self.dataset.type), + self.escape(self.search_operator), + self.escape(self.search_term[0])) + + where_clause = sub_clause + """ %sXRef.Locus = Geno.name and + Geno.SpeciesId = %s and + %s.Chr = Geno.Chr + """ % (self.escape(self.dataset.type), + self.escape(self.species_id), + self.escape(self.dataset.type)) + + print("where_clause is:", pf(where_clause)) + + query = self.compile_final_query(from_clause, where_clause) + + return self.execute(query) + class CisLrsSearch(LrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values @@ -324,10 +371,13 @@ class CisLrsSearch(LrsSearch): elif len(self.search_term) == 3: lower_limit, upper_limit, mb_buffer = self.search_term + + else: + SomeError sub_clause = """ %sXRef.LRS > %s and %sXRef.LRS < %s and - ABS(%s.Mb-Geno.Mb) < %s """ % ( + ABS(%s.Mb-Geno.Mb) < %s and """ % ( self.escape(self.dataset.type), self.escape(min(lower_limit, upper_limit)), self.escape(self.dataset.type), @@ -335,8 +385,6 @@ class CisLrsSearch(LrsSearch): self.escape(self.dataset.type), self.escape(mb_buffer) ) - - else: # Deal with >, <, >=, and <= @@ -495,10 +543,11 @@ if __name__ == "__main__": #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() - results = CisLrsSearch('99', '>', dataset, cursor, db_conn).run() # cisLRS > 99 + results = CisLrsSearch(['99'], '>', dataset, cursor, db_conn).run() # cisLRS > 99 + #results = LrsSearch('9', '99', '1', '50', '150', '=', dataset, cursor, db_conn).run() #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() #results = GoSearch("0045202", dataset, cursor, db_conn).run() - #print("results are:", pf(results)) \ No newline at end of file + print("results are:", pf(results)) \ No newline at end of file -- cgit v1.2.3 From 94300b4488aa334ced34981981ad5d0ecdec01d6 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 29 Nov 2012 18:44:01 -0600 Subject: Changed a number of variables (riset to group, db to dataset) Put most of the code for cisLRS and transLRS searches into the class CisTransLrsSearch (might change this name to something else later) Simplified escape code for searches in do_search.py Got search_results working again after some changes --- wqflask/base/data_set.py | 5 +- wqflask/base/webqtlFormData.py | 26 +-- wqflask/base/webqtlTrait.py | 146 ++++++------- wqflask/dbFunction/webqtlDatabaseFunction.py | 4 +- wqflask/wqflask/do_search.py | 237 +++++++++------------- wqflask/wqflask/search_results.py | 18 +- wqflask/wqflask/show_trait/show_trait.py | 83 ++++---- wqflask/wqflask/templates/index_page.html | 4 +- wqflask/wqflask/templates/search_result_page.html | 2 +- wqflask/wqflask/views.py | 3 + 10 files changed, 241 insertions(+), 287 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index d9d3a52b..633f7545 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -392,8 +392,9 @@ class MrnaAssayDataSet(DataSet): if len(description_display) > 1 and description_display != 'N/A' and len(target_string) > 1 and target_string != 'None': description_display = description_display + '; ' + target_string.strip() - # Save it for the jinja2 tablet + # Save it for the jinja2 template this_trait.description_display = description_display + #print(" xxxxdd [%s]: %s" % (type(this_trait.description_display), description_display)) #XZ: trait_location_value is used for sorting trait_location_repr = 'N/A' @@ -418,7 +419,7 @@ class MrnaAssayDataSet(DataSet): where ProbeSetXRef.ProbeSetFreezeId = %s and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSet.Name = '%s' - """ % (self.db_conn.escape_string(str(this_trait.db.id)), + """ % (self.db_conn.escape_string(str(this_trait.dataset.id)), self.db_conn.escape_string(this_trait.name))) print("query is:", pf(query)) diff --git a/wqflask/base/webqtlFormData.py b/wqflask/base/webqtlFormData.py index ff1db0e8..a3537c87 100755 --- a/wqflask/base/webqtlFormData.py +++ b/wqflask/base/webqtlFormData.py @@ -47,7 +47,7 @@ from utility import webqtlUtil class webqtlFormData(object): 'Represents data from a WebQTL form page, needed to generate the next page' - attrs = ('formID','RISet','genotype','samplelist','allsamplelist', 'display_variance' + attrs = ('formID','group','genotype','samplelist','allsamplelist', 'display_variance' 'suggestive','significance','submitID','identification', 'enablevariance', 'nperm','nboot','email','incparentsf1','genotype_1','genotype_2','traitInfo') @@ -104,11 +104,11 @@ class webqtlFormData(object): self.ppolar = None self.mpolar = None - print("[yellow] self.RISet is:", self.RISet) - if self.RISet: + print("[yellow] self.group is:", self.group) + if self.group: #try: # # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; - _f1, _f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.RISet] + _f1, _f12, self.mpolar, self.ppolar = webqtlUtil.ParInfo[self.group] #except: # f1 = f12 = self.mpolar = self.ppolar = None @@ -129,8 +129,8 @@ class webqtlFormData(object): #self.readGenotype() #self.readData() - if self.RISet == 'BXD300': - self.RISet = 'BXD' + if self.group == 'BXD300': + self.group = 'BXD' def __getitem__(self, key): @@ -153,17 +153,17 @@ class webqtlFormData(object): def readGenotype(self): '''read genotype from .geno file''' - if self.RISet == 'BXD300': - self.RISet = 'BXD' + if self.group == 'BXD300': + self.group = 'BXD' - assert self.RISet, "self.RISet needs to be set" + assert self.group, "self.group needs to be set" #genotype_1 is Dataset Object without parents and f1 #genotype_2 is Dataset Object with parents and f1 (not for intercross) self.genotype_1 = reaper.Dataset() - full_filename = os.path.join(webqtlConfig.GENODIR, self.RISet + '.geno') + full_filename = os.path.join(webqtlConfig.GENODIR, self.group + '.geno') # reaper barfs on unicode filenames, so here we ensure it's a string full_filename = str(full_filename) @@ -173,12 +173,12 @@ class webqtlFormData(object): try: # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; - _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.RISet] + _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.group] except KeyError: _f1 = _f12 = _mat = _pat = None self.genotype_2 = self.genotype_1 - if self.genotype_1.type == "riset" and _mat and _pat: + if self.genotype_1.type == "group" and _mat and _pat: self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) #determine default genotype object @@ -333,7 +333,7 @@ class webqtlFormData(object): def Sample(self): 'Create some dummy data for testing' - self.RISet = 'BXD' + self.group = 'BXD' self.incparentsf1 = 'on' #self.display = 9.2 #self.significance = 16.1 diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 29087721..cc0e2321 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -24,11 +24,11 @@ class webqtlTrait: print("in webqtlTrait") self.db_conn = db_conn self.cursor = self.db_conn.cursor() - self.db = None # database object + self.dataset = None # database object self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. self.cellid = '' self.identification = 'un-named trait' - self.riset = '' + self.group = '' self.haveinfo = 0 self.sequence = '' # Blat sequence, available for ProbeSet self.data = {} @@ -41,22 +41,22 @@ class webqtlTrait: elif name == 'fullname': name2 = value.split("::") if len(name2) == 2: - self.db, self.name = name2 + self.dataset, self.name = name2 elif len(name2) == 3: - self.db, self.name, self.cellid = name2 + self.dataset, self.name, self.cellid = name2 else: raise KeyError, repr(value) + ' parameter format error.' else: raise KeyError, repr(name) + ' not a valid parameter for this class.' - if self.db and isinstance(self.db, basestring): + if self.dataset and isinstance(self.dataset, basestring): assert self.cursor, "Don't have a cursor" - self.db = create_dataset(self.db_conn, self.db) + self.dataset = create_dataset(self.db_conn, self.dataset) - #if self.db == None, not from a database - print("self.db is:", self.db, type(self.db)) - if self.db: - if self.db.type == "Temp": + #if self.dataset == None, not from a database + print("self.dataset is:", self.dataset, type(self.dataset)) + if self.dataset: + if self.dataset.type == "Temp": self.cursor.execute(''' SELECT InbredSet.Name @@ -66,9 +66,11 @@ class webqtlTrait: Temp.InbredSetId = InbredSet.Id AND Temp.Name = "%s" ''', self.name) - self.riset = self.cursor.fetchone()[0] + self.group = self.cursor.fetchone()[0] else: - self.riset = self.db.get_group() + self.group = self.dataset.get_group() + + print("trinity, self.group is:", self.group) # # In ProbeSet, there are maybe several annotations match one sequence @@ -82,8 +84,8 @@ class webqtlTrait: # The variable self.sequence should be changed to self.BlatSeq # It also should be changed in other places where it are used. - if self.db: - if self.db.type == 'ProbeSet': + if self.dataset: + if self.dataset.type == 'ProbeSet': print("Doing ProbeSet Query") query = ''' SELECT @@ -95,7 +97,7 @@ class webqtlTrait: ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and ProbeSet.Name = %s and ProbeSetFreeze.Name = %s - ''', (self.name, self.db.name) + ''', (self.name, self.dataset.name) print("query is:", query) self.cursor.execute(*query) self.sequence = self.cursor.fetchone()[0] @@ -104,8 +106,8 @@ class webqtlTrait: def getName(self): str = "" - if self.db and self.name: - str = "%s::%s" % (self.db, self.name) + if self.dataset and self.name: + str = "%s::%s" % (self.dataset, self.name) if self.cellid: str += "::" + self.cellid else: @@ -124,8 +126,8 @@ class webqtlTrait: # def getGivenName(self): str = self.name - if self.db and self.name: - if self.db.type=='Temp': + if self.dataset and self.name: + if self.dataset.type=='Temp': self.cursor.execute('SELECT description FROM Temp WHERE Name=%s', self.name) desc = self.cursor.fetchone()[0] if desc.__contains__('PCA'): @@ -137,16 +139,16 @@ class webqtlTrait: def displayName(self): str = "" - if self.db and self.name: - if self.db.type=='Temp': + if self.dataset and self.name: + if self.dataset.type=='Temp': desc = self.description if desc.__contains__('PCA'): desc = desc[desc.rindex(':')+1:].strip() else: desc = desc[:desc.index('entered')].strip() - str = "%s::%s" % (self.db, desc) + str = "%s::%s" % (self.dataset, desc) else: - str = "%s::%s" % (self.db, self.name) + str = "%s::%s" % (self.dataset, self.name) if self.cellid: str += "::" + self.cellid else: @@ -156,7 +158,7 @@ class webqtlTrait: #def __str__(self): - # #return "%s %s" % (self.getName(), self.riset) + # #return "%s %s" % (self.getName(), self.group) # return self.getName() #__str__ = getName #__repr__ = __str__ @@ -207,7 +209,7 @@ class webqtlTrait: # def getSequence(self): assert self.cursor - if self.db.type == 'ProbeSet': + if self.dataset.type == 'ProbeSet': self.cursor.execute(''' SELECT ProbeSet.BlatSeq @@ -218,7 +220,7 @@ class webqtlTrait: ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and ProbeSet.Name = %s ProbeSetFreeze.Name = %s - ''', self.name, self.db.name) + ''', self.name, self.dataset.name) #self.cursor.execute(query) results = self.fetchone() @@ -230,9 +232,9 @@ class webqtlTrait: if samplelist == None: samplelist = [] - assert self.db and self.cursor + assert self.dataset and self.cursor - if self.db.type == 'Temp': + if self.dataset.type == 'Temp': query = ''' SELECT Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id @@ -246,7 +248,7 @@ class webqtlTrait: Strain.Name ''' % self.name #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE - elif self.db.type == 'Publish': + elif self.dataset.type == 'Publish': query = ''' SELECT Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id @@ -263,7 +265,7 @@ class webqtlTrait: PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id Order BY Strain.Name - ''' % (self.name, self.db.id) + ''' % (self.name, self.dataset.id) #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE elif self.cellid: @@ -287,9 +289,9 @@ class webqtlTrait: ProbeData.StrainId = Strain.Id Order BY Strain.Name - ''' % (self.cellid, self.name, self.db.name) + ''' % (self.cellid, self.name, self.dataset.name) #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE - elif self.db.type == 'ProbeSet': + elif self.dataset.type == 'ProbeSet': #ProbeSet Data query = ''' SELECT @@ -306,7 +308,7 @@ class webqtlTrait: ProbeSetData.StrainId = Strain.Id Order BY Strain.Name - ''' % (self.name, self.db.name) + ''' % (self.name, self.dataset.name) #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE else: #Geno Data @@ -326,7 +328,7 @@ class webqtlTrait: GenoData.StrainId = Strain.Id Order BY Strain.Name - ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.db.riset), self.name, self.db.name) + ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group), self.name, self.dataset.name) self.cursor.execute(query) @@ -341,7 +343,7 @@ class webqtlTrait: if not samplelist or (samplelist and name in samplelist): #if value != None: # num_cases = None - # if self.db.type in ('Publish', 'Temp'): + # if self.dataset.type in ('Publish', 'Temp'): # ndata = item[3] name = item[0] self.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) @@ -352,7 +354,7 @@ class webqtlTrait: # if val != None: # var = item[2] # ndata = None - # if self.db.type in ('Publish', 'Temp'): + # if self.dataset.type in ('Publish', 'Temp'): # ndata = item[3] # self.data[item[0]] = webqtlCaseData(val, var, ndata) # #end for @@ -370,9 +372,9 @@ class webqtlTrait: # return self.__dict__.items() def retrieveInfo(self, QTL = None): - assert self.db and self.cursor - if self.db.type == 'Publish': - #self.db.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ + assert self.dataset and self.cursor + if self.dataset.type == 'Publish': + #self.dataset.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ # 'Units', 'comments'] query = ''' @@ -393,11 +395,11 @@ class webqtlTrait: Publication.Id = PublishXRef.PublicationId AND PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND PublishFreeze.Id =%s - ''' % (self.name, self.db.id) + ''' % (self.name, self.dataset.id) #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. - elif self.db.type == 'ProbeSet': - display_fields_string = ',ProbeSet.'.join(self.db.display_fields) + elif self.dataset.type == 'ProbeSet': + display_fields_string = ',ProbeSet.'.join(self.dataset.display_fields) display_fields_string = 'ProbeSet.' + display_fields_string query = """ SELECT %s @@ -407,11 +409,11 @@ class webqtlTrait: ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' - """ % (display_fields_string, self.db.name, self.name) + """ % (display_fields_string, self.dataset.name, self.name) #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. - elif self.db.type == 'Geno': - display_fields_string = string.join(self.db.display_fields,',Geno.') + elif self.dataset.type == 'Geno': + display_fields_string = string.join(self.dataset.display_fields,',Geno.') display_fields_string = 'Geno.' + display_fields_string query = """ SELECT %s @@ -421,10 +423,10 @@ class webqtlTrait: GenoXRef.GenoId = Geno.Id AND GenoFreeze.Name = '%s' AND Geno.Name = '%s' - """ % (display_fields_string, self.db.name, self.name) + """ % (display_fields_string, self.dataset.name, self.name) else: #Temp type query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ - (string.join(self.db.display_fields,','), self.db.type, self.name) + (string.join(self.dataset.display_fields,','), self.dataset.type, self.name) self.cursor.execute(query) @@ -433,16 +435,16 @@ class webqtlTrait: self.haveinfo = 1 #XZ: assign SQL query result to trait attributes. - for i, field in enumerate(self.db.display_fields): + for i, field in enumerate(self.dataset.display_fields): setattr(self, field, traitInfo[i]) - if self.db.type == 'Publish': + if self.dataset.type == 'Publish': self.confidential = 0 if self.pre_publication_description and not self.pubmed_id: self.confidential = 1 self.homologeneid = None - if self.db.type == 'ProbeSet' and self.riset and self.geneid: + if self.dataset.type == 'ProbeSet' and self.group and self.geneid: #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. #XZ: So I have to test if geneid is number before execute the query. #XZ: The geneid values in database should be cleaned up. @@ -463,7 +465,7 @@ class webqtlTrait: InbredSet.Name = '%s' AND InbredSet.SpeciesId = Species.Id AND Species.TaxonomyId = Homologene.TaxonomyId - """ % (self.geneid, self.riset) + """ % (self.geneid, self.group) self.cursor.execute(query) result = self.cursor.fetchone() else: @@ -473,7 +475,7 @@ class webqtlTrait: self.homologeneid = result[0] if QTL: - if self.db.type == 'ProbeSet' and not self.cellid: + if self.dataset.type == 'ProbeSet' and not self.cellid: query = ''' SELECT ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean @@ -483,14 +485,14 @@ class webqtlTrait: ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSet.Name = "%s" AND ProbeSetXRef.ProbeSetFreezeId =%s - ''' % (self.name, self.db.id) + ''' % (self.name, self.dataset.id) self.cursor.execute(query) traitQTL = self.cursor.fetchone() if traitQTL: self.locus, self.lrs, self.pvalue, self.mean = traitQTL else: self.locus = self.lrs = self.pvalue = self.mean = "" - if self.db.type == 'Publish': + if self.dataset.type == 'Publish': query = ''' SELECT PublishXRef.Locus, PublishXRef.LRS @@ -500,7 +502,7 @@ class webqtlTrait: PublishXRef.Id = %s AND PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND PublishFreeze.Id =%s - ''' % (self.name, self.db.id) + ''' % (self.name, self.dataset.id) self.cursor.execute(query) traitQTL = self.cursor.fetchone() if traitQTL: @@ -514,7 +516,7 @@ class webqtlTrait: if not self.haveinfo: self.retrieveInfo() - if self.db.type == 'Publish': + if self.dataset.type == 'Publish': PubMedLink = "" if self.pubmed_id: PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, @@ -524,10 +526,10 @@ class webqtlTrait: if formName: setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % - (formName, self.db.name, self.name), Class = "fs14") + (formName, self.dataset.name, self.name), Class = "fs14") else: setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % - (self.db.name,self.name), Class = "fs14") + (self.dataset.name,self.name), Class = "fs14") if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) @@ -545,20 +547,20 @@ class webqtlTrait: setDescription2.append(HT.Italic('%s, and colleagues' % a1)) setDescription = HT.Span(PubMedLink, setDescription2) - elif self.db.type == 'Temp': + elif self.dataset.type == 'Temp': setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ - ('%s','%s','')" % (self.db.name,self.name), Class = "fs14") + ('%s','%s','')" % (self.dataset.name,self.name), Class = "fs14") setDescription = HT.Span(setDescription) - elif self.db.type == 'Geno': # Genome DB only available for single search + elif self.dataset.type == 'Geno': # Genome DB only available for single search if formName: setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ - (formName, self.db.name, self.name), Class = "fs14") + (formName, self.dataset.name, self.name), Class = "fs14") else: setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ - (self.db.name,self.name), Class = "fs14") + (self.dataset.name,self.name), Class = "fs14") setDescription = HT.Span(setDescription) @@ -566,20 +568,20 @@ class webqtlTrait: if self.cellid: if formName: setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ - "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.db.name,self.name,self.cellid), \ + "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.dataset.name,self.name,self.cellid), \ Class = "fs14") else: setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ - "javascript:showDatabase2('%s','%s','%s')" % (self.db.name,self.name,self.cellid), \ + "javascript:showDatabase2('%s','%s','%s')" % (self.dataset.name,self.name,self.cellid), \ Class = "fs14") else: if formName: setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.db.name,self.name), \ + "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.dataset.name,self.name), \ Class = "fs14") else: setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase2('%s','%s','')" % (self.db.name,self.name), \ + "javascript:showDatabase2('%s','%s','')" % (self.dataset.name,self.name), \ Class = "fs14") if self.symbol and self.chr and self.mb: setDescription.append(' [') @@ -591,9 +593,9 @@ class webqtlTrait: setDescription.append('; %s' % self.probe_target_description) setDescription = HT.Span(setDescription) - if self.db.type != 'Temp' and dispFromDatabase: + if self.dataset.type != 'Temp' and dispFromDatabase: setDescription.append( ' --- FROM : ') - setDescription.append(self.db.genHTML(Class='cori')) + setDescription.append(self.dataset.genHTML(Class='cori')) return setDescription @property @@ -654,13 +656,13 @@ class webqtlTrait: select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze where ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Id = %d""" % thisTrait.db.id) + ProbeSetFreeze.Id = %d""" % thisTrait.dataset.id) probeDBName = self.cursor.fetchone()[0] return dict(name = probeDBName, url = None) else: - return dict(name = self.db.fullname, - url = webqtlConfig.INFOPAGEHREF % self.db.name) + return dict(name = self.dataset.fullname, + url = webqtlConfig.INFOPAGEHREF % self.dataset.name) def calculate_correlation(self, values, method): """Calculate the correlation value and p value according to the method specified""" diff --git a/wqflask/dbFunction/webqtlDatabaseFunction.py b/wqflask/dbFunction/webqtlDatabaseFunction.py index 8f923b8a..1e028ecc 100755 --- a/wqflask/dbFunction/webqtlDatabaseFunction.py +++ b/wqflask/dbFunction/webqtlDatabaseFunction.py @@ -80,9 +80,9 @@ def getAllSpecies(cursor=None): #function: retrieve specie's name info based on RISet ########################################################################### -def retrieveSpecies(cursor=None, RISet=None): +def retrieveSpecies(cursor=None, group=None): try: - cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % RISet) + cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % group) return cursor.fetchone()[0] except: return None diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 2b8efd68..92a754e3 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -20,7 +20,7 @@ class DoSearch(object): def __init__(self, search_term, search_operator, dataset, cursor, db_conn): self.search_term = search_term # Make sure search_operator is something we expect - assert search_operator in ("=", "<", ">", "<=", ">="), "Bad search operator" + assert search_operator in (None, "=", "<", ">", "<=", ">="), "Bad search operator" self.search_operator = search_operator self.dataset = dataset self.db_conn = db_conn @@ -41,6 +41,12 @@ class DoSearch(object): def escape(self, stringy): """Shorter name than self.db_conn.escape_string""" return self.db_conn.escape_string(str(stringy)) + + def mescape(self, *items): + """Multiple escape""" + escaped = [self.escape(item) for item in items] + print("escaped is:", escaped) + return tuple(escaped) def normalize_spaces(self, stringy): """Strips out newlines/extra spaces and replaces them with just spaces""" @@ -91,8 +97,7 @@ class ProbeSetSearch(DoSearch): """Generates and runs a simple search of an mRNA expression dataset""" print("Running ProbeSetSearch") - query = (self.base_query + - """WHERE (MATCH (ProbeSet.Name, + query = self.base_query + """WHERE (MATCH (ProbeSet.Name, ProbeSet.description, ProbeSet.symbol, alias, @@ -102,8 +107,8 @@ class ProbeSetSearch(DoSearch): AGAINST ('%s' IN BOOLEAN MODE)) and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(self.search_term), - self.escape(self.dataset.id))) + """ % (self.escape(self.search_term[0]), + self.escape(self.dataset.id)) print("final query is:", pf(query)) @@ -275,7 +280,8 @@ class GoSearch(ProbeSetSearch): class LrsSearch(ProbeSetSearch): """Searches for genes with a QTL within the given LRS values - LRS searches can take 2 different forms: + LRS searches can take 3 different forms: + - LRS > (or <) min/max_LRS - LRS=(min_LRS max_LRS) - LRS=(min_LRS max_LRS chromosome start_Mb end_Mb) where min/max_LRS represent the range of LRS scores and start/end_Mb represent @@ -289,129 +295,128 @@ class LrsSearch(ProbeSetSearch): self.search_term = [float(value) for value in self.search_term] - from_clause = ", Geno" + self.from_clause = ", Geno" if self.search_operator == "=": - if len(self.search_term) >= 2: - if len(self.search_term) == 2: - lrs_min, lrs_max = self.search_term - elif len(self.search_term) == 5: - lrs_min, lrs_max, chr_num, mb_low, mb_high = self.search_term - else: - SomeError - - sub_clause = """ %sXRef.LRS > %s and - %sXRef.LRS < %s and """ % (self.escape(self.dataset.type), - self.escape(min(lrs_min, lrs_max)), - self.escape(self.dataset.type), - self.escape(max(lrs_min, lrs_max))) - + assert isinstance(self.search_term, (list, tuple)) + self.lrs_min, self.lrs_max = self.search_term[:2] + + self.sub_clause = """ %sXRef.LRS > %s and + %sXRef.LRS < %s and """ % self.mescape(self.dataset.type, + min(self.lrs_min, self.lrs_max), + self.dataset.type, + max(self.lrs_min, self.lrs_max)) + + if len(self.search_term) > 2: + self.chr_num = self.search_term[2] + self.sub_clause += """ Geno.Chr = %s and """ % (self.escape(self.chr_num)) if len(self.search_term) == 5: - sub_clause = sub_clause + """ Geno.Mb > %s and + self.mb_low, self.mb_high = self.search_term[3:] + self.sub_clause += """ Geno.Mb > %s and Geno.Mb < %s and - Geno.Chr = %s and - """ % (self.escape(min(mb_low, mb_high)), - self.escape(max(mb_low, mb_high)), - self.escape(chr_num)) + """ % self.mescape(min(self.mb_low, self.mb_high), + max(self.mb_low, self.mb_high)) + print("self.sub_clause is:", pf(self.sub_clause)) else: # Deal with >, <, >=, and <= - sub_clause = """ %sXRef.LRS %s %s and """ % (self.escape(self.dataset.type), - self.escape(self.search_operator), - self.escape(self.search_term[0])) + self.sub_clause = """ %sXRef.LRS %s %s and """ % self.mescape(self.dataset.type, + self.search_operator, + self.search_term[0]) - where_clause = sub_clause + """ %sXRef.Locus = Geno.name and + self.where_clause = self.sub_clause + """ %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr - """ % (self.escape(self.dataset.type), - self.escape(self.species_id), - self.escape(self.dataset.type)) + """ % self.mescape(self.dataset.type, + self.species_id, + self.dataset.type) - print("where_clause is:", pf(where_clause)) + print("where_clause is:", pf(self.where_clause)) - query = self.compile_final_query(from_clause, where_clause) + self.query = self.compile_final_query(self.from_clause, self.where_clause) - return self.execute(query) - -class CisLrsSearch(LrsSearch): - """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values + return self.execute(self.query) - A cisLRS search can take 3 forms: - - cisLRS=(min_LRS max_LRS) - - cisLRS=(min_LRS max_LRS mb_buffer) - - cisLRS>min_LRS - where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around - a particular QTL where its eQTL would be considered "cis". If there is no third parameter, - mb_buffer will default to 5 megabases. - A QTL is a cis-eQTL if a gene's expression is regulated by a QTL in roughly the same area - (where the area is determined by the mb_buffer that the user can choose). +class CisTransLrsSearch(LrsSearch): - """ - - # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps - # between this and the LrsSearch code. In the original code, commands are divided by - # the number of inputs they take, so these commands are completely separate - - DoSearch.search_types['CISLRS'] = "CisLrsSearch" - - def run(self): + def real_run(self, the_operator): #if isinstance(self.search_term, basestring): # self.search_term = [self.search_term] print("self.search_term is:", self.search_term) self.search_term = [float(value) for value in self.search_term] - mb_buffer = 5 # default - - from_clause = ", Geno " - + self.mb_buffer = 5 # default + self.from_clause = ", Geno " + if self.search_operator == "=": if len(self.search_term) == 2: - lower_limit, upper_limit = self.search_term + self.lrs_min, self.lrs_max = self.search_term #[int(value) for value in self.search_term] elif len(self.search_term) == 3: - lower_limit, upper_limit, mb_buffer = self.search_term + self.lrs_min, self.lrs_max, self.mb_buffer = self.search_term else: SomeError - sub_clause = """ %sXRef.LRS > %s and - %sXRef.LRS < %s and - ABS(%s.Mb-Geno.Mb) < %s and """ % ( - self.escape(self.dataset.type), - self.escape(min(lower_limit, upper_limit)), + self.sub_clause = """ %sXRef.LRS > %s and + %sXRef.LRS < %s and """ % ( self.escape(self.dataset.type), - self.escape(max(lower_limit, upper_limit)), + self.escape(min(self.lrs_min, self.lrs_max)), self.escape(self.dataset.type), - self.escape(mb_buffer) + self.escape(max(self.lrs_min, self.lrs_max)) ) - else: # Deal with >, <, >=, and <= - sub_clause = """ %sXRef.LRS %s %s and - ABS(%s.Mb-Geno.Mb) < %s and """ % ( + self.sub_clause = """ %sXRef.LRS %s %s and """ % ( self.escape(self.dataset.type), self.escape(self.search_operator), - self.escape(self.search_term[0]), - self.escape(self.dataset.type), - self.escape(mb_buffer) + self.escape(self.search_term[0]) ) - - where_clause = sub_clause + """%sXRef.Locus = Geno.name and + + self.where_clause = self.sub_clause + """ + ABS(%s.Mb-Geno.Mb) %s %s and + %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr""" % ( + self.escape(self.dataset.type), + the_operator, + self.escape(self.mb_buffer), self.escape(self.dataset.type), self.escape(self.species_id), self.escape(self.dataset.type) ) - print("where_clause is:", pf(where_clause)) + print("where_clause is:", pf(self.where_clause)) - query = self.compile_final_query(from_clause, where_clause) + self.query = self.compile_final_query(self.from_clause, self.where_clause) - return self.execute(query) + return self.execute(self.query) + + +class CisLrsSearch(CisTransLrsSearch): + """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values + + A cisLRS search can take 3 forms: + - cisLRS=(min_LRS max_LRS) + - cisLRS=(min_LRS max_LRS mb_buffer) + - cisLRS>min_LRS + where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around + a particular QTL where its eQTL would be considered "cis". If there is no third parameter, + mb_buffer will default to 5 megabases. + + A QTL is a cis-eQTL if a gene's expression is regulated by a QTL in roughly the same area + (where the area is determined by the mb_buffer that the user can choose). + + """ + + DoSearch.search_types['CISLRS'] = "CisLrsSearch" + + def run(self): + return self.real_run("<") + -class TransLrsSearch(LrsSearch): +class TransLrsSearch(CisTransLrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values A transLRS search can take 2 forms: @@ -425,70 +430,11 @@ class TransLrsSearch(LrsSearch): (where the area is determined by the mb_buffer that the user can choose). Opposite of cis-eQTL. """ - - # This is tentatively a child of LrsSearch; I'll need to check what code, if any, overlaps - # between this and the LrsSearch code. In the original code, commands are divided by - # the number of inputs they take, so these commands are completely separate DoSearch.search_types['TRANSLRS'] = "TransLrsSearch" def run(self): - if len(self.search_term) == 3: - lower_limit, upper_limit, min_threshold = [int(value) for value in self.search_term] - - where_clause = """ %sXRef.LRS > %s and - %sXRef.LRS < %s and - %sXRef.Locus = Geno.name and - Geno.SpeciesId = %s and - (%s.Chr != Geno.Chr or - ABS(%s.Mb-Geno.Mb) > %s) """ % ( - self.dataset.type, - min(lower_limit, upper_limit), - self.dataset.type, - max(lower_limit, upper_limit), - self.dataset.type, - self.species_id, - self.dataset.type, - self.dataset.type, - min_threshold - ) - - else: - NeedSomeErrorHere - - return None - - -#itemCmd = item[0] -#lowerLimit = float(item[1]) -#upperLimit = float(item[2]) -# -#if itemCmd.upper() in ("TRANSLRS", "CISLRS"): -# if item[3]: -# mthresh = float(item[3]) -# clauseItem = " %sXRef.LRS > %2.7f and %sXRef.LRS < %2.7f " % \ -# (self.dbType, min(lowerLimit, upperLimit), self.dbType, max(lowerLimit, upperLimit)) -# if itemCmd.upper() == "CISLRS": -# clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr and ABS(%s.Mb-Geno.Mb) < %2.7f """ % (self.dbType, self.speciesId, self.dbType, self.dbType, mthresh) -# DescriptionText.append(HT.Span(' with a ', HT.U('cis-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) -# else: -# clauseItem += """ and %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and (%s.Chr != Geno.Chr or (%s.Chr != Geno.Chr and ABS(%s.Mb-Geno.Mb) > %2.7f)) """ % (self.dbType, self.speciesId, self.dbType, self.dbType, self.dbType, mthresh) -# DescriptionText.append(HT.Span(' with a ', HT.U('trans-QTL'), ' having an LRS between %g and %g using a %g Mb exclusion buffer' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit), mthresh))) -# query.append(" (%s) " % clauseItem) -# self.orderByDefalut = "LRS" -# else: -# pass -#elif itemCmd.upper() in ("RANGE"): -# #XZ, 03/05/2009: Xiaodong changed Data to ProbeSetData -# clauseItem = " (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) > %2.7f and (select Pow(2, max(value) -min(value)) from ProbeSetData where Id = ProbeSetXRef.dataId) < %2.7f " % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)) -# query.append(" (%s) " % clauseItem) -# DescriptionText.append(HT.Span(' with a range of expression that varied between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)), " (fold difference)")) -#else: -# clauseItem = " %sXRef.%s > %2.7f and %sXRef.%s < %2.7f " % \ -# (self.dbType, itemCmd, min(lowerLimit, upperLimit), self.dbType, itemCmd, max(lowerLimit, upperLimit)) -# query.append(" (%s) " % clauseItem) -# self.orderByDefalut = itemCmd -# DescriptionText.append(HT.Span(' with ', HT.U(itemCmd), ' between %g and %g' % (min(lowerLimit, upperLimit), max(lowerLimit, upperLimit)))) + return self.real_run(">") class MeanSearch(ProbeSetSearch): @@ -508,7 +454,6 @@ if __name__ == "__main__": import MySQLdb import sys - from base import webqtlConfig from base.data_set import create_dataset from base.templatePage import templatePage @@ -540,11 +485,11 @@ if __name__ == "__main__": ProbeSetXRef.ProbeSetFreezeId = 112""") #print(pf(cursor.fetchall())) - #results = ProbeSetSearch("salt", dataset, cursor, db_conn).run() + results = ProbeSetSearch("shh", None, dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() - results = CisLrsSearch(['99'], '>', dataset, cursor, db_conn).run() # cisLRS > 99 - #results = LrsSearch('9', '99', '1', '50', '150', '=', dataset, cursor, db_conn).run() + #results = CisLrsSearch(['99'], '>', dataset, cursor, db_conn).run() # cisLRS > 99 + #results = LrsSearch('99', '>', dataset, cursor, db_conn).run() #results = TransLrsSearch(['9', '999', '10'], dataset, cursor, db_conn).run() #results = PhenotypeSearch("brain", dataset, cursor, db_conn).run() #results = GenotypeSearch("rs13475699", dataset, cursor, db_conn).run() diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index fe091f97..63e0153d 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -68,7 +68,7 @@ class SearchResultPage(templatePage): # return ########################################### - # Names and IDs of RISet / F2 set + # Names and IDs of group / F2 set ########################################### # All Phenotypes is a special case we'll deal with later @@ -97,23 +97,23 @@ class SearchResultPage(templatePage): """ self.trait_list = [] + + group = self.dataset.group + species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=group) + # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term print("self.results is:", pf(self.results)) for result in self.results: if not result: continue - - group = self.dataset.group - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=group) - + #### Excel file needs to be generated #### print("foo locals are:", locals()) trait_id = result[0] - this_trait = webqtlTrait(self.db_conn, db=self.dataset, name=trait_id) + this_trait = webqtlTrait(self.db_conn, dataset=self.dataset, name=trait_id) this_trait.retrieveInfo(QTL=True) - print("this_trait is:", pf(this_trait)) self.trait_list.append(this_trait) self.dataset.get_trait_info(self.trait_list, species) @@ -134,6 +134,8 @@ class SearchResultPage(templatePage): # We fall back to the dataset type as the key to get the right object search_type = self.dataset.type + print("search_type is:", pf(search_type)) + # This is throwing an error when a_search['key'] is None, so I changed above #search_type = string.upper(a_search['key']) #if not search_type: @@ -146,7 +148,7 @@ class SearchResultPage(templatePage): self.dataset, self.cursor, self.db_conn).run()) - + print("in the search results are:", self.results) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 3dac5933..db2636bc 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -35,12 +35,12 @@ class ShowTrait(templatePage): self.fd = fd templatePage.__init__(self, fd) - assert self.openMysql(), "No datbase!" + assert self.openMysql(), "No database!" this_trait = self.get_this_trait() ##read genotype file - fd.RISet = this_trait.riset + fd.group = this_trait.group fd.readGenotype() if not fd.genotype: @@ -62,7 +62,7 @@ class ShowTrait(templatePage): # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery hddn = OrderedDict( FormID = fmID, - RISet = fd.RISet, + group = fd.group, submitID = '', scale = 'physic', additiveCheck = 'ON', @@ -120,7 +120,7 @@ class ShowTrait(templatePage): hddn['attribute_names'] = "" hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, - groupName=fd.RISet) + groupName=fd.group) if fd.identification: hddn['identification'] = fd.identification @@ -159,8 +159,8 @@ class ShowTrait(templatePage): self.hddn = hddn self.sample_group_types = OrderedDict() - self.sample_group_types['samples_primary'] = fd.RISet + " Only" - self.sample_group_types['samples_other'] = "Non-" + fd.RISet + self.sample_group_types['samples_primary'] = fd.group + " Only" + self.sample_group_types['samples_other'] = "Non-" + fd.group self.sample_group_types['samples_all'] = "All Cases" sample_lists = [group.sample_list for group in self.sample_groups] print("sample_lists is:", pf(sample_lists)) @@ -180,12 +180,12 @@ class ShowTrait(templatePage): trait_id = self.fd['trait_id'] cell_id = self.fd.get('CellID') - this_trait = webqtlTrait(db=dataset, name=trait_id, cellid=cell_id, cursor=self.cursor) + this_trait = webqtlTrait(self.db_conn, db=dataset, name=trait_id, cellid=cell_id) ##identification, etc. self.fd.identification = '%s : %s' % (this_trait.db.shortname, trait_id) this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&RISet=%s&parentsf1=on' %(dataset, trait_id, self.fd['RISet']) + &ProbeSetID=%s&group=%s&parentsf1=on' %(dataset, trait_id, self.fd['group']) if cell_id: self.fd.identification = '%s/%s'%(self.fd.identification, cell_id) @@ -198,7 +198,7 @@ class ShowTrait(templatePage): def dispTraitInformation(self, fd, title1Body, hddn, this_trait): - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) #tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") @@ -245,9 +245,9 @@ class ShowTrait(templatePage): else: pass - self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.RISet) + self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.group) if this_trait: - addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.RISet, 'dataInput')) + addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.group, 'dataInput')) addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") #addSelectionButton.append(addSelectionButton_img) addSelectionText = "Add" @@ -403,8 +403,8 @@ class ShowTrait(templatePage): probeResult = self.cursor.fetchone() if probeResult[0] > 0: - probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&RISet=%s&incparentsf1=ON" \ - % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.db, this_trait.name, this_trait.cellid, fd.RISet) + probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&group=%s&incparentsf1=ON" \ + % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.db, this_trait.name, this_trait.cellid, fd.group) probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") #probeButton.append(probeButton_img) @@ -430,7 +430,7 @@ class ShowTrait(templatePage): # )) #tSpan = HT.Span(Class="fs13") - #tSpan.append(str(_Species).capitalize(), ", ", fd.RISet) + #tSpan.append(str(_Species).capitalize(), ", ", fd.group) # #tbl.append(HT.TR( # HT.TD('Species and Group: ', Class="fwb fs13", valign="top", nowrap="on"), @@ -805,6 +805,7 @@ class ShowTrait(templatePage): #stats_row = HT.TR() #stats_cell = HT.TD() + # This should still be riset here - Sam - Nov. 2012 if fd.genotype.type == "riset": samplelist = fd.f1list + fd.samplelist else: @@ -839,15 +840,15 @@ class ShowTrait(templatePage): other_samples = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + other_samples #XZ: note that fd.f1list and fd.parlist are added. print("ac1") # This is the one used for first sall3 self.MDP_menu.append(('All Cases','0')) - self.MDP_menu.append(('%s Only' % fd.RISet, '1')) - self.MDP_menu.append(('Non-%s Only' % fd.RISet, '2')) + self.MDP_menu.append(('%s Only' % fd.group, '1')) + self.MDP_menu.append(('Non-%s Only' % fd.group, '2')) else: if (len(other_samples) > 0) and (len(primary_samples) + len(other_samples) > 3): print("ac2") self.MDP_menu.append(('All Cases','0')) - self.MDP_menu.append(('%s Only' % fd.RISet,'1')) - self.MDP_menu.append(('Non-%s Only' % fd.RISet,'2')) + self.MDP_menu.append(('%s Only' % fd.group,'1')) + self.MDP_menu.append(('Non-%s Only' % fd.group,'2')) all_samples = primary_samples all_samples.sort(key=webqtlUtil.natsort_key) all_samples = map(lambda X:"_2nd_"+X, fd.f1list + fd.parlist) + all_samples @@ -895,7 +896,7 @@ class ShowTrait(templatePage): # for sampleNameOrig in all_samples]] # - #Using just the RISet sample + #Using just the group sample for sampleNameOrig in primary_samples: sampleName = sampleNameOrig.replace("_2nd_", "") @@ -908,7 +909,7 @@ class ShowTrait(templatePage): vals2.append(thisValFull) - #Using all non-RISet samples only + #Using all non-group samples only for sampleNameOrig in other_samples: sampleName = sampleNameOrig.replace("_2nd_", "") @@ -951,10 +952,10 @@ class ShowTrait(templatePage): break elif (i == 1 and len(primary_samples) < 4): stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") - #stats_container.append(HT.Div(HT.Italic("Fewer than 4 " + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + #stats_container.append(HT.Div(HT.Italic("Fewer than 4 " + fd.group + " case data were entered. No statistical analysis has been attempted."))) elif (i == 2 and len(other_samples) < 4): stats_container = HT.Div(id="stats_tabs%s" % i, Class="ui-tabs") - stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.RISet + " case data were entered. No statistical analysis has been attempted."))) + stats_container.append(HT.Div(HT.Italic("Fewer than 4 non-" + fd.group + " case data were entered. No statistical analysis has been attempted."))) #stats_script_text = """$(function() { $("#stats_tabs0").tabs(); $("#stats_tabs1").tabs(); $("#stats_tabs2").tabs();});""" else: continue @@ -995,7 +996,7 @@ class ShowTrait(templatePage): except: plotTitle = str(this_trait.name) - #normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, RISet=fd.RISet, title=plotTitle, specialStrains=specialStrains) + #normalplot_img = BasicStatisticsFunctions.plotNormalProbability(vals=vals, group=fd.group, title=plotTitle, specialStrains=specialStrains) #normalplot.append(HT.TR(HT.TD(normalplot_img))) #normalplot.append(HT.TR(HT.TD(HT.BR(),HT.BR(),"This plot evaluates whether data are \ #normally distributed. Different symbols represent different groups.",HT.BR(),HT.BR(), @@ -1018,7 +1019,7 @@ class ShowTrait(templatePage): #barName_div = HT.Div(id="statstabs-3") #barName_container = HT.Paragraph() #barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - #barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="name") + #barName_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, group=fd.group, vals=vals, type="name") #barName.append(HT.TR(HT.TD(barName_img))) #barName_container.append(barName) #barName_div.append(barName_container) @@ -1027,7 +1028,7 @@ class ShowTrait(templatePage): #barRank_div = HT.Div(id="statstabs-4") #barRank_container = HT.Paragraph() #barRank = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - #barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, RISet=fd.RISet, vals=vals, type="rank") + #barRank_img = BasicStatisticsFunctions.plotBarGraph(identification=fd.identification, group=fd.group, vals=vals, type="rank") #barRank.append(HT.TR(HT.TD(barRank_img))) #barRank_container.append(barRank) #barRank_div.append(barRank_container) @@ -1048,16 +1049,16 @@ class ShowTrait(templatePage): def build_correlation_tools(self, fd, this_trait): - #species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + #species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) - RISetgp = fd.RISet + this_group = fd.group # We're checking a string here! - assert isinstance(RISetgp, basestring), "We need a string type thing here" - if RISetgp[:3] == 'BXD': - RISetgp = 'BXD' + assert isinstance(this_group, basestring), "We need a string type thing here" + if this_group[:3] == 'BXD': + this_group = 'BXD' - if RISetgp: + if this_group: #sample_correlation = HT.Input(type='button',name='sample_corr', value=' Compute ', Class="button sample_corr") #lit_correlation = HT.Input(type='button',name='lit_corr', value=' Compute ', Class="button lit_corr") #tissue_correlation = HT.Input(type='button',name='tiss_corr', value=' Compute ', Class="button tiss_corr") @@ -1074,7 +1075,7 @@ class ShowTrait(templatePage): self.cursor.execute('''SELECT PublishFreeze.FullName,PublishFreeze.Name FROM PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = %s and PublishFreeze.public > %s''', - (RISetgp, webqtlConfig.PUBLICTHRESH)) + (this_group, webqtlConfig.PUBLICTHRESH)) for item in self.cursor.fetchall(): dataset_menu.append(dict(tissue=None, datasets=[item])) @@ -1082,7 +1083,7 @@ class ShowTrait(templatePage): self.cursor.execute('''SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze, InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = %s and GenoFreeze.public > %s''', - (RISetgp, webqtlConfig.PUBLICTHRESH)) + (this_group, webqtlConfig.PUBLICTHRESH)) for item in self.cursor.fetchall(): dataset_menu.append(dict(tissue=None, datasets=[item])) @@ -1098,7 +1099,7 @@ class ShowTrait(templatePage): InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %s and ProbeSetFreeze.public > %s and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like %s order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ''', - (tissue_id, webqtlConfig.PUBLICTHRESH, "%" + RISetgp + "%")) + (tissue_id, webqtlConfig.PUBLICTHRESH, "%" + this_group + "%")) print("phun8") dataset_sub_menu = [item for item in self.cursor.fetchall() if item] #for item2 in self.cursor.fetchall(): @@ -1257,11 +1258,11 @@ class ShowTrait(templatePage): def dispMappingTools(self, fd, title4Body, this_trait): - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, RISet=fd.RISet) + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) - RISetgp = fd.RISet - if RISetgp[:3] == 'BXD': - RISetgp = 'BXD' + this_group = fd.group + if this_group[:3] == 'BXD': + this_group = 'BXD' #check boxes - one for regular interval mapping, the other for composite permCheck1= HT.Input(type='checkbox', Class='checkbox', name='permCheck1',checked="on") @@ -1454,7 +1455,7 @@ class ShowTrait(templatePage): # Treat Interval Mapping and Marker Regression and Pair Scan as a group for displaying #disable Interval Mapping and Marker Regression and Pair Scan for human and the dataset doesn't have genotype file - mappingMethodId = webqtlDatabaseFunction.getMappingMethod(cursor=self.cursor, groupName=RISetgp) + mappingMethodId = webqtlDatabaseFunction.getMappingMethod(cursor=self.cursor, groupName=this_group) mapping_script = HT.Script(language="Javascript") mapping_script_text = """$(function() { $("#mapping_tabs").tabs(); });""" @@ -1526,7 +1527,7 @@ class ShowTrait(templatePage): sample_names=primary_sample_names, this_trait=this_trait, sample_group_type='primary', - header="%s Only" % (fd.RISet)) + header="%s Only" % (fd.group)) other_sample_names = [] for sample in this_trait.data.keys(): @@ -1547,7 +1548,7 @@ class ShowTrait(templatePage): sample_names=other_sample_names, this_trait=this_trait, sample_group_type='other', - header="Non-%s" % (fd.RISet)) + header="Non-%s" % (fd.group)) self.sample_groups = (primary_samples, other_samples) else: diff --git a/wqflask/wqflask/templates/index_page.html b/wqflask/wqflask/templates/index_page.html index a113bc15..c01898b3 100644 --- a/wqflask/wqflask/templates/index_page.html +++ b/wqflask/wqflask/templates/index_page.html @@ -92,8 +92,8 @@ "btn" value="Advanced Search" onclick= "javascript:window.open('/index3.html', '_self');"> - + + diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index e393ced6..54cdd42b 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -23,7 +23,7 @@ {% if search_terms %}
    • {% for word in search_terms %} - {{word.search_term}} {% if not loop.last %} or {% endif %} + {{word.search_term[0]}} {% if not loop.last %} or {% endif %} {% endfor %}
    • {% endif %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 41d1d714..fb93af53 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -65,6 +65,9 @@ def search_page(): the_search = search_results.SearchResultPage(request.args) print("template_vars is:", pf(the_search.__dict__)) #print("trait_list is:", pf(the_search.__dict__['trait_list'][0].__dict__)) + #for trait in the_search.trait_list: + # print(" -", trait.description_display) + return render_template("search_result_page.html", **the_search.__dict__) -- cgit v1.2.3 From 7929d5d5aace20b50a9c5b428eea784d8eac0b77 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 30 Nov 2012 14:04:59 -0600 Subject: Got searches working for RANGE and MEAN commands Created a file where renamed variables will be listed for future reference --- misc/new_variable_names.txt | 5 ++++ wqflask/wqflask/do_search.py | 59 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 misc/new_variable_names.txt diff --git a/misc/new_variable_names.txt b/misc/new_variable_names.txt new file mode 100644 index 00000000..2b10c07e --- /dev/null +++ b/misc/new_variable_names.txt @@ -0,0 +1,5 @@ +RISet/riset -> group +webqtlDataset.py -> data_set.py +webqtlDataset (class object) -> DataSet +database/db -> dataset/data_set +DataEditingPage -> show_trait.py/show_trait.html diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 92a754e3..11411b26 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -414,8 +414,7 @@ class CisLrsSearch(CisTransLrsSearch): def run(self): return self.real_run("<") - - + class TransLrsSearch(CisTransLrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values @@ -443,9 +442,63 @@ class MeanSearch(ProbeSetSearch): DoSearch.search_types['MEAN'] = "MeanSearch" def run(self): + + self.search_term = [float(value) for value in self.search_term] - return None + if self.search_operator == "=": + assert isinstance(self.search_term, (list, tuple)) + self.mean_min, self.mean_max = self.search_term[:2] + self.where_clause = """ %sXRef.mean > %s and + %sXRef.mean < %s """ % self.mescape(self.dataset.type, + min(self.mean_min, self.mean_max), + self.dataset.type, + max(self.mean_min, self.mean_max)) + else: + # Deal with >, <, >=, and <= + self.where_clause = """ %sXRef.mean %s %s """ % self.mescape(self.dataset.type, + self.search_operator, + self.search_term[0]) + + print("where_clause is:", pf(self.where_clause)) + + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + +class RangeSearch(ProbeSetSearch): + """Searches for genes with a range of expression varying between two values""" + + DoSearch.search_types['RANGE'] = "RangeSearch" + + def run(self): + + self.search_term = [float(value) for value in self.search_term] + + if self.search_operator == "=": + assert isinstance(self.search_term, (list, tuple)) + self.range_min, self.range_max = self.search_term[:2] + self.where_clause = """ (SELECT Pow(2, max(value) -min(value)) + FROM ProbeSetData + WHERE ProbeSetData.Id = ProbeSetXRef.dataId) > %s AND + (SELECT Pow(2, max(value) -min(value)) + FROM ProbeSetData + WHERE ProbeSetData.Id = ProbeSetXRef.dataId) < %s + """ % self.mescape(min(self.range_min, self.range_max), + max(self.range_min, self.range_max)) + else: + # Deal with >, <, >=, and <= + self.where_clause = """ (SELECT Pow(2, max(value) -min(value)) + FROM ProbeSetData + WHERE ProbeSetData.Id = ProbeSetXRef.dataId) > %s + """ % (self.escape(self.search_term[0])) + + print("where_clause is:", pf(self.where_clause)) + + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + if __name__ == "__main__": ### Usually this will be used as a library, but call it from the command line for testing -- cgit v1.2.3 From b8fa8728b7afebbada49f29b85fa5db40e137e1b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 30 Nov 2012 16:19:30 -0600 Subject: Finished pValue search Got headers working in search page --- wqflask/wqflask/do_search.py | 137 ++++++++++++++++++---- wqflask/wqflask/search_results.py | 8 +- wqflask/wqflask/show_trait/show_trait.py | 126 +++++++++++--------- wqflask/wqflask/templates/search_result_page.html | 1 + wqflask/wqflask/views.py | 3 +- 5 files changed, 193 insertions(+), 82 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 11411b26..17078802 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -74,6 +74,14 @@ class ProbeSetSearch(DoSearch): ProbeSet.name_num as TNAME_NUM FROM ProbeSetXRef, ProbeSet """ + header_fields = ['', + 'Record ID', + 'Symbol', + 'Description', + 'Location', + 'Mean', + 'Max LRS', + 'Max LRS Location'] def compile_final_query(self, from_clause = '', where_clause = ''): """Generates the final query string""" @@ -188,36 +196,49 @@ class GenotypeSearch(DoSearch): search_fields = ('Name', 'Chr') - def get_where_clause(self): - """Generate clause for WHERE portion of query""" + def get_fields_clause(self): + """Generate clause for part of the WHERE portion of query""" # This adds a clause to the query that matches the search term # against each field in search_fields (above) - where_clause = [] + fields_clause = [] + + if "'" not in self.search_term: + self.search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + for field in self.search_fields: - where_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % (self.dataset.type, field), - self.escape(self.search_term))) - print("where_clause is:", pf(where_clause)) - where_clause = "(%s)" % ' OR '.join(where_clause) + fields_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % self.mescape(self.dataset.type, + field, + self.search_term))) + print("hello ;where_clause is:", pf(fields_clause)) + fields_clause = "(%s)" % ' OR '.join(fields_clause) - return where_clause + return fields_clause - def run(self): - """Generates and runs a simple search of a genotype dataset""" - #Todo: Zach will figure out exactly what both these lines mean - #and comment here - if "'" not in self.search_term: - search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + def compile_final_query(self, from_clause = '', where_clause = ''): + """Generates the final query string""" + + from_clause = self.normalize_spaces(from_clause) query = (self.base_query + """WHERE %s and Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and - GenoFreeze.Id = %s"""% ( - self.get_where_clause(), - self.escape(self.dataset.id))) + GenoFreeze.Id = %s"""% (where_clause, + self.escape(self.dataset.id))) - return self.execute(query) + print("query is:", pf(query)) + + return query + + def run(self): + """Generates and runs a simple search of a genotype dataset""" + #Todo: Zach will figure out exactly what both these lines mean + #and comment here + + self.query = self.compile_final_query(where_clause = self.get_fields_clause()) + + return self.execute(self.query) class RifSearch(ProbeSetSearch): """Searches for traits with a Gene RIF entry including the search term.""" @@ -497,9 +518,84 @@ class RangeSearch(ProbeSetSearch): self.query = self.compile_final_query(where_clause = self.where_clause) - return self.execute(self.query) + return self.execute(self.query) + +class PositionSearch(DoSearch): + """Searches for genes/markers located within a specified range on a specified chromosome""" + + for search_key in ('POSITION', 'POS', 'MB'): + DoSearch.search_types[search_key] = "PositionSearch" + + def setup(self): + self.search_term = [float(value) for value in self.search_term] + self.chr, self.mb_min, self.mb_max = self.search_term[:3] + self.where_clause = """ %s.Chr = '%s' and + %s.Mb > %s and + %s.Mb < %s """ % self.mescape(self.dataset.type, + self.chr, + self.dataset.type, + min(self.mb_min, self.mb_max), + self.dataset.type, + max(self.mb_min, self.mb_max)) + + def real_run(self): + + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + +class MrnaPositionSearch(ProbeSetSearch, PositionSearch): + """Searches for genes located within a specified range on a specified chromosome""" + + def run(self): + + self.setup() + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + +class GenotypePositionSearch(GenotypeSearch, PositionSearch): + """Searches for genes located within a specified range on a specified chromosome""" + + def run(self): + + self.setup() + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + +class PvalueSearch(ProbeSetSearch): + """Searches for traits with a permutationed p-value between low and high""" + + def run(self): + + self.search_term = [float(value) for value in self.search_term] + + if self.search_operator == "=": + assert isinstance(self.search_term, (list, tuple)) + self.pvalue_min, self.pvalue_max = self.search_term[:2] + self.where_clause = """ %sXRef.pValue > %s and %sXRef.pValue < %s + """ % self.mescape( + self.dataset.type, + min(self.pvalue_min, self.pvalue_max), + self.dataset.type, + max(self.pvalue_min, self.pvalue_max)) + else: + # Deal with >, <, >=, and <= + self.where_clause = """ %sXRef.pValue %s %s + """ % self.mescape( + self.dataset.type, + self.search_operator, + self.search_term[0]) + + print("where_clause is:", pf(self.where_clause)) + + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + if __name__ == "__main__": ### Usually this will be used as a library, but call it from the command line for testing ### And it runs the code below @@ -538,7 +634,8 @@ if __name__ == "__main__": ProbeSetXRef.ProbeSetFreezeId = 112""") #print(pf(cursor.fetchall())) - results = ProbeSetSearch("shh", None, dataset, cursor, db_conn).run() + #results = ProbeSetSearch("shh", None, dataset, cursor, db_conn).run() + results = PvalueSearch(['0.005'], '<', dataset, cursor, db_conn).run() #results = RifSearch("diabetes", dataset, cursor, db_conn).run() #results = WikiSearch("nicotine", dataset, cursor, db_conn).run() #results = CisLrsSearch(['99'], '>', dataset, cursor, db_conn).run() # cisLRS > 99 diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 63e0153d..c7bbdaf2 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -143,14 +143,16 @@ class SearchResultPage(templatePage): search_ob = do_search.DoSearch.get_search(search_type) search_class = getattr(do_search, search_ob) - self.results.extend(search_class(search_term, + the_search = search_class(search_term, search_operator, self.dataset, self.cursor, - self.db_conn).run()) - + self.db_conn) + self.results.extend(the_search.run()) print("in the search results are:", self.results) + self.header_fields = the_search.header_fields + #ZS: This should be handled in the parser def encregexp(self,str): diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index db2636bc..e8ad0b1d 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -34,15 +34,22 @@ class ShowTrait(templatePage): def __init__(self, fd): self.fd = fd + print("red1 fd.group:", fd.group) templatePage.__init__(self, fd) + + print("red2 fd.group:", fd.group) assert self.openMysql(), "No database!" - + + print("red3 fd.group:", fd.group) this_trait = self.get_this_trait() - + + print("red4 fd.group:", fd.group) ##read genotype file fd.group = this_trait.group - fd.readGenotype() - + + print("[red5] fd.group is:", fd.group) + fd.readGenotype() + if not fd.genotype: fd.readData(incf1=1) @@ -107,8 +114,8 @@ class ShowTrait(templatePage): except: hddn['normalPlotTitle'] = str(this_trait.name) hddn['fromDataEditingPage'] = 1 - if this_trait.db and this_trait.db.type and this_trait.db.type == 'ProbeSet': - hddn['trait_type'] = this_trait.db.type + if this_trait.dataset and this_trait.dataset.type and this_trait.dataset.type == 'ProbeSet': + hddn['trait_type'] = this_trait.dataset.type if this_trait.cellid: hddn['cellid'] = this_trait.cellid else: @@ -130,7 +137,7 @@ class ShowTrait(templatePage): self.dispTraitInformation(fd, "", hddn, this_trait) #Display trait information + function buttons if this_trait == None: - this_trait = webqtlTrait(data=fd.allTraitData, db=None) + this_trait = webqtlTrait(data=fd.allTraitData, dataset=None) ## Variance submit page only #if fd.enablevariance and not variance_data_page: @@ -147,7 +154,7 @@ class ShowTrait(templatePage): self.make_sample_lists(fd, variance_data_page, this_trait) - + if fd.allsamplelist: hddn['allsamplelist'] = string.join(fd.allsamplelist, ' ') @@ -178,12 +185,12 @@ class ShowTrait(templatePage): #else: dataset = self.fd['dataset'] trait_id = self.fd['trait_id'] - cell_id = self.fd.get('CellID') + cell_id = self.fd.get('CellID') + + this_trait = webqtlTrait(self.db_conn, dataset=dataset, name=trait_id, cellid=cell_id) - this_trait = webqtlTrait(self.db_conn, db=dataset, name=trait_id, cellid=cell_id) - ##identification, etc. - self.fd.identification = '%s : %s' % (this_trait.db.shortname, trait_id) + self.fd.identification = '%s : %s' % (this_trait.dataset.shortname, trait_id) this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ &ProbeSetID=%s&group=%s&parentsf1=on' %(dataset, trait_id, self.fd['group']) @@ -191,10 +198,13 @@ class ShowTrait(templatePage): self.fd.identification = '%s/%s'%(self.fd.identification, cell_id) this_trait.returnURL = '%s&CellID=%s' % (this_trait.returnURL, cell_id) + print("yellow1:", self.group) this_trait.retrieveInfo() + print("yellow2:", self.group) this_trait.retrieveData() + print("yellow3:", self.group) return this_trait - + def dispTraitInformation(self, fd, title1Body, hddn, this_trait): @@ -225,13 +235,13 @@ class ShowTrait(templatePage): if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: - if this_trait==None or this_trait.db.type=='Temp': + if this_trait==None or this_trait.dataset.type=='Temp': updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") updateButton.append(updateButton_img) updateText = "Edit" - elif this_trait.db.type != 'Temp': - if this_trait.db.type == 'Publish' and this_trait.confidential: #XZ: confidential phenotype trait + elif this_trait.dataset.type != 'Temp': + if this_trait.dataset.type == 'Publish' and this_trait.confidential: #XZ: confidential phenotype trait if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") @@ -261,7 +271,7 @@ class ShowTrait(templatePage): # Microarray database information to display - if this_trait and this_trait.db and this_trait.db.type == 'ProbeSet': #before, this line was only reached if this_trait != 0, but now we need to check + if this_trait and this_trait.dataset and this_trait.dataset.type == 'ProbeSet': #before, this line was only reached if this_trait != 0, but now we need to check try: hddn['GeneId'] = int(string.strip(this_trait.geneid)) except: @@ -297,7 +307,7 @@ class ShowTrait(templatePage): geneWikiText = 'GeneWiki' #XZ: display similar traits in other selected datasets - if this_trait and this_trait.db and this_trait.db.type=="ProbeSet" and this_trait.symbol: + if this_trait and this_trait.dataset and this_trait.dataset.type=="ProbeSet" and this_trait.symbol: if _Species in ("mouse", "rat", "human"): similarUrl = "%s?cmd=sch&gene=%s&alias=1&species=%s" % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.symbol, _Species) similarButton = HT.Href(url="#redirect", onClick="openNewWin('%s')" % similarUrl) @@ -331,7 +341,7 @@ class ShowTrait(templatePage): ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (this_trait.db.name, this_trait.name) ) + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (this_trait.dataset.name, this_trait.name) ) seqs = self.cursor.fetchall() if not seqs: raise ValueError @@ -350,7 +360,7 @@ class ShowTrait(templatePage): ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSetFreeze.Name = '%s' AND ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (this_trait.db.name, this_trait.name) ) + Probe.ProbeSetId = ProbeSet.Id order by Probe.SerialOrder""" % (this_trait.dataset.name, this_trait.name) ) seqs = self.cursor.fetchall() for seqt in seqs: @@ -393,7 +403,7 @@ class ShowTrait(templatePage): pass #Display probe information (if any) - if this_trait.db.name.find('Liver') >= 0 and this_trait.db.name.find('F2') < 0: + if this_trait.dataset.name.find('Liver') >= 0 and this_trait.dataset.name.find('F2') < 0: pass else: #query database for number of probes associated with trait; if count > 0, set probe tool button and text @@ -404,7 +414,7 @@ class ShowTrait(templatePage): probeResult = self.cursor.fetchone() if probeResult[0] > 0: probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&group=%s&incparentsf1=ON" \ - % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.db, this_trait.name, this_trait.cellid, fd.group) + % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.dataset, this_trait.name, this_trait.cellid, fd.group) probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") #probeButton.append(probeButton_img) @@ -443,7 +453,7 @@ class ShowTrait(templatePage): # select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze # where # ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - # ProbeSetFreeze.Id = %d""" % this_trait.db.id) + # ProbeSetFreeze.Id = %d""" % this_trait.dataset.id) # probeDBName = self.cursor.fetchone()[0] # tbl.append(HT.TR( # HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), @@ -454,7 +464,7 @@ class ShowTrait(templatePage): #tbl.append(HT.TR( # HT.TD('Database: ', Class="fs13 fwb", valign="top", nowrap="on"), # HT.TD(width=10, valign="top"), - # HT.TD(HT.Href(text=this_trait.db.fullname, url = webqtlConfig.INFOPAGEHREF % this_trait.db.name, + # HT.TD(HT.Href(text=this_trait.dataset.fullname, url = webqtlConfig.INFOPAGEHREF % this_trait.dataset.name, # target='_blank', Class="fs13 fwn non_bold"), valign="top") # )) #pass @@ -635,7 +645,7 @@ class ShowTrait(templatePage): #Info2Disp.append(linkTable) #title1Body.append(tbl, HT.BR(), menuTable) - elif this_trait and this_trait.db and this_trait.db.type =='Publish': #Check if trait is phenotype + elif this_trait and this_trait.dataset and this_trait.dataset.type =='Publish': #Check if trait is phenotype if this_trait.confidential: pass @@ -723,7 +733,7 @@ class ShowTrait(templatePage): #title1Body.append(tbl, HT.BR(), menuTable) - elif this_trait and this_trait.db and this_trait.db.type == 'Geno': #Check if trait is genotype + elif this_trait and this_trait.dataset and this_trait.dataset.type == 'Geno': #Check if trait is genotype GenoInfo = HT.Paragraph() if this_trait.chr and this_trait.mb: @@ -775,7 +785,7 @@ class ShowTrait(templatePage): #title1Body.append(tbl, HT.BR(), menuTable) - elif (this_trait == None or this_trait.db.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) + elif (this_trait == None or this_trait.dataset.type == 'Temp'): #if temporary trait (user-submitted trait or PCA trait) #TempInfo = HT.Paragraph() if this_trait != None: @@ -888,13 +898,13 @@ class ShowTrait(templatePage): # continue vals1.append(thisValFull) - - + + #vals1 = [[sampleNameOrig.replace("_2nd_", ""), # this_trait.data[sampleName].val, # this_trait.data[sampleName].var] # for sampleNameOrig in all_samples]] - # + # #Using just the group sample for sampleNameOrig in primary_samples: @@ -971,11 +981,11 @@ class ShowTrait(templatePage): # #statsTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") - if this_trait.db: + if this_trait.dataset: if this_trait.cellid: - self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait.db.type, cellid=this_trait.cellid)) + self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait.dataset.type, cellid=this_trait.cellid)) else: - self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait.db.type)) + self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals, trait_type=this_trait.dataset.type)) else: self.stats_data.append(BasicStatisticsFunctions.basicStatsTable(vals=vals)) @@ -1005,7 +1015,7 @@ class ShowTrait(templatePage): #normalplot_container.append(normalplot) #normalplot_div.append(normalplot_container) #stats_container.append(normalplot_div) - + #boxplot_div = HT.Div(id="statstabs-2") #boxplot_container = HT.Paragraph() #boxplot = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") @@ -1014,8 +1024,8 @@ class ShowTrait(templatePage): #boxplot_container.append(boxplot) #boxplot_div.append(boxplot_container) #stats_container.append(boxplot_div) - - + + #barName_div = HT.Div(id="statstabs-3") #barName_container = HT.Paragraph() #barName = HT.TableLite(cellspacing=0, cellpadding=0, width="100%") @@ -1033,17 +1043,17 @@ class ShowTrait(templatePage): #barRank_container.append(barRank) #barRank_div.append(barRank_container) #stats_container.append(barRank_div) - + # stats_cell.append(stats_container) # #stats_script.append(stats_script_text) # #submitTable = HT.TableLite(cellspacing=0, cellpadding=0, width="100%", Class="target2") #stats_row.append(stats_cell) - + #submitTable.append(stats_row) #submitTable.append(stats_script) - + #title2Body.append(submitTable) @@ -1052,7 +1062,7 @@ class ShowTrait(templatePage): #species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) this_group = fd.group - + # We're checking a string here! assert isinstance(this_group, basestring), "We need a string type thing here" if this_group[:3] == 'BXD': @@ -1072,17 +1082,17 @@ class ShowTrait(templatePage): dataset_menu = [] print("[tape4] webqtlConfig.PUBLICTHRESH:", webqtlConfig.PUBLICTHRESH) print("[tape4] type webqtlConfig.PUBLICTHRESH:", type(webqtlConfig.PUBLICTHRESH)) - self.cursor.execute('''SELECT PublishFreeze.FullName,PublishFreeze.Name FROM - PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id - and InbredSet.Name = %s and PublishFreeze.public > %s''', + self.cursor.execute('''SELECT PublishFreeze.FullName,PublishFreeze.Name FROM + PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id + and InbredSet.Name = %s and PublishFreeze.public > %s''', (this_group, webqtlConfig.PUBLICTHRESH)) for item in self.cursor.fetchall(): dataset_menu.append(dict(tissue=None, datasets=[item])) self.cursor.execute('''SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze, - InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = - %s and GenoFreeze.public > %s''', + InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = + %s and GenoFreeze.public > %s''', (this_group, webqtlConfig.PUBLICTHRESH)) for item in self.cursor.fetchall(): dataset_menu.append(dict(tissue=None, @@ -1109,19 +1119,19 @@ class ShowTrait(templatePage): datasets=dataset_sub_menu)) # ("**heading**", tissue_name)) #dataset_menu.append(dataset_sub_menu) - + dataset_menu_selected = None if len(dataset_menu): - if this_trait and this_trait.db: - dataset_menu_selected = this_trait.db.name + if this_trait and this_trait.dataset: + dataset_menu_selected = this_trait.dataset.name #criteriaText = HT.Span("Return:", Class="ffl fwb fs12") #criteriaMenu1 = HT.Select(name='criteria1', selected='500', onMouseOver="if (NS4 || IE4) activateEl('criterias', event);") - + return_results_menu = (100, 200, 500, 1000, 2000, 5000, 10000, 15000, 20000) return_results_menu_selected = 500 - + #criteriaMenu1.append(('top 100','100')) #criteriaMenu1.append(('top 200','200')) #criteriaMenu1.append(('top 500','500')) @@ -1159,7 +1169,7 @@ class ShowTrait(templatePage): #corr_row = HT.TR() #corr_container = HT.Div(id="corr_tabs", Class="ui-tabs") # - #if (this_trait.db != None and this_trait.db.type =='ProbeSet'): + #if (this_trait.dataset != None and this_trait.dataset.type =='ProbeSet'): # corr_tab_list = [HT.Href(text='Sample r', url="#corrtabs-1"), # HT.Href(text='Literature r', url="#corrtabs-2"), # HT.Href(text='Tissue r', url="#corrtabs-3")] @@ -1210,8 +1220,8 @@ class ShowTrait(templatePage): #literature_container.append(literatureTable) #literature_div.append(literature_container) # - #if this_trait.db != None: - # if (this_trait.db.type =='ProbeSet'): + #if this_trait.dataset != None: + # if (this_trait.dataset.type =='ProbeSet'): # corr_container.append(literature_div) # #tissue_div = HT.Div(id="corrtabs-3") @@ -1235,8 +1245,8 @@ class ShowTrait(templatePage): # #tissue_container.append(tissueTable) #tissue_div.append(tissue_container) - #if this_trait.db != None: - # if (this_trait.db.type =='ProbeSet'): + #if this_trait.dataset != None: + # if (this_trait.dataset.type =='ProbeSet'): # corr_container.append(tissue_div) # #corr_row.append(HT.TD(corr_container)) @@ -1538,7 +1548,7 @@ class ShowTrait(templatePage): if other_sample_names: par_f1_samples = fd.parlist + fd.f1list - + other_sample_names.sort() #Sort other samples other_sample_names = par_f1_samples + other_sample_names @@ -1549,13 +1559,13 @@ class ShowTrait(templatePage): this_trait=this_trait, sample_group_type='other', header="Non-%s" % (fd.group)) - + self.sample_groups = (primary_samples, other_samples) else: self.sample_groups = (primary_samples,) #TODO: Figure out why this if statement is written this way - Zach - #if (other_sample_names or (fd.f1list and this_trait.data.has_key(fd.f1list[0])) + #if (other_sample_names or (fd.f1list and this_trait.data.has_key(fd.f1list[0])) # or (fd.f1list and this_trait.data.has_key(fd.f1list[1]))): # print("hjs") fd.allsamplelist = all_samples_ordered diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 54cdd42b..35ff4e8e 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -39,6 +39,7 @@ {% for header in header_fields %} {{header}} {% endfor %} + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index fb93af53..cdc3379f 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -67,7 +67,7 @@ def search_page(): #print("trait_list is:", pf(the_search.__dict__['trait_list'][0].__dict__)) #for trait in the_search.trait_list: # print(" -", trait.description_display) - + return render_template("search_result_page.html", **the_search.__dict__) @@ -87,6 +87,7 @@ def whats_new_page(): def show_trait_page(): # Here it's currently too complicated not to use an fd that is a webqtlFormData fd = webqtlFormData.webqtlFormData(request.args) + print("stp y1:", pf(vars(fd))) template_vars = show_trait.ShowTrait(fd) template_vars.js_data = json.dumps(template_vars.js_data, default=json_default_handler, -- cgit v1.2.3 From 43f69f26507d934a15d8e8d20f0ac3023fdb7691 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 30 Nov 2012 18:03:52 -0600 Subject: Started switching to using basic sqlalchemy to handle db connection/queries Began fixing bugs related to this fix, still in progress --- wqflask/base/data_set.py | 33 ++++++++------- wqflask/base/webqtlConfigLocal.py | 4 +- wqflask/base/webqtlTrait.py | 69 ++++++++++++++++++-------------- wqflask/cfg/zach_settings.py | 3 ++ wqflask/wqflask/do_search.py | 24 ++++++++--- wqflask/wqflask/search_results.py | 3 +- wqflask/wqflask/show_trait/show_trait.py | 25 ++++++------ wqflask/wqflask/views.py | 14 +++++-- 8 files changed, 106 insertions(+), 69 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 633f7545..015b2623 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -22,6 +22,8 @@ from __future__ import print_function, division +from flask import Flask, g + from htmlgen import HTMLgen2 as HT import webqtlConfig @@ -31,25 +33,28 @@ from pprint import pformat as pf # Used by create_database to instantiate objects DS_NAME_MAP = {} -def create_dataset(db_conn, dataset_name): - cursor = db_conn.cursor() - cursor.execute(""" +def create_dataset(dataset_name): + #cursor = db_conn.cursor() + print("dataset_name:", dataset_name) + + dataset_type = g.db.execute(""" SELECT DBType.Name FROM DBList, DBType WHERE DBList.Name = %s and DBType.Id = DBList.DBTypeId - """, (dataset_name)) - print("dataset_name:", dataset_name) - dataset_type = cursor.fetchone()[0] - print("dataset_type:", pf(dataset_type)) + """, (dataset_name)).fetchone().Name + + #dataset_type = cursor.fetchone()[0] + print("[blubber] dataset_type:", pf(dataset_type)) dataset_ob = DS_NAME_MAP[dataset_type] #dataset_class = getattr(data_set, dataset_ob) - + print("dataset_ob:", dataset_ob) print("DS_NAME_MAP:", pf(DS_NAME_MAP)) dataset_class = globals()[dataset_ob] - return dataset_class(dataset_name, db_conn) + return dataset_class(dataset_name) + class DataSet(object): """ @@ -58,12 +63,12 @@ class DataSet(object): """ - def __init__(self, name, db_conn): + def __init__(self, name): assert name self.name = name - self.db_conn = db_conn - self.cursor = self.db_conn.cursor() + #self.db_conn = db_conn + #self.cursor = self.db_conn.cursor() self.id = None self.type = None self.group = None @@ -271,7 +276,7 @@ class GenotypeDataSet(DataSet): def check_confidentiality(self): return geno_mrna_confidentiality(self) - def get_trait_info(self, trait_list): + def get_trait_info(self, trait_list, species=None): for this_trait in trait_list: if not this_trait.haveinfo: this_trait.retrieveInfo() @@ -355,7 +360,7 @@ class MrnaAssayDataSet(DataSet): ProbeFreeze.InbredSetId = InbredSet.Id AND ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND ProbeSetFreeze.Name = "%s" - ''' % self.db_conn.escape_string(self.name) + ''' % g.db.escape_string(self.name) def check_confidentiality(self): diff --git a/wqflask/base/webqtlConfigLocal.py b/wqflask/base/webqtlConfigLocal.py index 5aab48ac..84686234 100755 --- a/wqflask/base/webqtlConfigLocal.py +++ b/wqflask/base/webqtlConfigLocal.py @@ -4,12 +4,12 @@ MYSQL_SERVER = 'localhost' DB_NAME = 'db_webqtl_zas1024' -DB_USER = 'webqtlupd' +DB_USER = 'webqtl' DB_PASSWD = 'webqtl' MYSQL_UPDSERVER = 'localhost' DB_UPDNAME = 'db_webqtl_zas1024' -DB_UPDUSER = 'webqtlupd' +DB_UPDUSER = 'webqtl' DB_UPDPASSWD = 'webqtl' GNROOT = '/home/zas1024/gn/' diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index cc0e2321..1dceba08 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -12,6 +12,7 @@ from utility import webqtlUtil from pprint import pformat as pf +from flask import Flask, g class webqtlTrait: """ @@ -20,38 +21,46 @@ class webqtlTrait: """ - def __init__(self, db_conn, **kw): + def __init__(self, **kw): print("in webqtlTrait") - self.db_conn = db_conn - self.cursor = self.db_conn.cursor() - self.dataset = None # database object - self.name = '' # Trait ID, ProbeSet ID, Published ID, etc. - self.cellid = '' - self.identification = 'un-named trait' - self.group = '' - self.haveinfo = 0 - self.sequence = '' # Blat sequence, available for ProbeSet - self.data = {} - print("foo") - print("kw in webqtlTrait are:", pf(kw)) - print("printed\n\n") - for name, value in kw.items(): - if self.__dict__.has_key(name): - setattr(self, name, value) - elif name == 'fullname': - name2 = value.split("::") - if len(name2) == 2: - self.dataset, self.name = name2 - elif len(name2) == 3: - self.dataset, self.name, self.cellid = name2 - else: - raise KeyError, repr(value) + ' parameter format error.' - else: - raise KeyError, repr(name) + ' not a valid parameter for this class.' + #self.db_conn = db_conn + #self.cursor = self.db_conn.cursor() + self.dataset = kw.get('dataset', None) # database object + self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. + self.cellid = kw.get('cellid', None) + self.identification = kw.get('identification', 'un-named trait') + self.group = kw.get('group', None) + self.haveinfo = kw.get(haveinfo, False) + self.sequence = kw.get(sequence, None) # Blat sequence, available for ProbeSet + self.data = kw.get(data, {}) + + if kw.get('fullname'): + name2 = value.split("::") + if len(name2) == 2: + self.dataset, self.name = name2 + elif len(name2) == 3: + self.dataset, self.name, self.cellid = name2 + + #print("foo") + #print("kw in webqtlTrait are:", pf(kw)) + #print("printed\n\n") + #for name, value in kw.items(): + # if self.__dict__.has_key(name): + # setattr(self, name, value) + # elif name == 'fullname': + # name2 = value.split("::") + # if len(name2) == 2: + # self.dataset, self.name = name2 + # elif len(name2) == 3: + # self.dataset, self.name, self.cellid = name2 + # else: + # raise KeyError, repr(value) + ' parameter format error.' + # else: + # raise KeyError, repr(name) + ' not a valid parameter for this class.' if self.dataset and isinstance(self.dataset, basestring): - assert self.cursor, "Don't have a cursor" - self.dataset = create_dataset(self.db_conn, self.dataset) + #assert self.cursor, "Don't have a cursor" + self.dataset = create_dataset(self.dataset) #if self.dataset == None, not from a database print("self.dataset is:", self.dataset, type(self.dataset)) @@ -432,7 +441,7 @@ class webqtlTrait: self.cursor.execute(query) traitInfo = self.cursor.fetchone() if traitInfo: - self.haveinfo = 1 + self.haveinfo = True #XZ: assign SQL query result to trait attributes. for i, field in enumerate(self.dataset.display_fields): diff --git a/wqflask/cfg/zach_settings.py b/wqflask/cfg/zach_settings.py index ed97f222..8d3bf4ab 100644 --- a/wqflask/cfg/zach_settings.py +++ b/wqflask/cfg/zach_settings.py @@ -1,2 +1,5 @@ LOGFILE = """/tmp/flask_gn_log""" + TRAP_BAD_REQUEST_ERRORS = True + +DB_URI = """mysql://webqtl:webqtl@localhost/db_webqtl_zas1024""" \ No newline at end of file diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 17078802..bae3df08 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -144,14 +144,22 @@ class PhenotypeSearch(DoSearch): 'Publication.Title', 'Publication.Authors', 'PublishXRef.Id') + + header_fields = ['', + 'Record ID', + 'Description', + 'Authors', + 'Year', + 'Max LRS', + 'Max LRS Location'] def get_where_clause(self): """Generate clause for WHERE portion of query""" #Todo: Zach will figure out exactly what both these lines mean #and comment here - if "'" not in self.search_term: - search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + if "'" not in self.search_term[0]: + search_term = "[[:<:]]" + self.search_term[0] + "[[:>:]]" # This adds a clause to the query that matches the search term # against each field in the search_fields tuple @@ -195,6 +203,10 @@ class GenotypeSearch(DoSearch): FROM GenoXRef, GenoFreeze, Geno """ search_fields = ('Name', 'Chr') + + header_fields = ['', + 'Record ID', + 'Location'] def get_fields_clause(self): """Generate clause for part of the WHERE portion of query""" @@ -203,13 +215,13 @@ class GenotypeSearch(DoSearch): # against each field in search_fields (above) fields_clause = [] - if "'" not in self.search_term: - self.search_term = "[[:<:]]" + self.search_term + "[[:>:]]" + if "'" not in self.search_term[0]: + self.search_term = "[[:<:]]" + self.search_term[0] + "[[:>:]]" for field in self.search_fields: fields_clause.append('''%s REGEXP "%s"''' % ("%s.%s" % self.mescape(self.dataset.type, - field, - self.search_term))) + field), + self.search_term)) print("hello ;where_clause is:", pf(fields_clause)) fields_clause = "(%s)" % ' OR '.join(fields_clause) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index c7bbdaf2..04b14e8f 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -83,7 +83,8 @@ class SearchResultPage(templatePage): self.dataset_group_ids = map(lambda x: x[2], results) else: print("self.dataset is:", pf(self.dataset)) - self.dataset = create_dataset(self.db_conn, self.dataset) + # Replaces a string with an object + self.dataset = create_dataset(self.dataset) print("self.dataset is now:", pf(self.dataset)) self.search() diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index e8ad0b1d..7060f2ea 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -31,16 +31,15 @@ from pprint import pformat as pf class ShowTrait(templatePage): - def __init__(self, fd): - self.fd = fd + def __init__(self, args): + print("in ShowTrait, args are:", args) + self.group = args.group + self.trait_id = trait_id + self.dataset = dataset - print("red1 fd.group:", fd.group) - templatePage.__init__(self, fd) + #assert self.openMysql(), "No database!" - print("red2 fd.group:", fd.group) - assert self.openMysql(), "No database!" - - print("red3 fd.group:", fd.group) + #print("red3 fd.group:", fd.group) this_trait = self.get_this_trait() print("red4 fd.group:", fd.group) @@ -183,11 +182,13 @@ class ShowTrait(templatePage): #if traitInfos: # database, ProbeSetID, CellID = traitInfos #else: - dataset = self.fd['dataset'] - trait_id = self.fd['trait_id'] - cell_id = self.fd.get('CellID') + #dataset = self.fd['dataset'] + #trait_id = self.fd['trait_id'] + #cell_id = self.fd.get('CellID') - this_trait = webqtlTrait(self.db_conn, dataset=dataset, name=trait_id, cellid=cell_id) + this_trait = webqtlTrait(dataset=dataset, + name=trait_id, + cellid=cell_id) ##identification, etc. self.fd.identification = '%s : %s' % (this_trait.dataset.shortname, trait_id) diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index cdc3379f..17dc42fb 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -7,10 +7,12 @@ import simplejson as json import yaml import flask +import sqlalchemy +#import config from wqflask import app -from flask import render_template, request, make_response, Response +from flask import render_template, request, make_response, Response, Flask, g, config from wqflask import search_results from wqflask.show_trait import show_trait @@ -27,6 +29,10 @@ from pprint import pformat as pf #logging.basicConfig(filename="/tmp/gn_log", level=logging.INFO) #_log = logging.getLogger("correlation") +@app.before_request +def connect_db(): + print("blue app.config:", app.config, pf(vars(app.config))) + g.db = sqlalchemy.create_engine(app.config['DB_URI']) @app.route("/") def index_page(): @@ -86,9 +92,9 @@ def whats_new_page(): @app.route("/show_trait") def show_trait_page(): # Here it's currently too complicated not to use an fd that is a webqtlFormData - fd = webqtlFormData.webqtlFormData(request.args) - print("stp y1:", pf(vars(fd))) - template_vars = show_trait.ShowTrait(fd) + #fd = webqtlFormData.webqtlFormData(request.args) + #print("stp y1:", pf(vars(fd))) + template_vars = show_trait.ShowTrait(request.args) template_vars.js_data = json.dumps(template_vars.js_data, default=json_default_handler, indent=" ", -- cgit v1.2.3 From 21253f4424fbcdf76212a55011e657ebeb87da82 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 30 Nov 2012 18:27:59 -0600 Subject: Added example of escaping strings now that trasitioning to simple SQLAlchemy --- wqflask/base/data_set.py | 88 ++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 015b2623..34e5eaa1 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -28,6 +28,7 @@ from htmlgen import HTMLgen2 as HT import webqtlConfig +from MySQLdb import escape_string as escape from pprint import pformat as pf # Used by create_database to instantiate objects @@ -36,22 +37,22 @@ DS_NAME_MAP = {} def create_dataset(dataset_name): #cursor = db_conn.cursor() print("dataset_name:", dataset_name) - + dataset_type = g.db.execute(""" SELECT DBType.Name FROM DBList, DBType WHERE DBList.Name = %s and DBType.Id = DBList.DBTypeId """, (dataset_name)).fetchone().Name - + #dataset_type = cursor.fetchone()[0] print("[blubber] dataset_type:", pf(dataset_type)) - + dataset_ob = DS_NAME_MAP[dataset_type] #dataset_class = getattr(data_set, dataset_ob) print("dataset_ob:", dataset_ob) print("DS_NAME_MAP:", pf(DS_NAME_MAP)) - + dataset_class = globals()[dataset_ob] return dataset_class(dataset_name) @@ -75,12 +76,12 @@ class DataSet(object): #if self.cursor and self.id == 0: self.setup() - + self.check_confidentiality() - + self.retrieve_name() self.get_group() - + # Delete this eventually @property @@ -101,9 +102,9 @@ class DataSet(object): """ If the data set name parameter is not found in the 'Name' field of the data set table, check if it is actually the FullName or ShortName instead. - + This is not meant to retrieve the data set info if no name at all is passed. - + """ query_args = tuple(self.db_conn.escape_string(x) for x in ( @@ -113,7 +114,7 @@ class DataSet(object): self.name, self.name)) print("query_args are:", query_args) - + query = ''' SELECT Id, Name, FullName, ShortName @@ -123,7 +124,7 @@ class DataSet(object): public > %s AND (Name = "%s" OR FullName = "%s" OR ShortName = "%s") ''' % (query_args) - + self.cursor.execute(query) self.id, self.name, self.fullname, self.shortname = self.cursor.fetchone() @@ -147,7 +148,7 @@ class PhenotypeDataSet(DataSet): 'Publication.Title', 'Publication.Authors', 'PublishXRef.Id'] - + # Figure out what display_fields is self.display_fields = ['name', 'pubmed_id', @@ -172,10 +173,10 @@ class PhenotypeDataSet(DataSet): 'Authors', 'Year', 'Max LRS', - 'Max LRS Location'] + 'Max LRS Location'] self.type = 'Publish' - + self.query = ''' SELECT InbredSet.Name, InbredSet.Id @@ -185,11 +186,11 @@ class PhenotypeDataSet(DataSet): PublishFreeze.InbredSetId = InbredSet.Id AND PublishFreeze.Name = "%s" ''' % self.db_conn.escape_string(self.name) - + def check_confidentiality(self): # (Urgently?) Need to write this pass - + def get_trait_info(self, trait_list, species = ''): for this_trait in trait_list: if not this_trait.haveinfo: @@ -238,31 +239,31 @@ class PhenotypeDataSet(DataSet): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) - + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + class GenotypeDataSet(DataSet): DS_NAME_MAP['Geno'] = 'GenotypeDataSet' - + def setup(self): # Fields in the database table self.search_fields = ['Name', 'Chr'] - + # Find out what display_fields is self.display_fields = ['name', 'chr', 'mb', 'source2', 'sequence'] - + # Fields displayed in the search results table header self.header_fields = ['', 'ID', - 'Location'] - + 'Location'] + # Todo: Obsolete or rename this field self.type = 'Geno' - + self.query = ''' SELECT InbredSet.Name, InbredSet.Id @@ -272,10 +273,10 @@ class GenotypeDataSet(DataSet): GenoFreeze.InbredSetId = InbredSet.Id AND GenoFreeze.Name = "%s" ''' % self.db_conn.escape_string(self.name) - + def check_confidentiality(self): return geno_mrna_confidentiality(self) - + def get_trait_info(self, trait_list, species=None): for this_trait in trait_list: if not this_trait.haveinfo: @@ -295,16 +296,16 @@ class GenotypeDataSet(DataSet): trait_location_value = ord(str(this_trait.chr).upper()[0])*1000 + this_trait.mb this_trait.location_repr = 'Chr%s: %.4f' % (this_trait.chr, float(this_trait.mb) ) - this_trait.location_value = trait_location_value - - + this_trait.location_value = trait_location_value + + class MrnaAssayDataSet(DataSet): ''' An mRNA Assay is a quantitative assessment (assay) associated with an mRNA trait - + This used to be called ProbeSet, but that term only refers specifically to the Affymetrix platform and is far too specific. - + ''' DS_NAME_MAP['ProbeSet'] = 'MrnaAssayDataSet' @@ -346,7 +347,7 @@ class MrnaAssayDataSet(DataSet): 'Location', 'Mean Expr', 'Max LRS', - 'Max LRS Location'] + 'Max LRS Location'] # Todo: Obsolete or rename this field self.type = 'ProbeSet' @@ -360,12 +361,12 @@ class MrnaAssayDataSet(DataSet): ProbeFreeze.InbredSetId = InbredSet.Id AND ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND ProbeSetFreeze.Name = "%s" - ''' % g.db.escape_string(self.name) + ''' % escape(self.name) def check_confidentiality(self): return geno_mrna_confidentiality(self) - + def get_trait_info(self, trait_list=None, species=''): # Note: setting trait_list to [] is probably not a great idea. @@ -428,7 +429,7 @@ class MrnaAssayDataSet(DataSet): self.db_conn.escape_string(this_trait.name))) print("query is:", pf(query)) - + self.cursor.execute(query) result = self.cursor.fetchone() @@ -475,30 +476,30 @@ class MrnaAssayDataSet(DataSet): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) class TempDataSet(DataSet): '''Temporary user-generated data set''' - + def setup(self): self.search_fields = ['name', 'description'] - + self.display_fields = ['name', 'description'] - + self.header_fields = ['Name', 'Description'] - + self.type = 'Temp' - + # Need to double check later how these are used self.id = 1 self.fullname = 'Temporary Storage' self.shortname = 'Temp' - - + + def geno_mrna_confidentiality(ob): dataset_table = ob.type + "Freeze" print("dataset_table [%s]: %s" % (type(dataset_table), dataset_table)) @@ -517,4 +518,3 @@ def geno_mrna_confidentiality(ob): if confidential: # Allow confidential data later NoConfindetialDataForYouTodaySorry - \ No newline at end of file -- cgit v1.2.3 From 0e17939e123ec80c4da3f665004b08347aa9480b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 4 Dec 2012 16:19:46 -0600 Subject: Began changing references to cursor/db_conn to use sqlalchemy Wrote function for phenotype author searches --- wqflask/base/data_set.py | 34 +++++++------ wqflask/base/webqtlTrait.py | 15 +++--- wqflask/wqflask/do_search.py | 101 ++++++++++++++++++++++++++++---------- wqflask/wqflask/search_results.py | 2 +- 4 files changed, 103 insertions(+), 49 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 34e5eaa1..cd9e810e 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -90,9 +90,7 @@ class DataSet(object): def get_group(self): - assert self.cursor - self.cursor.execute(self.query) - self.group, self.group_id = self.cursor.fetchone() + self.group, self.group_id = g.db.execute(self.query).fetchone() if self.group == 'BXD300': self.group = "BXD" #return group @@ -107,7 +105,7 @@ class DataSet(object): """ - query_args = tuple(self.db_conn.escape_string(x) for x in ( + query_args = tuple(escape(x) for x in ( (self.type + "Freeze"), str(webqtlConfig.PUBLICTHRESH), self.name, @@ -115,18 +113,22 @@ class DataSet(object): self.name)) print("query_args are:", query_args) - query = ''' - SELECT - Id, Name, FullName, ShortName - FROM - %s - WHERE - public > %s AND - (Name = "%s" OR FullName = "%s" OR ShortName = "%s") - ''' % (query_args) + print(""" + SELECT Id, Name, FullName, ShortName + FROM %s + WHERE public > %s AND + (Name = '%s' OR FullName = '%s' OR ShortName = '%s') + """ % (query_args)) + + self.id, self.name, self.fullname, self.shortname = g.db.execute(""" + SELECT Id, Name, FullName, ShortName + FROM %s + WHERE public > %s AND + (Name = '%s' OR FullName = '%s' OR ShortName = '%s') + """ % (query_args)).fetchone() - self.cursor.execute(query) - self.id, self.name, self.fullname, self.shortname = self.cursor.fetchone() + #self.cursor.execute(query) + #self.id, self.name, self.fullname, self.shortname = self.cursor.fetchone() #def genHTML(self, Class='c0dd'): @@ -185,7 +187,7 @@ class PhenotypeDataSet(DataSet): WHERE PublishFreeze.InbredSetId = InbredSet.Id AND PublishFreeze.Name = "%s" - ''' % self.db_conn.escape_string(self.name) + ''' % escape(self.name) def check_confidentiality(self): # (Urgently?) Need to write this diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 1dceba08..9763e441 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -30,9 +30,9 @@ class webqtlTrait: self.cellid = kw.get('cellid', None) self.identification = kw.get('identification', 'un-named trait') self.group = kw.get('group', None) - self.haveinfo = kw.get(haveinfo, False) - self.sequence = kw.get(sequence, None) # Blat sequence, available for ProbeSet - self.data = kw.get(data, {}) + self.haveinfo = kw.get('haveinfo', False) + self.sequence = kw.get('sequence', None) # Blat sequence, available for ProbeSet + self.data = kw.get('data', {}) if kw.get('fullname'): name2 = value.split("::") @@ -381,7 +381,7 @@ class webqtlTrait: # return self.__dict__.items() def retrieveInfo(self, QTL = None): - assert self.dataset and self.cursor + assert self.dataset if self.dataset.type == 'Publish': #self.dataset.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ @@ -434,10 +434,11 @@ class webqtlTrait: Geno.Name = '%s' """ % (display_fields_string, self.dataset.name, self.name) else: #Temp type - query = 'SELECT %s FROM %s WHERE Name = "%s"' % \ - (string.join(self.dataset.display_fields,','), self.dataset.type, self.name) - + traitInfo = g.db.execute("""SELECT %s FROM %s WHERE Name = '%s' + """, (string.join(self.dataset.display_fields,','), + self.dataset.type, self.name)).fetchone() + self.cursor.execute(query) traitInfo = self.cursor.fetchone() if traitInfo: diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index bae3df08..802cbea5 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -3,6 +3,9 @@ from __future__ import print_function, division +from flask import Flask, g + +from MySQLdb import escape_string as escape from pprint import pformat as pf import sys @@ -34,13 +37,13 @@ class DoSearch(object): """Executes query and returns results""" query = self.normalize_spaces(query) print("in do_search query is:", pf(query)) - self.cursor.execute(query) + g.db.execute(query) results = self.cursor.fetchall() return results def escape(self, stringy): """Shorter name than self.db_conn.escape_string""" - return self.db_conn.escape_string(str(stringy)) + return escape(str(stringy)) def mescape(self, *items): """Multiple escape""" @@ -153,7 +156,7 @@ class PhenotypeSearch(DoSearch): 'Max LRS', 'Max LRS Location'] - def get_where_clause(self): + def get_fields_clause(self): """Generate clause for WHERE portion of query""" #Todo: Zach will figure out exactly what both these lines mean @@ -163,15 +166,17 @@ class PhenotypeSearch(DoSearch): # This adds a clause to the query that matches the search term # against each field in the search_fields tuple - where_clause = [] + fields_clause = [] for field in self.search_fields: - where_clause.append('''%s REGEXP "%s"''' % (field, search_term)) - where_clause = "(%s)" % ' OR '.join(where_clause) + fields_clause.append('''%s REGEXP "%s"''' % (field, search_term)) + fields_clause = "(%s)" % ' OR '.join(fields_clause) - return where_clause + return fields_clause - def run(self): - """Generates and runs a simple search of a phenotype dataset""" + def compile_final_query(self, from_clause = '', where_clause = ''): + """Generates the final query string""" + + from_clause = self.normalize_spaces(from_clause) #Get group information for dataset self.dataset.get_group() @@ -182,12 +187,42 @@ class PhenotypeSearch(DoSearch): PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %s""" % ( - self.get_where_clause(), + self.get_fields_clause(), self.escape(self.dataset.group_id), self.escape(self.dataset.id))) - return self.execute(query) + print("query is:", pf(query)) + return query + + def run(self): + """Generates and runs a simple search of a phenotype dataset""" + + self.query = self.compile_final_query(where_clause = self.get_fields_clause()) + +# self.query = """SELECT PublishXRef.Id, +#PublishFreeze.createtime as thistable, +#Publication.PubMed_ID as Publication_PubMed_ID, +#Phenotype.Post_publication_description as Phenotype_Name FROM Phenotype, +#PublishFreeze, Publication, PublishXRef WHERE (Phenotype.Post_publication_description +#REGEXP "[[:<:]]brain[[:>:]]" OR Phenotype.Pre_publication_description REGEXP "[[:<:]]brain[[:>:]]" +#OR Phenotype.Pre_publication_abbreviation REGEXP "[[:<:]]brain[[:>:]]" +#OR Phenotype.Post_publication_abbreviation REGEXP "[[:<:]]brain[[:>:]]" +#OR Phenotype.Lab_code REGEXP "[[:<:]]brain[[:>:]]" +#OR Publication.PubMed_ID REGEXP "[[:<:]]brain[[:>:]]" +#OR Publication.Abstract REGEXP "[[:<:]]brain[[:>:]]" +#OR Publication.Title REGEXP "[[:<:]]brain[[:>:]]" +#OR Publication.Authors REGEXP "[[:<:]]brain[[:>:]]" +#OR PublishXRef.Id REGEXP "[[:<:]]brain[[:>:]]") +#and PublishXRef.InbredSetId = 1 +#and PublishXRef.PhenotypeId = Phenotype.Id +#and PublishXRef.PublicationId = Publication.Id +#and PublishFreeze.Id = 1;""" + + + results = g.db.execute(self.query, no_parameters=True).fetchall() + print("in [df] run results are:", results) + return results class GenotypeSearch(DoSearch): """A search within a genotype dataset""" @@ -606,6 +641,22 @@ class PvalueSearch(ProbeSetSearch): return self.execute(self.query) +class AuthorSearch(PhenotypeSearch): + """Searches for phenotype traits with specified author(s)""" + + DoSearch.search_types["NAME"] = "AuthorSearch" + + def run(self): + + self.search_term = [float(value) for value in self.search_term] + + self.where_clause = """ Publication.Authors LIKE %s and + """ % (self.escape(self.search_term[0])) + + self.query = self.compile_final_query(where_clause = self.where_clause) + + return self.execute(self.query) + if __name__ == "__main__": @@ -630,20 +681,20 @@ if __name__ == "__main__": dataset_name = "HC_M2_0606_P" dataset = create_dataset(db_conn, dataset_name) - cursor.execute(""" - SELECT ProbeSet.Name as TNAME, 0 as thistable, - ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS, - ProbeSetXRef.PVALUE as TPVALUE, ProbeSet.Chr_num as TCHR_NUM, - ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, - ProbeSet.name_num as TNAME_NUM - FROM ProbeSetXRef, ProbeSet, Geno - WHERE ProbeSetXRef.LRS > 99.0 and - ABS(ProbeSet.Mb-Geno.Mb) < 5 and - ProbeSetXRef.Locus = Geno.name and - Geno.SpeciesId = 1 and - ProbeSet.Chr = Geno.Chr and - ProbeSet.Id = ProbeSetXRef.ProbeSetId and - ProbeSetXRef.ProbeSetFreezeId = 112""") + #cursor.execute(""" + # SELECT ProbeSet.Name as TNAME, 0 as thistable, + # ProbeSetXRef.Mean as TMEAN, ProbeSetXRef.LRS as TLRS, + # ProbeSetXRef.PVALUE as TPVALUE, ProbeSet.Chr_num as TCHR_NUM, + # ProbeSet.Mb as TMB, ProbeSet.Symbol as TSYMBOL, + # ProbeSet.name_num as TNAME_NUM + # FROM ProbeSetXRef, ProbeSet, Geno + # WHERE ProbeSetXRef.LRS > 99.0 and + # ABS(ProbeSet.Mb-Geno.Mb) < 5 and + # ProbeSetXRef.Locus = Geno.name and + # Geno.SpeciesId = 1 and + # ProbeSet.Chr = Geno.Chr and + # ProbeSet.Id = ProbeSetXRef.ProbeSetId and + # ProbeSetXRef.ProbeSetFreezeId = 112""") #print(pf(cursor.fetchall())) #results = ProbeSetSearch("shh", None, dataset, cursor, db_conn).run() diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 04b14e8f..52f628f6 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -113,7 +113,7 @@ class SearchResultPage(templatePage): print("foo locals are:", locals()) trait_id = result[0] - this_trait = webqtlTrait(self.db_conn, dataset=self.dataset, name=trait_id) + this_trait = webqtlTrait(dataset=self.dataset, name=trait_id) this_trait.retrieveInfo(QTL=True) self.trait_list.append(this_trait) -- cgit v1.2.3 From 01785471d63de156fa9787a0fb38c9df09824183 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 4 Dec 2012 18:08:09 -0600 Subject: Changed parser to allow quotes (i.e. name="rw williams") Renamed webqtlTrait to GeneralTrait and began rewriting parts Changed database code in many places to use simple sqlalchemy --- wqflask/base/data_set.py | 18 ++- wqflask/base/webqtlTrait.py | 166 +++++++++++++-------------- wqflask/dbFunction/webqtlDatabaseFunction.py | 26 ++--- wqflask/wqflask/do_search.py | 78 ++++++------- wqflask/wqflask/parser.py | 4 +- wqflask/wqflask/search_results.py | 7 +- 6 files changed, 138 insertions(+), 161 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index cd9e810e..7833f5c1 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -68,13 +68,10 @@ class DataSet(object): assert name self.name = name - #self.db_conn = db_conn - #self.cursor = self.db_conn.cursor() self.id = None self.type = None self.group = None - #if self.cursor and self.id == 0: self.setup() self.check_confidentiality() @@ -200,6 +197,7 @@ class PhenotypeDataSet(DataSet): description = this_trait.post_publication_description if this_trait.confidential: + continue # for now if not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): description = this_trait.pre_publication_description this_trait.description_display = description @@ -217,13 +215,13 @@ class PhenotypeDataSet(DataSet): this_trait.LRS_location_value = 1000000 if this_trait.lrs: - self.cursor.execute(""" + result = g.db.execute(""" select Geno.Chr, Geno.Mb from Geno, Species - where Species.Name = '%s' and - Geno.Name = '%s' and + where Species.Name = %s and + Geno.Name = %s and Geno.SpeciesId = Species.Id - """ % (species, this_trait.locus)) - result = self.cursor.fetchone() + """, (species, this_trait.locus)).fetchone() + #result = self.cursor.fetchone() if result: if result[0] and result[1]: @@ -509,13 +507,13 @@ def geno_mrna_confidentiality(ob): query = '''SELECT Id, Name, FullName, confidentiality, AuthorisedUsers FROM %s WHERE Name = %%s''' % (dataset_table) - ob.cursor.execute(query, ob.name) + result = g.db.execute(query, ob.name) (dataset_id, name, full_name, confidential, - authorized_users) = ob.cursor.fetchall()[0] + authorized_users) = result.fetchall()[0] if confidential: # Allow confidential data later diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index 9763e441..dec5fa00 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -14,7 +14,7 @@ from pprint import pformat as pf from flask import Flask, g -class webqtlTrait: +class GeneralTrait: """ Trait class defines a trait in webqtl, can be either Microarray, Published phenotype, genotype, or user input trait @@ -22,9 +22,7 @@ class webqtlTrait: """ def __init__(self, **kw): - print("in webqtlTrait") - #self.db_conn = db_conn - #self.cursor = self.db_conn.cursor() + print("in GeneralTrait") self.dataset = kw.get('dataset', None) # database object self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. self.cellid = kw.get('cellid', None) @@ -41,45 +39,31 @@ class webqtlTrait: elif len(name2) == 3: self.dataset, self.name, self.cellid = name2 - #print("foo") - #print("kw in webqtlTrait are:", pf(kw)) - #print("printed\n\n") - #for name, value in kw.items(): - # if self.__dict__.has_key(name): - # setattr(self, name, value) - # elif name == 'fullname': - # name2 = value.split("::") - # if len(name2) == 2: - # self.dataset, self.name = name2 - # elif len(name2) == 3: - # self.dataset, self.name, self.cellid = name2 - # else: - # raise KeyError, repr(value) + ' parameter format error.' - # else: - # raise KeyError, repr(name) + ' not a valid parameter for this class.' - - if self.dataset and isinstance(self.dataset, basestring): - #assert self.cursor, "Don't have a cursor" - self.dataset = create_dataset(self.dataset) + #if self.dataset and isinstance(self.dataset, basestring): + self.dataset = create_dataset(self.dataset) + + - #if self.dataset == None, not from a database print("self.dataset is:", self.dataset, type(self.dataset)) - if self.dataset: - if self.dataset.type == "Temp": - self.cursor.execute(''' - SELECT - InbredSet.Name - FROM - InbredSet, Temp - WHERE - Temp.InbredSetId = InbredSet.Id AND - Temp.Name = "%s" - ''', self.name) - self.group = self.cursor.fetchone()[0] - else: - self.group = self.dataset.get_group() + #if self.dataset: + + self.dataset.get_group() + + if self.dataset.type == "Temp": + self.cursor.execute(''' + SELECT + InbredSet.Name + FROM + InbredSet, Temp + WHERE + Temp.InbredSetId = InbredSet.Id AND + Temp.Name = "%s" + ''', self.name) + self.group = self.cursor.fetchone()[0] + else: + self.group = self.dataset.get_group() - print("trinity, self.group is:", self.group) + print("trinity, self.group is:", self.group) # # In ProbeSet, there are maybe several annotations match one sequence @@ -93,24 +77,24 @@ class webqtlTrait: # The variable self.sequence should be changed to self.BlatSeq # It also should be changed in other places where it are used. - if self.dataset: - if self.dataset.type == 'ProbeSet': - print("Doing ProbeSet Query") - query = ''' - SELECT - ProbeSet.BlatSeq - FROM - ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - ProbeSet.Name = %s and - ProbeSetFreeze.Name = %s - ''', (self.name, self.dataset.name) - print("query is:", query) - self.cursor.execute(*query) - self.sequence = self.cursor.fetchone()[0] - print("self.sequence is:", self.sequence) + #if self.dataset: + if self.dataset.type == 'ProbeSet': + print("Doing ProbeSet Query") + query = ''' + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and + ProbeSet.Name = %s and + ProbeSetFreeze.Name = %s + ''', (self.name, self.dataset.name) + print("query is:", query) + self.sequence = g.db.execute(*query).fetchone()[0] + #self.sequence = self.cursor.fetchone()[0] + print("self.sequence is:", self.sequence) def getName(self): @@ -380,13 +364,10 @@ class webqtlTrait: #def items(self): # return self.__dict__.items() - def retrieveInfo(self, QTL = None): - assert self.dataset + def retrieve_info(self, QTL=False): + assert self.dataset, "Dataset doesn't exist" if self.dataset.type == 'Publish': - #self.dataset.DisField = ['Name','PubMed_ID','Phenotype','Abbreviation','Authors','Title',\ - # 'Abstract', 'Journal','Volume','Pages','Month','Year','Sequence',\ - # 'Units', 'comments'] - query = ''' + traitInfo = g.db.execute(""" SELECT PublishXRef.Id, Publication.PubMed_ID, Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, @@ -404,43 +385,50 @@ class webqtlTrait: Publication.Id = PublishXRef.PublicationId AND PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND PublishFreeze.Id =%s - ''' % (self.name, self.dataset.id) + """, (self.name, self.dataset.id)).fetchone() #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif self.dataset.type == 'ProbeSet': display_fields_string = ',ProbeSet.'.join(self.dataset.display_fields) display_fields_string = 'ProbeSet.' + display_fields_string - query = """ + traitInfo = g.db.execute(""" SELECT %s FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' - """ % (display_fields_string, self.dataset.name, self.name) + ProbeSetFreeze.Name = %s AND + ProbeSet.Name = %s + """, (display_fields_string, self.dataset.name, self.name)).fetchone() #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif self.dataset.type == 'Geno': display_fields_string = string.join(self.dataset.display_fields,',Geno.') display_fields_string = 'Geno.' + display_fields_string - query = """ + traitInfo = g.db.execute(""" SELECT %s FROM Geno, GenoFreeze, GenoXRef WHERE GenoXRef.GenoFreezeId = GenoFreeze.Id AND GenoXRef.GenoId = Geno.Id AND - GenoFreeze.Name = '%s' AND - Geno.Name = '%s' - """ % (display_fields_string, self.dataset.name, self.name) + GenoFreeze.Name = %s AND + Geno.Name = %s + """, (display_fields_string, self.dataset.name, self.name)).fetchone() else: #Temp type - traitInfo = g.db.execute("""SELECT %s FROM %s WHERE Name = '%s' + traitInfo = g.db.execute("""SELECT %s FROM %s WHERE Name = %s """, (string.join(self.dataset.display_fields,','), self.dataset.type, self.name)).fetchone() + + query = """SELECT %s FROM %s WHERE Name = %s + """ % (string.join(self.dataset.display_fields,','), + self.dataset.type, self.name) + + print("query is:", pf(query)) + print("traitInfo is: ", pf(traitInfo)) - - self.cursor.execute(query) - traitInfo = self.cursor.fetchone() + + #self.cursor.execute(query) + #traitInfo = self.cursor.fetchone() if traitInfo: self.haveinfo = True @@ -465,7 +453,7 @@ class webqtlTrait: geneidIsNumber = 0 if geneidIsNumber: - query = """ + result = g.db.execute(""" SELECT HomologeneId FROM @@ -475,9 +463,9 @@ class webqtlTrait: InbredSet.Name = '%s' AND InbredSet.SpeciesId = Species.Id AND Species.TaxonomyId = Homologene.TaxonomyId - """ % (self.geneid, self.group) - self.cursor.execute(query) - result = self.cursor.fetchone() + """, (self.geneid, self.group)).fetchone() + #self.cursor.execute(query) + #result = self.cursor.fetchone() else: result = None @@ -486,7 +474,7 @@ class webqtlTrait: if QTL: if self.dataset.type == 'ProbeSet' and not self.cellid: - query = ''' + traitQTL = g.db.execute(""" SELECT ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean FROM @@ -495,15 +483,15 @@ class webqtlTrait: ProbeSetXRef.ProbeSetId = ProbeSet.Id AND ProbeSet.Name = "%s" AND ProbeSetXRef.ProbeSetFreezeId =%s - ''' % (self.name, self.dataset.id) - self.cursor.execute(query) - traitQTL = self.cursor.fetchone() + """, (self.name, self.dataset.id)).fetchone() + #self.cursor.execute(query) + #traitQTL = self.cursor.fetchone() if traitQTL: self.locus, self.lrs, self.pvalue, self.mean = traitQTL else: self.locus = self.lrs = self.pvalue = self.mean = "" if self.dataset.type == 'Publish': - query = ''' + traitQTL = g.db.execute(""" SELECT PublishXRef.Locus, PublishXRef.LRS FROM @@ -512,9 +500,9 @@ class webqtlTrait: PublishXRef.Id = %s AND PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND PublishFreeze.Id =%s - ''' % (self.name, self.dataset.id) - self.cursor.execute(query) - traitQTL = self.cursor.fetchone() + """, (self.name, self.dataset.id)).fetchone() + #self.cursor.execute(query) + #traitQTL = self.cursor.fetchone() if traitQTL: self.locus, self.lrs = traitQTL else: diff --git a/wqflask/dbFunction/webqtlDatabaseFunction.py b/wqflask/dbFunction/webqtlDatabaseFunction.py index 1e028ecc..299114b4 100755 --- a/wqflask/dbFunction/webqtlDatabaseFunction.py +++ b/wqflask/dbFunction/webqtlDatabaseFunction.py @@ -21,6 +21,8 @@ # This module is used by GeneNetwork project (www.genenetwork.org) +from flask import Flask, g + import MySQLdb import string from base import webqtlConfig @@ -80,25 +82,15 @@ def getAllSpecies(cursor=None): #function: retrieve specie's name info based on RISet ########################################################################### -def retrieveSpecies(cursor=None, group=None): - try: - cursor.execute("select Species.Name from Species, InbredSet where InbredSet.Name = '%s' and InbredSet.SpeciesId = Species.Id" % group) - return cursor.fetchone()[0] - except: - return None +def retrieve_species(group): + return g.db.execute("""select Species.Name + from Species, InbredSet + where InbredSet.Name = %s and + InbredSet.SpeciesId = Species.Id""", (group)).fetchone()[0] -########################################################################### -#input: cursor, RISet (string) -#output: specie's Id (string), value will be None or else -#function: retrieve specie's Id info based on RISet -########################################################################### +def retrieve_species_id(group): + return g.db.execute("select SpeciesId from InbredSet where Name = %s", (group)).fetchone()[0] -def retrieveSpeciesId(cursor=None, RISet=None): - try: - cursor.execute("select SpeciesId from InbredSet where Name = '%s'" % RISet) - return cursor.fetchone()[0] - except: - return None ########################################################################### # input: cursor diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 802cbea5..2094ed14 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -20,34 +20,32 @@ class DoSearch(object): # Used to translate search phrases into classes search_types = dict() - def __init__(self, search_term, search_operator, dataset, cursor, db_conn): + def __init__(self, search_term, search_operator, dataset): self.search_term = search_term # Make sure search_operator is something we expect assert search_operator in (None, "=", "<", ">", "<=", ">="), "Bad search operator" self.search_operator = search_operator self.dataset = dataset - self.db_conn = db_conn - self.cursor = cursor #Get group information for dataset and the species id self.dataset.get_group() - self.species_id = webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group) + self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group) def execute(self, query): """Executes query and returns results""" query = self.normalize_spaces(query) print("in do_search query is:", pf(query)) - g.db.execute(query) - results = self.cursor.fetchall() + results = g.db.execute(query).fetchall() + #results = self.cursor.fetchall() return results - def escape(self, stringy): - """Shorter name than self.db_conn.escape_string""" - return escape(str(stringy)) + #def escape(self, stringy): + # """Shorter name than self.db_conn.escape_string""" + # return escape(str(stringy)) def mescape(self, *items): """Multiple escape""" - escaped = [self.escape(item) for item in items] + escaped = [escape(item) for item in items] print("escaped is:", escaped) return tuple(escaped) @@ -96,9 +94,9 @@ class ProbeSetSearch(DoSearch): WHERE %s and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(from_clause), + """ % (escape(from_clause), where_clause, - self.escape(self.dataset.id))) + escape(self.dataset.id))) print("query is:", pf(query)) @@ -118,8 +116,8 @@ class ProbeSetSearch(DoSearch): AGAINST ('%s' IN BOOLEAN MODE)) and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSetXRef.ProbeSetFreezeId = %s - """ % (self.escape(self.search_term[0]), - self.escape(self.dataset.id)) + """ % (escape(self.search_term[0]), + escape(str(self.dataset.id))) print("final query is:", pf(query)) @@ -182,14 +180,16 @@ class PhenotypeSearch(DoSearch): self.dataset.get_group() query = (self.base_query + - """WHERE %s and + """%s + WHERE %s PublishXRef.InbredSetId = %s and PublishXRef.PhenotypeId = Phenotype.Id and PublishXRef.PublicationId = Publication.Id and PublishFreeze.Id = %s""" % ( - self.get_fields_clause(), - self.escape(self.dataset.group_id), - self.escape(self.dataset.id))) + from_clause, + where_clause, + escape(str(self.dataset.group_id)), + escape(str(self.dataset.id)))) print("query is:", pf(query)) @@ -272,7 +272,7 @@ class GenotypeSearch(DoSearch): Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and GenoFreeze.Id = %s"""% (where_clause, - self.escape(self.dataset.id))) + escape(self.dataset.id))) print("query is:", pf(query)) @@ -332,7 +332,7 @@ class GoSearch(ProbeSetSearch): statements = ("""%s.symbol=GOgene_product.symbol and GOassociation.gene_product_id=GOgene_product.id and GOterm.id=GOassociation.term_id""" % ( - self.db_conn.escape_string(self.dataset.type))) + escape(self.dataset.type))) where_clause = " %s = '%s' and %s " % (field, go_id, statements) @@ -377,7 +377,7 @@ class LrsSearch(ProbeSetSearch): if len(self.search_term) > 2: self.chr_num = self.search_term[2] - self.sub_clause += """ Geno.Chr = %s and """ % (self.escape(self.chr_num)) + self.sub_clause += """ Geno.Chr = %s and """ % (escape(self.chr_num)) if len(self.search_term) == 5: self.mb_low, self.mb_high = self.search_term[3:] self.sub_clause += """ Geno.Mb > %s and @@ -429,17 +429,17 @@ class CisTransLrsSearch(LrsSearch): self.sub_clause = """ %sXRef.LRS > %s and %sXRef.LRS < %s and """ % ( - self.escape(self.dataset.type), - self.escape(min(self.lrs_min, self.lrs_max)), - self.escape(self.dataset.type), - self.escape(max(self.lrs_min, self.lrs_max)) + escape(self.dataset.type), + escape(min(self.lrs_min, self.lrs_max)), + escape(self.dataset.type), + escape(max(self.lrs_min, self.lrs_max)) ) else: # Deal with >, <, >=, and <= self.sub_clause = """ %sXRef.LRS %s %s and """ % ( - self.escape(self.dataset.type), - self.escape(self.search_operator), - self.escape(self.search_term[0]) + escape(self.dataset.type), + escape(self.search_operator), + escape(self.search_term[0]) ) self.where_clause = self.sub_clause + """ @@ -447,12 +447,12 @@ class CisTransLrsSearch(LrsSearch): %sXRef.Locus = Geno.name and Geno.SpeciesId = %s and %s.Chr = Geno.Chr""" % ( - self.escape(self.dataset.type), + escape(self.dataset.type), the_operator, - self.escape(self.mb_buffer), - self.escape(self.dataset.type), - self.escape(self.species_id), - self.escape(self.dataset.type) + escape(self.mb_buffer), + escape(self.dataset.type), + escape(self.species_id), + escape(self.dataset.type) ) print("where_clause is:", pf(self.where_clause)) @@ -559,7 +559,7 @@ class RangeSearch(ProbeSetSearch): self.where_clause = """ (SELECT Pow(2, max(value) -min(value)) FROM ProbeSetData WHERE ProbeSetData.Id = ProbeSetXRef.dataId) > %s - """ % (self.escape(self.search_term[0])) + """ % (escape(self.search_term[0])) print("where_clause is:", pf(self.where_clause)) @@ -647,16 +647,14 @@ class AuthorSearch(PhenotypeSearch): DoSearch.search_types["NAME"] = "AuthorSearch" def run(self): - - self.search_term = [float(value) for value in self.search_term] - - self.where_clause = """ Publication.Authors LIKE %s and - """ % (self.escape(self.search_term[0])) + + self.where_clause = """ Publication.Authors REGEXP "[[:<:]]%s[[:>:]]" and + """ % (self.search_term[0]) self.query = self.compile_final_query(where_clause = self.where_clause) return self.execute(self.query) - + if __name__ == "__main__": diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index efe479e6..f991d8c7 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -28,7 +28,7 @@ def parse(pstring): returned item serach_term is always a list, even if only one element """ - pstring = re.split(r"""(?:(\w+\s*=\s*[\(\[][^)]*[\)\]]) | # LRS=(1 2 3), cisLRS=[4 5 6], etc + pstring = re.split(r"""(?:(\w+\s*=\s*[\('"\[][^)'"]*[\)\]'"]) | # LRS=(1 2 3), cisLRS=[4 5 6], etc (\w+\s*[=:\>\<][\w\*]+) | # wiki=bar, GO:foobar, etc ([\w\*]+)) # shh, brain, etc """, pstring, flags=re.VERBOSE) @@ -78,6 +78,8 @@ if __name__ == '__main__': parse("WIKI=ho*") parse("LRS>9") parse("LRS>=18") + parse("NAME='rw williams'") + parse('NAME="rw williams"') parse("foo <= 2") parse("cisLRS<20") parse("foo=[3 2 1)") diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 52f628f6..efa1c5cc 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -100,7 +100,7 @@ class SearchResultPage(templatePage): self.trait_list = [] group = self.dataset.group - species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=group) + species = webqtlDatabaseFunction.retrieve_species(group=group) # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term @@ -114,7 +114,7 @@ class SearchResultPage(templatePage): print("foo locals are:", locals()) trait_id = result[0] this_trait = webqtlTrait(dataset=self.dataset, name=trait_id) - this_trait.retrieveInfo(QTL=True) + this_trait.retrieve_info(QTL=True) self.trait_list.append(this_trait) self.dataset.get_trait_info(self.trait_list, species) @@ -147,8 +147,7 @@ class SearchResultPage(templatePage): the_search = search_class(search_term, search_operator, self.dataset, - self.cursor, - self.db_conn) + ) self.results.extend(the_search.run()) print("in the search results are:", self.results) -- cgit v1.2.3 From 292d177f768e8f949bc50f8896b560879aaae178 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 5 Dec 2012 14:33:02 -0600 Subject: Continued to make changes related to getting rid of cursor/db_conn and using simple sqlalchemy Got Pheno/MrnaAssay dataset searches working again --- misc/new_variable_names.txt | 1 + wqflask/base/data_set.py | 9 ++--- wqflask/base/webqtlTrait.py | 46 +++++++++++----------- wqflask/wqflask/correlation/CorrelationPage.py | 2 +- wqflask/wqflask/correlation/correlationFunction.py | 2 +- wqflask/wqflask/do_search.py | 10 ++--- wqflask/wqflask/search_results.py | 4 +- wqflask/wqflask/show_trait/SampleList.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 2 +- 9 files changed, 38 insertions(+), 40 deletions(-) diff --git a/misc/new_variable_names.txt b/misc/new_variable_names.txt index 2b10c07e..c11c160e 100644 --- a/misc/new_variable_names.txt +++ b/misc/new_variable_names.txt @@ -3,3 +3,4 @@ webqtlDataset.py -> data_set.py webqtlDataset (class object) -> DataSet database/db -> dataset/data_set DataEditingPage -> show_trait.py/show_trait.html +webqtlTrait -> GeneralTrait \ No newline at end of file diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 7833f5c1..70b33014 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -272,7 +272,7 @@ class GenotypeDataSet(DataSet): WHERE GenoFreeze.InbredSetId = InbredSet.Id AND GenoFreeze.Name = "%s" - ''' % self.db_conn.escape_string(self.name) + ''' % escape(self.name) def check_confidentiality(self): return geno_mrna_confidentiality(self) @@ -425,13 +425,12 @@ class MrnaAssayDataSet(DataSet): where ProbeSetXRef.ProbeSetFreezeId = %s and ProbeSet.Id = ProbeSetXRef.ProbeSetId and ProbeSet.Name = '%s' - """ % (self.db_conn.escape_string(str(this_trait.dataset.id)), - self.db_conn.escape_string(this_trait.name))) + """ % (escape(str(this_trait.dataset.id)), + escape(this_trait.name))) print("query is:", pf(query)) - self.cursor.execute(query) - result = self.cursor.fetchone() + result = g.db.execute(query).fetchone() if result: if result[0]: diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py index dec5fa00..5367b41f 100755 --- a/wqflask/base/webqtlTrait.py +++ b/wqflask/base/webqtlTrait.py @@ -10,6 +10,7 @@ from data_set import create_dataset from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil +from MySQLdb import escape_string as escape from pprint import pformat as pf from flask import Flask, g @@ -40,9 +41,7 @@ class GeneralTrait: self.dataset, self.name, self.cellid = name2 #if self.dataset and isinstance(self.dataset, basestring): - self.dataset = create_dataset(self.dataset) - - + self.dataset = create_dataset(self.dataset.name) print("self.dataset is:", self.dataset, type(self.dataset)) #if self.dataset: @@ -367,7 +366,7 @@ class GeneralTrait: def retrieve_info(self, QTL=False): assert self.dataset, "Dataset doesn't exist" if self.dataset.type == 'Publish': - traitInfo = g.db.execute(""" + query = """ SELECT PublishXRef.Id, Publication.PubMed_ID, Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, @@ -384,47 +383,46 @@ class GeneralTrait: Phenotype.Id = PublishXRef.PhenotypeId AND Publication.Id = PublishXRef.PublicationId AND PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishFreeze.Id =%s - """, (self.name, self.dataset.id)).fetchone() + PublishFreeze.Id = %s + """ % (self.name, self.dataset.id) + traitInfo = g.db.execute(query).fetchone() #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. elif self.dataset.type == 'ProbeSet': - display_fields_string = ',ProbeSet.'.join(self.dataset.display_fields) + display_fields_string = ', ProbeSet.'.join(self.dataset.display_fields) display_fields_string = 'ProbeSet.' + display_fields_string - traitInfo = g.db.execute(""" + query = """ SELECT %s FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef WHERE ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = %s AND - ProbeSet.Name = %s - """, (display_fields_string, self.dataset.name, self.name)).fetchone() + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' + """ % (display_fields_string, self.dataset.name, self.name) + traitInfo = g.db.execute(query).fetchone() + print("traitInfo is: ", pf(traitInfo)) #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name # to avoid the problem of same marker name from different species. elif self.dataset.type == 'Geno': display_fields_string = string.join(self.dataset.display_fields,',Geno.') display_fields_string = 'Geno.' + display_fields_string - traitInfo = g.db.execute(""" + query = """ SELECT %s FROM Geno, GenoFreeze, GenoXRef WHERE GenoXRef.GenoFreezeId = GenoFreeze.Id AND GenoXRef.GenoId = Geno.Id AND - GenoFreeze.Name = %s AND - Geno.Name = %s - """, (display_fields_string, self.dataset.name, self.name)).fetchone() + GenoFreeze.Name = '%s' AND + Geno.Name = '%s' + """ % (display_fields_string, self.dataset.name, self.name) + traitInfo = g.db.execute(query).fetchone() + print("traitInfo is: ", pf(traitInfo)) else: #Temp type - traitInfo = g.db.execute("""SELECT %s FROM %s WHERE Name = %s - """, (string.join(self.dataset.display_fields,','), - self.dataset.type, self.name)).fetchone() - - query = """SELECT %s FROM %s WHERE Name = %s + query = """SELECT %s FROM %s WHERE Name = %s """ % (string.join(self.dataset.display_fields,','), - self.dataset.type, self.name) - - print("query is:", pf(query)) - print("traitInfo is: ", pf(traitInfo)) + self.dataset.type, self.name) + traitInfo = g.db.execute(query).fetchone() #self.cursor.execute(query) diff --git a/wqflask/wqflask/correlation/CorrelationPage.py b/wqflask/wqflask/correlation/CorrelationPage.py index 8af30d1e..f1dd96ef 100644 --- a/wqflask/wqflask/correlation/CorrelationPage.py +++ b/wqflask/wqflask/correlation/CorrelationPage.py @@ -46,7 +46,7 @@ import reaper from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell -from base.webqtlTrait import webqtlTrait +from base.webqtlTrait import GeneralTrait from base.data_set import create_dataset from base.templatePage import templatePage from utility import webqtlUtil diff --git a/wqflask/wqflask/correlation/correlationFunction.py b/wqflask/wqflask/correlation/correlationFunction.py index 4d62a468..8638cb1e 100644 --- a/wqflask/wqflask/correlation/correlationFunction.py +++ b/wqflask/wqflask/correlation/correlationFunction.py @@ -31,7 +31,7 @@ import pp import string from utility import webqtlUtil -from base.webqtlTrait import webqtlTrait +from base.webqtlTrait import GeneralTrait from dbFunction import webqtlDatabaseFunction diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 2094ed14..4301fb50 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -35,7 +35,7 @@ class DoSearch(object): """Executes query and returns results""" query = self.normalize_spaces(query) print("in do_search query is:", pf(query)) - results = g.db.execute(query).fetchall() + results = g.db.execute(query, no_parameters=True).fetchall() #results = self.cursor.fetchall() return results @@ -167,7 +167,7 @@ class PhenotypeSearch(DoSearch): fields_clause = [] for field in self.search_fields: fields_clause.append('''%s REGEXP "%s"''' % (field, search_term)) - fields_clause = "(%s)" % ' OR '.join(fields_clause) + fields_clause = "(%s) and " % ' OR '.join(fields_clause) return fields_clause @@ -198,7 +198,7 @@ class PhenotypeSearch(DoSearch): def run(self): """Generates and runs a simple search of a phenotype dataset""" - self.query = self.compile_final_query(where_clause = self.get_fields_clause()) + query = self.compile_final_query(where_clause = self.get_fields_clause()) # self.query = """SELECT PublishXRef.Id, #PublishFreeze.createtime as thistable, @@ -220,7 +220,7 @@ class PhenotypeSearch(DoSearch): #and PublishFreeze.Id = 1;""" - results = g.db.execute(self.query, no_parameters=True).fetchall() + results = self.execute(query) print("in [df] run results are:", results) return results @@ -272,7 +272,7 @@ class GenotypeSearch(DoSearch): Geno.Id = GenoXRef.GenoId and GenoXRef.GenoFreezeId = GenoFreeze.Id and GenoFreeze.Id = %s"""% (where_clause, - escape(self.dataset.id))) + escape(str(self.dataset.id)))) print("query is:", pf(query)) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index efa1c5cc..cd478110 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -30,7 +30,7 @@ from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell from base.data_set import create_dataset -from base.webqtlTrait import webqtlTrait +from base.webqtlTrait import GeneralTrait from base.templatePage import templatePage from wqflask import parser from wqflask import do_search @@ -113,7 +113,7 @@ class SearchResultPage(templatePage): print("foo locals are:", locals()) trait_id = result[0] - this_trait = webqtlTrait(dataset=self.dataset, name=trait_id) + this_trait = GeneralTrait(dataset=self.dataset, name=trait_id) this_trait.retrieve_info(QTL=True) self.trait_list.append(this_trait) diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index df0dc61e..25877521 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -2,7 +2,7 @@ from __future__ import absolute_import, print_function, division from base import webqtlCaseData from utility import webqtlUtil, Plot, Bunch -from base.webqtlTrait import webqtlTrait +from base.webqtlTrait import GeneralTrait from pprint import pformat as pf diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 7060f2ea..aef9219f 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -13,7 +13,7 @@ from base import webqtlConfig from base import webqtlCaseData from wqflask.show_trait.SampleList import SampleList from utility import webqtlUtil, Plot, Bunch -from base.webqtlTrait import webqtlTrait +from base.webqtlTrait import GeneralTrait from dbFunction import webqtlDatabaseFunction from base.templatePage import templatePage from basicStatistics import BasicStatisticsFunctions -- cgit v1.2.3 From a7cc1119ebfbfab3ba5260be75c87cd4496f09b7 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 5 Dec 2012 18:03:23 -0600 Subject: Renamed webqtlTrait.py to trait.py Renamed webqtlTrait class to GeneralTrait Began process of removing fd from show_trait.py Created DatasetGroup object in data_set.py (this may end up becoming its own file later if it becomes big enough) --- misc/notes.txt | 10 +- misc/todo.txt | 4 +- wqflask/base/data_set.py | 221 +++++++++- wqflask/base/trait.py | 708 +++++++++++++++++++++++++++++++ wqflask/base/webqtlTrait.py | 695 ------------------------------ wqflask/wqflask/do_search.py | 5 +- wqflask/wqflask/search_results.py | 5 +- wqflask/wqflask/show_trait/show_trait.py | 295 ++++++++----- 8 files changed, 1129 insertions(+), 814 deletions(-) create mode 100755 wqflask/base/trait.py delete mode 100755 wqflask/base/webqtlTrait.py diff --git a/misc/notes.txt b/misc/notes.txt index 59ab79cb..b0c0762c 100644 --- a/misc/notes.txt +++ b/misc/notes.txt @@ -14,6 +14,9 @@ export TERM=screen To search for commands in history if necessary: history | grep "(whatever is being searched for)" +Run web server: +/usr/local/nginx/sbin/nginx + Run server: python runserver.py @@ -63,11 +66,16 @@ Classes should always inherit "object" htop: Gives information on processes, cpu/memory load, etc dstat: Also gives various system information, resource usage, etc df: Reports file system disk space usage - +d =========================================== tidyp - Improves/beautifies html code tidyp -m -i -w 100 index_page.html +=========================================== + +ps -ax - View processes + +kill (process #) diff --git a/misc/todo.txt b/misc/todo.txt index 609e053f..60655a71 100644 --- a/misc/todo.txt +++ b/misc/todo.txt @@ -1 +1,3 @@ -- Read about grep/locate/find \ No newline at end of file +- Check about using trait id instead of trait name in queries in data_set.py + +- Ask Rob about Probe/cellid traits \ No newline at end of file diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 70b33014..68f5e5ed 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -21,12 +21,16 @@ # This module is used by GeneNetwork project (www.genenetwork.org) from __future__ import print_function, division +import os from flask import Flask, g from htmlgen import HTMLgen2 as HT +import reaper + import webqtlConfig +from utility import webqtlUtil from MySQLdb import escape_string as escape from pprint import pformat as pf @@ -57,6 +61,74 @@ def create_dataset(dataset_name): return dataset_class(dataset_name) +class DatasetGroup(object): + """ + Each group has multiple datasets; each species has multiple groups. + + For example, Mouse has multiple groups (BXD, BXA, etc), and each group + has multiple datasets associated with it. + + """ + def __init__(self, dataset): + """This sets self.group and self.group_id""" + self.name, self.group_id = g.db.execute(dataset.query).fetchone() + if self.name == 'BXD300': + self.name = "BXD" + + self.incparentsf1 = False + + + #def read_genotype(self): + # self.read_genotype_file() + # + # if not self.genotype: # Didn'd succeed, so we try method 2 + # self.read_genotype_data() + + def read_genotype_file(self): + '''read genotype from .geno file instead of database''' + #if self.group == 'BXD300': + # self.group = 'BXD' + # + #assert self.group, "self.group needs to be set" + + #genotype_1 is Dataset Object without parents and f1 + #genotype_2 is Dataset Object with parents and f1 (not for intercross) + + self.genotype_1 = reaper.Dataset() + + # reaper barfs on unicode filenames, so here we ensure it's a string + full_filename = str(os.path.join(webqtlConfig.GENODIR, self.name + '.geno')) + self.genotype_1.read(full_filename) + + print("Got to after read") + + try: + # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; + _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.name] + except KeyError: + _f1 = _f12 = _mat = _pat = None + + self.genotype_2 = self.genotype_1 + if self.genotype_1.type == "group" and _mat and _pat: + self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) + + #determine default genotype object + if self.incparentsf1 and self.genotype_1.type != "intercross": + self.genotype = self.genotype_2 + else: + self.incparentsf1 = 0 + self.genotype = self.genotype_1 + + self.samplelist = list(self.genotype.prgy) + self.f1list = [] + self.parlist = [] + + if _f1 and _f12: + self.f1list = [_f1, _f12] + if _mat and _pat: + self.parlist = [_mat, _pat] + + class DataSet(object): """ DataSet class defines a dataset in webqtl, can be either Microarray, @@ -70,27 +142,35 @@ class DataSet(object): self.name = name self.id = None self.type = None - self.group = None self.setup() self.check_confidentiality() self.retrieve_name() - self.get_group() + self.group = DatasetGroup(self) # sets self.group and self.group_id + + + def get_desc(self): + """Gets overridden later, at least for Temp...used by trait's get_given_name""" + return None # Delete this eventually @property def riset(): Weve_Renamed_This_As_Group + + + #@property + #def group(self): + # if not self._group: + # self.get_group() + # + # return self._group + - def get_group(self): - self.group, self.group_id = g.db.execute(self.query).fetchone() - if self.group == 'BXD300': - self.group = "BXD" - #return group def retrieve_name(self): @@ -176,7 +256,7 @@ class PhenotypeDataSet(DataSet): self.type = 'Publish' - self.query = ''' + self.query_for_group = ''' SELECT InbredSet.Name, InbredSet.Id FROM @@ -239,7 +319,29 @@ class PhenotypeDataSet(DataSet): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs - this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb)) + + def retrieve_sample_data(self, trait): + query = """ + SELECT + Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + FROM + (PublishData, Strain, PublishXRef, PublishFreeze) + left join PublishSE on + (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) + left join NStrain on + (NStrain.DataId = PublishData.Id AND + NStrain.StrainId = PublishData.StrainId) + WHERE + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND + PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id + Order BY + Strain.Name + """ % (self.trait.name, self.id) + results = g.db.execute(query).fetchall() + return results + class GenotypeDataSet(DataSet): DS_NAME_MAP['Geno'] = 'GenotypeDataSet' @@ -297,6 +399,26 @@ class GenotypeDataSet(DataSet): this_trait.location_repr = 'Chr%s: %.4f' % (this_trait.chr, float(this_trait.mb) ) this_trait.location_value = trait_location_value + + def retrieve_sample_data(self, trait): + query = """ + SELECT + Strain.Name, GenoData.value, GenoSE.error, GenoData.Id + FROM + (GenoData, GenoFreeze, Strain, Geno, GenoXRef) + left join GenoSE on + (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) + WHERE + Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoFreeze.Name = '%s' AND + GenoXRef.DataId = GenoData.Id AND + GenoData.StrainId = Strain.Id + Order BY + Strain.Name + """ % (webqtlDatabaseFunction.retrieve_species_id(self.group), trait.name, self.name) + results = g.db.execute(query).fetchall() + return results class MrnaAssayDataSet(DataSet): @@ -476,6 +598,42 @@ class MrnaAssayDataSet(DataSet): this_trait.LRS_score_repr = LRS_score_repr = '%3.1f' % this_trait.lrs this_trait.LRS_score_value = LRS_score_value = this_trait.lrs this_trait.LRS_location_repr = LRS_location_repr = 'Chr %s: %.4f Mb' % (LRS_Chr, float(LRS_Mb) ) + + def get_sequence(self): + query = """ + SELECT + ProbeSet.BlatSeq + FROM + ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSet.Id=ProbeSetXRef.ProbeSetId and + ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and + ProbeSet.Name = %s + ProbeSetFreeze.Name = %s + """ % (escape(self.name), escape(self.dataset.name)) + results = g.db.execute(query).fetchone() + + return results[0] + + def retrieve_sample_data(self, trait): + query = """ + SELECT + Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id + FROM + (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) + left join ProbeSetSE on + (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) + WHERE + ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSetXRef.DataId = ProbeSetData.Id AND + ProbeSetData.StrainId = Strain.Id + Order BY + Strain.Name + """ % (escape(trait.name), escape(self.name)) + results = g.db.execute(query).fetchall() + return results class TempDataSet(DataSet): @@ -497,6 +655,51 @@ class TempDataSet(DataSet): self.id = 1 self.fullname = 'Temporary Storage' self.shortname = 'Temp' + + + @staticmethod + def handle_pca(desc): + if 'PCA' in desc: + # Todo: Modernize below lines + desc = desc[desc.rindex(':')+1:].strip() + else: + desc = desc[:desc.index('entered')].strip() + return desc + + def get_desc(self): + g.db.execute('SELECT description FROM Temp WHERE Name=%s', self.name) + desc = g.db.fetchone()[0] + desc = self.handle_pca(desc) + return desc + + def get_group(self): + self.cursor.execute(""" + SELECT + InbredSet.Name, InbredSet.Id + FROM + InbredSet, Temp + WHERE + Temp.InbredSetId = InbredSet.Id AND + Temp.Name = "%s" + """, self.name) + self.group, self.group_id = self.cursor.fetchone() + #return self.group + + def retrieve_sample_data(self, trait): + query = """ + SELECT + Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id + FROM + TempData, Temp, Strain + WHERE + TempData.StrainId = Strain.Id AND + TempData.Id = Temp.DataId AND + Temp.name = '%s' + Order BY + Strain.Name + """ % escape(trait.name) + + results = g.db.execute(query).fetchall() def geno_mrna_confidentiality(ob): diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py new file mode 100755 index 00000000..d3753fc1 --- /dev/null +++ b/wqflask/base/trait.py @@ -0,0 +1,708 @@ +from __future__ import division, print_function + +import string + +from htmlgen import HTMLgen2 as HT + +import webqtlConfig +from webqtlCaseData import webqtlCaseData +from data_set import create_dataset +from dbFunction import webqtlDatabaseFunction +from utility import webqtlUtil + +from MySQLdb import escape_string as escape +from pprint import pformat as pf + +from flask import Flask, g + +class GeneralTrait: + """ + Trait class defines a trait in webqtl, can be either Microarray, + Published phenotype, genotype, or user input trait + + """ + + def __init__(self, **kw): + print("in GeneralTrait") + self.dataset = kw.get('dataset', None) # database object + self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. + self.cellid = kw.get('cellid', None) + self.identification = kw.get('identification', 'un-named trait') + #self.group = kw.get('group', None) + self.haveinfo = kw.get('haveinfo', False) + self.sequence = kw.get('sequence', None) # Blat sequence, available for ProbeSet + self.data = kw.get('data', {}) + + if kw.get('fullname'): + name2 = value.split("::") + if len(name2) == 2: + self.dataset, self.name = name2 + elif len(name2) == 3: + self.dataset, self.name, self.cellid = name2 + + #if self.dataset and isinstance(self.dataset, basestring): + self.dataset = create_dataset(self.dataset) + + print("self.dataset is:", self.dataset, type(self.dataset)) + #if self.dataset: + + #self.dataset.get_group() + + #if self.dataset.type == "Temp": + # self.cursor.execute(''' + # SELECT + # InbredSet.Name + # FROM + # InbredSet, Temp + # WHERE + # Temp.InbredSetId = InbredSet.Id AND + # Temp.Name = "%s" + # ''', self.name) + # self.group = self.cursor.fetchone()[0] + #else: + # self.group = self.dataset.get_group() + + #print("trinity, self.group is:", self.group) + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + + #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. + # The variable self.sequence should be changed to self.BlatSeq + # It also should be changed in other places where it are used. + + #if self.dataset: + #if self.dataset.type == 'ProbeSet': + # print("Doing ProbeSet Query") + # query = ''' + # SELECT + # ProbeSet.BlatSeq + # FROM + # ProbeSet, ProbeSetFreeze, ProbeSetXRef + # WHERE + # ProbeSet.Id=ProbeSetXRef.ProbeSetId and + # ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and + # ProbeSet.Name = %s and + # ProbeSetFreeze.Name = %s + # ''', (self.name, self.dataset.name) + # print("query is:", query) + # self.sequence = g.db.execute(*query).fetchone()[0] + # #self.sequence = self.cursor.fetchone()[0] + # print("self.sequence is:", self.sequence) + + + def get_name(self): + stringy = "" + if self.dataset and self.name: + stringy = "%s::%s" % (self.dataset, self.name) + if self.cellid: + stringy += "::" + self.cellid + else: + stringy = self.description + return stringy + + + def get_given_name(self): + """ + when user enter a trait or GN generate a trait, user want show the name + not the name that generated by GN randomly, the two follow function are + used to give the real name and the database. displayName() will show the + database also, getGivenName() just show the name. + For other trait, displayName() as same as getName(), getGivenName() as + same as self.name + + Hongqiang 11/29/07 + + """ + stringy = self.name + if self.dataset and self.name: + desc = self.dataset.get_desc() + if desc: + #desc = self.handle_pca(desc) + stringy = desc + return stringy + + + + def display_name(self): + stringy = "" + if self.dataset and self.name: + desc = self.dataset.get_desc() + #desc = self.handle_pca(desc) + if desc: + #desc = self.handle_pca(desc) + #stringy = desc + #if desc.__contains__('PCA'): + # desc = desc[desc.rindex(':')+1:].strip() + #else: + # desc = desc[:desc.index('entered')].strip() + #desc = self.handle_pca(desc) + stringy = "%s::%s" % (self.dataset, desc) + else: + stringy = "%s::%s" % (self.dataset, self.name) + if self.cellid: + stringy += "::" + self.cellid + else: + stringy = self.description + + return stringy + + + #def __str__(self): + # #return "%s %s" % (self.getName(), self.group) + # return self.getName() + #__str__ = getName + #__repr__ = __str__ + + def export_data(self, samplelist, the_type="val"): + """ + export data according to samplelist + mostly used in calculating correlation + + """ + result = [] + for sample in samplelist: + if self.data.has_key(sample): + if the_type=='val': + result.append(self.data[sample].val) + elif the_type=='var': + result.append(self.data[sample].var) + elif the_type=='N': + result.append(self.data[sample].N) + else: + raise KeyError, `the_type`+' the_type is incorrect.' + else: + result.append(None) + return result + + def export_informative(self, incVar=0): + """ + export informative sample + mostly used in qtl regression + + """ + samples = [] + vals = [] + the_vars = [] + for sample, value in self.data.items(): + if value.val != None: + if not incVar or value.var != None: + samples.append(sample) + vals.append(value.val) + the_vars.append(value.var) + return samples, vals, the_vars + + + # + # In ProbeSet, there are maybe several annotations match one sequence + # so we need use sequence(BlatSeq) as the identification, when we update + # one annotation, we update the others who match the sequence also. + # + # Hongqiang Li, 3/3/2008 + # + #def getSequence(self): + # assert self.cursor + # if self.dataset.type == 'ProbeSet': + # self.cursor.execute(''' + # SELECT + # ProbeSet.BlatSeq + # FROM + # ProbeSet, ProbeSetFreeze, ProbeSetXRef + # WHERE + # ProbeSet.Id=ProbeSetXRef.ProbeSetId and + # ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and + # ProbeSet.Name = %s + # ProbeSetFreeze.Name = %s + # ''', self.name, self.dataset.name) + # #self.cursor.execute(query) + # results = self.fetchone() + # + # return results[0] + + + + def retrieve_sample_data(self, samplelist=None): + if samplelist == None: + samplelist = [] + + assert self.dataset + + #if self.cellid: + # #Probe Data + # query = ''' + # SELECT + # Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id + # FROM + # (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, + # Strain, Probe, ProbeSet) + # left join ProbeSE on + # (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) + # WHERE + # Probe.Name = '%s' AND ProbeSet.Name = '%s' AND + # Probe.ProbeSetId = ProbeSet.Id AND + # ProbeXRef.ProbeId = Probe.Id AND + # ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND + # ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND + # ProbeSetFreeze.Name = '%s' AND + # ProbeXRef.DataId = ProbeData.Id AND + # ProbeData.StrainId = Strain.Id + # Order BY + # Strain.Name + # ''' % (self.cellid, self.name, self.dataset.name) + # + #else: + results = self.dataset.retrieve_sample_data(self) + + #if self.dataset.type == 'Temp': + # query = ''' + # SELECT + # Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id + # FROM + # TempData, Temp, Strain + # WHERE + # TempData.StrainId = Strain.Id AND + # TempData.Id = Temp.DataId AND + # Temp.name = '%s' + # Order BY + # Strain.Name + # ''' % self.name + ##XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE + #elif self.dataset.type == 'Publish': + # query = ''' + # SELECT + # Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + # FROM + # (PublishData, Strain, PublishXRef, PublishFreeze) + # left join PublishSE on + # (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) + # left join NStrain on + # (NStrain.DataId = PublishData.Id AND + # NStrain.StrainId = PublishData.StrainId) + # WHERE + # PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + # PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND + # PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id + # Order BY + # Strain.Name + # ''' % (self.name, self.dataset.id) + + #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE + #elif self.cellid: + + #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE + #elif self.dataset.type == 'ProbeSet': + # #ProbeSet Data + # query = ''' + # SELECT + # Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id + # FROM + # (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) + # left join ProbeSetSE on + # (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) + # WHERE + # ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + # ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + # ProbeSetFreeze.Name = '%s' AND + # ProbeSetXRef.DataId = ProbeSetData.Id AND + # ProbeSetData.StrainId = Strain.Id + # Order BY + # Strain.Name + # ''' % (self.name, self.dataset.name) + ##XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE + #else: + # #Geno Data + # #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. + # query = ''' + # SELECT + # Strain.Name, GenoData.value, GenoSE.error, GenoData.Id + # FROM + # (GenoData, GenoFreeze, Strain, Geno, GenoXRef) + # left join GenoSE on + # (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) + # WHERE + # Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND + # GenoXRef.GenoFreezeId = GenoFreeze.Id AND + # GenoFreeze.Name = '%s' AND + # GenoXRef.DataId = GenoData.Id AND + # GenoData.StrainId = Strain.Id + # Order BY + # Strain.Name + # ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group), self.name, self.dataset.name) + + + #self.cursor.execute(query) + #results = self.cursor.fetchall() + + # Todo: is this necessary? If not remove + self.data.clear() + + if results: + #self.mysqlid = results[0][-1] + #if samplelist: + for item in results: + #name, value, variance, num_cases = item + if not samplelist or (samplelist and name in samplelist): + #if value != None: + # num_cases = None + # if self.dataset.type in ('Publish', 'Temp'): + # ndata = item[3] + name = item[0] + self.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) + #end for + # else: + # for item in results: + # val = item[1] + # if val != None: + # var = item[2] + # ndata = None + # if self.dataset.type in ('Publish', 'Temp'): + # ndata = item[3] + # self.data[item[0]] = webqtlCaseData(val, var, ndata) + # #end for + # #end if + + #def keys(self): + # return self.__dict__.keys() + # + #def has_key(self, key): + # return self.__dict__.has_key(key) + # + #def items(self): + # return self.__dict__.items() + + def retrieve_info(self, QTL=False): + assert self.dataset, "Dataset doesn't exist" + if self.dataset.type == 'Publish': + query = """ + SELECT + PublishXRef.Id, Publication.PubMed_ID, + Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, + Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, + Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, + Publication.Authors, Publication.Title, Publication.Abstract, + Publication.Journal, Publication.Volume, Publication.Pages, + Publication.Month, Publication.Year, PublishXRef.Sequence, + Phenotype.Units, PublishXRef.comments + FROM + PublishXRef, Publication, Phenotype, PublishFreeze + WHERE + PublishXRef.Id = %s AND + Phenotype.Id = PublishXRef.PhenotypeId AND + Publication.Id = PublishXRef.PublicationId AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id = %s + """ % (self.name, self.dataset.id) + traitInfo = g.db.execute(query).fetchone() + #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name + #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. + elif self.dataset.type == 'ProbeSet': + display_fields_string = ', ProbeSet.'.join(self.dataset.display_fields) + display_fields_string = 'ProbeSet.' + display_fields_string + query = """ + SELECT %s + FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef + WHERE + ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSetFreeze.Name = '%s' AND + ProbeSet.Name = '%s' + """ % (escape(display_fields_string), + escape(self.dataset.name), + escape(self.name)) + traitInfo = g.db.execute(query).fetchone() + print("traitInfo is: ", pf(traitInfo)) + #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name + # to avoid the problem of same marker name from different species. + elif self.dataset.type == 'Geno': + display_fields_string = string.join(self.dataset.display_fields,',Geno.') + display_fields_string = 'Geno.' + display_fields_string + query = """ + SELECT %s + FROM Geno, GenoFreeze, GenoXRef + WHERE + GenoXRef.GenoFreezeId = GenoFreeze.Id AND + GenoXRef.GenoId = Geno.Id AND + GenoFreeze.Name = '%s' AND + Geno.Name = '%s' + """ % (escape(display_fields_string), escape(self.dataset.name), escape(self.name)) + traitInfo = g.db.execute(query).fetchone() + print("traitInfo is: ", pf(traitInfo)) + else: #Temp type + query = """SELECT %s FROM %s WHERE Name = %s + """ % (string.join(self.dataset.display_fields,','), + self.dataset.type, self.name) + traitInfo = g.db.execute(query).fetchone() + + + #self.cursor.execute(query) + #traitInfo = self.cursor.fetchone() + if traitInfo: + self.haveinfo = True + + #XZ: assign SQL query result to trait attributes. + for i, field in enumerate(self.dataset.display_fields): + setattr(self, field, traitInfo[i]) + + if self.dataset.type == 'Publish': + self.confidential = 0 + if self.pre_publication_description and not self.pubmed_id: + self.confidential = 1 + + self.homologeneid = None + if self.dataset.type == 'ProbeSet' and self.dataset.group and self.geneid: + #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. + #XZ: So I have to test if geneid is number before execute the query. + #XZ: The geneid values in database should be cleaned up. + try: + junk = float(self.geneid) + geneidIsNumber = 1 + except: + geneidIsNumber = 0 + + if geneidIsNumber: + query = """ + SELECT + HomologeneId + FROM + Homologene, Species, InbredSet + WHERE + Homologene.GeneId =%s AND + InbredSet.Name = '%s' AND + InbredSet.SpeciesId = Species.Id AND + Species.TaxonomyId = Homologene.TaxonomyId + """ % (escape(str(self.geneid)), escape(self.dataset.group.name)) + result = g.db.execute(query).fetchone() + else: + result = None + + if result: + self.homologeneid = result[0] + + if QTL: + if self.dataset.type == 'ProbeSet' and not self.cellid: + traitQTL = g.db.execute(""" + SELECT + ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean + FROM + ProbeSetXRef, ProbeSet + WHERE + ProbeSetXRef.ProbeSetId = ProbeSet.Id AND + ProbeSet.Name = "%s" AND + ProbeSetXRef.ProbeSetFreezeId =%s + """, (self.name, self.dataset.id)).fetchone() + #self.cursor.execute(query) + #traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs, self.pvalue, self.mean = traitQTL + else: + self.locus = self.lrs = self.pvalue = self.mean = "" + if self.dataset.type == 'Publish': + traitQTL = g.db.execute(""" + SELECT + PublishXRef.Locus, PublishXRef.LRS + FROM + PublishXRef, PublishFreeze + WHERE + PublishXRef.Id = %s AND + PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND + PublishFreeze.Id =%s + """, (self.name, self.dataset.id)).fetchone() + #self.cursor.execute(query) + #traitQTL = self.cursor.fetchone() + if traitQTL: + self.locus, self.lrs = traitQTL + else: + self.locus = self.lrs = "" + else: + raise KeyError, `self.name`+' information is not found in the database.' + + def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): + if not self.haveinfo: + self.retrieveInfo() + + if self.dataset.type == 'Publish': + PubMedLink = "" + if self.pubmed_id: + PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, + target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) + else: + PubMedLink = HT.Span("Unpublished : ", Class="fs15") + + if formName: + setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % + (formName, self.dataset.name, self.name), Class = "fs14") + else: + setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % + (self.dataset.name,self.name), Class = "fs14") + + if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): + setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) + else: + setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description)) + + #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1. + #if self.sequence > 1: + # setDescription2.append(' btach %d' % self.sequence) + if self.authors: + a1 = string.split(self.authors,',')[0] + while a1[0] == '"' or a1[0] == "'" : + a1 = a1[1:] + setDescription2.append(' by ') + setDescription2.append(HT.Italic('%s, and colleagues' % a1)) + setDescription = HT.Span(PubMedLink, setDescription2) + + elif self.dataset.type == 'Temp': + setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ + ('%s','%s','')" % (self.dataset.name,self.name), Class = "fs14") + setDescription = HT.Span(setDescription) + + elif self.dataset.type == 'Geno': # Genome DB only available for single search + if formName: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ + (formName, self.dataset.name, self.name), Class = "fs14") + else: + setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ + '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ + (self.dataset.name,self.name), Class = "fs14") + + setDescription = HT.Span(setDescription) + + else: + if self.cellid: + if formName: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ + "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.dataset.name,self.name,self.cellid), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ + "javascript:showDatabase2('%s','%s','%s')" % (self.dataset.name,self.name,self.cellid), \ + Class = "fs14") + else: + if formName: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.dataset.name,self.name), \ + Class = "fs14") + else: + setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ + "javascript:showDatabase2('%s','%s','')" % (self.dataset.name,self.name), \ + Class = "fs14") + if self.symbol and self.chr and self.mb: + setDescription.append(' [') + setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb")) + setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb)) + if self.description: + setDescription.append(': %s' % self.description) + if self.probe_target_description: + setDescription.append('; %s' % self.probe_target_description) + setDescription = HT.Span(setDescription) + + if self.dataset.type != 'Temp' and dispFromDatabase: + setDescription.append( ' --- FROM : ') + setDescription.append(self.dataset.genHTML(Class='cori')) + return setDescription + + @property + def description_fmt(self): + '''Return a text formated description''' + if self.description: + formatted = self.description + if self.probe_target_description: + formatted += "; " + self.probe_target_description + else: + formatted = "Not available" + return formatted.capitalize() + + @property + def alias_fmt(self): + '''Return a text formatted alias''' + if self.alias: + alias = string.replace(self.alias, ";", " ") + alias = string.join(string.split(alias), ", ") + return alias + + + @property + def location_fmt(self): + '''Return a text formatted location + + While we're at it we set self.location in case we need it later (do we?) + + ''' + + if self.chr and self.mb: + self.location = 'Chr %s @ %s Mb' % (self.chr,self.mb) + elif self.chr: + self.location = 'Chr %s @ Unknown position' % (self.chr) + else: + self.location = 'Not available' + + fmt = self.location + ##XZ: deal with direction + if self.strand_probe == '+': + fmt += (' on the plus strand ') + elif self.strand_probe == '-': + fmt += (' on the minus strand ') + + return fmt + + + def get_database(self): + """ + Returns the database, and the url referring to the database if it exists + + We're going to to return two values here, and we don't want to have to call this twice from + the template. So it's not a property called from the template, but instead is called from the view + + """ + if self.cellid: + self.cursor.execute(""" + select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze + where + ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND + ProbeSetFreeze.Id = %d""" % thisTrait.dataset.id) + probeDBName = self.cursor.fetchone()[0] + return dict(name = probeDBName, + url = None) + else: + return dict(name = self.dataset.fullname, + url = webqtlConfig.INFOPAGEHREF % self.dataset.name) + + def calculate_correlation(self, values, method): + """Calculate the correlation value and p value according to the method specified""" + + #ZS: This takes the list of values of the trait our selected trait is being correlated against and removes the values of the samples our trait has no value for + #There's probably a better way of dealing with this, but I'll have to ask Christian + updated_raw_values = [] + updated_values = [] + for i in range(len(values)): + if values[i] != "None": + updated_raw_values.append(self.raw_values[i]) + updated_values.append(values[i]) + + self.raw_values = updated_raw_values + values = updated_values + + if method == METHOD_SAMPLE_PEARSON or method == METHOD_LIT or method == METHOD_TISSUE_PEARSON: + corr, nOverlap = webqtlUtil.calCorrelation(self.raw_values, values, len(values)) + else: + corr, nOverlap = webqtlUtil.calCorrelationRank(self.raw_values, values, len(values)) + + self.correlation = corr + self.overlap = nOverlap + + if self.overlap < 3: + self.p_value = 1.0 + else: + #ZS - This is probably the wrong way to deal with this. Correlation values of 1.0 definitely exist (the trait correlated against itself), so zero division needs to br prevented. + if abs(self.correlation) >= 1.0: + self.p_value = 0.0 + else: + ZValue = 0.5*log((1.0+self.correlation)/(1.0-self.correlation)) + ZValue = ZValue*sqrt(self.overlap-3) + self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue))) diff --git a/wqflask/base/webqtlTrait.py b/wqflask/base/webqtlTrait.py deleted file mode 100755 index 5367b41f..00000000 --- a/wqflask/base/webqtlTrait.py +++ /dev/null @@ -1,695 +0,0 @@ -from __future__ import division, print_function - -import string - -from htmlgen import HTMLgen2 as HT - -import webqtlConfig -from webqtlCaseData import webqtlCaseData -from data_set import create_dataset -from dbFunction import webqtlDatabaseFunction -from utility import webqtlUtil - -from MySQLdb import escape_string as escape -from pprint import pformat as pf - -from flask import Flask, g - -class GeneralTrait: - """ - Trait class defines a trait in webqtl, can be either Microarray, - Published phenotype, genotype, or user input trait - - """ - - def __init__(self, **kw): - print("in GeneralTrait") - self.dataset = kw.get('dataset', None) # database object - self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. - self.cellid = kw.get('cellid', None) - self.identification = kw.get('identification', 'un-named trait') - self.group = kw.get('group', None) - self.haveinfo = kw.get('haveinfo', False) - self.sequence = kw.get('sequence', None) # Blat sequence, available for ProbeSet - self.data = kw.get('data', {}) - - if kw.get('fullname'): - name2 = value.split("::") - if len(name2) == 2: - self.dataset, self.name = name2 - elif len(name2) == 3: - self.dataset, self.name, self.cellid = name2 - - #if self.dataset and isinstance(self.dataset, basestring): - self.dataset = create_dataset(self.dataset.name) - - print("self.dataset is:", self.dataset, type(self.dataset)) - #if self.dataset: - - self.dataset.get_group() - - if self.dataset.type == "Temp": - self.cursor.execute(''' - SELECT - InbredSet.Name - FROM - InbredSet, Temp - WHERE - Temp.InbredSetId = InbredSet.Id AND - Temp.Name = "%s" - ''', self.name) - self.group = self.cursor.fetchone()[0] - else: - self.group = self.dataset.get_group() - - print("trinity, self.group is:", self.group) - - # - # In ProbeSet, there are maybe several annotations match one sequence - # so we need use sequence(BlatSeq) as the identification, when we update - # one annotation, we update the others who match the sequence also. - # - # Hongqiang Li, 3/3/2008 - # - - #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. - # The variable self.sequence should be changed to self.BlatSeq - # It also should be changed in other places where it are used. - - #if self.dataset: - if self.dataset.type == 'ProbeSet': - print("Doing ProbeSet Query") - query = ''' - SELECT - ProbeSet.BlatSeq - FROM - ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - ProbeSet.Name = %s and - ProbeSetFreeze.Name = %s - ''', (self.name, self.dataset.name) - print("query is:", query) - self.sequence = g.db.execute(*query).fetchone()[0] - #self.sequence = self.cursor.fetchone()[0] - print("self.sequence is:", self.sequence) - - - def getName(self): - str = "" - if self.dataset and self.name: - str = "%s::%s" % (self.dataset, self.name) - if self.cellid: - str += "::" + self.cellid - else: - str = self.description - return str - - # - # when user enter a trait or GN generate a trait, user want show the name - # not the name that generated by GN randomly, the two follow function are - # used to give the real name and the database. displayName() will show the - # database also, getGivenName() just show the name. - # For other trait, displayName() as same as getName(), getGivenName() as - # same as self.name - # - # Hongqiang 11/29/07 - # - def getGivenName(self): - str = self.name - if self.dataset and self.name: - if self.dataset.type=='Temp': - self.cursor.execute('SELECT description FROM Temp WHERE Name=%s', self.name) - desc = self.cursor.fetchone()[0] - if desc.__contains__('PCA'): - desc = desc[desc.rindex(':')+1:].strip() - else: - desc = desc[:desc.index('entered')].strip() - str = desc - return str - - def displayName(self): - str = "" - if self.dataset and self.name: - if self.dataset.type=='Temp': - desc = self.description - if desc.__contains__('PCA'): - desc = desc[desc.rindex(':')+1:].strip() - else: - desc = desc[:desc.index('entered')].strip() - str = "%s::%s" % (self.dataset, desc) - else: - str = "%s::%s" % (self.dataset, self.name) - if self.cellid: - str += "::" + self.cellid - else: - str = self.description - - return str - - - #def __str__(self): - # #return "%s %s" % (self.getName(), self.group) - # return self.getName() - #__str__ = getName - #__repr__ = __str__ - - def exportData(self, samplelist, type="val"): - """ - export data according to samplelist - mostly used in calculating correlation - """ - result = [] - for sample in samplelist: - if self.data.has_key(sample): - if type=='val': - result.append(self.data[sample].val) - elif type=='var': - result.append(self.data[sample].var) - elif type=='N': - result.append(self.data[sample].N) - else: - raise KeyError, `type`+' type is incorrect.' - else: - result.append(None) - return result - - def exportInformative(self, incVar=0): - """ - export informative sample - mostly used in qtl regression - """ - samples = [] - vals = [] - vars = [] - for sample, value in self.data.items(): - if value.val != None: - if not incVar or value.var != None: - samples.append(sample) - vals.append(value.val) - vars.append(value.var) - return samples, vals, vars - - - # - # In ProbeSet, there are maybe several annotations match one sequence - # so we need use sequence(BlatSeq) as the identification, when we update - # one annotation, we update the others who match the sequence also. - # - # Hongqiang Li, 3/3/2008 - # - def getSequence(self): - assert self.cursor - if self.dataset.type == 'ProbeSet': - self.cursor.execute(''' - SELECT - ProbeSet.BlatSeq - FROM - ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSet.Id=ProbeSetXRef.ProbeSetId and - ProbeSetFreeze.Id = ProbeSetXRef.ProbSetFreezeId and - ProbeSet.Name = %s - ProbeSetFreeze.Name = %s - ''', self.name, self.dataset.name) - #self.cursor.execute(query) - results = self.fetchone() - - return results[0] - - - - def retrieveData(self, samplelist=None): - - if samplelist == None: - samplelist = [] - assert self.dataset and self.cursor - - if self.dataset.type == 'Temp': - query = ''' - SELECT - Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id - FROM - TempData, Temp, Strain - WHERE - TempData.StrainId = Strain.Id AND - TempData.Id = Temp.DataId AND - Temp.name = '%s' - Order BY - Strain.Name - ''' % self.name - #XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE - elif self.dataset.type == 'Publish': - query = ''' - SELECT - Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id - FROM - (PublishData, Strain, PublishXRef, PublishFreeze) - left join PublishSE on - (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) - left join NStrain on - (NStrain.DataId = PublishData.Id AND - NStrain.StrainId = PublishData.StrainId) - WHERE - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND - PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.name, self.dataset.id) - - #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE - elif self.cellid: - #Probe Data - query = ''' - SELECT - Strain.Name, ProbeData.value, ProbeSE.error, ProbeData.Id - FROM - (ProbeData, ProbeFreeze, ProbeSetFreeze, ProbeXRef, - Strain, Probe, ProbeSet) - left join ProbeSE on - (ProbeSE.DataId = ProbeData.Id AND ProbeSE.StrainId = ProbeData.StrainId) - WHERE - Probe.Name = '%s' AND ProbeSet.Name = '%s' AND - Probe.ProbeSetId = ProbeSet.Id AND - ProbeXRef.ProbeId = Probe.Id AND - ProbeXRef.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeXRef.DataId = ProbeData.Id AND - ProbeData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.cellid, self.name, self.dataset.name) - #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE - elif self.dataset.type == 'ProbeSet': - #ProbeSet Data - query = ''' - SELECT - Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id - FROM - (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) - left join ProbeSetSE on - (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) - WHERE - ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSetXRef.DataId = ProbeSetData.Id AND - ProbeSetData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (self.name, self.dataset.name) - #XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE - else: - #Geno Data - #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. - query = ''' - SELECT - Strain.Name, GenoData.value, GenoSE.error, GenoData.Id - FROM - (GenoData, GenoFreeze, Strain, Geno, GenoXRef) - left join GenoSE on - (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) - WHERE - Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoFreeze.Name = '%s' AND - GenoXRef.DataId = GenoData.Id AND - GenoData.StrainId = Strain.Id - Order BY - Strain.Name - ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group), self.name, self.dataset.name) - - - self.cursor.execute(query) - results = self.cursor.fetchall() - self.data.clear() - - if results: - self.mysqlid = results[0][-1] - #if samplelist: - for item in results: - #name, value, variance, num_cases = item - if not samplelist or (samplelist and name in samplelist): - #if value != None: - # num_cases = None - # if self.dataset.type in ('Publish', 'Temp'): - # ndata = item[3] - name = item[0] - self.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) - #end for - # else: - # for item in results: - # val = item[1] - # if val != None: - # var = item[2] - # ndata = None - # if self.dataset.type in ('Publish', 'Temp'): - # ndata = item[3] - # self.data[item[0]] = webqtlCaseData(val, var, ndata) - # #end for - # #end if - #else: - # pass - - #def keys(self): - # return self.__dict__.keys() - # - #def has_key(self, key): - # return self.__dict__.has_key(key) - # - #def items(self): - # return self.__dict__.items() - - def retrieve_info(self, QTL=False): - assert self.dataset, "Dataset doesn't exist" - if self.dataset.type == 'Publish': - query = """ - SELECT - PublishXRef.Id, Publication.PubMed_ID, - Phenotype.Pre_publication_description, Phenotype.Post_publication_description, Phenotype.Original_description, - Phenotype.Pre_publication_abbreviation, Phenotype.Post_publication_abbreviation, - Phenotype.Lab_code, Phenotype.Submitter, Phenotype.Owner, Phenotype.Authorized_Users, - Publication.Authors, Publication.Title, Publication.Abstract, - Publication.Journal, Publication.Volume, Publication.Pages, - Publication.Month, Publication.Year, PublishXRef.Sequence, - Phenotype.Units, PublishXRef.comments - FROM - PublishXRef, Publication, Phenotype, PublishFreeze - WHERE - PublishXRef.Id = %s AND - Phenotype.Id = PublishXRef.PhenotypeId AND - Publication.Id = PublishXRef.PublicationId AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishFreeze.Id = %s - """ % (self.name, self.dataset.id) - traitInfo = g.db.execute(query).fetchone() - #XZ, 05/08/2009: Xiaodong add this block to use ProbeSet.Id to find the probeset instead of just using ProbeSet.Name - #XZ, 05/08/2009: to avoid the problem of same probeset name from different platforms. - elif self.dataset.type == 'ProbeSet': - display_fields_string = ', ProbeSet.'.join(self.dataset.display_fields) - display_fields_string = 'ProbeSet.' + display_fields_string - query = """ - SELECT %s - FROM ProbeSet, ProbeSetFreeze, ProbeSetXRef - WHERE - ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSetFreeze.Name = '%s' AND - ProbeSet.Name = '%s' - """ % (display_fields_string, self.dataset.name, self.name) - traitInfo = g.db.execute(query).fetchone() - print("traitInfo is: ", pf(traitInfo)) - #XZ, 05/08/2009: We also should use Geno.Id to find marker instead of just using Geno.Name - # to avoid the problem of same marker name from different species. - elif self.dataset.type == 'Geno': - display_fields_string = string.join(self.dataset.display_fields,',Geno.') - display_fields_string = 'Geno.' + display_fields_string - query = """ - SELECT %s - FROM Geno, GenoFreeze, GenoXRef - WHERE - GenoXRef.GenoFreezeId = GenoFreeze.Id AND - GenoXRef.GenoId = Geno.Id AND - GenoFreeze.Name = '%s' AND - Geno.Name = '%s' - """ % (display_fields_string, self.dataset.name, self.name) - traitInfo = g.db.execute(query).fetchone() - print("traitInfo is: ", pf(traitInfo)) - else: #Temp type - query = """SELECT %s FROM %s WHERE Name = %s - """ % (string.join(self.dataset.display_fields,','), - self.dataset.type, self.name) - traitInfo = g.db.execute(query).fetchone() - - - #self.cursor.execute(query) - #traitInfo = self.cursor.fetchone() - if traitInfo: - self.haveinfo = True - - #XZ: assign SQL query result to trait attributes. - for i, field in enumerate(self.dataset.display_fields): - setattr(self, field, traitInfo[i]) - - if self.dataset.type == 'Publish': - self.confidential = 0 - if self.pre_publication_description and not self.pubmed_id: - self.confidential = 1 - - self.homologeneid = None - if self.dataset.type == 'ProbeSet' and self.group and self.geneid: - #XZ, 05/26/2010: From time to time, this query get error message because some geneid values in database are not number. - #XZ: So I have to test if geneid is number before execute the query. - #XZ: The geneid values in database should be cleaned up. - try: - junk = float(self.geneid) - geneidIsNumber = 1 - except: - geneidIsNumber = 0 - - if geneidIsNumber: - result = g.db.execute(""" - SELECT - HomologeneId - FROM - Homologene, Species, InbredSet - WHERE - Homologene.GeneId =%s AND - InbredSet.Name = '%s' AND - InbredSet.SpeciesId = Species.Id AND - Species.TaxonomyId = Homologene.TaxonomyId - """, (self.geneid, self.group)).fetchone() - #self.cursor.execute(query) - #result = self.cursor.fetchone() - else: - result = None - - if result: - self.homologeneid = result[0] - - if QTL: - if self.dataset.type == 'ProbeSet' and not self.cellid: - traitQTL = g.db.execute(""" - SELECT - ProbeSetXRef.Locus, ProbeSetXRef.LRS, ProbeSetXRef.pValue, ProbeSetXRef.mean - FROM - ProbeSetXRef, ProbeSet - WHERE - ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - ProbeSet.Name = "%s" AND - ProbeSetXRef.ProbeSetFreezeId =%s - """, (self.name, self.dataset.id)).fetchone() - #self.cursor.execute(query) - #traitQTL = self.cursor.fetchone() - if traitQTL: - self.locus, self.lrs, self.pvalue, self.mean = traitQTL - else: - self.locus = self.lrs = self.pvalue = self.mean = "" - if self.dataset.type == 'Publish': - traitQTL = g.db.execute(""" - SELECT - PublishXRef.Locus, PublishXRef.LRS - FROM - PublishXRef, PublishFreeze - WHERE - PublishXRef.Id = %s AND - PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - PublishFreeze.Id =%s - """, (self.name, self.dataset.id)).fetchone() - #self.cursor.execute(query) - #traitQTL = self.cursor.fetchone() - if traitQTL: - self.locus, self.lrs = traitQTL - else: - self.locus = self.lrs = "" - else: - raise KeyError, `self.name`+' information is not found in the database.' - - def genHTML(self, formName = "", dispFromDatabase=0, privilege="guest", userName="Guest", authorized_users=""): - if not self.haveinfo: - self.retrieveInfo() - - if self.dataset.type == 'Publish': - PubMedLink = "" - if self.pubmed_id: - PubMedLink = HT.Href(text="PubMed %d : " % self.pubmed_id, - target = "_blank", url = webqtlConfig.PUBMEDLINK_URL % self.pubmed_id) - else: - PubMedLink = HT.Span("Unpublished : ", Class="fs15") - - if formName: - setDescription2 = HT.Href(url="javascript:showDatabase3('%s','%s','%s','')" % - (formName, self.dataset.name, self.name), Class = "fs14") - else: - setDescription2 = HT.Href(url="javascript:showDatabase2('%s','%s','')" % - (self.dataset.name,self.name), Class = "fs14") - - if self.confidential and not webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=privilege, userName=userName, authorized_users=authorized_users): - setDescription2.append('RecordID/%s - %s' % (self.name, self.pre_publication_description)) - else: - setDescription2.append('RecordID/%s - %s' % (self.name, self.post_publication_description)) - - #XZ 03/26/2011: Xiaodong comment out the following two lins as Rob asked. Need to check with Rob why in PublishXRef table, there are few row whose Sequence > 1. - #if self.sequence > 1: - # setDescription2.append(' btach %d' % self.sequence) - if self.authors: - a1 = string.split(self.authors,',')[0] - while a1[0] == '"' or a1[0] == "'" : - a1 = a1[1:] - setDescription2.append(' by ') - setDescription2.append(HT.Italic('%s, and colleagues' % a1)) - setDescription = HT.Span(PubMedLink, setDescription2) - - elif self.dataset.type == 'Temp': - setDescription = HT.Href(text="%s" % (self.description),url="javascript:showDatabase2\ - ('%s','%s','')" % (self.dataset.name,self.name), Class = "fs14") - setDescription = HT.Span(setDescription) - - elif self.dataset.type == 'Geno': # Genome DB only available for single search - if formName: - setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ - '%2.3f' % self.mb),url="javascript:showDatabase3('%s','%s','%s','')" % \ - (formName, self.dataset.name, self.name), Class = "fs14") - else: - setDescription = HT.Href(text="Locus %s [Chr %s @ %s Mb]" % (self.name,self.chr,\ - '%2.3f' % self.mb),url="javascript:showDatabase2('%s','%s','')" % \ - (self.dataset.name,self.name), Class = "fs14") - - setDescription = HT.Span(setDescription) - - else: - if self.cellid: - if formName: - setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name, self.cellid),url=\ - "javascript:showDatabase3('%s','%s','%s','%s')" % (formName, self.dataset.name,self.name,self.cellid), \ - Class = "fs14") - else: - setDescription = HT.Href(text="ProbeSet/%s/%s" % (self.name,self.cellid),url=\ - "javascript:showDatabase2('%s','%s','%s')" % (self.dataset.name,self.name,self.cellid), \ - Class = "fs14") - else: - if formName: - setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase3('%s','%s','%s','')" % (formName, self.dataset.name,self.name), \ - Class = "fs14") - else: - setDescription = HT.Href(text="ProbeSet/%s" % self.name, url=\ - "javascript:showDatabase2('%s','%s','')" % (self.dataset.name,self.name), \ - Class = "fs14") - if self.symbol and self.chr and self.mb: - setDescription.append(' [') - setDescription.append(HT.Italic('%s' % self.symbol,Class="cdg fwb")) - setDescription.append(' on Chr %s @ %s Mb]' % (self.chr,self.mb)) - if self.description: - setDescription.append(': %s' % self.description) - if self.probe_target_description: - setDescription.append('; %s' % self.probe_target_description) - setDescription = HT.Span(setDescription) - - if self.dataset.type != 'Temp' and dispFromDatabase: - setDescription.append( ' --- FROM : ') - setDescription.append(self.dataset.genHTML(Class='cori')) - return setDescription - - @property - def description_fmt(self): - '''Return a text formated description''' - if self.description: - formatted = self.description - if self.probe_target_description: - formatted += "; " + self.probe_target_description - else: - formatted = "Not available" - return formatted.capitalize() - - @property - def alias_fmt(self): - '''Return a text formatted alias''' - if self.alias: - alias = string.replace(self.alias, ";", " ") - alias = string.join(string.split(alias), ", ") - return alias - - - @property - def location_fmt(self): - '''Return a text formatted location - - While we're at it we set self.location in case we need it later (do we?) - - ''' - - if self.chr and self.mb: - self.location = 'Chr %s @ %s Mb' % (self.chr,self.mb) - elif self.chr: - self.location = 'Chr %s @ Unknown position' % (self.chr) - else: - self.location = 'Not available' - - fmt = self.location - ##XZ: deal with direction - if self.strand_probe == '+': - fmt += (' on the plus strand ') - elif self.strand_probe == '-': - fmt += (' on the minus strand ') - - return fmt - - - def get_database(self): - """ - Returns the database, and the url referring to the database if it exists - - We're going to to return two values here, and we don't want to have to call this twice from - the template. So it's not a property called from the template, but instead is called from the view - - """ - if self.cellid: - self.cursor.execute(""" - select ProbeFreeze.Name from ProbeFreeze, ProbeSetFreeze - where - ProbeFreeze.Id = ProbeSetFreeze.ProbeFreezeId AND - ProbeSetFreeze.Id = %d""" % thisTrait.dataset.id) - probeDBName = self.cursor.fetchone()[0] - return dict(name = probeDBName, - url = None) - else: - return dict(name = self.dataset.fullname, - url = webqtlConfig.INFOPAGEHREF % self.dataset.name) - - def calculate_correlation(self, values, method): - """Calculate the correlation value and p value according to the method specified""" - - #ZS: This takes the list of values of the trait our selected trait is being correlated against and removes the values of the samples our trait has no value for - #There's probably a better way of dealing with this, but I'll have to ask Christian - updated_raw_values = [] - updated_values = [] - for i in range(len(values)): - if values[i] != "None": - updated_raw_values.append(self.raw_values[i]) - updated_values.append(values[i]) - - self.raw_values = updated_raw_values - values = updated_values - - if method == METHOD_SAMPLE_PEARSON or method == METHOD_LIT or method == METHOD_TISSUE_PEARSON: - corr, nOverlap = webqtlUtil.calCorrelation(self.raw_values, values, len(values)) - else: - corr, nOverlap = webqtlUtil.calCorrelationRank(self.raw_values, values, len(values)) - - self.correlation = corr - self.overlap = nOverlap - - if self.overlap < 3: - self.p_value = 1.0 - else: - #ZS - This is probably the wrong way to deal with this. Correlation values of 1.0 definitely exist (the trait correlated against itself), so zero division needs to br prevented. - if abs(self.correlation) >= 1.0: - self.p_value = 0.0 - else: - ZValue = 0.5*log((1.0+self.correlation)/(1.0-self.correlation)) - ZValue = ZValue*sqrt(self.overlap-3) - self.p_value = 2.0*(1.0 - reaper.normp(abs(ZValue))) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 4301fb50..69602748 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -26,10 +26,11 @@ class DoSearch(object): assert search_operator in (None, "=", "<", ">", "<=", ">="), "Bad search operator" self.search_operator = search_operator self.dataset = dataset + print("self.dataset is boo: ", type(self.dataset), pf(self.dataset)) + print("self.dataset.group is: ", pf(self.dataset.group)) #Get group information for dataset and the species id - self.dataset.get_group() - self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group) + self.species_id = webqtlDatabaseFunction.retrieve_species_id(self.dataset.group.name) def execute(self, query): """Executes query and returns results""" diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index cd478110..7c50dfeb 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -30,7 +30,7 @@ from base import webqtlConfig from utility.THCell import THCell from utility.TDCell import TDCell from base.data_set import create_dataset -from base.webqtlTrait import GeneralTrait +from base.trait import GeneralTrait from base.templatePage import templatePage from wqflask import parser from wqflask import do_search @@ -99,8 +99,7 @@ class SearchResultPage(templatePage): """ self.trait_list = [] - group = self.dataset.group - species = webqtlDatabaseFunction.retrieve_species(group=group) + species = webqtlDatabaseFunction.retrieve_species(self.dataset.group.name) # result_set represents the results for each search term; a search of # "shh grin2b" would have two sets of results, one for each term diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index aef9219f..2bc4fc9c 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -13,7 +13,8 @@ from base import webqtlConfig from base import webqtlCaseData from wqflask.show_trait.SampleList import SampleList from utility import webqtlUtil, Plot, Bunch -from base.webqtlTrait import GeneralTrait +from base.trait import GeneralTrait +from base.data_set import create_dataset from dbFunction import webqtlDatabaseFunction from base.templatePage import templatePage from basicStatistics import BasicStatisticsFunctions @@ -33,105 +34,111 @@ class ShowTrait(templatePage): def __init__(self, args): print("in ShowTrait, args are:", args) - self.group = args.group - self.trait_id = trait_id - self.dataset = dataset + #self.group = args.group + self.trait_id = args['trait_id'] + self.dataset = create_dataset(args['dataset']) + self.cell_id = None #assert self.openMysql(), "No database!" #print("red3 fd.group:", fd.group) this_trait = self.get_this_trait() - print("red4 fd.group:", fd.group) + #print("red4 fd.group:", fd.group) ##read genotype file - fd.group = this_trait.group + #fd.group = this_trait.group - print("[red5] fd.group is:", fd.group) - fd.readGenotype() + #print("[red5] fd.group is:", fd.group) + self.dataset.group.read_genotype_file() + #fd.readGenotype() - if not fd.genotype: - fd.readData(incf1=1) + if not self.dataset.group.genotype: + self.read_data(incf1=1) - # determine data editing page format - variance_data_page = 0 - if fd.formID == 'varianceChoice': - variance_data_page = 1 - - if variance_data_page: - fmID='dataEditing' - else: - if fd.enablevariance: - fmID='pre_dataEditing' - else: - fmID='dataEditing' - - # Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery - hddn = OrderedDict( - FormID = fmID, - group = fd.group, - submitID = '', - scale = 'physic', - additiveCheck = 'ON', - showSNP = 'ON', - showGenes = 'ON', - method = None, - parentsf14regression = 'OFF', - stats_method = '1', - chromosomes = '-1', - topten = '', - viewLegend = 'ON', - intervalAnalystCheck = 'ON', - valsHidden = 'OFF', - database = '', - criteria = None, - MDPChoice = None, - bootCheck = None, - permCheck = None, - applyVarianceSE = None, - sampleNames = '_', - sampleVals = '_', - sampleVars = '_', - otherStrainNames = '_', - otherStrainVals = '_', - otherStrainVars = '_', - extra_attributes = '_', - other_extra_attributes = '_', - export_data = None - ) - - if fd.enablevariance: - hddn['enablevariance']='ON' - if fd.incparentsf1: - hddn['incparentsf1']='ON' - - if this_trait: - hddn['fullname'] = str(this_trait) - try: - hddn['normalPlotTitle'] = this_trait.symbol - hddn['normalPlotTitle'] += ": " - hddn['normalPlotTitle'] += this_trait.name - except: - hddn['normalPlotTitle'] = str(this_trait.name) - hddn['fromDataEditingPage'] = 1 - if this_trait.dataset and this_trait.dataset.type and this_trait.dataset.type == 'ProbeSet': - hddn['trait_type'] = this_trait.dataset.type - if this_trait.cellid: - hddn['cellid'] = this_trait.cellid - else: - self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % - this_trait.mysqlid) - heritability = self.cursor.fetchone() - hddn['heritability'] = heritability - - hddn['attribute_names'] = "" - - hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, - groupName=fd.group) - - if fd.identification: - hddn['identification'] = fd.identification - else: - hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named + ## determine data editing page format + #variance_data_page = 0 + #if fd.formID == 'varianceChoice': + # variance_data_page = 1 + # + #if variance_data_page: + # fmID='dataEditing' + #else: + # if fd.enablevariance: + # fmID='pre_dataEditing' + # else: + # fmID='dataEditing' + + # Todo: Add back in the ones we actually need from below, as we discover we need them + hddn = OrderedDict() + + + ## Some fields, like method, are defaulted to None; otherwise in IE the field can't be changed using jquery + #hddn = OrderedDict( + # FormID = fmID, + # group = fd.group, + # submitID = '', + # scale = 'physic', + # additiveCheck = 'ON', + # showSNP = 'ON', + # showGenes = 'ON', + # method = None, + # parentsf14regression = 'OFF', + # stats_method = '1', + # chromosomes = '-1', + # topten = '', + # viewLegend = 'ON', + # intervalAnalystCheck = 'ON', + # valsHidden = 'OFF', + # database = '', + # criteria = None, + # MDPChoice = None, + # bootCheck = None, + # permCheck = None, + # applyVarianceSE = None, + # sampleNames = '_', + # sampleVals = '_', + # sampleVars = '_', + # otherStrainNames = '_', + # otherStrainVals = '_', + # otherStrainVars = '_', + # extra_attributes = '_', + # other_extra_attributes = '_', + # export_data = None + # ) + + #if fd.enablevariance: + # hddn['enablevariance']='ON' + #if fd.incparentsf1: + # hddn['incparentsf1']='ON' + + #if this_trait: + # hddn['fullname'] = str(this_trait) + # try: + # hddn['normalPlotTitle'] = this_trait.symbol + # hddn['normalPlotTitle'] += ": " + # hddn['normalPlotTitle'] += this_trait.name + # except: + # hddn['normalPlotTitle'] = str(this_trait.name) + # hddn['fromDataEditingPage'] = 1 + # if this_trait.dataset and this_trait.dataset.type and this_trait.dataset.type == 'ProbeSet': + # hddn['trait_type'] = this_trait.dataset.type + # if this_trait.cellid: + # hddn['cellid'] = this_trait.cellid + # else: + # self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % + # this_trait.mysqlid) + # heritability = self.cursor.fetchone() + # hddn['heritability'] = heritability + # + # hddn['attribute_names'] = "" + # + #hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, + # groupName=fd.group) + # + #if fd.identification: + # hddn['identification'] = fd.identification + #else: + # hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named self.dispTraitInformation(fd, "", hddn, this_trait) #Display trait information + function buttons @@ -186,27 +193,109 @@ class ShowTrait(templatePage): #trait_id = self.fd['trait_id'] #cell_id = self.fd.get('CellID') - this_trait = webqtlTrait(dataset=dataset, - name=trait_id, - cellid=cell_id) + this_trait = GeneralTrait(dataset=self.dataset.name, + name=self.trait_id, + cellid=self.cell_id) ##identification, etc. - self.fd.identification = '%s : %s' % (this_trait.dataset.shortname, trait_id) + self.identification = '%s : %s' % (self.dataset.shortname, self.trait_id) this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&group=%s&parentsf1=on' %(dataset, trait_id, self.fd['group']) + &ProbeSetID=%s&group=%s&parentsf1=on' %(self.dataset, self.trait_id, self.dataset.group.name) - if cell_id: - self.fd.identification = '%s/%s'%(self.fd.identification, cell_id) - this_trait.returnURL = '%s&CellID=%s' % (this_trait.returnURL, cell_id) + if self.cell_id: + self.identification = '%s/%s'%(self.identification, self.cell_id) + this_trait.returnURL = '%s&CellID=%s' % (this_trait.returnURL, self.cell_id) - print("yellow1:", self.group) - this_trait.retrieveInfo() - print("yellow2:", self.group) - this_trait.retrieveData() - print("yellow3:", self.group) + print("yellow1:", self.dataset.group) + this_trait.retrieve_info() + print("yellow2:", self.dataset.group) + this_trait.retrieve_sample_data() + print("yellow3:", self.dataset.group) return this_trait + def read_data(self): + '''read user input data or from trait data and analysis form''' + + if incf1 == None: + incf1 = [] + + if not self.genotype: + self.readGenotype() + if not samplelist: + if incf1: + samplelist = self.f1list + self.samplelist + else: + samplelist = self.samplelist + + #print("before traitfiledata self.traitfile is:", pf(self.traitfile)) + + traitfiledata = getattr(self, "traitfile", None) + traitpastedata = getattr(self, "traitpaste", None) + variancefiledata = getattr(self, "variancefile", None) + variancepastedata = getattr(self, "variancepaste", None) + Nfiledata = getattr(self, "Nfile", None) + + #### Todo: Rewrite below when we get to someone submitting their own trait ##### + + def to_float(item): + try: + return float(item) + except ValueError: + return None + + print("bottle samplelist is:", samplelist) + if traitfiledata: + tt = traitfiledata.split() + values = map(webqtlUtil.StringAsFloat, tt) + elif traitpastedata: + tt = traitpastedata.split() + values = map(webqtlUtil.StringAsFloat, tt) + else: + print("mapping formdataasfloat") + #values = map(self.FormDataAsFloat, samplelist) + values = [to_float(getattr(self, key)) for key in samplelist] + print("rocket values is:", values) + + + if len(values) < len(samplelist): + values += [None] * (len(samplelist) - len(values)) + elif len(values) > len(samplelist): + values = values[:len(samplelist)] + print("now values is:", values) + + + if variancefiledata: + tt = variancefiledata.split() + variances = map(webqtlUtil.StringAsFloat, tt) + elif variancepastedata: + tt = variancepastedata.split() + variances = map(webqtlUtil.StringAsFloat, tt) + else: + variances = map(self.FormVarianceAsFloat, samplelist) + + if len(variances) < len(samplelist): + variances += [None]*(len(samplelist) - len(variances)) + elif len(variances) > len(samplelist): + variances = variances[:len(samplelist)] + + if Nfiledata: + tt = string.split(Nfiledata) + nsamples = map(webqtlUtil.IntAsFloat, tt) + if len(nsamples) < len(samplelist): + nsamples += [None]*(len(samplelist) - len(nsamples)) + else: + nsamples = map(self.FormNAsFloat, samplelist) + + ##values, variances, nsamples is obsolete + self.allTraitData = {} + for i, _sample in enumerate(samplelist): + if values[i] != None: + self.allTraitData[_sample] = webqtlCaseData( + _sample, values[i], variances[i], nsamples[i]) + print("allTraitData is:", pf(self.allTraitData)) + + def dispTraitInformation(self, fd, title1Body, hddn, this_trait): _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) -- cgit v1.2.3 From 6749d3c9be414ad15b9c39b2d1817ca27566d959 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 6 Dec 2012 14:27:53 -0600 Subject: Made many small changes to show_trait/data_set/search_results/trait to remove use of the formData object and cursor --- wqflask/base/data_set.py | 7 +- wqflask/base/trait.py | 4 +- wqflask/wqflask/search_results.py | 4 +- wqflask/wqflask/show_trait/SampleList.py | 8 +- wqflask/wqflask/show_trait/show_trait.py | 129 ++++++++++++++++--------------- 5 files changed, 78 insertions(+), 74 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 68f5e5ed..14e4055e 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -42,12 +42,13 @@ def create_dataset(dataset_name): #cursor = db_conn.cursor() print("dataset_name:", dataset_name) - dataset_type = g.db.execute(""" + query = """ SELECT DBType.Name FROM DBList, DBType - WHERE DBList.Name = %s and + WHERE DBList.Name = '%s' and DBType.Id = DBList.DBTypeId - """, (dataset_name)).fetchone().Name + """ % (escape(dataset_name)) + dataset_type = g.db.execute(query).fetchone().Name #dataset_type = cursor.fetchone()[0] print("[blubber] dataset_type:", pf(dataset_type)) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index d3753fc1..d0158ebd 100755 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -24,7 +24,7 @@ class GeneralTrait: def __init__(self, **kw): print("in GeneralTrait") - self.dataset = kw.get('dataset', None) # database object + self.dataset = kw.get('dataset', None) # database name self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. self.cellid = kw.get('cellid', None) self.identification = kw.get('identification', 'un-named trait') @@ -230,7 +230,7 @@ class GeneralTrait: if samplelist == None: samplelist = [] - assert self.dataset + #assert self.dataset #if self.cellid: # #Probe Data diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 7c50dfeb..b518ab99 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -112,11 +112,11 @@ class SearchResultPage(templatePage): print("foo locals are:", locals()) trait_id = result[0] - this_trait = GeneralTrait(dataset=self.dataset, name=trait_id) + this_trait = GeneralTrait(dataset=self.dataset.name, name=trait_id) this_trait.retrieve_info(QTL=True) self.trait_list.append(this_trait) - self.dataset.get_trait_info(self.trait_list, species) + self.dataset.get_trait_info(self.trait_list, species) def search(self): diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 25877521..53bb24fb 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -9,7 +9,7 @@ from pprint import pformat as pf class SampleList(object): def __init__(self, cursor, - fd, + dataset, variance_data_page, sample_names, this_trait, @@ -17,7 +17,7 @@ class SampleList(object): header): self.cursor = cursor - self.fd = fd + self.dataset = dataset self.this_trait = this_trait self.sample_group_type = sample_group_type # primary or other self.header = header @@ -42,7 +42,7 @@ class SampleList(object): #if fd.RISet == 'AXBXA' and sampleName in ('AXB18/19/20','AXB13/14','BXA8/17'): # sampleNameAdd = HT.Href(url='/mouseCross.html#AXB/BXA', text=HT.Sup('#'), Class='fs12', target="_blank") sample.extra_info = {} - if self.fd.RISet == 'AXBXA' and sample_name in ('AXB18/19/20','AXB13/14','BXA8/17'): + if self.dataset.group.name == 'AXBXA' and sample_name in ('AXB18/19/20','AXB13/14','BXA8/17'): sample.extra_info['url'] = "/mouseCross.html#AXB/BXA" sample.extra_info['css_class'] = "fs12" @@ -124,7 +124,7 @@ class SampleList(object): WHERE Strain.Name = %s and StrainXRef.StrainId = Strain.Id and InbredSet.Id = StrainXRef.InbredSetId and - InbredSet.Name = %s""", (sample_name, self.fd.RISet)) + InbredSet.Name = %s""", (sample_name, self.dataset.group.name)) sample_id = self.cursor.fetchone()[0] diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 2bc4fc9c..73b438d0 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -7,6 +7,8 @@ import cPickle from collections import OrderedDict +from flask import Flask, g + from htmlgen import HTMLgen2 as HT from base import webqtlConfig @@ -140,10 +142,10 @@ class ShowTrait(templatePage): #else: # hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named - self.dispTraitInformation(fd, "", hddn, this_trait) #Display trait information + function buttons + self.dispTraitInformation(args, "", hddn, this_trait) #Display trait information + function buttons if this_trait == None: - this_trait = webqtlTrait(data=fd.allTraitData, dataset=None) + this_trait = webqtlTrait(data=args['allTraitData'], dataset=None) ## Variance submit page only #if fd.enablevariance and not variance_data_page: @@ -156,15 +158,14 @@ class ShowTrait(templatePage): # print("Calling dispBasicStatistics") # self.dispBasicStatistics(fd, this_trait) - self.build_correlation_tools(fd, this_trait) - + self.build_correlation_tools(args, this_trait) - self.make_sample_lists(fd, variance_data_page, this_trait) + self.make_sample_lists(args, variance_data_page, this_trait) - if fd.allsamplelist: - hddn['allsamplelist'] = string.join(fd.allsamplelist, ' ') + if args['allsamplelist']: + hddn['allsamplelist'] = string.join(args['allsamplelist'], ' ') - if fd.varianceDispName != 'Variance': + if args['varianceDispName'] != 'Variance': hddn['isSE'] = "yes" # We'll need access to this_trait and hddn in the Jinja2 Template, so we put it inside self @@ -172,8 +173,8 @@ class ShowTrait(templatePage): self.hddn = hddn self.sample_group_types = OrderedDict() - self.sample_group_types['samples_primary'] = fd.group + " Only" - self.sample_group_types['samples_other'] = "Non-" + fd.group + self.sample_group_types['samples_primary'] = self.dataset.group.name + " Only" + self.sample_group_types['samples_other'] = "Non-" + self.dataset.group.name self.sample_group_types['samples_all'] = "All Cases" sample_lists = [group.sample_list for group in self.sample_groups] print("sample_lists is:", pf(sample_lists)) @@ -221,7 +222,7 @@ class ShowTrait(templatePage): incf1 = [] if not self.genotype: - self.readGenotype() + self.dataset.read_genotype_file() if not samplelist: if incf1: samplelist = self.f1list + self.samplelist @@ -296,9 +297,9 @@ class ShowTrait(templatePage): print("allTraitData is:", pf(self.allTraitData)) - def dispTraitInformation(self, fd, title1Body, hddn, this_trait): + def dispTraitInformation(self, args, title1Body, hddn, this_trait): - _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) + _Species = webqtlDatabaseFunction.retrieve_species(group=self.dataset.group.name) #tbl = HT.TableLite(cellpadding=2, Class="collap", style="margin-left:20px;", width="840", valign="top", id="target1") @@ -323,31 +324,31 @@ class ShowTrait(templatePage): snpBrowserText = "" updateText = "" - if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: - - if this_trait==None or this_trait.dataset.type=='Temp': - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - elif this_trait.dataset.type != 'Temp': - if this_trait.dataset.type == 'Publish' and this_trait.confidential: #XZ: confidential phenotype trait - if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - else: - updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") - updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") - updateButton.append(updateButton_img) - updateText = "Edit" - else: - pass + #if webqtlConfig.USERDICT[self.privilege] >= webqtlConfig.USERDICT['user']: + # + # if this_trait==None or this_trait.dataset.type=='Temp': + # updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'addPublish');") + # updateButton_img = HT.Image("/images/edit_icon.jpg", name="addnew", alt="Add To Publish", title="Add To Publish", style="border:none;") + # updateButton.append(updateButton_img) + # updateText = "Edit" + # elif this_trait.dataset.type != 'Temp': + # if this_trait.dataset.type == 'Publish' and this_trait.confidential: #XZ: confidential phenotype trait + # if webqtlUtil.hasAccessToConfidentialPhenotypeTrait(privilege=self.privilege, userName=self.userName, authorized_users=this_trait.authorized_users): + # updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + # updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + # updateButton.append(updateButton_img) + # updateText = "Edit" + # else: + # updateButton = HT.Href(url="#redirect", onClick="dataEditingFunc(document.getElementsByName('dataInput')[0],'updateRecord');") + # updateButton_img = HT.Image("/images/edit_icon.jpg", name="update", alt="Edit", title="Edit", style="border:none;") + # updateButton.append(updateButton_img) + # updateText = "Edit" + # else: + # pass - self.cursor.execute('SELECT Name FROM InbredSet WHERE Name="%s"' % fd.group) + g.db.execute("SELECT Name FROM InbredSet WHERE Name=%s", self.dataset.group.name) if this_trait: - addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (fd.group, 'dataInput')) + addSelectionButton = HT.Href(url="#redirect", onClick="addRmvSelection('%s', document.getElementsByName('%s')[0], 'addToSelection');" % (self.dataset.group.name, 'dataInput')) addSelectionButton_img = HT.Image("/images/add_icon.jpg", name="addselect", alt="Add To Collection", title="Add To Collection", style="border:none;") #addSelectionButton.append(addSelectionButton_img) addSelectionText = "Add" @@ -373,8 +374,7 @@ class ShowTrait(templatePage): if this_trait.symbol: #XZ: Show SNP Browser only for mouse if _Species == 'mouse': - self.cursor.execute("select geneSymbol from GeneList where geneSymbol = %s", this_trait.symbol) - geneName = self.cursor.fetchone() + geneName = g.db.execute("SELECT geneSymbol FROM GeneList WHERE geneSymbol = %s", this_trait.symbol).fetchone() if geneName: snpurl = os.path.join(webqtlConfig.CGIDIR, "main.py?FormID=SnpBrowserResultPage&submitStatus=1&diffAlleles=True&customStrain=True") + "&geneName=%s" % geneName[0] else: @@ -496,15 +496,14 @@ class ShowTrait(templatePage): if this_trait.dataset.name.find('Liver') >= 0 and this_trait.dataset.name.find('F2') < 0: pass else: + query = """SELECT count(*) + FROM Probe, ProbeSet + WHERE ProbeSet.Name = '%s' AND Probe.ProbeSetId = ProbeSet.Id""" % (this_trait.name) #query database for number of probes associated with trait; if count > 0, set probe tool button and text - self.cursor.execute("""SELECT count(*) - FROM Probe, ProbeSet - WHERE ProbeSet.Name = '%s' AND Probe.ProbeSetId = ProbeSet.Id""" % (this_trait.name)) - - probeResult = self.cursor.fetchone() + probeResult = g.db.execute(query).fetchone() if probeResult[0] > 0: probeurl = "%s?FormID=showProbeInfo&database=%s&ProbeSetID=%s&CellID=%s&group=%s&incparentsf1=ON" \ - % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.dataset, this_trait.name, this_trait.cellid, fd.group) + % (os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), this_trait.dataset, this_trait.name, this_trait.cellid, self.dataset.group.name) probeButton = HT.Href(url="#", onClick="javascript:openNewWin('%s'); return false;" % probeurl) probeButton_img = HT.Image("/images/probe_icon.jpg", name="probe", alt=" Check sequence of probes ", title=" Check sequence of probes ", style="border:none;") #probeButton.append(probeButton_img) @@ -632,18 +631,21 @@ class ShowTrait(templatePage): #symatlas_species = "Mus musculus" #self.cursor.execute("SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = '%s'" % this_trait.symbol) - self.cursor.execute('SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = "%s"' % this_trait.symbol) - try: - chr, txst, txen = self.cursor.fetchall()[0] - if chr and txst and txen and this_trait.refseq_transcriptid : - txst = int(txst*1000000) - txen = int(txen*1000000) - tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ - title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('mm9',this_trait.refseq_transcriptid,chr,txst,txen), - Class="fs14 fwn"), style=linkStyle) - , " "*2) - except: - pass + #try: + this_chr, txst, txen = g.db.execute("SELECT chromosome,txStart,txEnd FROM GeneList WHERE geneSymbol = %s", (this_trait.symbol)).fetchone() + if this_chr and txst and txen and this_trait.refseq_transcriptid : + txst = int(txst*1000000) + txen = int(txen*1000000) + #tSpan.append(HT.Span(HT.Href(text= 'UCSC',target="mainFrame",\ + # title= 'Info from UCSC Genome Browser', url = webqtlConfig.UCSC_REFSEQ % ('mm9', + # this_trait.refseq_transcriptid, + # this_chr, + # txst, + # txen), + # Class="fs14 fwn"), style=linkStyle) + # , " "*2) + #except: + # pass #XZ, 7/16/2009: The url for SymAtlas (renamed as BioGPS) has changed. We don't need this any more #tSpan.append(HT.Span(HT.Href(text= 'SymAtlas',target="mainFrame",\ @@ -1147,11 +1149,11 @@ class ShowTrait(templatePage): #title2Body.append(submitTable) - def build_correlation_tools(self, fd, this_trait): + def build_correlation_tools(self, this_trait): #species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) - this_group = fd.group + this_group = self.dataset.group.name # We're checking a string here! assert isinstance(this_group, basestring), "We need a string type thing here" @@ -1172,6 +1174,7 @@ class ShowTrait(templatePage): dataset_menu = [] print("[tape4] webqtlConfig.PUBLICTHRESH:", webqtlConfig.PUBLICTHRESH) print("[tape4] type webqtlConfig.PUBLICTHRESH:", type(webqtlConfig.PUBLICTHRESH)) + query = self.cursor.execute('''SELECT PublishFreeze.FullName,PublishFreeze.Name FROM PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = %s and PublishFreeze.public > %s''', @@ -1610,10 +1613,10 @@ class ShowTrait(templatePage): def make_sample_lists(self, fd, variance_data_page, this_trait): - if fd.parlist: - all_samples_ordered = fd.parlist + fd.f1list + fd.samplelist + if args['parlist']: + all_samples_ordered = args['parlist'] + args['f1list'] + args['samplelist'] else: - all_samples_ordered = fd.f1list + fd.samplelist + all_samples_ordered = args['f1list'] + args['samplelist'] this_trait_samples = set(this_trait.data.keys()) @@ -1622,12 +1625,12 @@ class ShowTrait(templatePage): print("-*- primary_samplelist is:", pf(primary_sample_names)) primary_samples = SampleList(self.cursor, - fd=fd, + args=args, variance_data_page=variance_data_page, sample_names=primary_sample_names, this_trait=this_trait, sample_group_type='primary', - header="%s Only" % (fd.group)) + header="%s Only" % (self.dataset.group.name)) other_sample_names = [] for sample in this_trait.data.keys(): -- cgit v1.2.3 From 2ec627563efa9fdf4fc74cb4764bfebb5ab90933 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 6 Dec 2012 15:39:28 -0600 Subject: Got show_trait running again for MrnaAssay traits --- wqflask/base/data_set.py | 37 +++++++------- wqflask/wqflask/show_trait/SampleList.py | 48 +++++++++--------- wqflask/wqflask/show_trait/show_trait.py | 81 ++++++++++++++----------------- wqflask/wqflask/templates/show_trait.html | 2 +- 4 files changed, 80 insertions(+), 88 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 14e4055e..9f0f3fac 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -77,6 +77,9 @@ class DatasetGroup(object): self.name = "BXD" self.incparentsf1 = False + self.f1list = None + self.parlist = None + self.allsamples = None #def read_genotype(self): @@ -95,39 +98,39 @@ class DatasetGroup(object): #genotype_1 is Dataset Object without parents and f1 #genotype_2 is Dataset Object with parents and f1 (not for intercross) - self.genotype_1 = reaper.Dataset() + genotype_1 = reaper.Dataset() # reaper barfs on unicode filenames, so here we ensure it's a string full_filename = str(os.path.join(webqtlConfig.GENODIR, self.name + '.geno')) - self.genotype_1.read(full_filename) + genotype_1.read(full_filename) print("Got to after read") try: # NL, 07/27/2010. ParInfo has been moved from webqtlForm.py to webqtlUtil.py; - _f1, _f12, _mat, _pat = webqtlUtil.ParInfo[self.name] + f1, f12, maternal, paternal = webqtlUtil.ParInfo[self.name] except KeyError: - _f1 = _f12 = _mat = _pat = None + f1 = f12 = maternal = paternal = None - self.genotype_2 = self.genotype_1 - if self.genotype_1.type == "group" and _mat and _pat: - self.genotype_2 = self.genotype_1.add(Mat=_mat, Pat=_pat) #, F1=_f1) + + if genotype_1.type == "group" and maternal and paternal: + genotype_2 = genotype_1.add(Mat=maternal, Pat=paternal) #, F1=_f1) + else: + genotype_2 = genotype_1 #determine default genotype object - if self.incparentsf1 and self.genotype_1.type != "intercross": - self.genotype = self.genotype_2 + if self.incparentsf1 and genotype_1.type != "intercross": + self.genotype = genotype_2 else: self.incparentsf1 = 0 - self.genotype = self.genotype_1 + self.genotype = genotype_1 self.samplelist = list(self.genotype.prgy) - self.f1list = [] - self.parlist = [] - if _f1 and _f12: - self.f1list = [_f1, _f12] - if _mat and _pat: - self.parlist = [_mat, _pat] + if f1 and f12: + self.f1list = [f1, f12] + if maternal and paternal: + self.parlist = [maternal, paternal] class DataSet(object): @@ -169,8 +172,6 @@ class DataSet(object): # self.get_group() # # return self._group - - diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 53bb24fb..0c752617 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -1,5 +1,7 @@ from __future__ import absolute_import, print_function, division +from flask import Flask, g + from base import webqtlCaseData from utility import webqtlUtil, Plot, Bunch from base.webqtlTrait import GeneralTrait @@ -8,22 +10,19 @@ from pprint import pformat as pf class SampleList(object): def __init__(self, - cursor, dataset, - variance_data_page, sample_names, this_trait, sample_group_type, header): - - self.cursor = cursor + self.dataset = dataset self.this_trait = this_trait self.sample_group_type = sample_group_type # primary or other self.header = header self.sample_list = [] # The actual list - + self.get_attributes() print("camera: attributes are:", pf(self.attributes)) @@ -54,7 +53,7 @@ class SampleList(object): sample.this_id = "Other_" + str(counter) #### For extra attribute columns; currently only used by several datasets - Zach - if self.this_trait and self.this_trait.db and self.this_trait.db.type == 'ProbeSet': + if self.this_trait and self.dataset and self.dataset.type == 'ProbeSet': sample.extra_attributes = self.get_extra_attribute_values(sample_name) print("sample.extra_attributes is", pf(sample.extra_attributes)) self.sample_list.append(sample) @@ -88,27 +87,27 @@ class SampleList(object): def get_attributes(self): """Finds which extra attributes apply to this dataset""" - #ZS: Id and name values for this trait's extra attributes - self.cursor.execute('''SELECT CaseAttribute.Id, CaseAttribute.Name + #ZS: Id and name values for this trait's extra attributes + case_attributes = g.db.execute('''SELECT CaseAttribute.Id, CaseAttribute.Name FROM CaseAttribute, CaseAttributeXRef WHERE CaseAttributeXRef.ProbeSetFreezeId = %s AND CaseAttribute.Id = CaseAttributeXRef.CaseAttributeId group by CaseAttributeXRef.CaseAttributeId''', - (str(self.this_trait.db.id),)) + (str(self.dataset.id),)) self.attributes = {} - for key, value in self.cursor.fetchall(): + for key, value in case_attributes.fetchall(): print("radish: %s - %s" % (key, value)) self.attributes[key] = Bunch() self.attributes[key].name = value - self.cursor.execute('''SELECT DISTINCT CaseAttributeXRef.Value - FROM CaseAttribute, CaseAttributeXRef - WHERE CaseAttribute.Name = %s AND - CaseAttributeXRef.CaseAttributeId = CaseAttribute.Id''', (value,)) + attribute_values = g.db.execute('''SELECT DISTINCT CaseAttributeXRef.Value + FROM CaseAttribute, CaseAttributeXRef + WHERE CaseAttribute.Name = %s AND + CaseAttributeXRef.CaseAttributeId = CaseAttribute.Id''', (value,)) - self.attributes[key].distinct_values = [item[0] for item in self.cursor.fetchall()] + self.attributes[key].distinct_values = [item[0] for item in attribute_values.fetchall()] self.attributes[key].distinct_values.sort(key=natural_sort_key) @@ -119,27 +118,28 @@ class SampleList(object): if self.attributes: #ZS: Get StrainId value for the next query - self.cursor.execute("""SELECT Strain.Id + result = g.db.execute("""SELECT Strain.Id FROM Strain, StrainXRef, InbredSet WHERE Strain.Name = %s and StrainXRef.StrainId = Strain.Id and InbredSet.Id = StrainXRef.InbredSetId and - InbredSet.Name = %s""", (sample_name, self.dataset.group.name)) + InbredSet.Name = %s""", (sample_name, + self.dataset.group.name)) - sample_id = self.cursor.fetchone()[0] + sample_id = result.fetchone().Id for attribute in self.attributes: #ZS: Add extra case attribute values (if any) - self.cursor.execute("""SELECT Value + result = g.db.execute("""SELECT Value FROM CaseAttributeXRef - WHERE ProbeSetFreezeId = '%s' AND - StrainId = '%s' AND - CaseAttributeId = '%s' - group by CaseAttributeXRef.CaseAttributeId""" % ( + WHERE ProbeSetFreezeId = %s AND + StrainId = %s AND + CaseAttributeId = %s + group by CaseAttributeXRef.CaseAttributeId""", ( self.this_trait.db.id, sample_id, str(attribute))) - attribute_value = self.cursor.fetchone()[0] #Trait-specific attributes, if any + attribute_value = result.fetchone().Value #Trait-specific attributes, if any #ZS: If it's an int, turn it into one for sorting #(for example, 101 would be lower than 80 if they're strings instead of ints) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 73b438d0..cd61d70c 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -55,7 +55,7 @@ class ShowTrait(templatePage): #fd.readGenotype() if not self.dataset.group.genotype: - self.read_data(incf1=1) + self.read_data(include_f1=True) #incf1=1) ## determine data editing page format #variance_data_page = 0 @@ -158,15 +158,15 @@ class ShowTrait(templatePage): # print("Calling dispBasicStatistics") # self.dispBasicStatistics(fd, this_trait) - self.build_correlation_tools(args, this_trait) + self.build_correlation_tools(this_trait) - self.make_sample_lists(args, variance_data_page, this_trait) + self.make_sample_lists(this_trait) - if args['allsamplelist']: - hddn['allsamplelist'] = string.join(args['allsamplelist'], ' ') + if self.dataset.group.allsamples: + hddn['allsamples'] = string.join(self.dataset.group.allsamples, ' ') - if args['varianceDispName'] != 'Variance': - hddn['isSE'] = "yes" + #if args['varianceDispName'] != 'Variance': + # hddn['isSE'] = "yes" # We'll need access to this_trait and hddn in the Jinja2 Template, so we put it inside self self.this_trait = this_trait @@ -215,22 +215,20 @@ class ShowTrait(templatePage): return this_trait - def read_data(self): + def read_data(self, include_f1=False): '''read user input data or from trait data and analysis form''' - if incf1 == None: - incf1 = [] + #if incf1 == None: + # incf1 = [] if not self.genotype: self.dataset.read_genotype_file() if not samplelist: - if incf1: + if include_f1: samplelist = self.f1list + self.samplelist else: samplelist = self.samplelist - #print("before traitfiledata self.traitfile is:", pf(self.traitfile)) - traitfiledata = getattr(self, "traitfile", None) traitpastedata = getattr(self, "traitpaste", None) variancefiledata = getattr(self, "variancefile", None) @@ -1174,39 +1172,34 @@ class ShowTrait(templatePage): dataset_menu = [] print("[tape4] webqtlConfig.PUBLICTHRESH:", webqtlConfig.PUBLICTHRESH) print("[tape4] type webqtlConfig.PUBLICTHRESH:", type(webqtlConfig.PUBLICTHRESH)) - query = - self.cursor.execute('''SELECT PublishFreeze.FullName,PublishFreeze.Name FROM + results = g.db.execute("""SELECT PublishFreeze.FullName,PublishFreeze.Name FROM PublishFreeze,InbredSet WHERE PublishFreeze.InbredSetId = InbredSet.Id - and InbredSet.Name = %s and PublishFreeze.public > %s''', + and InbredSet.Name = %s and PublishFreeze.public > %s""", (this_group, webqtlConfig.PUBLICTHRESH)) - for item in self.cursor.fetchall(): + for item in results.fetchall(): dataset_menu.append(dict(tissue=None, datasets=[item])) - self.cursor.execute('''SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze, + results = g.db.execute("""SELECT GenoFreeze.FullName,GenoFreeze.Name FROM GenoFreeze, InbredSet WHERE GenoFreeze.InbredSetId = InbredSet.Id and InbredSet.Name = - %s and GenoFreeze.public > %s''', + %s and GenoFreeze.public > %s""", (this_group, webqtlConfig.PUBLICTHRESH)) - for item in self.cursor.fetchall(): + for item in results.fetchall(): dataset_menu.append(dict(tissue=None, datasets=[item])) #03/09/2009: Xiaodong changed the SQL query to order by Name as requested by Rob. - self.cursor.execute('SELECT Id, Name FROM Tissue order by Name') - for item in self.cursor.fetchall(): + tissues = g.db.execute("SELECT Id, Name FROM Tissue order by Name") + for item in tissues.fetchall(): tissue_id, tissue_name = item #databaseMenuSub = HT.Optgroup(label = '%s ------' % tissue_name) #dataset_sub_menu = [] - print("phun9") - self.cursor.execute('''SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, + data_sets = g.db.execute('''SELECT ProbeSetFreeze.FullName,ProbeSetFreeze.Name FROM ProbeSetFreeze, ProbeFreeze, InbredSet WHERE ProbeSetFreeze.ProbeFreezeId = ProbeFreeze.Id and ProbeFreeze.TissueId = %s and ProbeSetFreeze.public > %s and ProbeFreeze.InbredSetId = InbredSet.Id and InbredSet.Name like %s order by ProbeSetFreeze.CreateTime desc, ProbeSetFreeze.AvgId ''', (tissue_id, webqtlConfig.PUBLICTHRESH, "%" + this_group + "%")) - print("phun8") - dataset_sub_menu = [item for item in self.cursor.fetchall() if item] - #for item2 in self.cursor.fetchall(): - # dataset_sub_menu.append(item2) + dataset_sub_menu = [item for item in data_sets.fetchall() if item] if dataset_sub_menu: dataset_menu.append(dict(tissue=tissue_name, datasets=dataset_sub_menu)) @@ -1612,11 +1605,13 @@ class ShowTrait(templatePage): title4Body.append(submitTable) - def make_sample_lists(self, fd, variance_data_page, this_trait): - if args['parlist']: - all_samples_ordered = args['parlist'] + args['f1list'] + args['samplelist'] + def make_sample_lists(self, this_trait): + if self.dataset.group.parlist: + all_samples_ordered = (self.dataset.group.parlist + + self.dataset.group.f1list + + self.dataset.group.samplelist) else: - all_samples_ordered = args['f1list'] + args['samplelist'] + all_samples_ordered = self.dataset.group.f1list + self.dataset.group.samplelist this_trait_samples = set(this_trait.data.keys()) @@ -1624,9 +1619,7 @@ class ShowTrait(templatePage): print("-*- primary_samplelist is:", pf(primary_sample_names)) - primary_samples = SampleList(self.cursor, - args=args, - variance_data_page=variance_data_page, + primary_samples = SampleList(dataset = self.dataset, sample_names=primary_sample_names, this_trait=this_trait, sample_group_type='primary', @@ -1640,18 +1633,16 @@ class ShowTrait(templatePage): other_sample_names.append(sample) if other_sample_names: - par_f1_samples = fd.parlist + fd.f1list + parent_f1_samples = self.dataset.group.parlist + self.dataset.group.f1list other_sample_names.sort() #Sort other samples - other_sample_names = par_f1_samples + other_sample_names + other_sample_names = parent_f1_samples + other_sample_names - other_samples = SampleList(self.cursor, - fd=fd, - variance_data_page=variance_data_page, - sample_names=other_sample_names, - this_trait=this_trait, - sample_group_type='other', - header="Non-%s" % (fd.group)) + other_samples = SampleList(dataset=self.dataset, + sample_names=other_sample_names, + this_trait=this_trait, + sample_group_type='other', + header="Non-%s" % (self.dataset.group.name)) self.sample_groups = (primary_samples, other_samples) else: @@ -1661,4 +1652,4 @@ class ShowTrait(templatePage): #if (other_sample_names or (fd.f1list and this_trait.data.has_key(fd.f1list[0])) # or (fd.f1list and this_trait.data.has_key(fd.f1list[1]))): # print("hjs") - fd.allsamplelist = all_samples_ordered + self.dataset.group.allsamples = all_samples_ordered diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index b5c1d6ac..163be69c 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -19,7 +19,7 @@
      -- cgit v1.2.3 From 41721f0d386c034470fe68e0017295474242ab48 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 6 Dec 2012 16:50:20 -0600 Subject: Added minimum/maximum to basic statistics table Continued bug-shooting related to getting show_trait running with phenotype traits --- wqflask/base/data_set.py | 32 +++++--- wqflask/wqflask/do_search.py | 5 +- wqflask/wqflask/search_results.py | 7 -- wqflask/wqflask/show_trait/show_trait.py | 7 +- .../static/new/javascript/show_trait.coffee | 86 ++++++++++++---------- .../wqflask/static/new/javascript/show_trait.js | 10 ++- wqflask/wqflask/static/new/javascript/stats.coffee | 31 +++++--- wqflask/wqflask/static/new/javascript/stats.js | 18 ++++- wqflask/wqflask/templates/search_result_page.html | 4 +- wqflask/wqflask/templates/show_trait.html | 2 +- wqflask/wqflask/templates/show_trait_details.html | 2 +- .../wqflask/templates/show_trait_edit_data.html | 2 +- 12 files changed, 122 insertions(+), 84 deletions(-) diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 9f0f3fac..2182fe9e 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -30,6 +30,7 @@ from htmlgen import HTMLgen2 as HT import reaper import webqtlConfig +from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil from MySQLdb import escape_string as escape @@ -72,10 +73,12 @@ class DatasetGroup(object): """ def __init__(self, dataset): """This sets self.group and self.group_id""" - self.name, self.group_id = g.db.execute(dataset.query).fetchone() + self.name, self.id = g.db.execute(dataset.query_for_group).fetchone() if self.name == 'BXD300': self.name = "BXD" + self.species = webqtlDatabaseFunction.retrieve_species(self.name) + self.incparentsf1 = False self.f1list = None self.parlist = None @@ -151,14 +154,25 @@ class DataSet(object): self.check_confidentiality() - self.retrieve_name() + self.retrieve_other_names() self.group = DatasetGroup(self) # sets self.group and self.group_id def get_desc(self): """Gets overridden later, at least for Temp...used by trait's get_given_name""" return None - + + #@staticmethod + #def get_by_trait_id(trait_id): + # """Gets the dataset object given the trait id""" + # + # + # + # name = g.db.execute(""" SELECT + # + # """) + # + # return DataSet(name) # Delete this eventually @property @@ -175,7 +189,7 @@ class DataSet(object): - def retrieve_name(self): + def retrieve_other_names(self): """ If the data set name parameter is not found in the 'Name' field of the data set table, check if it is actually the FullName or ShortName instead. @@ -326,7 +340,7 @@ class PhenotypeDataSet(DataSet): def retrieve_sample_data(self, trait): query = """ SELECT - Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id + Strain.Name, PublishData.value, PublishSE.error, NStrain.count FROM (PublishData, Strain, PublishXRef, PublishFreeze) left join PublishSE on @@ -340,7 +354,7 @@ class PhenotypeDataSet(DataSet): PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id Order BY Strain.Name - """ % (self.trait.name, self.id) + """ % (trait.name, self.id) results = g.db.execute(query).fetchall() return results @@ -368,7 +382,7 @@ class GenotypeDataSet(DataSet): # Todo: Obsolete or rename this field self.type = 'Geno' - self.query = ''' + self.query_for_group = ''' SELECT InbredSet.Name, InbredSet.Id FROM @@ -418,7 +432,7 @@ class GenotypeDataSet(DataSet): GenoData.StrainId = Strain.Id Order BY Strain.Name - """ % (webqtlDatabaseFunction.retrieve_species_id(self.group), trait.name, self.name) + """ % (webqtlDatabaseFunction.retrieve_species_id(self.group.name), trait.name, self.name) results = g.db.execute(query).fetchall() return results @@ -476,7 +490,7 @@ class MrnaAssayDataSet(DataSet): # Todo: Obsolete or rename this field self.type = 'ProbeSet' - self.query = ''' + self.query_for_group = ''' SELECT InbredSet.Name, InbredSet.Id FROM diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 69602748..403f1b5e 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -177,9 +177,6 @@ class PhenotypeSearch(DoSearch): from_clause = self.normalize_spaces(from_clause) - #Get group information for dataset - self.dataset.get_group() - query = (self.base_query + """%s WHERE %s @@ -189,7 +186,7 @@ class PhenotypeSearch(DoSearch): PublishFreeze.Id = %s""" % ( from_clause, where_clause, - escape(str(self.dataset.group_id)), + escape(str(self.dataset.group.id)), escape(str(self.dataset.id)))) print("query is:", pf(query)) diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index b518ab99..5cb8e314 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -4,13 +4,6 @@ from wqflask import app from flask import render_template -################################################### -# # -# This file uses only spaces for indentation # -# # -################################################### - -#import string import os import cPickle import re diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index cd61d70c..d1c60877 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -32,13 +32,16 @@ from pprint import pformat as pf -class ShowTrait(templatePage): +class ShowTrait(object): def __init__(self, args): print("in ShowTrait, args are:", args) #self.group = args.group self.trait_id = args['trait_id'] + self.dataset = create_dataset(args['dataset']) + + #self.dataset = create_dataset(args['dataset']) self.cell_id = None #assert self.openMysql(), "No database!" @@ -817,7 +820,7 @@ class ShowTrait(templatePage): # )) pass - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") + #menuTable = HT.TableLite(cellpadding=2, Class="collap", width="150", id="target1") #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 6e22119f..3d9fcd5a 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -23,15 +23,15 @@ $ -> id = "#" + process_id(category, value_type) console.log("the_id:", id) in_box = $(id).html - + current_value = parseFloat($(in_box)).toFixed(decimal_places) - + console.log("urgh:", category, value_type) the_value = sample_sets[category][value_type]() console.log("After running sample_sets, the_value is:", the_value) if decimal_places > 0 the_value = the_value.toFixed(decimal_places) - + console.log("*-* the_value:", the_value) console.log("*-* current_value:", current_value) if the_value != current_value @@ -40,16 +40,16 @@ $ -> update_stat_values = (sample_sets)-> for category in ['samples_primary', 'samples_other', 'samples_all'] change_stats_value(sample_sets, category, "n_of_samples", 0) - for stat in ["mean", "median", "std_dev", "std_error"] + for stat in ["mean", "median", "std_dev", "std_error", "min", "max"] console.log("Calling change_stats_value") change_stats_value(sample_sets, category, stat, 2) - edit_data_change = -> + edit_data_change = -> sample_sets = samples_primary: new Stats([]) samples_other: new Stats([]) samples_all: new Stats([]) - + console.log("at beginning:", sample_sets) # ########## @@ -114,6 +114,14 @@ $ -> { vn: "std_dev" pretty: "Standard Deviation (SD)" + }, + { + vn: "min" + pretty: "Minimum" + }, + { + vn: "max" + pretty: "Maximum" } ] @@ -150,8 +158,8 @@ $ -> processed += "-" processed += value return processed - - + + show_hide_outliers = -> console.log("FOOBAR in beginning of show_hide_outliers") label = $('#show_hide_outliers').val() @@ -163,10 +171,10 @@ $ -> $('#show_hide_outliers').val("Hide Outliers") console.log("Should be now Hide Outliers") - + ##Calculate Correlations Code - - + + on_corr_method_change = -> console.log("in beginning of on_corr_method_change") corr_method = $('select[name=corr_method]').val() @@ -179,15 +187,15 @@ $ -> $("#corr_sample_method_options").show() $('select[name=corr_method]').change(on_corr_method_change) - - + + ##End Calculate Correlations Code - + ##Populate Samples Attribute Values Code - + create_value_dropdown = (value) -> return """""" - + populate_sample_attributes_values_dropdown = -> console.log("in beginning of psavd") $('#attribute_values').empty() @@ -205,14 +213,14 @@ $ -> if js_data.attribute_names.length > 0 populate_sample_attributes_values_dropdown() $('#exclude_menu').change(populate_sample_attributes_values_dropdown) - + ##End Populate Samples Attribute Values Codess ##Block Samples By Attribute Value Code block_by_attribute_value = -> attribute_name = $('#exclude_menu').val() exclude_by_value = $('#attribute_values').val() - + cell_class = ".column_name-#{attribute_name}" $(cell_class).each (index, element) => if $.trim($(element).text()) == exclude_by_value @@ -220,11 +228,11 @@ $ -> $(row).find(".trait_value_input").val("x") $('#exclude_group').click(block_by_attribute_value) - + ##End Block Samples By Attribute Value Code - + ##Block Samples By Index Code - + block_by_index = -> index_string = $('#remove_samples_field').val() index_list = [] @@ -241,7 +249,7 @@ $ -> index = parseInt(index_set) console.log("index:", index) index_list.push(index) - #catch(erro) + #catch(erro) # alert("Syntax error") console.log("index_list:", index_list) for index in index_list @@ -251,33 +259,33 @@ $ -> $('#Primary_'+index.toString()).find('.trait_value_input').val("x") else if $('#block_group').val() == "other" console.log("block_group:", $('#block_group').val()) - console.log("row:", $('#Other_'+index.toString())) + console.log("row:", $('#Other_'+index.toString())) $('#Other_'+index.toString()).find('.trait_value_input').val("x") - + $('#block_by_index').click(block_by_index) ##End Block Samples By Index Code - + ##Hide Sample Rows With No Value (value of 'x') Code - + hide_no_value = -> $('.value_se').each (_index, element) => if $(element).find('.trait_value_input').val() == 'x' $(element).hide() - + $('#hide_no_value').click(hide_no_value) ##End Hide Sample Rows With No Value Code - + ##Block Outliers Code block_outliers = -> $('.outlier').each (_index, element) => $(element).find('.trait_value_input').val('x') - + $('#block_outliers').click(block_outliers) - + ##End Block Outliers Code - + ##Reset Table Values Code reset_samples_table = -> $('.trait_value_input').each (_index, element) => @@ -289,9 +297,9 @@ $ -> $('#reset').click(reset_samples_table) ##End Reset Table Values Code - + ##Get Sample Data From Table Code - + get_sample_table_data = -> samples = {} primary_samples = [] @@ -315,27 +323,27 @@ $ -> ##End Get Sample Data from Table Code ##Export Sample Table Data Code - + export_sample_table_data = -> sample_data = get_sample_table_data() console.log("sample_data is:", sample_data) json_sample_data = JSON.stringify(sample_data) console.log("json_sample_data is:", json_sample_data) - + $('input[name=export_data]').val(json_sample_data) console.log("export_data is", $('input[name=export_data]').val()) - + format = $('#export_format').val() if format == "excel" $('#trait_data_form').attr('action', '/export_trait_excel') else $('#trait_data_form').attr('action', '/export_trait_csv') console.log("action is:", $('#trait_data_form').attr('action')) - + $('#trait_data_form').submit() $('#export').click(export_sample_table_data) - + ##End Export Sample Table Data Code @@ -344,7 +352,7 @@ $ -> console.log("after registering block_outliers") _.mixin(_.str.exports()); # Add string fuctions directly to underscore - $('#value_table').change(edit_data_change) + $('#edit_sample_lists').change(edit_data_change) console.log("loaded") #console.log("basic_table is:", basic_table) # Add back following two lines later diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 919bc766..84282aef 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -53,7 +53,7 @@ change_stats_value(sample_sets, category, "n_of_samples", 0); _results.push((function() { var _j, _len1, _ref1, _results1; - _ref1 = ["mean", "median", "std_dev", "std_error"]; + _ref1 = ["mean", "median", "std_dev", "std_error", "min", "max"]; _results1 = []; for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { stat = _ref1[_j]; @@ -126,6 +126,12 @@ }, { vn: "std_dev", pretty: "Standard Deviation (SD)" + }, { + vn: "min", + pretty: "Minimum" + }, { + vn: "max", + pretty: "Maximum" } ]; console.log("rows are:", rows); @@ -362,7 +368,7 @@ $('#block_outliers').click(block_outliers); console.log("after registering block_outliers"); _.mixin(_.str.exports()); - $('#value_table').change(edit_data_change); + $('#edit_sample_lists').change(edit_data_change); console.log("loaded"); make_table(); edit_data_change(); diff --git a/wqflask/wqflask/static/new/javascript/stats.coffee b/wqflask/wqflask/static/new/javascript/stats.coffee index 677dc258..118ee7a8 100644 --- a/wqflask/wqflask/static/new/javascript/stats.coffee +++ b/wqflask/wqflask/static/new/javascript/stats.coffee @@ -1,20 +1,20 @@ class Stats constructor: (@the_values) -> - + add_value: (value) -> @the_values.push(value) - + n_of_samples: -> return @the_values.length - + sum: -> total = 0 total += value for value in @the_values return total - + mean: -> return @sum() / @n_of_samples() - + median: -> is_odd = @the_values.length % 2 median_position = Math.floor(@the_values.length / 2) @@ -24,7 +24,7 @@ class Stats else return (the_values_sorted[median_position] + the_values_sorted[median_position - 1]) / 2 - + std_dev: -> sum = 0 for value in @the_values @@ -32,15 +32,22 @@ class Stats sum += step_a step_b = sum / @the_values.length return Math.sqrt(step_b) - + std_error: -> return @std_dev() / Math.sqrt(@n_of_samples()) + min: -> + return Math.min(@the_values...) + + max: -> + return Math.max(@the_values...) + bxd_only = new Stats([3, 5, 7, 8]) -console.log("[red] bxd_only mean:", bxd_only.mean()) -console.log("[green] bxd_only median:", bxd_only.median()) -console.log("[purple] bxd_only std_dev:", bxd_only.std_dev()) -console.log("[magenta] bxd_only std_error:", bxd_only.std_error()) +console.log("[xred] bxd_only mean:", bxd_only.mean()) +console.log("[xgreen] bxd_only median:", bxd_only.median()) +console.log("[xpurple] bxd_only std_dev:", bxd_only.std_dev()) +console.log("[xmagenta] bxd_only std_error:", bxd_only.std_error()) +console.log("[xyellow] bxd_only min:", bxd_only.min()) -window.Stats = Stats \ No newline at end of file +window.Stats = Stats diff --git a/wqflask/wqflask/static/new/javascript/stats.js b/wqflask/wqflask/static/new/javascript/stats.js index f95d03d4..620f7d5d 100644 --- a/wqflask/wqflask/static/new/javascript/stats.js +++ b/wqflask/wqflask/static/new/javascript/stats.js @@ -62,19 +62,29 @@ return this.std_dev() / Math.sqrt(this.n_of_samples()); }; + Stats.prototype.min = function() { + return Math.min.apply(Math, this.the_values); + }; + + Stats.prototype.max = function() { + return Math.max.apply(Math, this.the_values); + }; + return Stats; })(); bxd_only = new Stats([3, 5, 7, 8]); - console.log("[red] bxd_only mean:", bxd_only.mean()); + console.log("[xred] bxd_only mean:", bxd_only.mean()); + + console.log("[xgreen] bxd_only median:", bxd_only.median()); - console.log("[green] bxd_only median:", bxd_only.median()); + console.log("[xpurple] bxd_only std_dev:", bxd_only.std_dev()); - console.log("[purple] bxd_only std_dev:", bxd_only.std_dev()); + console.log("[xmagenta] bxd_only std_error:", bxd_only.std_error()); - console.log("[magenta] bxd_only std_error:", bxd_only.std_error()); + console.log("[xyellow] bxd_only min:", bxd_only.min()); window.Stats = Stats; diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 35ff4e8e..11f68bba 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -51,9 +51,9 @@ + dataset = dataset.name + )}}"> {{ this_trait.name }} diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 163be69c..28341186 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -18,7 +18,7 @@
      -
      +
      {% for sample_type in sample_groups %}

      {{ sample_type.header }}

      -- cgit v1.2.3 From ef464fe82d8dfd517af2fae775973c46926e4c9b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 6 Dec 2012 18:21:30 -0600 Subject: Continued work on basic statistics table in show_trait Continued work towards getting show_trait to work with phenotype traits --- .../static/new/javascript/show_trait.coffee | 108 ++++++++++++++------- .../wqflask/static/new/javascript/show_trait.js | 101 +++++++++++-------- wqflask/wqflask/static/new/javascript/stats.coffee | 14 +++ wqflask/wqflask/static/new/javascript/stats.js | 17 ++++ wqflask/wqflask/templates/show_trait_details.html | 2 +- wqflask/wqflask/views.py | 12 ++- 6 files changed, 175 insertions(+), 79 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 3d9fcd5a..278a134b 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -4,6 +4,61 @@ console.log("start_b") is_number = (o) -> return ! isNaN (o-0) && o != null +Stat_Table_Rows = [ + { + vn: "n_of_samples" + pretty: "N of Samples" + digits: 0 + }, + { + vn: "mean" + pretty: "Mean" + digits: 2 + }, + { + vn: "median" + pretty: "Median" + digits: 2 + }, + { + vn: "std_error" + pretty: "Standard Error (SE)" + digits: 2 + }, + { + vn: "std_dev" + pretty: "Standard Deviation (SD)" + digits: 2 + }, + { + vn: "min" + pretty: "Minimum" + digits: 2 + }, + { + vn: "max" + pretty: "Maximum" + digits: 2 + }, + { + vn: "range" + pretty: "Range (log2)" + digits: 2 + }, + { + vn: "range_fold" + pretty: "Range (fold)" + digits: 2 + }, + { + vn: "interquartile" + pretty: "Interquartile Range" + url: "/glossary.html#Interquartile" + digits: 2 + } + + ] + $ -> hide_tabs = (start) -> for x in [start..10] @@ -30,19 +85,29 @@ $ -> the_value = sample_sets[category][value_type]() console.log("After running sample_sets, the_value is:", the_value) if decimal_places > 0 + title_value = the_value.toFixed(decimal_places * 2) the_value = the_value.toFixed(decimal_places) + else + title_value = null console.log("*-* the_value:", the_value) console.log("*-* current_value:", current_value) if the_value != current_value $(id).html(the_value).effect("highlight") + # We go ahead and always change the title value if we have it + if title_value + $(id).attr('title', title_value) + update_stat_values = (sample_sets)-> for category in ['samples_primary', 'samples_other', 'samples_all'] - change_stats_value(sample_sets, category, "n_of_samples", 0) - for stat in ["mean", "median", "std_dev", "std_error", "min", "max"] + #change_stats_value(sample_sets, category, "n_of_samples", 0) + + #for stat in ["mean", "median", "std_dev", "std_error", "min", "max"] + #for stat in (row.vn for row in Stat_Table_Rows) + for row in Stat_Table_Rows console.log("Calling change_stats_value") - change_stats_value(sample_sets, category, stat, 2) + change_stats_value(sample_sets, category, row.vn, row.digits) edit_data_change = -> sample_sets = @@ -94,41 +159,10 @@ $ -> header += "" console.log("windex header is:", header) - rows = [ - { - vn: "n_of_samples" - pretty: "N of Samples" - }, - { - vn: "mean" - pretty: "Mean" - }, - { - vn: "median" - pretty: "Median" - }, - { - vn: "std_error" - pretty: "Standard Error (SE)" - }, - { - vn: "std_dev" - pretty: "Standard Deviation (SD)" - }, - { - vn: "min" - pretty: "Minimum" - }, - { - vn: "max" - pretty: "Maximum" - } - ] - - console.log("rows are:", rows) + #console.log("rows are:", rows) the_rows = "" - console.log("length of rows:", rows.length) - for row in rows + #console.log("length of rows:", rows.length) + for row in Stat_Table_Rows console.log("rowing") row_line = """""" row_line += """#{ row.pretty }""" diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 84282aef..3a7bc387 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.3.3 (function() { - var is_number, + var Stat_Table_Rows, is_number, __hasProp = {}.hasOwnProperty, __slice = [].slice; @@ -10,6 +10,51 @@ return !isNaN((o - 0) && o !== null); }; + Stat_Table_Rows = [ + { + vn: "n_of_samples", + pretty: "N of Samples", + digits: 0 + }, { + vn: "mean", + pretty: "Mean", + digits: 2 + }, { + vn: "median", + pretty: "Median", + digits: 2 + }, { + vn: "std_error", + pretty: "Standard Error (SE)", + digits: 2 + }, { + vn: "std_dev", + pretty: "Standard Deviation (SD)", + digits: 2 + }, { + vn: "min", + pretty: "Minimum", + digits: 2 + }, { + vn: "max", + pretty: "Maximum", + digits: 2 + }, { + vn: "range", + pretty: "Range (log2)", + digits: 2 + }, { + vn: "range_fold", + pretty: "Range (fold)", + digits: 2 + }, { + vn: "interquartile", + pretty: "Interquartile Range", + url: "/glossary.html#Interquartile", + digits: 2 + } + ]; + $(function() { var block_by_attribute_value, block_by_index, block_outliers, change_stats_value, create_value_dropdown, edit_data_change, export_sample_table_data, get_sample_table_data, hide_no_value, hide_tabs, make_table, on_corr_method_change, populate_sample_attributes_values_dropdown, process_id, reset_samples_table, show_hide_outliers, stats_mdp_change, update_stat_values; hide_tabs = function(start) { @@ -27,7 +72,7 @@ return $("#stats_tabs" + selected).show(); }; change_stats_value = function(sample_sets, category, value_type, decimal_places) { - var current_value, id, in_box, the_value; + var current_value, id, in_box, the_value, title_value; id = "#" + process_id(category, value_type); console.log("the_id:", id); in_box = $(id).html; @@ -36,29 +81,33 @@ the_value = sample_sets[category][value_type](); console.log("After running sample_sets, the_value is:", the_value); if (decimal_places > 0) { + title_value = the_value.toFixed(decimal_places * 2); the_value = the_value.toFixed(decimal_places); + } else { + title_value = null; } console.log("*-* the_value:", the_value); console.log("*-* current_value:", current_value); if (the_value !== current_value) { - return $(id).html(the_value).effect("highlight"); + $(id).html(the_value).effect("highlight"); + } + if (title_value) { + return $(id).attr('title', title_value); } }; update_stat_values = function(sample_sets) { - var category, stat, _i, _len, _ref, _results; + var category, row, _i, _len, _ref, _results; _ref = ['samples_primary', 'samples_other', 'samples_all']; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { category = _ref[_i]; - change_stats_value(sample_sets, category, "n_of_samples", 0); _results.push((function() { - var _j, _len1, _ref1, _results1; - _ref1 = ["mean", "median", "std_dev", "std_error", "min", "max"]; + var _j, _len1, _results1; _results1 = []; - for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { - stat = _ref1[_j]; + for (_j = 0, _len1 = Stat_Table_Rows.length; _j < _len1; _j++) { + row = Stat_Table_Rows[_j]; console.log("Calling change_stats_value"); - _results1.push(change_stats_value(sample_sets, category, stat, 2)); + _results1.push(change_stats_value(sample_sets, category, row.vn, row.digits)); } return _results1; })()); @@ -96,7 +145,7 @@ return update_stat_values(sample_sets); }; make_table = function() { - var header, key, row, row_line, rows, table, the_id, the_rows, value, _i, _len, _ref, _ref1; + var header, key, row, row_line, table, the_id, the_rows, value, _i, _len, _ref, _ref1; header = " "; console.log("js_data.sample_group_types:", js_data.sample_group_types); _ref = js_data.sample_group_types; @@ -110,35 +159,9 @@ } header += ""; console.log("windex header is:", header); - rows = [ - { - vn: "n_of_samples", - pretty: "N of Samples" - }, { - vn: "mean", - pretty: "Mean" - }, { - vn: "median", - pretty: "Median" - }, { - vn: "std_error", - pretty: "Standard Error (SE)" - }, { - vn: "std_dev", - pretty: "Standard Deviation (SD)" - }, { - vn: "min", - pretty: "Minimum" - }, { - vn: "max", - pretty: "Maximum" - } - ]; - console.log("rows are:", rows); the_rows = ""; - console.log("length of rows:", rows.length); - for (_i = 0, _len = rows.length; _i < _len; _i++) { - row = rows[_i]; + for (_i = 0, _len = Stat_Table_Rows.length; _i < _len; _i++) { + row = Stat_Table_Rows[_i]; console.log("rowing"); row_line = ""; row_line += "" + row.pretty + ""; diff --git a/wqflask/wqflask/static/new/javascript/stats.coffee b/wqflask/wqflask/static/new/javascript/stats.coffee index 118ee7a8..d6d39245 100644 --- a/wqflask/wqflask/static/new/javascript/stats.coffee +++ b/wqflask/wqflask/static/new/javascript/stats.coffee @@ -42,6 +42,20 @@ class Stats max: -> return Math.max(@the_values...) + range: -> + return @max() - @min() + + range_fold: -> + return Math.pow(2, @range()) + + interquartile: -> + length = @the_values.length + # Todo: Consider averaging q1 and a3 when the length is odd + q1 = @the_values[Math.round(length * .25)] + q3 = @the_values[Math.round(length * .75)] + iq = q3 - q1 + return Math.pow(2, iq) + bxd_only = new Stats([3, 5, 7, 8]) console.log("[xred] bxd_only mean:", bxd_only.mean()) diff --git a/wqflask/wqflask/static/new/javascript/stats.js b/wqflask/wqflask/static/new/javascript/stats.js index 620f7d5d..5b7603ba 100644 --- a/wqflask/wqflask/static/new/javascript/stats.js +++ b/wqflask/wqflask/static/new/javascript/stats.js @@ -70,6 +70,23 @@ return Math.max.apply(Math, this.the_values); }; + Stats.prototype.range = function() { + return this.max() - this.min(); + }; + + Stats.prototype.range_fold = function() { + return Math.pow(2, this.range()); + }; + + Stats.prototype.interquartile = function() { + var iq, length, q1, q3; + length = this.the_values.length; + q1 = this.the_values[Math.round(length * .25)]; + q3 = this.the_values[Math.round(length * .75)]; + iq = q3 - q1; + return Math.pow(2, iq); + }; + return Stats; })(); diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index e04fdd66..4b3862c7 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -7,7 +7,7 @@
      Database
      - + {{ dataset.name }}
      diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 17dc42fb..70d8cd20 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -4,6 +4,7 @@ import csv import StringIO # Todo: Use cStringIO? import simplejson as json +#import json import yaml import flask @@ -95,10 +96,17 @@ def show_trait_page(): #fd = webqtlFormData.webqtlFormData(request.args) #print("stp y1:", pf(vars(fd))) template_vars = show_trait.ShowTrait(request.args) + + print("js_data before dump:", template_vars.js_data) + template_vars.js_data = json.dumps(template_vars.js_data, default=json_default_handler, - indent=" ", - sort_keys=True) + indent=" ") + # Sorting the keys messes up the ordered dictionary, so don't do that + #sort_keys=True) + + print("js_data after dump:", template_vars.js_data) + print("show_trait template_vars:", pf(template_vars.__dict__)) return render_template("show_trait.html", **template_vars.__dict__) -- cgit v1.2.3 From 8d0199efadafc0c6dff70415f2dc45b5b363da0f Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 6 Dec 2012 18:36:39 -0600 Subject: All 10 stats working --- wqflask/wqflask/static/new/javascript/stats.coffee | 8 ++++++-- wqflask/wqflask/static/new/javascript/stats.js | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/stats.coffee b/wqflask/wqflask/static/new/javascript/stats.coffee index d6d39245..bf79d6c3 100644 --- a/wqflask/wqflask/static/new/javascript/stats.coffee +++ b/wqflask/wqflask/static/new/javascript/stats.coffee @@ -36,6 +36,8 @@ class Stats std_error: -> return @std_dev() / Math.sqrt(@n_of_samples()) + # We could also just use the first value here (and last in max) because we assume the + # lists are sorted for things like interquartile (and in fact they are) min: -> return Math.min(@the_values...) @@ -51,8 +53,10 @@ class Stats interquartile: -> length = @the_values.length # Todo: Consider averaging q1 and a3 when the length is odd - q1 = @the_values[Math.round(length * .25)] - q3 = @the_values[Math.round(length * .75)] + console.log("in interquartile the_values are:", @the_values) + console.log("length is:", length) + q1 = @the_values[Math.floor(length * .25)] + q3 = @the_values[Math.floor(length * .75)] iq = q3 - q1 return Math.pow(2, iq) diff --git a/wqflask/wqflask/static/new/javascript/stats.js b/wqflask/wqflask/static/new/javascript/stats.js index 5b7603ba..36e96640 100644 --- a/wqflask/wqflask/static/new/javascript/stats.js +++ b/wqflask/wqflask/static/new/javascript/stats.js @@ -81,8 +81,10 @@ Stats.prototype.interquartile = function() { var iq, length, q1, q3; length = this.the_values.length; - q1 = this.the_values[Math.round(length * .25)]; - q3 = this.the_values[Math.round(length * .75)]; + console.log("in interquartile the_values are:", this.the_values); + console.log("length is:", length); + q1 = this.the_values[Math.floor(length * .25)]; + q3 = this.the_values[Math.floor(length * .75)]; iq = q3 - q1; return Math.pow(2, iq); }; -- cgit v1.2.3 From 8aa6cc5c1cf85ae9f3ac6c87ff0c354af5c947c7 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 7 Dec 2012 14:12:14 -0600 Subject: Got show_trait page to appear again for phenotype traits Need to see why other samples list doesn't appear for traits in BXDPublishedPhenotypes --- wqflask/wqflask/do_search.py | 26 ++++------------------- wqflask/wqflask/show_trait/SampleList.py | 3 ++- wqflask/wqflask/show_trait/show_trait.py | 3 ++- wqflask/wqflask/templates/show_trait_details.html | 5 ++++- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 403f1b5e..3ce613e9 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -198,26 +198,6 @@ class PhenotypeSearch(DoSearch): query = self.compile_final_query(where_clause = self.get_fields_clause()) -# self.query = """SELECT PublishXRef.Id, -#PublishFreeze.createtime as thistable, -#Publication.PubMed_ID as Publication_PubMed_ID, -#Phenotype.Post_publication_description as Phenotype_Name FROM Phenotype, -#PublishFreeze, Publication, PublishXRef WHERE (Phenotype.Post_publication_description -#REGEXP "[[:<:]]brain[[:>:]]" OR Phenotype.Pre_publication_description REGEXP "[[:<:]]brain[[:>:]]" -#OR Phenotype.Pre_publication_abbreviation REGEXP "[[:<:]]brain[[:>:]]" -#OR Phenotype.Post_publication_abbreviation REGEXP "[[:<:]]brain[[:>:]]" -#OR Phenotype.Lab_code REGEXP "[[:<:]]brain[[:>:]]" -#OR Publication.PubMed_ID REGEXP "[[:<:]]brain[[:>:]]" -#OR Publication.Abstract REGEXP "[[:<:]]brain[[:>:]]" -#OR Publication.Title REGEXP "[[:<:]]brain[[:>:]]" -#OR Publication.Authors REGEXP "[[:<:]]brain[[:>:]]" -#OR PublishXRef.Id REGEXP "[[:<:]]brain[[:>:]]") -#and PublishXRef.InbredSetId = 1 -#and PublishXRef.PhenotypeId = Phenotype.Id -#and PublishXRef.PublicationId = Publication.Id -#and PublishFreeze.Id = 1;""" - - results = self.execute(query) print("in [df] run results are:", results) return results @@ -461,7 +441,8 @@ class CisTransLrsSearch(LrsSearch): class CisLrsSearch(CisTransLrsSearch): - """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values + """ + Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values A cisLRS search can take 3 forms: - cisLRS=(min_LRS max_LRS) @@ -484,9 +465,10 @@ class CisLrsSearch(CisTransLrsSearch): class TransLrsSearch(CisTransLrsSearch): """Searches for genes on a particular chromosome with a cis-eQTL within the given LRS values - A transLRS search can take 2 forms: + A transLRS search can take 3 forms: - transLRS=(min_LRS max_LRS) - transLRS=(min_LRS max_LRS mb_buffer) + - transLRS>min_LRS where min/max_LRS represent the range of LRS scores and the mb_buffer is the range around a particular QTL where its eQTL would be considered "cis". If there is no third parameter, mb_buffer will default to 5 megabases. diff --git a/wqflask/wqflask/show_trait/SampleList.py b/wqflask/wqflask/show_trait/SampleList.py index 0c752617..d98a810a 100644 --- a/wqflask/wqflask/show_trait/SampleList.py +++ b/wqflask/wqflask/show_trait/SampleList.py @@ -56,7 +56,8 @@ class SampleList(object): if self.this_trait and self.dataset and self.dataset.type == 'ProbeSet': sample.extra_attributes = self.get_extra_attribute_values(sample_name) print("sample.extra_attributes is", pf(sample.extra_attributes)) - self.sample_list.append(sample) + + self.sample_list.append(sample) print("self.attributes is", pf(self.attributes)) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index d1c60877..0f593216 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -1627,10 +1627,11 @@ class ShowTrait(object): this_trait=this_trait, sample_group_type='primary', header="%s Only" % (self.dataset.group.name)) + print("primary_samples is: ", pf(primary_samples)) + other_sample_names = [] for sample in this_trait.data.keys(): - print("hjk - sample is:", sample) if sample not in all_samples_ordered: all_samples_ordered.append(sample) other_sample_names.append(sample) diff --git a/wqflask/wqflask/templates/show_trait_details.html b/wqflask/wqflask/templates/show_trait_details.html index 4b3862c7..c3abfc9f 100644 --- a/wqflask/wqflask/templates/show_trait_details.html +++ b/wqflask/wqflask/templates/show_trait_details.html @@ -12,6 +12,7 @@ + {% if this_trait.probe_set_specificity %}
      @@ -19,9 +20,11 @@
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      - + {% endif %} + {% if this_trait.probe_set_blat_score %}
      BLAT Score
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      + {% endif %} -- cgit v1.2.3 From ef26532ba2792afdcca65d5f5f3c03f93a33f1ae Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 7 Dec 2012 15:04:44 -0600 Subject: Got basic statistics in show_trait to display the correct number of samples for each group Got show_trait page to display for genotype traits --- wqflask/base/trait.py | 102 +-------------------- wqflask/wqflask/do_search.py | 18 ++-- wqflask/wqflask/parser.py | 17 ++++ wqflask/wqflask/search_results.py | 23 ----- wqflask/wqflask/show_trait/show_trait.py | 50 +++++----- .../static/new/javascript/show_trait.coffee | 22 ++--- .../wqflask/static/new/javascript/show_trait.js | 12 ++- 7 files changed, 72 insertions(+), 172 deletions(-) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index d0158ebd..8c9e3b10 100755 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -258,113 +258,15 @@ class GeneralTrait: #else: results = self.dataset.retrieve_sample_data(self) - #if self.dataset.type == 'Temp': - # query = ''' - # SELECT - # Strain.Name, TempData.value, TempData.SE, TempData.NStrain, TempData.Id - # FROM - # TempData, Temp, Strain - # WHERE - # TempData.StrainId = Strain.Id AND - # TempData.Id = Temp.DataId AND - # Temp.name = '%s' - # Order BY - # Strain.Name - # ''' % self.name - ##XZ, 03/02/2009: Xiaodong changed Data to PublishData, SE to PublishSE - #elif self.dataset.type == 'Publish': - # query = ''' - # SELECT - # Strain.Name, PublishData.value, PublishSE.error, NStrain.count, PublishData.Id - # FROM - # (PublishData, Strain, PublishXRef, PublishFreeze) - # left join PublishSE on - # (PublishSE.DataId = PublishData.Id AND PublishSE.StrainId = PublishData.StrainId) - # left join NStrain on - # (NStrain.DataId = PublishData.Id AND - # NStrain.StrainId = PublishData.StrainId) - # WHERE - # PublishXRef.InbredSetId = PublishFreeze.InbredSetId AND - # PublishData.Id = PublishXRef.DataId AND PublishXRef.Id = %s AND - # PublishFreeze.Id = %d AND PublishData.StrainId = Strain.Id - # Order BY - # Strain.Name - # ''' % (self.name, self.dataset.id) - - #XZ, 03/02/2009: Xiaodong changed Data to ProbeData, SE to ProbeSE - #elif self.cellid: - - #XZ, 03/02/2009: Xiaodong added this block for ProbeSetData and ProbeSetSE - #elif self.dataset.type == 'ProbeSet': - # #ProbeSet Data - # query = ''' - # SELECT - # Strain.Name, ProbeSetData.value, ProbeSetSE.error, ProbeSetData.Id - # FROM - # (ProbeSetData, ProbeSetFreeze, Strain, ProbeSet, ProbeSetXRef) - # left join ProbeSetSE on - # (ProbeSetSE.DataId = ProbeSetData.Id AND ProbeSetSE.StrainId = ProbeSetData.StrainId) - # WHERE - # ProbeSet.Name = '%s' AND ProbeSetXRef.ProbeSetId = ProbeSet.Id AND - # ProbeSetXRef.ProbeSetFreezeId = ProbeSetFreeze.Id AND - # ProbeSetFreeze.Name = '%s' AND - # ProbeSetXRef.DataId = ProbeSetData.Id AND - # ProbeSetData.StrainId = Strain.Id - # Order BY - # Strain.Name - # ''' % (self.name, self.dataset.name) - ##XZ, 03/02/2009: Xiaodong changeded Data to GenoData, SE to GenoSE - #else: - # #Geno Data - # #XZ: The SpeciesId is not necessary, but it's nice to keep it to speed up database search. - # query = ''' - # SELECT - # Strain.Name, GenoData.value, GenoSE.error, GenoData.Id - # FROM - # (GenoData, GenoFreeze, Strain, Geno, GenoXRef) - # left join GenoSE on - # (GenoSE.DataId = GenoData.Id AND GenoSE.StrainId = GenoData.StrainId) - # WHERE - # Geno.SpeciesId = %s AND Geno.Name = '%s' AND GenoXRef.GenoId = Geno.Id AND - # GenoXRef.GenoFreezeId = GenoFreeze.Id AND - # GenoFreeze.Name = '%s' AND - # GenoXRef.DataId = GenoData.Id AND - # GenoData.StrainId = Strain.Id - # Order BY - # Strain.Name - # ''' % (webqtlDatabaseFunction.retrieveSpeciesId(self.cursor, self.dataset.group), self.name, self.dataset.name) - - - #self.cursor.execute(query) - #results = self.cursor.fetchall() - # Todo: is this necessary? If not remove self.data.clear() if results: - #self.mysqlid = results[0][-1] - #if samplelist: for item in results: #name, value, variance, num_cases = item if not samplelist or (samplelist and name in samplelist): - #if value != None: - # num_cases = None - # if self.dataset.type in ('Publish', 'Temp'): - # ndata = item[3] name = item[0] self.data[name] = webqtlCaseData(*item) #name, value, variance, num_cases) - #end for - # else: - # for item in results: - # val = item[1] - # if val != None: - # var = item[2] - # ndata = None - # if self.dataset.type in ('Publish', 'Temp'): - # ndata = item[3] - # self.data[item[0]] = webqtlCaseData(val, var, ndata) - # #end for - # #end if #def keys(self): # return self.__dict__.keys() @@ -429,7 +331,9 @@ class GeneralTrait: GenoXRef.GenoId = Geno.Id AND GenoFreeze.Name = '%s' AND Geno.Name = '%s' - """ % (escape(display_fields_string), escape(self.dataset.name), escape(self.name)) + """ % (escape(display_fields_string), + escape(self.dataset.name), + escape(self.name)) traitInfo = g.db.execute(query).fetchone() print("traitInfo is: ", pf(traitInfo)) else: #Temp type diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index 3ce613e9..fc45395c 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -60,7 +60,7 @@ class DoSearch(object): return cls.search_types[search_type] -class ProbeSetSearch(DoSearch): +class MrnaAssaySearch(DoSearch): """A search within an mRNA expression dataset""" DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" @@ -265,7 +265,7 @@ class GenotypeSearch(DoSearch): return self.execute(self.query) -class RifSearch(ProbeSetSearch): +class RifSearch(MrnaAssaySearch): """Searches for traits with a Gene RIF entry including the search term.""" DoSearch.search_types['RIF'] = "RifSearch" @@ -280,7 +280,7 @@ class RifSearch(ProbeSetSearch): return self.execute(query) -class WikiSearch(ProbeSetSearch): +class WikiSearch(MrnaAssaySearch): """Searches GeneWiki for traits other people have annotated""" DoSearch.search_types['WIKI'] = "WikiSearch" @@ -298,7 +298,7 @@ class WikiSearch(ProbeSetSearch): return self.execute(query) -class GoSearch(ProbeSetSearch): +class GoSearch(MrnaAssaySearch): """Searches for synapse-associated genes listed in the Gene Ontology.""" DoSearch.search_types['GO'] = "GoSearch" @@ -323,7 +323,7 @@ class GoSearch(ProbeSetSearch): return self.execute(query) #ZS: Not sure what the best way to deal with LRS searches is -class LrsSearch(ProbeSetSearch): +class LrsSearch(MrnaAssaySearch): """Searches for genes with a QTL within the given LRS values LRS searches can take 3 different forms: @@ -484,7 +484,7 @@ class TransLrsSearch(CisTransLrsSearch): return self.real_run(">") -class MeanSearch(ProbeSetSearch): +class MeanSearch(MrnaAssaySearch): """Searches for genes expressed within an interval (log2 units) determined by the user""" DoSearch.search_types['MEAN'] = "MeanSearch" @@ -514,7 +514,7 @@ class MeanSearch(ProbeSetSearch): return self.execute(self.query) -class RangeSearch(ProbeSetSearch): +class RangeSearch(MrnaAssaySearch): """Searches for genes with a range of expression varying between two values""" DoSearch.search_types['RANGE'] = "RangeSearch" @@ -571,7 +571,7 @@ class PositionSearch(DoSearch): return self.execute(self.query) -class MrnaPositionSearch(ProbeSetSearch, PositionSearch): +class MrnaPositionSearch(MrnaAssaySearch, PositionSearch): """Searches for genes located within a specified range on a specified chromosome""" def run(self): @@ -591,7 +591,7 @@ class GenotypePositionSearch(GenotypeSearch, PositionSearch): return self.execute(self.query) -class PvalueSearch(ProbeSetSearch): +class PvalueSearch(MrnaAssaySearch): """Searches for traits with a permutationed p-value between low and high""" def run(self): diff --git a/wqflask/wqflask/parser.py b/wqflask/wqflask/parser.py index f991d8c7..be92014d 100644 --- a/wqflask/wqflask/parser.py +++ b/wqflask/wqflask/parser.py @@ -73,6 +73,23 @@ def parse(pstring): print("* items are:", pf(items) + "\n") return(items) + #def encregexp(self,str): + # if not str: + # return [] + # else: + # wildcardkeyword = str.strip() + # wildcardkeyword = string.replace(wildcardkeyword,',',' ') + # wildcardkeyword = string.replace(wildcardkeyword,';',' ') + # wildcardkeyword = wildcardkeyword.split() + # NNN = len(wildcardkeyword) + # for i in range(NNN): + # keyword = wildcardkeyword[i] + # keyword = string.replace(keyword,"*",".*") + # keyword = string.replace(keyword,"?",".") + # wildcardkeyword[i] = keyword#'[[:<:]]'+ keyword+'[[:>:]]' + # return wildcardkeyword + + if __name__ == '__main__': parse("foo=[3 2 1]") parse("WIKI=ho*") diff --git a/wqflask/wqflask/search_results.py b/wqflask/wqflask/search_results.py index 5cb8e314..d986a2e0 100644 --- a/wqflask/wqflask/search_results.py +++ b/wqflask/wqflask/search_results.py @@ -54,11 +54,6 @@ class SearchResultPage(templatePage): # change back to self.dataset #if not self.dataset or self.dataset == 'spacer': # #Error, No dataset selected - # heading = "Search Result" - # detail = ['''No dataset was selected for this search, please - # go back and SELECT at least one dataset.'''] - # self.error(heading=heading,detail=detail,error="No dataset Selected") - # return ########################################### # Names and IDs of group / F2 set @@ -144,21 +139,3 @@ class SearchResultPage(templatePage): print("in the search results are:", self.results) self.header_fields = the_search.header_fields - - - #ZS: This should be handled in the parser - def encregexp(self,str): - if not str: - return [] - else: - wildcardkeyword = str.strip() - wildcardkeyword = string.replace(wildcardkeyword,',',' ') - wildcardkeyword = string.replace(wildcardkeyword,';',' ') - wildcardkeyword = wildcardkeyword.split() - NNN = len(wildcardkeyword) - for i in range(NNN): - keyword = wildcardkeyword[i] - keyword = string.replace(keyword,"*",".*") - keyword = string.replace(keyword,"?",".") - wildcardkeyword[i] = keyword#'[[:<:]]'+ keyword+'[[:>:]]' - return wildcardkeyword diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 0f593216..836d37ea 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -828,35 +828,34 @@ class ShowTrait(object): elif this_trait and this_trait.dataset and this_trait.dataset.type == 'Geno': #Check if trait is genotype - GenoInfo = HT.Paragraph() if this_trait.chr and this_trait.mb: location = ' Chr %s @ %s Mb' % (this_trait.chr,this_trait.mb) else: location = "not available" - if this_trait.sequence and len(this_trait.sequence) > 100: - if _Species == "rat": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', this_trait.sequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('rat', 'rn3', this_trait.sequence) - elif _Species == "mouse": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', this_trait.sequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', this_trait.sequence) - elif _Species == "human": - UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) - UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('human', 'hg19', this_trait.sequence) - else: - UCSC_BLAT_URL = "" - UTHSC_BLAT_URL = "" - if UCSC_BLAT_URL: - #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) - verifyButton = HT.Href(url="#") - verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") - verifyButton.append(verifyButtonImg) - verifyText = "Verify" - rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) - rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") - rnaseqButton.append(rnaseqButtonImg) - rnaseqText = "RNA-seq" + #if this_trait.sequence and len(this_trait.sequence) > 100: + # if _Species == "rat": + # UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('rat', 'rn3', this_trait.sequence) + # UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('rat', 'rn3', this_trait.sequence) + # elif _Species == "mouse": + # UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('mouse', 'mm9', this_trait.sequence) + # UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('mouse', 'mm9', this_trait.sequence) + # elif _Species == "human": + # UCSC_BLAT_URL = webqtlConfig.UCSC_BLAT % ('human', 'hg19', blatsequence) + # UTHSC_BLAT_URL = webqtlConfig.UTHSC_BLAT % ('human', 'hg19', this_trait.sequence) + # else: + # UCSC_BLAT_URL = "" + # UTHSC_BLAT_URL = "" + # if UCSC_BLAT_URL: + # #verifyButton = HT.Href(url="#", onClick="openNewWin('%s')" % UCSC_BLAT_URL) + # verifyButton = HT.Href(url="#") + # verifyButtonImg = HT.Image("/images/verify_icon.jpg", name="verify", alt=" Check probe locations at UCSC ", title=" Check probe locations at UCSC ", style="border:none;") + # verifyButton.append(verifyButtonImg) + # verifyText = "Verify" + # rnaseqButton = HT.Href(url="#", onClick="openNewWin('%s')" % UTHSC_BLAT_URL) + # rnaseqButtonImg = HT.Image("/images/rnaseq_icon.jpg", name="rnaseq", alt=" View probes, SNPs, and RNA-seq at UTHSC ", title=" View probes, SNPs, and RNA-seq at UTHSC ", style="border:none;") + # rnaseqButton.append(rnaseqButtonImg) + # rnaseqText = "RNA-seq" #tbl.append(HT.TR( # HT.TD('Location: ', Class="fs13 fwb", @@ -872,7 +871,7 @@ class ShowTrait(object): # valign="top", width=740) # )) - menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") + #menuTable = HT.TableLite(cellpadding=2, Class="collap", width="275", id="target1") #menuTable.append(HT.TR(HT.TD(addSelectionButton, align="center"),HT.TD(verifyButton, align="center"),HT.TD(rnaseqButton, align="center"), HT.TD(updateButton, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) #menuTable.append(HT.TR(HT.TD(addSelectionText, align="center"),HT.TD(verifyText, align="center"),HT.TD(rnaseqText, align="center"), HT.TD(updateText, align="center"), colspan=3, height=50, style="vertical-align:bottom;")) @@ -1629,7 +1628,6 @@ class ShowTrait(object): header="%s Only" % (self.dataset.group.name)) print("primary_samples is: ", pf(primary_samples)) - other_sample_names = [] for sample in this_trait.data.keys(): if sample not in all_samples_ordered: diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 278a134b..04d55be7 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -110,6 +110,7 @@ $ -> change_stats_value(sample_sets, category, row.vn, row.digits) edit_data_change = -> + already_seen = {} sample_sets = samples_primary: new Stats([]) samples_other: new Stats([]) @@ -117,21 +118,14 @@ $ -> console.log("at beginning:", sample_sets) - # ########## - # Bug here #value_table doesn't exist and why is it a class? - # ########## - - #values = $('.value_table').find(".edit_sample_value") - - tables = ['samples_primary', 'samples_other'] for table in tables rows = $("#" + table).find('tr') console.log("[fuji3] rows:", rows) for row in rows + name = $(row).find('.edit_sample_sample_name').html() + name = $.trim(name) real_value = $(row).find('.edit_sample_value').val() - #row = $(value).closest("tr") - #category = row[0].id console.log("real_value:", real_value) checkbox = $(row).find(".edit_sample_checkbox") checked = $(checkbox).attr('checked') @@ -139,11 +133,13 @@ $ -> if checked and is_number(real_value) and real_value != "" console.log("in the iffy if") real_value = parseFloat(real_value) - #if _(category).startsWith("Primary") + sample_sets[table].add_value(real_value) - #else if _(category).startsWith("Other") - # sample_sets.other_only.add_value(real_value) - sample_sets['samples_all'].add_value(real_value) + console.log("checking name of:", name) + if not (name of already_seen) + console.log("haven't seen") + sample_sets['samples_all'].add_value(real_value) + already_seen[name] = true console.log("towards end:", sample_sets) update_stat_values(sample_sets) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 3a7bc387..1037c890 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -115,7 +115,8 @@ return _results; }; edit_data_change = function() { - var checkbox, checked, real_value, row, rows, sample_sets, table, tables, _i, _j, _len, _len1; + var already_seen, checkbox, checked, name, real_value, row, rows, sample_sets, table, tables, _i, _j, _len, _len1; + already_seen = {}; sample_sets = { samples_primary: new Stats([]), samples_other: new Stats([]), @@ -129,6 +130,8 @@ console.log("[fuji3] rows:", rows); for (_j = 0, _len1 = rows.length; _j < _len1; _j++) { row = rows[_j]; + name = $(row).find('.edit_sample_sample_name').html(); + name = $.trim(name); real_value = $(row).find('.edit_sample_value').val(); console.log("real_value:", real_value); checkbox = $(row).find(".edit_sample_checkbox"); @@ -137,7 +140,12 @@ console.log("in the iffy if"); real_value = parseFloat(real_value); sample_sets[table].add_value(real_value); - sample_sets['samples_all'].add_value(real_value); + console.log("checking name of:", name); + if (!(name in already_seen)) { + console.log("haven't seen"); + sample_sets['samples_all'].add_value(real_value); + already_seen[name] = true; + } } } } -- cgit v1.2.3 From a0ab498f670a674b96e6f10064e787fb995403ac Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 7 Dec 2012 15:17:30 -0600 Subject: Got links working for statistics table labels --- wqflask/wqflask/static/new/javascript/show_trait.coffee | 5 ++++- wqflask/wqflask/static/new/javascript/show_trait.js | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.coffee b/wqflask/wqflask/static/new/javascript/show_trait.coffee index 04d55be7..eb87cf04 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait.coffee @@ -161,7 +161,10 @@ $ -> for row in Stat_Table_Rows console.log("rowing") row_line = """""" - row_line += """#{ row.pretty }""" + if row.url? + row_line += """#{ row.pretty }""" + else + row_line += """#{ row.pretty }""" console.log("box - js_data.sample_group_types:", js_data.sample_group_types) for own key, value of js_data.sample_group_types console.log("apple key:", key) diff --git a/wqflask/wqflask/static/new/javascript/show_trait.js b/wqflask/wqflask/static/new/javascript/show_trait.js index 1037c890..ff705ea5 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait.js +++ b/wqflask/wqflask/static/new/javascript/show_trait.js @@ -172,7 +172,11 @@ row = Stat_Table_Rows[_i]; console.log("rowing"); row_line = ""; - row_line += "" + row.pretty + ""; + if (row.url != null) { + row_line += "" + row.pretty + ""; + } else { + row_line += "" + row.pretty + ""; + } console.log("box - js_data.sample_group_types:", js_data.sample_group_types); _ref1 = js_data.sample_group_types; for (key in _ref1) { -- cgit v1.2.3 From daea7eb0eb4eef445140275522703e7e2214154b Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 18 Dec 2012 17:15:09 -0600 Subject: Created new file species.py and species class object TheSpecies Converted html for the mapping tabs to bootstrap and redid html inside of the Interval Mapping tab Added text input for # of permutation tests and bootstrap tests --- wqflask/base/data_set.py | 8 +- wqflask/base/species.py | 16 + wqflask/wqflask/show_trait/show_trait.py | 3 +- .../templates/show_trait_mapping_tools.html | 551 +++++++-------------- wqflask/wqflask/views.py | 8 + 5 files changed, 218 insertions(+), 368 deletions(-) create mode 100644 wqflask/base/species.py diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 2182fe9e..612b9209 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -30,6 +30,7 @@ from htmlgen import HTMLgen2 as HT import reaper import webqtlConfig +from base import species from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil @@ -145,7 +146,7 @@ class DataSet(object): def __init__(self, name): - assert name + assert name, "Need a name" self.name = name self.id = None self.type = None @@ -155,7 +156,10 @@ class DataSet(object): self.check_confidentiality() self.retrieve_other_names() - self.group = DatasetGroup(self) # sets self.group and self.group_id + + self.species = species.TheSpecies(self) + self.group = DatasetGroup(self) # sets self.group and self.group_id and gets genotype + def get_desc(self): diff --git a/wqflask/base/species.py b/wqflask/base/species.py new file mode 100644 index 00000000..98941ce5 --- /dev/null +++ b/wqflask/base/species.py @@ -0,0 +1,16 @@ +from __future__ import print_function, division + + +class TheSpecies(object): + def __init__(self, dataset): + self.dataset = dataset + + @property + def chromosomes(self): + chromosomes = [("All", -1)] + + for counter, genotype in enumerate(self.dataset.group.genotype): + if len(genotype) > 1: + chromosomes.append((genotype.name, counter)) + + return chromosomes diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 836d37ea..c605cb58 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -1354,7 +1354,8 @@ class ShowTrait(object): return_results_menu_selected = return_results_menu_selected,) - def dispMappingTools(self, fd, title4Body, this_trait): + def build_mapping_tools(self, this_trait): + _Species = webqtlDatabaseFunction.retrieveSpecies(cursor=self.cursor, group=fd.group) diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index 90498e9a..1109ded3 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -1,382 +1,203 @@ -

        Mapping Tools

      - -

      - - - -
      -
      - - -
      - - - - - - +
      +

      Mapping Tools

      + +
      + + +
      +
      + + +
      + {% if dataset.group.genotype.Mbmap %} + + + {% endif %} +
      + + + + +
      + + +
      + +
      +
      +
      - - - - - - - - - - - - -
      Chromosome:
      Mapping Scale:

      - Permutation Test (n=2000)
      - Bootstrap Test (n=2000)
      - Use Parents
      - Use Weighted
      -
      -
      -
      -
      + + + + + + + +
      + + + + + + + + + + + + + + + + + + +
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      +
      +
      +
      Marker regression computes and displays LRS + values for individual markers.
      + This function also lists additive effects (phenotype units per allele) and
      + dominance deviations for some datasets.

      +
      + +
      + + + + + + + + +
      + + + + + + + + + + + + +
      Sort by:
      Return:

      + Permutation Test + (n=500)
      +
      +
      +
      +
      Pair-Scan searches for pairs of chromosomal regions + that are
      + involved in two-locus epistatic interactions.

      +
      +
      + + + + diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 70d8cd20..503b0972 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -160,6 +160,14 @@ def corr_compute_page(): print("Made it to rendering") return render_template("correlation_page.html", **template_vars.__dict__) +@app.route("/int_mapping", methods=('POST',)) +def interval_mapping_page(): + fd = webqtlFormData.webqtlFormData(request.form) + print("Have fd") + template_vars = CorrelationPage.CorrelationPage(fd) + print("Made it to rendering") + return render_template("correlation_page.html", **template_vars.__dict__) + # Todo: Can we simplify this? -Sam def sharing_info_page(): -- cgit v1.2.3 From 58965a746aea4d6fc34e101a0958ecdc46493acb Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Tue, 18 Dec 2012 18:02:19 -0600 Subject: Changed html for the marker regression tab Created file show_trait_mapping_tools.coffee to handle submitting the form to the marker regression page Changed form name/id in show_trait.html to "trait_data_form" --- .../new/javascript/show_trait_mapping_tools.coffee | 8 +++ .../new/javascript/show_trait_mapping_tools.js | 16 ++++++ wqflask/wqflask/templates/show_trait.html | 3 +- .../templates/show_trait_mapping_tools.html | 57 ++++++++++------------ 4 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee create mode 100644 wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee new file mode 100644 index 00000000..cd6dc1d8 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee @@ -0,0 +1,8 @@ +$ -> + run_marker_regression = -> + console.log("In marker regression") + url = "/marker_regression" + $("#trait_data_form").attr("action", url); + $("#trait_data_form").submit() + + $("#marker_regression_btn").click(run_marker_regression) \ No newline at end of file diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js new file mode 100644 index 00000000..cca396a9 --- /dev/null +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -0,0 +1,16 @@ +// Generated by CoffeeScript 1.3.3 +(function() { + + $(function() { + var run_marker_regression; + run_marker_regression = function() { + var url; + console.log("In marker regression"); + url = "/marker_regression"; + $("#trait_data_form").attr("action", url); + return $("#trait_data_form").submit(); + }; + return $("#marker_regression_btn").click(run_marker_regression); + }); + +}).call(this); diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 28341186..6d1a3d4b 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -11,7 +11,7 @@ -
      + {% for key in hddn %} {% endfor %} @@ -48,5 +48,6 @@ + {% endblock %} diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index 1109ded3..d584a774 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -49,43 +49,36 @@ Use Weighted
      - + +
      + Composite Mapping + - Control for a marker as a co-factor (e.g.: rs12345): + + +
      + +
      - - - - - - - '; + })).appendTo(self.dialog).addClass('ui-dialog-content ui-widget-content'); + + self._initAllParts(); + self._generateAllParts(); + self.generated = true; + } + }, + + _layoutTable: function(layout, callback) { + var layout = layout.sort(function(a, b) { + if (a.pos[1] == b.pos[1]) { + return a.pos[0] - b.pos[0]; + } + return a.pos[1] - b.pos[1]; + }), + bitmap, + x, + y, + width, height, + columns, rows, + index, + cell, + html; + + // Determine dimensions of the table + width = 0; + height = 0; + for (index in layout) { + width = Math.max(width, layout[index].pos[0] + layout[index].pos[2]); + height = Math.max(height, layout[index].pos[1] + layout[index].pos[3]); + } + + // Initialize bitmap + bitmap = []; + for (x = 0; x < width; ++x) { + bitmap.push(new Array(height)); + } + + // Mark rows and columns which have layout assigned + rows = new Array(height); + columns = new Array(width); + for (index in layout) { + // mark columns + for (x = 0; x < layout[index].pos[2]; x += 1) { + columns[layout[index].pos[0] + x] = true; + } + for (y = 0; y < layout[index].pos[3]; y += 1) { + rows[layout[index].pos[1] + y] = true; + } + } + + // Generate the table + html = ''; + cell = layout[index = 0]; + for (y = 0; y < height; ++y) { + html += ''; + for (x = 0; x < width;) { + if (cell !== undefined && x == cell.pos[0] && y == cell.pos[1]) { + // Create a "real" cell + var w, + h; + + html += callback(cell, x, y); + + for (h = 0; h < cell.pos[3]; h +=1) { + for (w = 0; w < cell.pos[2]; w +=1) { + bitmap[x + w][y + h] = true; + } + } + + x += cell.pos[2]; + cell = layout[++index]; + } else { + // Fill in the gaps + var colspan = 0; + var walked = false; + + while (x < width && bitmap[x][y] === undefined && (cell === undefined || y < cell.pos[1] || (y == cell.pos[1] && x < cell.pos[0]))) { + if (columns[x] === true) { + colspan += 1; + } + walked = true; + x += 1; + } + + if (colspan > 0) { + html += ''; + } else if (!walked) { + x += 1; + } + } + } + html += ''; + } + + return '
      - - - - - - - - - - - - - - - - - - -
      Display LRS greater than:
      Display all LRS
      Use Parents
      Use Weighted

      -
      -
      -
      Marker regression computes and displays LRS + + + + + + +
      -- cgit v1.2.3 From f807e10d835077ecca5e886ea27a9f70cbc1b40c Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 20 Dec 2012 15:06:56 -0600 Subject: Form data passed via POST for marker regression Removed "Use Parents" and "Use Weighted" Created text box to input # permutations for pair scan --- .../templates/show_trait_mapping_tools.html | 29 ++++++---------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index d584a774..83454c08 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -32,22 +32,13 @@ {% endif %}
      -
      -- cgit v1.2.3 From 25fccfb3447012c3f2a75e3f54520e700d801487 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 3 Jan 2013 15:54:53 -0600 Subject: Created template for marek regression page and made the compute button direct to it added asbolute_import in data_set.py and trait.py Made several minor changes and deleted commented out code in trait.py --- wqflask/base/data_set.py | 7 +- wqflask/base/trait.py | 78 +++--------- wqflask/wqflask/do_search.py | 2 +- wqflask/wqflask/show_trait/show_trait.py | 133 +++++---------------- .../new/javascript/show_trait_mapping_tools.coffee | 18 ++- .../new/javascript/show_trait_mapping_tools.js | 15 ++- wqflask/wqflask/templates/marker_regression.html | 51 ++++++++ .../templates/show_trait_mapping_tools.html | 8 +- wqflask/wqflask/views.py | 63 +++++----- 9 files changed, 160 insertions(+), 215 deletions(-) create mode 100644 wqflask/wqflask/templates/marker_regression.html diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 612b9209..36d4acaf 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -16,11 +16,11 @@ # Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) # at rwilliams@uthsc.edu and xzhou15@uthsc.edu # -# +#we # # This module is used by GeneNetwork project (www.genenetwork.org) -from __future__ import print_function, division +from __future__ import absolute_import, print_function, division import os from flask import Flask, g @@ -29,7 +29,7 @@ from htmlgen import HTMLgen2 as HT import reaper -import webqtlConfig +from base import webqtlConfig from base import species from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil @@ -50,6 +50,7 @@ def create_dataset(dataset_name): WHERE DBList.Name = '%s' and DBType.Id = DBList.DBTypeId """ % (escape(dataset_name)) + print("query is: ", pf(query)) dataset_type = g.db.execute(query).fetchone().Name #dataset_type = cursor.fetchone()[0] diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 8c9e3b10..241bf2ab 100755 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -1,12 +1,12 @@ -from __future__ import division, print_function +from __future__ import absolute_import, division, print_function import string from htmlgen import HTMLgen2 as HT -import webqtlConfig -from webqtlCaseData import webqtlCaseData -from data_set import create_dataset +from base import webqtlConfig +from base.webqtlCaseData import webqtlCaseData +from base.data_set import create_dataset from dbFunction import webqtlDatabaseFunction from utility import webqtlUtil @@ -24,76 +24,28 @@ class GeneralTrait: def __init__(self, **kw): print("in GeneralTrait") - self.dataset = kw.get('dataset', None) # database name - self.name = kw.get('name', None) # Trait ID, ProbeSet ID, Published ID, etc. - self.cellid = kw.get('cellid', None) + self.dataset = kw.get('dataset') # database name + self.name = kw.get('name') # Trait ID, ProbeSet ID, Published ID, etc. + self.cellid = kw.get('cellid') self.identification = kw.get('identification', 'un-named trait') - #self.group = kw.get('group', None) self.haveinfo = kw.get('haveinfo', False) - self.sequence = kw.get('sequence', None) # Blat sequence, available for ProbeSet + self.sequence = kw.get('sequence') # Blat sequence, available for ProbeSet self.data = kw.get('data', {}) - + if kw.get('fullname'): name2 = value.split("::") if len(name2) == 2: self.dataset, self.name = name2 + # self.cellid is set to None above elif len(name2) == 3: self.dataset, self.name, self.cellid = name2 - - #if self.dataset and isinstance(self.dataset, basestring): - self.dataset = create_dataset(self.dataset) - print("self.dataset is:", self.dataset, type(self.dataset)) - #if self.dataset: - - #self.dataset.get_group() + self.dataset = create_dataset(self.dataset) - #if self.dataset.type == "Temp": - # self.cursor.execute(''' - # SELECT - # InbredSet.Name - # FROM - # InbredSet, Temp - # WHERE - # Temp.InbredSetId = InbredSet.Id AND - # Temp.Name = "%s" - # ''', self.name) - # self.group = self.cursor.fetchone()[0] - #else: - # self.group = self.dataset.get_group() - - #print("trinity, self.group is:", self.group) - - # - # In ProbeSet, there are maybe several annotations match one sequence - # so we need use sequence(BlatSeq) as the identification, when we update - # one annotation, we update the others who match the sequence also. - # - # Hongqiang Li, 3/3/2008 - # - - #XZ, 05/08/2009: This block is not neccessary. We can add 'BlatSeq' into disfield. - # The variable self.sequence should be changed to self.BlatSeq - # It also should be changed in other places where it are used. - - #if self.dataset: - #if self.dataset.type == 'ProbeSet': - # print("Doing ProbeSet Query") - # query = ''' - # SELECT - # ProbeSet.BlatSeq - # FROM - # ProbeSet, ProbeSetFreeze, ProbeSetXRef - # WHERE - # ProbeSet.Id=ProbeSetXRef.ProbeSetId and - # ProbeSetFreeze.Id = ProbeSetXRef.ProbeSetFreezeId and - # ProbeSet.Name = %s and - # ProbeSetFreeze.Name = %s - # ''', (self.name, self.dataset.name) - # print("query is:", query) - # self.sequence = g.db.execute(*query).fetchone()[0] - # #self.sequence = self.cursor.fetchone()[0] - # print("self.sequence is:", self.sequence) + # Todo: These two lines are necessary most of the time, but perhaps not all of the time + # So we could add a simple if statement to short-circuit this if necessary + self.retrieve_info() + self.retrieve_sample_data() def get_name(self): diff --git a/wqflask/wqflask/do_search.py b/wqflask/wqflask/do_search.py index fc45395c..a2eddfc6 100644 --- a/wqflask/wqflask/do_search.py +++ b/wqflask/wqflask/do_search.py @@ -63,7 +63,7 @@ class DoSearch(object): class MrnaAssaySearch(DoSearch): """A search within an mRNA expression dataset""" - DoSearch.search_types['ProbeSet'] = "ProbeSetSearch" + DoSearch.search_types['ProbeSet'] = "MrnaAssaySearch" base_query = """SELECT ProbeSet.Name as TNAME, 0 as thistable, diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index c605cb58..807761a2 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -34,45 +34,26 @@ from pprint import pformat as pf class ShowTrait(object): - def __init__(self, args): - print("in ShowTrait, args are:", args) - #self.group = args.group - self.trait_id = args['trait_id'] + def __init__(self, kw): + print("in ShowTrait, kw are:", kw) + self.trait_id = kw['trait_id'] - self.dataset = create_dataset(args['dataset']) - - #self.dataset = create_dataset(args['dataset']) - self.cell_id = None + self.dataset = create_dataset(kw['dataset']) + + #self.cell_id = None - #assert self.openMysql(), "No database!" - #print("red3 fd.group:", fd.group) - this_trait = self.get_this_trait() + this_trait = GeneralTrait(dataset=self.dataset.name, + name=self.trait_id, + cellid=None) - #print("red4 fd.group:", fd.group) - ##read genotype file - #fd.group = this_trait.group - #print("[red5] fd.group is:", fd.group) self.dataset.group.read_genotype_file() - #fd.readGenotype() if not self.dataset.group.genotype: - self.read_data(include_f1=True) #incf1=1) + self.read_data(include_f1=True) - ## determine data editing page format - #variance_data_page = 0 - #if fd.formID == 'varianceChoice': - # variance_data_page = 1 - # - #if variance_data_page: - # fmID='dataEditing' - #else: - # if fd.enablevariance: - # fmID='pre_dataEditing' - # else: - # fmID='dataEditing' - + # Todo: Add back in the ones we actually need from below, as we discover we need them hddn = OrderedDict() @@ -111,55 +92,19 @@ class ShowTrait(object): # export_data = None # ) - #if fd.enablevariance: - # hddn['enablevariance']='ON' - #if fd.incparentsf1: - # hddn['incparentsf1']='ON' - #if this_trait: - # hddn['fullname'] = str(this_trait) - # try: - # hddn['normalPlotTitle'] = this_trait.symbol - # hddn['normalPlotTitle'] += ": " - # hddn['normalPlotTitle'] += this_trait.name - # except: - # hddn['normalPlotTitle'] = str(this_trait.name) - # hddn['fromDataEditingPage'] = 1 # if this_trait.dataset and this_trait.dataset.type and this_trait.dataset.type == 'ProbeSet': - # hddn['trait_type'] = this_trait.dataset.type - # if this_trait.cellid: - # hddn['cellid'] = this_trait.cellid - # else: # self.cursor.execute("SELECT h2 from ProbeSetXRef WHERE DataId = %d" % # this_trait.mysqlid) # heritability = self.cursor.fetchone() - # hddn['heritability'] = heritability - # - # hddn['attribute_names'] = "" - # + #hddn['mappingMethodId'] = webqtlDatabaseFunction.getMappingMethod (cursor=self.cursor, # groupName=fd.group) - # - #if fd.identification: - # hddn['identification'] = fd.identification - #else: - # hddn['identification'] = "Un-named trait" #If no identification, set identification to un-named - - self.dispTraitInformation(args, "", hddn, this_trait) #Display trait information + function buttons - if this_trait == None: - this_trait = webqtlTrait(data=args['allTraitData'], dataset=None) + self.dispTraitInformation(kw, "", hddn, this_trait) #Display trait information + function buttons - ## Variance submit page only - #if fd.enablevariance and not variance_data_page: - # pass - # #title2Body.append("Click the next button to go to the variance submission form.", - # # HT.Center(next,reset)) - #else: - # pass - # # We'll get this part working later - # print("Calling dispBasicStatistics") - # self.dispBasicStatistics(fd, this_trait) + #if this_trait == None: + # this_trait = webqtlTrait(data=kw['allTraitData'], dataset=None) self.build_correlation_tools(this_trait) @@ -168,9 +113,6 @@ class ShowTrait(object): if self.dataset.group.allsamples: hddn['allsamples'] = string.join(self.dataset.group.allsamples, ' ') - #if args['varianceDispName'] != 'Variance': - # hddn['isSE'] = "yes" - # We'll need access to this_trait and hddn in the Jinja2 Template, so we put it inside self self.this_trait = this_trait self.hddn = hddn @@ -188,34 +130,23 @@ class ShowTrait(object): self.js_data = js_data - def get_this_trait(self): - # When is traitInfos used? - #if traitInfos: - # database, ProbeSetID, CellID = traitInfos - #else: - #dataset = self.fd['dataset'] - #trait_id = self.fd['trait_id'] - #cell_id = self.fd.get('CellID') - - this_trait = GeneralTrait(dataset=self.dataset.name, - name=self.trait_id, - cellid=self.cell_id) - - ##identification, etc. - self.identification = '%s : %s' % (self.dataset.shortname, self.trait_id) - this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ - &ProbeSetID=%s&group=%s&parentsf1=on' %(self.dataset, self.trait_id, self.dataset.group.name) - - if self.cell_id: - self.identification = '%s/%s'%(self.identification, self.cell_id) - this_trait.returnURL = '%s&CellID=%s' % (this_trait.returnURL, self.cell_id) - - print("yellow1:", self.dataset.group) - this_trait.retrieve_info() - print("yellow2:", self.dataset.group) - this_trait.retrieve_sample_data() - print("yellow3:", self.dataset.group) - return this_trait + #def get_this_trait(self): + # this_trait = GeneralTrait(dataset=self.dataset.name, + # name=self.trait_id, + # cellid=self.cell_id) + # + # ###identification, etc. + # #self.identification = '%s : %s' % (self.dataset.shortname, self.trait_id) + # #this_trait.returnURL = webqtlConfig.CGIDIR + webqtlConfig.SCRIPTFILE + '?FormID=showDatabase&database=%s\ + # # &ProbeSetID=%s&group=%s&parentsf1=on' %(self.dataset, self.trait_id, self.dataset.group.name) + # # + # #if self.cell_id: + # # self.identification = '%s/%s'%(self.identification, self.cell_id) + # # this_trait.returnURL = '%s&CellID=%s' % (this_trait.returnURL, self.cell_id) + # + # this_trait.retrieve_info() + # this_trait.retrieve_sample_data() + # return this_trait def read_data(self, include_f1=False): diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee index b1f5b186..d0fc869d 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.coffee @@ -1,11 +1,17 @@ $ -> - run_marker_regression = -> - console.log("In marker regression") - url = "/marker_regression" + submit_special = -> + # Add submit_special class plus a data-url field to any button + # And it will submit to that url + # No js changes necessary + console.log("In submit_special") + console.log("this is:", this) + console.log("$(this) is:", $(this)) + url = $(this).data("url") + console.log("url is:", url) $("#trait_data_form").attr("action", url); $("#trait_data_form").submit() - $("#do_marker_regression").click(run_marker_regression) + $(".submit_special").click(submit_special) composite_mapping_fields = -> @@ -14,10 +20,10 @@ $ -> $("#use_composite_choice").change(composite_mapping_fields) + #### Todo: Redo below so its like submit_special and requires no js hardcoding toggle_enable_disable = (elem) -> - $(elem).prop("disabled", !$(elem.prop("disabled"))) + $(elem).prop("disabled", !$(elem).prop("disabled")) - $("#choose_closet_control").change(-> toggle_enable_disable("#control_locus") ) diff --git a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js index c8328498..c6766288 100644 --- a/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js +++ b/wqflask/wqflask/static/new/javascript/show_trait_mapping_tools.js @@ -2,21 +2,24 @@ (function() { $(function() { - var composite_mapping_fields, run_marker_regression, toggle_enable_disable; - run_marker_regression = function() { + var composite_mapping_fields, submit_special, toggle_enable_disable; + submit_special = function() { var url; - console.log("In marker regression"); - url = "/marker_regression"; + console.log("In submit_special"); + console.log("this is:", this); + console.log("$(this) is:", $(this)); + url = $(this).data("url"); + console.log("url is:", url); $("#trait_data_form").attr("action", url); return $("#trait_data_form").submit(); }; - $("#do_marker_regression").click(run_marker_regression); + $(".submit_special").click(submit_special); composite_mapping_fields = function() { return $(".composite_fields").toggle(); }; $("#use_composite_choice").change(composite_mapping_fields); toggle_enable_disable = function(elem) { - return $(elem).prop("disabled", !$(elem.prop("disabled"))); + return $(elem).prop("disabled", !$(elem).prop("disabled")); }; $("#choose_closet_control").change(function() { return toggle_enable_disable("#control_locus"); diff --git a/wqflask/wqflask/templates/marker_regression.html b/wqflask/wqflask/templates/marker_regression.html new file mode 100644 index 00000000..db2de604 --- /dev/null +++ b/wqflask/wqflask/templates/marker_regression.html @@ -0,0 +1,51 @@ +{% extends "base.html" %} +{% block title %}Marker Regression{% endblock %} +{% block content %} + +
      +
      +

      Marker Regression

      +

      + {{ this_trait.name }}: {{ this_trait.description_fmt }} +

      +
      +
      + +
      +
      Aliases
      +
      {{ this_trait.alias_fmt }}
      + +
      Location
      +
      {{ this_trait.location_fmt }}
      + +
      Database
      +
      + + {{ dataset.name }} + +
      + + {% if this_trait.probe_set_specificity %} +
      + + BLAT Specifity + +
      +
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      + {% endif %} + {% if this_trait.probe_set_blat_score %} +
      BLAT Score
      +
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      + {% endif %} +
      + + + +{% endblock %} + +{% block js %} + +{% endblock %} \ No newline at end of file diff --git a/wqflask/wqflask/templates/show_trait_mapping_tools.html b/wqflask/wqflask/templates/show_trait_mapping_tools.html index 8436703d..72b152fa 100644 --- a/wqflask/wqflask/templates/show_trait_mapping_tools.html +++ b/wqflask/wqflask/templates/show_trait_mapping_tools.html @@ -101,7 +101,8 @@
      - @@ -135,8 +136,9 @@
      -
      diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 503b0972..f6c0dfb0 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -18,6 +18,7 @@ from flask import render_template, request, make_response, Response, Flask, g, c from wqflask import search_results from wqflask.show_trait import show_trait from wqflask.show_trait import export_trait_data +from wqflask.marker_regression import marker_regression from wqflask.correlation import CorrelationPage from wqflask.dataSharing import SharingInfo, SharingInfoPage @@ -89,27 +90,6 @@ def whats_new_page(): print("\nnews_item is: %s\n" % (news_item)) return render_template("whats_new.html", news_items=news_items) - -@app.route("/show_trait") -def show_trait_page(): - # Here it's currently too complicated not to use an fd that is a webqtlFormData - #fd = webqtlFormData.webqtlFormData(request.args) - #print("stp y1:", pf(vars(fd))) - template_vars = show_trait.ShowTrait(request.args) - - print("js_data before dump:", template_vars.js_data) - - template_vars.js_data = json.dumps(template_vars.js_data, - default=json_default_handler, - indent=" ") - # Sorting the keys messes up the ordered dictionary, so don't do that - #sort_keys=True) - - print("js_data after dump:", template_vars.js_data) - - print("show_trait template_vars:", pf(template_vars.__dict__)) - return render_template("show_trait.html", **template_vars.__dict__) - @app.route('/export_trait_csv', methods=('POST',)) def export_trait_excel(): """Excel file consisting of the sample data from the trait data and analysis page""" @@ -150,33 +130,52 @@ def export_trait_csv(): mimetype='text/csv', headers={"Content-Disposition":"attachment;filename=test.csv"}) +@app.route("/show_trait") +def show_trait_page(): + # Here it's currently too complicated not to use an fd that is a webqtlFormData + #fd = webqtlFormData.webqtlFormData(request.args) + #print("stp y1:", pf(vars(fd))) + template_vars = show_trait.ShowTrait(request.args) + print("js_data before dump:", template_vars.js_data) + template_vars.js_data = json.dumps(template_vars.js_data, + default=json_default_handler, + indent=" ") + # Sorting the keys messes up the ordered dictionary, so don't do that + #sort_keys=True) + + print("js_data after dump:", template_vars.js_data) + print("show_trait template_vars:", pf(template_vars.__dict__)) + return render_template("show_trait.html", **template_vars.__dict__) + +@app.route("/marker_regression", methods=('POST',)) +def marker_regression_page(): + template_vars = marker_regression.MarkerRegression(request.form) + #print("js_data before dump:", template_vars.js_data) + #template_vars.js_data = json.dumps(template_vars.js_data, + # default=json_default_handler, + # indent=" ") + #print("js_data after dump:", template_vars.js_data) + print("marker_regression template_vars:", pf(template_vars.__dict__)) + return render_template("marker_regression.html", **template_vars.__dict__) @app.route("/corr_compute", methods=('POST',)) def corr_compute_page(): - #print("In corr_compute, request.args is:", pf(request.form)) + print("In corr_compute, request.args is:", pf(request.form)) fd = webqtlFormData.webqtlFormData(request.form) - print("Have fd") template_vars = CorrelationPage.CorrelationPage(fd) - print("Made it to rendering") return render_template("correlation_page.html", **template_vars.__dict__) @app.route("/int_mapping", methods=('POST',)) def interval_mapping_page(): - fd = webqtlFormData.webqtlFormData(request.form) - print("Have fd") - template_vars = CorrelationPage.CorrelationPage(fd) - print("Made it to rendering") - return render_template("correlation_page.html", **template_vars.__dict__) - + template_vars = interval_mapping.IntervalMapping(request.args) + return render_template("interval_mapping.html", **template_vars.__dict__) # Todo: Can we simplify this? -Sam def sharing_info_page(): """Info page displayed when the user clicks the "Info" button next to the dataset selection""" print("In sharing_info_page") fd = webqtlFormData.webqtlFormData(request.args) - print("2Have fd") template_vars = SharingInfoPage.SharingInfoPage(fd) - print("2 Made it to rendering") return template_vars -- cgit v1.2.3 From fb1c44d09f47fa2e72a90df286ff8bb2a3107f2c Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 3 Jan 2013 16:14:48 -0600 Subject: marker_regression page is up again --- wqflask/wqflask/show_trait/show_trait.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wqflask/wqflask/show_trait/show_trait.py b/wqflask/wqflask/show_trait/show_trait.py index 807761a2..9bd45905 100755 --- a/wqflask/wqflask/show_trait/show_trait.py +++ b/wqflask/wqflask/show_trait/show_trait.py @@ -113,6 +113,9 @@ class ShowTrait(object): if self.dataset.group.allsamples: hddn['allsamples'] = string.join(self.dataset.group.allsamples, ' ') + hddn['trait_id'] = self.trait_id + hddn['dataset_name'] = self.dataset.name + # We'll need access to this_trait and hddn in the Jinja2 Template, so we put it inside self self.this_trait = this_trait self.hddn = hddn -- cgit v1.2.3 From 91ed29ef68e8ad29b728f7f574ccc83730d9f7ab Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Thu, 3 Jan 2013 18:15:32 -0600 Subject: Began working on marker_regression.py and created Chromosomes class in species.py --- wqflask/base/data_set.py | 6 +- wqflask/base/species.py | 52 +- wqflask/wqflask/interval_analyst/GeneUtil.py | 124 ++ .../interval_analyst/IntervalAnalystPage.py | 405 +++++ wqflask/wqflask/interval_analyst/__init__.py | 0 .../marker_regression/MarkerRegressionPage.py | 1648 ++++++++++++++++++++ wqflask/wqflask/marker_regression/__init__.py | 0 .../wqflask/marker_regression/marker_regression.py | 1648 ++++++++++++++++++++ 8 files changed, 3870 insertions(+), 13 deletions(-) create mode 100755 wqflask/wqflask/interval_analyst/GeneUtil.py create mode 100755 wqflask/wqflask/interval_analyst/IntervalAnalystPage.py create mode 100644 wqflask/wqflask/interval_analyst/__init__.py create mode 100644 wqflask/wqflask/marker_regression/MarkerRegressionPage.py create mode 100644 wqflask/wqflask/marker_regression/__init__.py create mode 100755 wqflask/wqflask/marker_regression/marker_regression.py diff --git a/wqflask/base/data_set.py b/wqflask/base/data_set.py index 36d4acaf..50ef8f57 100755 --- a/wqflask/base/data_set.py +++ b/wqflask/base/data_set.py @@ -85,8 +85,8 @@ class DatasetGroup(object): self.f1list = None self.parlist = None self.allsamples = None - - + + #def read_genotype(self): # self.read_genotype_file() # @@ -158,8 +158,8 @@ class DataSet(object): self.retrieve_other_names() - self.species = species.TheSpecies(self) self.group = DatasetGroup(self) # sets self.group and self.group_id and gets genotype + self.species = species.TheSpecies(self) diff --git a/wqflask/base/species.py b/wqflask/base/species.py index 98941ce5..1fd76772 100644 --- a/wqflask/base/species.py +++ b/wqflask/base/species.py @@ -1,16 +1,48 @@ -from __future__ import print_function, division +from __future__ import absolute_import, print_function, division +import collections + +from flask import Flask, g + +#from MySQLdb import escape_string as escape + +from pprint import pformat as pf class TheSpecies(object): def __init__(self, dataset): self.dataset = dataset + print("self.dataset is:", pf(self.dataset.__dict__)) + self.chromosomes = Chromosomes(self.dataset.group.name) + + #@property + #def chromosomes(self): + # chromosomes = [("All", -1)] + # + # for counter, genotype in enumerate(self.dataset.group.genotype): + # if len(genotype) > 1: + # chromosomes.append((genotype.name, counter)) + # + # print("chromosomes is: ", pf(chromosomes)) + # + # return chromosomes + + + +class Chromosomes(object): + def __init__(self, group_name): + self.chromosomes = collections.OrderedDict() + + results = g.db.execute(""" + Select + Chr_Length.Name, Length from Chr_Length, InbredSet + where + Chr_Length.SpeciesId = InbredSet.SpeciesId AND + InbredSet.Name = %s + Order by OrderId + """, group_name).fetchall() + print("bike:", results) + + for item in results: + self.chromosomes[item.Name] = item.Length - @property - def chromosomes(self): - chromosomes = [("All", -1)] - - for counter, genotype in enumerate(self.dataset.group.genotype): - if len(genotype) > 1: - chromosomes.append((genotype.name, counter)) - - return chromosomes + print("self.chromosomes:", self.chromosomes) diff --git a/wqflask/wqflask/interval_analyst/GeneUtil.py b/wqflask/wqflask/interval_analyst/GeneUtil.py new file mode 100755 index 00000000..43008ecf --- /dev/null +++ b/wqflask/wqflask/interval_analyst/GeneUtil.py @@ -0,0 +1,124 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import string + +#Just return a list of dictionaries +#each dictionary contains sub-dictionary +def loadGenes(cursor, chrName, diffCol, startMb, endMb, webqtlDb =None, species='mouse'): + #cursor.execute("desc GeneList") + #results = cursor.fetchall() + #fetchFields = map(lambda X:X[0], results) + fetchFields = ['SpeciesId', 'Id', 'GeneSymbol', 'GeneDescription', 'Chromosome', 'TxStart', 'TxEnd', + 'Strand', 'GeneID', 'NM_ID', 'kgID', 'GenBankID', 'UnigenID', 'ProteinID', 'AlignID', + 'exonCount', 'exonStarts', 'exonEnds', 'cdsStart', 'cdsEnd'] + + ##List All Species in the Gene Table + speciesDict = {} + cursor.execute("select Species.Name, GeneList.SpeciesId from Species, GeneList where \ + GeneList.SpeciesId = Species.Id group by GeneList.SpeciesId") + results = cursor.fetchall() + for item in results: + speciesDict[item[0]] = item[1] + + ##List current Species and other Species + speciesId = speciesDict[species] + otherSpecies = map(lambda X: [X, speciesDict[X]], speciesDict.keys()) + otherSpecies.remove([species, speciesId]) + + cursor.execute("""SELECT %s from GeneList + where + SpeciesId = %d AND Chromosome = '%s' AND + ((TxStart > %f and TxStart <= %f) OR (TxEnd > %f and TxEnd <= %f)) + order by txStart + """ + % (string.join(fetchFields, ", "), speciesId, chrName, startMb, endMb, startMb, endMb)) + results = cursor.fetchall() + GeneList = [] + + if results: + for result in results: + newdict = {} + for j, item in enumerate(fetchFields): + newdict[item] = result[j] + #count SNPs if possible + if diffCol and species=='mouse': + cursor.execute(""" + select + count(*) from BXDSnpPosition + where + Chr = '%s' AND Mb >= %2.6f AND Mb < %2.6f AND + StrainId1 = %d AND StrainId2 = %d + """ % (chrName, newdict["TxStart"], newdict["TxEnd"], diffCol[0], diffCol[1])) + newdict["snpCount"] = cursor.fetchone()[0] + newdict["snpDensity"] = newdict["snpCount"]/(newdict["TxEnd"]-newdict["TxStart"])/1000.0 + else: + newdict["snpDensity"] = newdict["snpCount"] = 0 + + try: + newdict['GeneLength'] = 1000.0*(newdict['TxEnd'] - newdict['TxStart']) + except: + pass + + #load gene from other Species by the same name + for item in otherSpecies: + othSpec, othSpecId = item + newdict2 = {} + + cursor.execute("SELECT %s from GeneList where SpeciesId = %d and geneSymbol= '%s' limit 1" % + (string.join(fetchFields, ", "), othSpecId, newdict["GeneSymbol"])) + resultsOther = cursor.fetchone() + if resultsOther: + for j, item in enumerate(fetchFields): + newdict2[item] = resultsOther[j] + + #count SNPs if possible, could be a separate function + if diffCol and othSpec == 'mouse': + cursor.execute(""" + select + count(*) from BXDSnpPosition + where + Chr = '%s' AND Mb >= %2.6f AND Mb < %2.6f AND + StrainId1 = %d AND StrainId2 = %d + """ % (chrName, newdict["TxStart"], newdict["TxEnd"], diffCol[0], diffCol[1])) + + newdict2["snpCount"] = cursor.fetchone()[0] + newdict2["snpDensity"] = newdict2["snpCount"]/(newdict2["TxEnd"]-newdict2["TxStart"])/1000.0 + else: + newdict2["snpDensity"] = newdict2["snpCount"] = 0 + + try: + newdict2['GeneLength'] = 1000.0*(newdict2['TxEnd'] - newdict2['TxStart']) + except: + pass + + newdict['%sGene' % othSpec] = newdict2 + + GeneList.append(newdict) + + return GeneList + + diff --git a/wqflask/wqflask/interval_analyst/IntervalAnalystPage.py b/wqflask/wqflask/interval_analyst/IntervalAnalystPage.py new file mode 100755 index 00000000..ec9aa29c --- /dev/null +++ b/wqflask/wqflask/interval_analyst/IntervalAnalystPage.py @@ -0,0 +1,405 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +from mod_python import apache, util, Cookie +import os +import time +import pyXLWriter as xl + +from htmlgen import HTMLgen2 as HT + +import GeneUtil +from base.templatePage import templatePage +from utility import webqtlUtil +from base import webqtlConfig + + +class IntervalAnalystPage(templatePage): + filename = webqtlUtil.genRandStr("Itan_") + + _scriptfile = "main.py?FormID=intervalAnalyst" + + #A dictionary that lets us map the html form names "txStart_mm6" -> "Mb Start (mm8)" + #the first item is the short name (column headers) and the second item is the long name (dropdown list) + # [short name, long name, category] + columnNames = {"GeneSymbol" : ["Gene", "Gene Name", 'gene'], + "GeneDescription" : ["Description", "Gene Description", 'species'], + 'GeneNeighborsCount' : ["Neighbors", "Gene Neighbors", 'gene'], + 'GeneNeighborsRange' : ["Neighborhood", "Gene Neighborhood (Mb)", 'gene'], + 'GeneNeighborsDensity' : ["Gene Density", "Gene Density (Neighbors/Mb)", 'gene'], + "ProteinID" : ["Prot ID", "Protein ID", 'protein'], + "Chromosome" : ["Chr", "Chromosome", 'species'], + "TxStart" : ["Start", "Mb Start", 'species'], + "TxEnd" : ["End", "Mb End", 'species'], + "GeneLength" : ["Length", "Kb Length", 'species'], + "cdsStart" : ["CDS Start", "Mb CDS Start", 'species'], + "cdsEnd" : ["CDS End", "Mb CDS End", 'species'], + "exonCount" : ["Num Exons", "Exon Count", 'species'], + "exonStarts" : ["Exon Starts", "Exon Starts", 'species'], + "exonEnds" : ["Exon Ends", "Exon Ends", 'species'], + "Strand" : ["Strand", "Strand", 'species'], + "GeneID" : ["Gene ID", "Gene ID", 'species'], + "GenBankID" : ["GenBank", "GenBank ID", 'species'], + "UnigenID" : ["Unigen", "Unigen ID", 'species'], + "NM_ID" : ["NM ID", "NM ID", 'species'], + "kgID" : ["kg ID", "kg ID", 'species'], + "snpCount" : ["SNPs", "SNP Count", 'species'], + "snpDensity" : ["SNP Density", "SNP Density", 'species'], + "lrs" : ["LRS", "Likelihood Ratio Statistic", 'misc'], + "lod" : ["LOD", "Likelihood Odds Ratio", 'misc'], + "pearson" : ["Pearson", "Pearson Product Moment", 'misc'], + "literature" : ["Lit Corr", "Literature Correlation", 'misc'], + } + + ###Species Freeze + speciesFreeze = {'mouse':'mm9', 'rat':'rn3', 'human':'hg19'} + for key in speciesFreeze.keys(): + speciesFreeze[speciesFreeze[key]] = key + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + fd.formdata['remote_ip'] = fd.remote_ip + if not self.openMysql(): + return + + self.species = fd.formdata.getvalue("species", "mouse") + try: + self.startMb = float(fd.formdata.getvalue("startMb")) + except: + self.startMb = 10 + try: + self.endMb = float(fd.formdata.getvalue("endMb")) + except: + self.endMb = self.startMb + 10 + + self.Chr = fd.formdata.getvalue("chromosome", "1") + self.xls = fd.formdata.getvalue("xls", "1") + try: + s1 = int(fd.formdata.getvalue("s1")) + s2 = int(fd.formdata.getvalue("s2")) + self.diffColDefault = self.diffCol = [s1, s2] + except: + self.diffColDefault = self.diffCol = [] + if self.species != 'mouse': + self.diffColDefault = [2, 3]#default is B6 and D2 for other species + + controlFrm, dispFields = self.genControlForm(fd) + geneTable, filename = self.genGeneTable(fd, dispFields) + + infoTD = HT.TD(width=400, valign= "top") + infoTD.append(HT.Paragraph("Interval Analyst : Chr %s" % self.Chr, Class="title"), + HT.Strong("Species : "), self.species.title(), HT.BR(), + HT.Strong("Database : "), "UCSC %s" % self.speciesFreeze[self.species], HT.BR(), + HT.Strong("Range : "), "%2.6f Mb - %2.6f Mb" % (self.startMb, self.endMb), HT.BR(), + ) + if filename: + infoTD.append(HT.BR(), HT.BR(), HT.Href(text="Download", url = "/tmp/" + filename, Class="normalsize") + , " output in MS excel format.") + + mainTable = HT.TableLite(HT.TR(infoTD, HT.TD(controlFrm, Class="doubleBorder", width=400), HT.TD(" ", width="")), cellpadding=10) + mainTable.append(HT.TR(HT.TD(geneTable, colspan=3))) + self.dict['body'] = HT.TD(mainTable) + self.dict['title'] = "Interval Analyst" + + def genGeneTable(self, fd, dispFields): + filename = "" + if self.xls: + #import pyXLWriter as xl + filename = "IntAn_Chr%s_%2.6f-%2.6f" % (self.Chr, self.startMb, self.endMb) + filename += ".xls" + + # Create a new Excel workbook + workbook = xl.Writer(os.path.join(webqtlConfig.TMPDIR, filename)) + worksheet = workbook.add_worksheet() + titleStyle = workbook.add_format(align = 'left', bold = 0, size=18, border = 1, border_color="gray") + headingStyle = workbook.add_format(align = 'center', bold = 1, size=13, fg_color = 0x1E, color="white", border = 1, border_color="gray") + + ##Write title Info + worksheet.write([0, 0], "GeneNetwork Interval Analyst Table", titleStyle) + worksheet.write([1, 0], "%s%s" % (webqtlConfig.PORTADDR, os.path.join(webqtlConfig.CGIDIR, self._scriptfile))) + # + worksheet.write([2, 0], "Date : %s" % time.strftime("%B %d, %Y", time.gmtime())) + worksheet.write([3, 0], "Time : %s GMT" % time.strftime("%H:%M ", time.gmtime())) + worksheet.write([4, 0], "Search by : %s" % fd.formdata['remote_ip']) + worksheet.write([5, 0], "view region : Chr %s %2.6f - %2.6f Mb" % (self.Chr, self.startMb, self.endMb)) + nTitleRow = 7 + + geneTable = HT.TableLite(Class="collap", cellpadding=5) + headerRow = HT.TR(HT.TD(" ", Class="fs13 fwb ffl b1 cw cbrb", width="1")) + if self.xls: + worksheet.write([nTitleRow, 0], "Index", headingStyle) + + for ncol, column in enumerate(dispFields): + if len(column) == 1: + headerRow.append(HT.TD(self.columnNames[column[0]][0], Class="fs13 fwb ffl b1 cw cbrb", NOWRAP=1,align="Center")) + if self.xls: + colTitle = self.columnNames[column[0]][0] + worksheet.write([nTitleRow, ncol+1], colTitle, headingStyle) + worksheet.set_column([ncol+1, ncol+1], 2*len(colTitle)) + else: + headerRow.append(HT.TD(self.columnNames[column[0]][0], HT.BR(), " (%s)" % self.speciesFreeze[column[1]], + Class="fs13 fwb ffl b1 cw cbrb", NOWRAP=1, align="Center")) + if self.xls: + colTitle = self.columnNames[column[0]][0] + " (%s)" % self.speciesFreeze[column[1]] + worksheet.write([nTitleRow, ncol+1], colTitle, headingStyle) + worksheet.set_column([ncol+1, ncol+1], 2*len(colTitle)) + #headerRow.append(HT.TD(self.columnNames[column[0]][0], HT.BR(), + # "(%s %s)" % (column[1].title(), self.speciesFreeze[column[1]]), + # Class="colorBlue", NOWRAP=1, align="Center")) + geneTable.append(headerRow) + + geneCol = GeneUtil.loadGenes(self.cursor, self.Chr, self.diffColDefault, self.startMb, self.endMb, species=self.species) + for gIndex, theGO in enumerate(geneCol): + geneRow = HT.TR(HT.TD(gIndex+1, Class="fs12 fwn b1", align="right")) + if self.xls: + nTitleRow += 1 + worksheet.write([nTitleRow, 0], gIndex + 1) + + for ncol, column in enumerate(dispFields): + if len(column) == 1 or column[1]== self.species: + keyValue = "" + fieldName = column[0] + curSpecies = self.species + curGO = theGO + if theGO.has_key(fieldName): + keyValue = theGO[fieldName] + else: + fieldName , othSpec = column + curSpecies = othSpec + subGO = '%sGene' % othSpec + keyValue = "" + curGO = theGO[subGO] + if theGO[subGO].has_key(fieldName): + keyValue = theGO[subGO][fieldName] + + if self.xls: + worksheet.write([nTitleRow, ncol+1], keyValue) + geneRow.append(self.formatTD(keyValue, fieldName, curSpecies, curGO)) + + geneTable.append(geneRow) + + if self.xls: + workbook.close() + return geneTable, filename + + def formatTD(self, keyValue, fieldName, Species, theGO): + if keyValue is None: + keyValue = "" + if keyValue != "": + if fieldName in ("exonStarts", "exonEnds"): + keyValue = string.replace(keyValue, ',', ' ') + return HT.TD(HT.Span(keyValue, Class="code", Id="green"), width=350, Class="fs12 fwn b1") + elif fieldName in ("GeneDescription"): + if keyValue == "---": + keyValue = "" + return HT.TD(keyValue, Class="fs12 fwn b1", width=300) + elif fieldName in ("GeneSymbol"): + webqtlLink = HT.Href("./%s?cmd=sch&gene=%s&alias=1&species=%s" % (webqtlConfig.SCRIPTFILE, keyValue, Species), + HT.Image("/images/webqtl_search.gif", border=0, valign="top"), target="_blank") + if theGO['GeneID']: + geneSymbolLink = HT.Href(webqtlConfig.NCBI_LOCUSID % theGO['GeneID'], keyValue, Class="normalsize", target="_blank") + else: + geneSymbolLink = keyValue + return HT.TD(webqtlLink, geneSymbolLink, Class="fs12 fwn b1",NOWRAP=1) + elif fieldName == 'UnigenID': + try: + gurl = HT.Href(webqtlConfig.UNIGEN_ID % tuple(string.split(keyValue,'.')[:2]), keyValue, Class="normalsize", target="_blank") + except: + gurl = keyValue + return HT.TD(gurl, Class="fs12 fwn b1",NOWRAP=1) + elif fieldName in ("exonCount", "Chromosome"): + return HT.TD(keyValue, Class="fs12 fwn b1",align="right") + elif fieldName in ("snpCount"): + if keyValue: + snpString = HT.Href(url="%s&chr=%s&start=%s&end=%s&geneName=%s&s1=%d&s2=%d" % (os.path.join(webqtlConfig.CGIDIR, 'main.py?FormID=snpBrowser'), + theGO["Chromosome"], theGO["TxStart"], theGO["TxEnd"], theGO["GeneSymbol"], self.diffColDefault[0], self.diffColDefault[1]), + text=theGO["snpCount"], target="_blank", Class="normalsize") + else: + snpString = keyValue + return HT.TD(snpString, Class="fs12 fwn b1",align="right") + elif fieldName in ("snpDensity", "GeneLength"): + if keyValue: keyValue = "%2.3f" % keyValue + else: keyValue = "" + return HT.TD(keyValue, Class="fs12 fwn b1",align="right") + elif fieldName in ("TxStart", "TxEnd"): + return HT.TD("%2.6f" % keyValue, Class="fs12 fwn b1",align="right") + else: + return HT.TD(keyValue, Class="fs12 fwn b1",NOWRAP=1) + else: + return HT.TD(keyValue, Class="fs12 fwn b1",NOWRAP=1,align="right") + + def genControlForm(self, fd): + ##desc GeneList + self.cursor.execute("Desc GeneList") + GeneListFields = self.cursor.fetchall() + GeneListFields = map(lambda X: X[0], GeneListFields) + + #group columns by category--used for creating the dropdown list of possible columns + categories = {} + for item in self.columnNames.keys(): + category = self.columnNames[item] + if category[-1] not in categories.keys(): + categories[category[-1]] = [item ] + else: + categories[category[-1]] = categories[category[-1]]+[item] + + ##List All Species in the Gene Table + speciesDict = {} + self.cursor.execute("select Species.Name, GeneList.SpeciesId from Species, GeneList where \ + GeneList.SpeciesId = Species.Id group by GeneList.SpeciesId order by Species.Id") + results = self.cursor.fetchall() + speciesField = categories.pop('species', []) + categoriesOrder = ['gene', 'protein'] + for item in results: + specName, specId = item + categoriesOrder.append(specName) + speciesDict[specName] = specId + AppliedField = [] + for item2 in speciesField: + if item2 in GeneListFields: + self.cursor.execute("select %s from GeneList where SpeciesId = %d and %s is not NULL limit 1 " % (item2, specId, item2)) + columnApply = self.cursor.fetchone() + if not columnApply: + continue + elif specName != 'mouse' and item2 in ('snpCount', 'snpDensity'): + continue + else: + pass + AppliedField.append(item2) + categories[specName] = AppliedField + + categoriesOrder += ['misc'] + + ############################################################ + ## Create the list of possible columns for the dropdown list + ############################################################ + allColumnsList = HT.Select(name="allColumns", Class="snpBrowserDropBox") + + for category in categoriesOrder: + allFields = categories[category] + if allFields: + geneOpt = HT.Optgroup(label=category.title()) + for item in allFields: + if category in self.speciesFreeze.keys(): + geneOpt.append(("%s (%s %s)" % (self.columnNames[item][1], category.title(), self.speciesFreeze[category]), + "%s__%s" % (item, self.speciesFreeze[category]))) + else: + geneOpt.append((self.columnNames[item][1], item)) + geneOpt.sort() + allColumnsList.append(geneOpt) + + ###################################### + ## Create the list of selected columns + ###################################### + + #cols contains the value of all the selected columns + submitCols = cols = fd.formdata.getvalue("columns", "default") + + if cols == "default": + if self.species=="mouse": #these are the same columns that are shown on intervalPage.py + cols = ['GeneSymbol', 'GeneDescription', 'Chromosome', 'TxStart', 'Strand', 'GeneLength', 'GeneID', 'NM_ID', 'snpCount', 'snpDensity'] + elif self.species=="rat": + cols = ['GeneSymbol', 'GeneDescription', 'Chromosome', 'TxStart', 'GeneLength', 'Strand', 'GeneID', 'UnigenID'] + else: + #should not happen + cols = [] + else: + if type(cols)==type(""): + cols = [cols] + + colsLst = [] + dispFields = [] + for column in cols: + if submitCols == "default" and column not in ('GeneSymbol') and (column in GeneListFields or column in speciesField): + colsLst.append(("%s (%s %s)" % (self.columnNames[column][1], self.species.title(), self.speciesFreeze[self.species]), + "%s__%s" % (column, self.speciesFreeze[self.species]))) + dispFields.append([column, self.species]) + else: + column2 = column.split("__") + if len(column2) == 1: + colsLst.append((self.columnNames[column2[0]][1], column)) + dispFields.append([column]) + else: + thisSpecies = self.speciesFreeze[column2[1]] + colsLst.append(("%s (%s %s)" % (self.columnNames[column2[0]][1], thisSpecies.title(), column2[1]), + column)) + dispFields.append((column2[0], thisSpecies)) + selectedColumnsList = HT.Select(name="columns", Class="snpBrowserSelectBox", multiple="true", data=colsLst, size=6) + + ########################## + ## Create the columns form + ########################## + columnsForm = HT.Form(name="columnsForm", submit=HT.Input(type='hidden'), cgi=os.path.join(webqtlConfig.CGIDIR, self._scriptfile), enctype="multipart/form-data") + columnsForm.append(HT.Input(type="hidden", name="fromdatabase", value= fd.formdata.getvalue("fromdatabase", "unknown"))) + columnsForm.append(HT.Input(type="hidden", name="species", value=self.species)) + if self.diffCol: + columnsForm.append(HT.Input(type="hidden", name="s1", value=self.diffCol[0])) + columnsForm.append(HT.Input(type="hidden", name="s2", value=self.diffCol[1])) + startBox = HT.Input(type="text", name="startMb", value=self.startMb, size=10) + endBox = HT.Input(type="text", name="endMb", value=self.endMb, size=10) + addButton = HT.Input(type="button", name="add", value="Add", Class="button", onClick="addToList(this.form.allColumns.options[this.form.allColumns.selectedIndex].text, this.form.allColumns.options[this.form.allColumns.selectedIndex].value, this.form.columns)") + removeButton = HT.Input(type="button", name="remove", value="Remove", Class="button", onClick="removeFromList(this.form.columns.selectedIndex, this.form.columns)") + upButton = HT.Input(type="button", name="up", value="Up", Class="button", onClick="swapOptions(this.form.columns.selectedIndex, this.form.columns.selectedIndex-1, this.form.columns)") + downButton = HT.Input(type="button", name="down", value="Down", Class="button", onClick="swapOptions(this.form.columns.selectedIndex, this.form.columns.selectedIndex+1, this.form.columns)") + clearButton = HT.Input(type="button", name="clear", value="Clear", Class="button", onClick="deleteAllElements(this.form.columns)") + submitButton = HT.Input(type="submit", value="Refresh", Class="button", onClick="selectAllElements(this.form.columns)") + + selectChrBox = HT.Select(name="chromosome") + self.cursor.execute(""" + Select + Chr_Length.Name, Length from Chr_Length, Species + where + Chr_Length.SpeciesId = Species.Id AND + Species.Name = '%s' + Order by + Chr_Length.OrderId + """ % self.species) + + results = self.cursor.fetchall() + for chrInfo in results: + selectChrBox.append((chrInfo[0], chrInfo[0])) + selectChrBox.selected.append(self.Chr) + + innerColumnsTable = HT.TableLite(border=0, Class="collap", cellpadding = 2) + innerColumnsTable.append(HT.TR(HT.TD(selectedColumnsList)), + HT.TR(HT.TD(clearButton, removeButton, upButton, downButton))) + columnsTable = HT.TableLite(border=0, cellpadding=2, cellspacing=0) + columnsTable.append(HT.TR(HT.TD(HT.Font("Chr: ", size=-1)), + HT.TD(selectChrBox, submitButton)), + HT.TR(HT.TD(HT.Font("View: ", size=-1)), + HT.TD(startBox, HT.Font("Mb to ", size=-1), endBox, HT.Font("Mb", size=-1))), + HT.TR(HT.TD(HT.Font("Show: ", size=-1)), + HT.TD(allColumnsList, addButton)), + HT.TR(HT.TD(""), + HT.TD(innerColumnsTable))) + columnsForm.append(columnsTable) + #columnsForm.append(HT.Input(type="hidden", name="sort", value=diffCol), + # HT.Input(type="hidden", name="identification", value=identification), + # HT.Input(type="hidden", name="traitInfo", value=traitInfo)) + + return columnsForm, dispFields diff --git a/wqflask/wqflask/interval_analyst/__init__.py b/wqflask/wqflask/interval_analyst/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/wqflask/marker_regression/MarkerRegressionPage.py b/wqflask/wqflask/marker_regression/MarkerRegressionPage.py new file mode 100644 index 00000000..d02d80b3 --- /dev/null +++ b/wqflask/wqflask/marker_regression/MarkerRegressionPage.py @@ -0,0 +1,1648 @@ +# Copyright (C) University of Tennessee Health Science Center, Memphis, TN. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU Affero General Public License for more details. +# +# This program is available from Source Forge: at GeneNetwork Project +# (sourceforge.net/projects/genenetwork/). +# +# Contact Drs. Robert W. Williams and Xiaodong Zhou (2010) +# at rwilliams@uthsc.edu and xzhou15@uthsc.edu +# +# This module is used by GeneNetwork project (www.genenetwork.org) +# +# Created by GeneNetwork Core Team 2010/08/10 +# +# Last updated by GeneNetwork Core Team 2010/10/20 + +import time +import string +import math +from math import * +import piddle as pid +import sys,os +import httplib, urllib + +from htmlgen import HTMLgen2 as HT +from utility import Plot +from intervalAnalyst import GeneUtil +from base.webqtlTrait import webqtlTrait +from base.templatePage import templatePage +from utility import webqtlUtil +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +from base.GeneralObject import GeneralObject + +import reaper +import cPickle +from utility.THCell import THCell +from utility.TDCell import TDCell + +class MarkerRegressionPage(templatePage): + + def __init__(self, fd): + + templatePage.__init__(self, fd) + + if not self.openMysql(): + return + + self.initializeParameters(fd) + + filename= webqtlUtil.genRandStr("Itvl_") + ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList= self.getChrNameOrderIdLength(RISet=fd.RISet) + + if self.mappingMethodId == '4': # For PLINK + + traitInfoList = string.split(string.strip(fd.identification),':') + probesetName = string.strip(traitInfoList[-1]) + plinkOutputFileName= webqtlUtil.genRandStr("%s_%s_"%(fd.RISet,probesetName)) + + # get related values from fd.allTraitData; the format of 'allTraitValueDict'is {strainName1: value=-0.2...} + fd.readData() + allTraitValueDict = fd.allTraitData + + #automatically generate pheno txt file for PLINK + self.genPhenoTxtFileForPlink(phenoFileName=plinkOutputFileName,RISetName=fd.RISet,probesetName=probesetName, valueDict=allTraitValueDict) + # os.system full path is required for input and output files; specify missing value is -9999 + plink_command = '%splink/plink --noweb --ped %splink/%s.ped --no-fid --no-parents --no-sex --no-pheno --map %splink/%s.map --pheno %s/%s.txt --pheno-name %s --missing-phenotype -9999 --out %s%s --assoc ' % (webqtlConfig.HTMLPATH, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.TMPDIR, plinkOutputFileName, probesetName, webqtlConfig.TMPDIR, plinkOutputFileName) + + os.system(plink_command) + + if fd.identification: + heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) + heading2.__setattr__("class","subtitle") + self.dict['title'] = '%s: Genome Association' % fd.identification + else: + heading2 = "" + self.dict['title'] = 'Genome Association' + + if fd.traitInfo: + symbol,chromosome,MB = string.split(fd.traitInfo,'\t') + heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) + else: + heading3 = "" + + heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) + heading.__setattr__("class","title") + + # header info part:Trait Data Entered for HLC Set & Trait ID: + headerdiv = HT.TR(HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee')) + + self.ChrList=ChrList # get chr name from '1' to 'X' + self.ChrLengthMbList = ChrLengthMbList + + # build plink result dict based on chr, key is chr name, value is in list type including Snpname, bp and pvalue info + plinkResultDict={} + count,minPvalue,plinkResultDict =self.getPlinkResultDict(outputFileName=plinkOutputFileName,thresholdPvalue=self.pValue,ChrOrderIdNameDict=ChrOrderIdNameDict) + + # if can not find results which are matched with assigned p-value, system info will show up + if count >0: + + #for genome association report table + reportTable="" + # sortable table object + resultstable,tblobj,bottomInfo = self.GenReportForPLINK(ChrNameOrderIdDict=ChrNameOrderIdDict, RISet=fd.RISet,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue,chrList=self.ChrList) + + # creat object for result table for sort function + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + sortby = ("Index", "up") + reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + + descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) + descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) + descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) + descriptionTable.append(bottomInfo) + + # get each chr's length + self.ChrLengthMbList = map(lambda x: x/1000000.0, self.ChrLengthMbList) # change unit from bp to mb + self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0)# get total length of all chrs + if self.ChrLengthMbList: + self.GraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval + else: + self.GraphInterval = 1 + + # for human data, there's no CM value + self.ChrLengthCMList = [] + self.ChrLengthCMSum = 0 + + # begin: common part with human data + intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) + gifmap = self.plotIntMappingForPLINK(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, plinkResultDict=plinkResultDict) + + intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') + intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') + + TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) + self.dict['body'] = str(headerdiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) + + else: + heading = "Genome Association" + detail = ['There is no association with marker that meets this criteria. Please provide a less stringend threshold. The minimun p-value is %s.'%minPvalue] + self.error(heading=heading,detail=detail) + return + + elif self.mappingMethodId == '1': # QTLreaper result + if not fd.genotype: + fd.readData() + + fd.parentsf14regression = fd.formdata.getvalue('parentsf14regression') + weightedRegression = fd.formdata.getvalue('applyVarianceSE') + + if fd.parentsf14regression and fd.genotype_2: + _genotype = fd.genotype_2 + else: + _genotype = fd.genotype_1 + + _strains, _vals, _vars, N = fd.informativeStrains(_genotype.prgy, weightedRegression) + + if fd.identification: + heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) + heading2.__setattr__("class","subtitle") + self.dict['title'] = '%s: Genome Association' % fd.identification + else: + heading2 = "" + self.dict['title'] = 'Genome Association' + + if fd.traitInfo: + symbol,chromosome,MB = string.split(fd.traitInfo,'\t') + heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) + else: + heading3 = "" + + if N < webqtlConfig.KMININFORMATIVE: + heading = "Genome Association" + detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) + heading.__setattr__("class","title") + + datadiv = HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee') + resultstable,tblobj,bottomInfo = self.GenReport(ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars) + #resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars) + + # creat object for result table for sort function + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + sortby = ("Index", "up") + reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + + descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) + descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) + descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) + descriptionTable.append(bottomInfo) + + self.traitList=_vals + + ##########################plot####################### + + ################################################################ + # Generate Chr list and Retrieve Length Information + ################################################################ + self.genotype= _genotype + self.ChrList = [("All", -1)] + + for i, indChr in enumerate(self.genotype): + self.ChrList.append((indChr.name, i)) + + self.cursor.execute(""" + Select + Length from Chr_Length, InbredSet + where + Chr_Length.SpeciesId = InbredSet.SpeciesId AND + InbredSet.Name = '%s' AND + Chr_Length.Name in (%s) + Order by + OrderId + """ % (fd.RISet, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", "))) + + self.ChrLengthMbList = self.cursor.fetchall() + self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList) + self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) + if self.ChrLengthMbList: + self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval + else: + self.MbGraphInterval = 1 + + self.ChrLengthCMList = [] + for i, _chr in enumerate(self.genotype): + self.ChrLengthCMList.append(_chr[-1].cM - _chr[0].cM) + self.ChrLengthCMSum = reduce(lambda x, y:x+y, self.ChrLengthCMList, 0.0)# used for calculate plot scale + + self.GraphInterval = self.MbGraphInterval #Mb + + # begin: common part with human data + intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) + gifmap = self.plotIntMapping(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= "") + filename= webqtlUtil.genRandStr("Itvl_") + intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') + intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') + + ################################################################ + # footnote goes here + ################################################################ + btminfo = HT.Paragraph(Id="smallsize") #Small('More information about this graph is available here.') + + if (self.additiveChecked): + btminfo.append(HT.BR(), 'A positive additive coefficient (', HT.Font('green', color='green'), ' line) indicates that %s alleles increase trait values. In contrast, a negative additive coefficient (' % fd.ppolar, HT.Font('red', color='red'), ' line) indicates that %s alleles increase trait values.' % fd.mpolar) + + + TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) + + self.dict['body'] = str(datadiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) + + # end: common part with human data + + else: + pass + + + # add by NL 10-2-2011 + def initializeParameters(self, fd): + """ + Initializes all of the MarkerRegressionPage class parameters, + acquiring most values from the formdata (fd) + """ + ################################### + # manhattam plot parameters + ################################### + + self.graphHeight = 600 + self.graphWidth = 1280 + self.plotScale = 'physic' + self.selectedChr = -1 + self.GRAPH_BACK_DARK_COLOR = pid.HexColor(0xF1F1F9) + self.GRAPH_BACK_LIGHT_COLOR = pid.HexColor(0xFBFBFF) + self.LRS_COLOR = pid.HexColor(0x0000FF) + self.LRS_LOD ='LRS' + self.lrsMax = float(fd.formdata.getvalue('lrsMax', 0)) + self.startMb = fd.formdata.getvalue('startMb', "-1") + self.endMb = fd.formdata.getvalue('endMb', "-1") + self.mappingMethodId = fd.formdata.getvalue('mappingMethodId', "0") + self.permChecked=True + self.multipleInterval=False + self.SIGNIFICANT_WIDTH = 5 + self.SUGGESTIVE_WIDTH = 5 + self.SIGNIFICANT_COLOR = pid.HexColor(0xEBC7C7) + self.SUGGESTIVE_COLOR = pid.gainsboro + self.colorCollection = [self.LRS_COLOR] + self.additiveChecked= True + self.ADDITIVE_COLOR_POSITIVE = pid.green + self.legendChecked =False + self.pValue=float(fd.formdata.getvalue('pValue',-1)) + + # allow user to input p-value greater than 1, + # in this case, the value will be treated as -lgP value. so the input value needs to be transferred to power of 10 format + if self.pValue >1: + self.pValue =10**-(self.pValue) + + try: + self.startMb = float(self.startMb) + self.endMb = float(self.endMb) + if self.startMb > self.endMb: + temp = self.startMb + self.startMb = self.endMb + self.endMb = temp + #minimal distance 10bp + if self.endMb - self.startMb < 0.00001: + self.endMb = self.startMb + 0.00001 + except: + self.startMb = self.endMb = -1 + + def GenReportForPLINK(self, ChrNameOrderIdDict={},RISet='',plinkResultDict= {},thresholdPvalue=-1,chrList=[]): + + 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + ######################################### + # Genome Association report + ######################################### + locusFormName = webqtlUtil.genRandStr("fm_") + locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \ + enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':RISet+"Geno",'CellID':'_', \ + 'RISet':RISet, 'incparentsf1':'on'} + for key in hddn.keys(): + locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + regressionHeading = HT.Paragraph('Genome Association Report') + regressionHeading.__setattr__("class","title") + + filename= webqtlUtil.genRandStr("GenomeAsscociation_") + fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb') + fpText.write('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue) + pValueInfo =HT.Paragraph('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue) + + textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn') + bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),Class="fs12 fwn"), colspan=3)) + + tblobj={} # build dict for genTableObj function; keys include header and body + tblobj_header = [] # value of key 'header' + tblobj_body=[] # value of key 'body' + reportHeaderRow=[] # header row list for tblobj_header (html part) + headerList=['Index','SNP Name','Chr','Mb','-log(P)'] + headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header + cellColorStyle = "fs13 b1 fwn c222" # style of the cells + + if headerList: + for ncol, item in enumerate(headerList): + reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol)) + #download file for table headers' names + fpText.write('SNP_Name\tChromosome\tMb\t-log(P)\n') + + tblobj_header.append(reportHeaderRow) + tblobj['header']=tblobj_header + + index=1 + for chr in chrList: + + if plinkResultDict.has_key(chr): + if chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[chr] + else: + chrOrderId=chr + + valueList=plinkResultDict[chr] + + for value in valueList: + reportBodyRow=[] # row list for tblobj_body (html part) + snpName=value[0] + bp=value[1] + mb=int(bp)/1000000.0 + + try: + pValue =float(value[2]) + except: + pValue =1 + formattedPvalue = -math.log10(pValue) + + formattedPvalue = webqtlUtil.SciFloat(formattedPvalue) + dbSnprs=snpName.replace('rs','') + SnpHref = HT.Href(text=snpName, url="http://www.ncbi.nlm.nih.gov/projects/SNP/snp_ref.cgi?rs=%s"%dbSnprs, target="_blank") + + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(HT.TD(SnpHref, Class=cellColorStyle,nowrap='ON'),snpName, snpName)) + reportBodyRow.append(TDCell(HT.TD(chr, Class=cellColorStyle, align="center",nowrap='ON'),chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%mb, Class=cellColorStyle, align="center",nowrap='ON'),mb, mb)) + reportBodyRow.append(TDCell(HT.TD(formattedPvalue, Class=cellColorStyle, align="center",nowrap='ON'),formattedPvalue, float(formattedPvalue))) + + fpText.write('%s\t%s\t%3.6f\t%s\n' % (snpName, str(chr), mb, formattedPvalue)) + index+=1 + + tblobj_body.append(reportBodyRow) + + tblobj['body']=tblobj_body + rv=HT.TR(HT.TD(regressionHeading,pValueInfo, locusForm, HT.P(), width='55%',valign='top', align='left',bgColor='#eeeeee')) + + return rv, tblobj,bottomInfo + + + def GenReport(self, ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars= []): + 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + #calculate QTL for each trait + self.qtlresults = [] + if webqtlUtil.ListNotNull(_vars): + qtlresults = _genotype.regression(strains = _strains, trait = _vals, variance = _vars) + LRSArray = _genotype.permutation(strains = _strains, trait = _vals, variance = _vars, nperm=fd.nperm) + else: + qtlresults = _genotype.regression(strains = _strains, trait = _vals) + LRSArray = _genotype.permutation(strains = _strains, trait = _vals,nperm=fd.nperm) + + self.qtlresults.append(qtlresults) + + filename= webqtlUtil.genRandStr("GenomeAsscociation_") + + # set suggestive, significant and highly significant LRS + if fd.suggestive == None: + fd.suggestive = LRSArray[int(fd.nperm*0.37-1)] + else: + fd.suggestive = float(fd.suggestive) + if fd.significance == None: + fd.significance = LRSArray[int(fd.nperm*0.95-1)] + else: + fd.significance = float(fd.significance) + + self.significance =fd.significance + self.suggestive = fd.suggestive + self.highlysignificant = LRSArray[int(fd.nperm*0.99-1)] + _dispAllLRS = 0 + if fd.formdata.getvalue('displayAllLRS'): + _dispAllLRS = 1 + qtlresults2 = [] + if _dispAllLRS: + filtered = qtlresults[:] + else: + filtered = filter(lambda x, y=fd.suggestive: x.lrs > y, qtlresults) + if len(filtered) == 0: + qtlresults2 = qtlresults[:] + qtlresults2.sort() + filtered = qtlresults2[-10:] + + ######################################### + # Permutation Graph + ######################################### + myCanvas = pid.PILCanvas(size=(400,300)) + #plotBar(myCanvas,10,10,390,290,LRSArray,XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test',identification=fd.identification) + Plot.plotBar(myCanvas, LRSArray,XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test') + filename= webqtlUtil.genRandStr("Reg_") + myCanvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0,alt='Histogram of Permutation Test') + + if fd.suggestive == None: + fd.suggestive = LRSArray[int(fd.nperm*0.37-1)] + else: + fd.suggestive = float(fd.suggestive) + if fd.significance == None: + fd.significance = LRSArray[int(fd.nperm*0.95-1)] + else: + fd.significance = float(fd.significance) + + permutationHeading = HT.Paragraph('Histogram of Permutation Test') + permutationHeading.__setattr__("class","title") + + permutation = HT.TableLite() + permutation.append(HT.TR(HT.TD(img))) + + + ######################################### + # Genome Association report + ######################################### + locusFormName = webqtlUtil.genRandStr("fm_") + locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \ + enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':fd.RISet+"Geno",'CellID':'_', \ + 'RISet':fd.RISet, 'incparentsf1':'on'} + for key in hddn.keys(): + locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + regressionHeading = HT.Paragraph('Genome Association Report') + regressionHeading.__setattr__("class","title") + # report is the info part above report table + if qtlresults2 != []: + report = HT.Blockquote(HT.Font('No association ',color="#FF0000"),HT.Font('with a likelihood ratio statistic greater than %3.1f was found. Here are the top 10 LRSs.' % fd.suggestive,color="#000000")) + else: + report = HT.Blockquote('The following loci in the %s data set have associations with the above trait data.\n' % fd.RISet, HT.P()) + report.__setattr__("class","normalsize") + + fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb') + fpText.write('Suggestive LRS =%3.2f\n'%self.suggestive) + fpText.write('Significant LRS =%3.2f\n'%self.significance) + fpText.write('Highly Significant LRS =%3.2f\n'%self.highlysignificant) + LRSInfo =HT.Paragraph('    Suggestive LRS =%3.2f\n'%fd.suggestive, HT.BR(), '    Significant LRS =%3.2f\n'%fd.significance,HT.BR(),'    Highly Significant LRS =%3.2f\n' % self.highlysignificant) + + textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn') + + bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),'LRS values marked with',HT.Font(' * ',color="red"), 'are greater than the significance threshold (specified by you or by permutation test). ' , HT.BR(), HT.BR(), HT.Strong('Additive Effect'), ' is half the difference in the mean phenotype of all cases that are homozygous for one parental allel at this marker minus the mean of all cases that are homozygous for the other parental allele at this marker. ','In the case of %s strains, for example,' % fd.RISet,' A positive additive effect indicates that %s alleles increase trait values. Negative additive effect indicates that %s alleles increase trait values.'% (fd.ppolar,fd.mpolar),Class="fs12 fwn"))) + + tblobj={} # build dict for genTableObj function; keys include header and body + tblobj_header = [] # value of key 'header' + tblobj_body=[] # value of key 'body' + reportHeaderRow=[] # header row list for tblobj_header (html part) + headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header + cellColorStyle = "fs13 b1 fwn c222" # style of the cells + + headerList=['Index','LRS','Chr','Mb','Locus','Additive Effect'] + for ncol, item in enumerate(headerList): + reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol)) + + if fd.genotype.type == 'intercross': + ncol =len(headerList) + reportHeaderRow.append(THCell(HT.TD('Dominance Effect', Class=headerStyle, valign='bottom',nowrap='ON'),text='Dominance Effect', idx=ncol)) + + #download file for table headers' names + fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\tDominance Effect\n') + + index=1 + for ii in filtered: + #add by NL 06-20-2011: set LRS to 460 when LRS is infinite, + if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS: + LRS=webqtlConfig.MAXLRS #maximum LRS value + else: + LRS=ii.lrs + + if LRS > fd.significance: + lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle) + else: + lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle) + + if ii.locus.chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[ii.locus.chr] + else: + chrOrderId=ii.locus.chr + + reportBodyRow=[] # row list for tblobj_body (html part) + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(lrs,LRS, LRS)) + reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb)) + reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.dominance, Class=cellColorStyle, align="center",nowrap='ON'),ii.dominance, ii.dominance)) + + fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive, ii.dominance)) + index+=1 + tblobj_body.append(reportBodyRow) + else: + #download file for table headers' names + fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\n') + + index=1 + for ii in filtered: + #add by NL 06-20-2011: set LRS to 460 when LRS is infinite, + if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS: + LRS=webqtlConfig.MAXLRS #maximum LRS value + else: + LRS=ii.lrs + + if LRS > fd.significance: + lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle) + else: + lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle) + + if ii.locus.chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[ii.locus.chr] + else: + chrOrderId=ii.locus.chr + + reportBodyRow=[] # row list for tblobj_body (html part) + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(lrs,LRS, LRS)) + reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb)) + reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive)) + + fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive)) + index+=1 + tblobj_body.append(reportBodyRow) + + tblobj_header.append(reportHeaderRow) + tblobj['header']=tblobj_header + tblobj['body']=tblobj_body + + rv=HT.TD(regressionHeading,LRSInfo,report, locusForm, HT.P(),width='55%',valign='top', align='left', bgColor='#eeeeee') + if fd.genotype.type == 'intercross': + bottomInfo.append(HT.BR(), HT.BR(), HT.Strong('Dominance Effect'),' is the difference between the mean trait value of cases heterozygous at a marker and the average mean for the two groups homozygous at this marker: e.g., BD - (BB+DD)/2]. A positive dominance effect indicates that the average phenotype of BD heterozygotes exceeds the mean of BB and DD homozygotes. No dominance deviation can be computed for a set of recombinant inbred strains or for a backcross.') + return rv,tblobj,bottomInfo + + return rv,tblobj,bottomInfo + + def plotIntMappingForPLINK(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = "",plinkResultDict={}): + #calculating margins + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + xLeftOffset = int(xLeftOffset*fontZoom) + xRightOffset = int(xRightOffset*fontZoom) + yBottomOffset = int(yBottomOffset*fontZoom) + + cWidth = canvas.size[0] + cHeight = canvas.size[1] + plotWidth = cWidth - xLeftOffset - xRightOffset + plotHeight = cHeight - yTopOffset - yBottomOffset + startPixelX = xLeftOffset + endPixelX = (xLeftOffset + plotWidth) + + #Drawing Area Height + drawAreaHeight = plotHeight + if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr + drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom + if self.geneChecked: + drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom + else: + if self.selectedChr > -1: + drawAreaHeight -= 20 + else:# for all chrs + drawAreaHeight -= 30 + + #Image map + gifmap = HT.Map(name='WebQTLImageMap') + + newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset) + # Draw the alternating-color background first and get plotXScale + plotXScale = self.drawGraphBackgroundForPLINK(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict) + + # Draw X axis + self.drawXAxisForPLINK(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + # Draw manhattam plot + self.drawManhattanPlotForPLINK(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue) + + return gifmap + + + def plotIntMapping(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = ""): + #calculating margins + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + xLeftOffset = int(xLeftOffset*fontZoom) + xRightOffset = int(xRightOffset*fontZoom) + yBottomOffset = int(yBottomOffset*fontZoom) + + cWidth = canvas.size[0] + cHeight = canvas.size[1] + plotWidth = cWidth - xLeftOffset - xRightOffset + plotHeight = cHeight - yTopOffset - yBottomOffset + startPixelX = xLeftOffset + endPixelX = (xLeftOffset + plotWidth) + + #Drawing Area Height + drawAreaHeight = plotHeight + if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr + drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom + if self.geneChecked: + drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom + else:# for all chrs + if self.selectedChr > -1: + drawAreaHeight -= 20 + else: + drawAreaHeight -= 30 + + #Image map + gifmap = HT.Map(name='WebQTLImageMap') + + newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset) + # Draw the alternating-color background first and get plotXScale + plotXScale = self.drawGraphBackground(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + + # Draw X axis + self.drawXAxis(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + # Draw QTL curve + self.drawQTL(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + + #draw legend + if self.multipleInterval: + self.drawMultiTraitName(fd, canvas, gifmap, showLocusForm, offset=newoffset) + elif self.legendChecked: + self.drawLegendPanel(fd, canvas, offset=newoffset) + else: + pass + + #draw position, no need to use a separate function + if fd.genotype.Mbmap: + self.drawProbeSetPosition(canvas, plotXScale, offset=newoffset) + + return gifmap + + + # functions for manhattam plot of markers + def drawManhattanPlotForPLINK(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None,plinkResultDict={},thresholdPvalue=-1): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + # INTERCROSS = (self.genotype.type=="intercross") + INTERCROSS ='' #?????? + + ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + GraphInterval=self.GraphInterval + pvalueHeightThresh = drawAreaHeight - 80 #ZS: Otherwise the plot gets very close to the chromosome labels + + #draw the pvalue scale + #We first determine whether or not we are using a sliding scale. + #If so, we need to compute the maximum pvalue value to determine where the max y-value should be, and call this pvalueMax. + #pvalueTop is then defined to be above the pvalueMax by enough to add one additional pvalueScale increment. + #if we are using a set-scale, then we set pvalueTop to be the user's value, and pvalueMax doesn't matter. + + # for human data we use p value instead of lrs + pValueList=[] + for key in plinkResultDict: + valueList = plinkResultDict[key] + for item in valueList: + pValue = item[-1] + pValueList.append(pValue) + + formattedPValueList=[] + for pValue in pValueList: + try: + pValue=float(pValue) + except: + pValue =1 + formattedpValue = -math.log10(pValue) + formattedPValueList.append(formattedpValue) + + #sliding scale + pvalueMax = max(formattedPValueList) + #pvalueMax =pvalueMax +1 + # no permutation result for plink func: GenReport() + pvalueMin = int(-math.log10(thresholdPvalue)) + + if pvalueMax> 100: + pvalueScale = 20.0 + elif pvalueMax > 20: + pvalueScale = 5.0 + elif pvalueMax > 7.5: + pvalueScale = 2.5 + else: + pvalueScale = 1.0 + + # the base line for x-axis is -log(thresholdPvalue) + pvalueAxisList = Plot.frange(pvalueMin, pvalueMax, pvalueScale) + #make sure the user's value appears on the y-axis + #ZS: There is no way to do this without making the position of the points not directly proportional to a given distance on the y-axis + #tempPvalueMax=round(pvalueMax) + tempPvalueMax = pvalueAxisList[len(pvalueAxisList)-1] + pvalueScale + pvalueAxisList.append(tempPvalueMax) + + #ZS: I don't understand this; the if statement will be true for any number that isn't exactly X.5. + #if abs(tempPvalueMax-pvalueMax) <0.5: + # tempPvalueMax=tempPvalueMax+1 + # pvalueAxisList.append(tempPvalueMax) + + #draw the "pvalue" string to the left of the axis + pvalueScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0) + pvalueLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + yZero = yTopOffset + plotHeight + + #yAxis label display area + yAxis_label ='-log(P)' + canvas.drawString(yAxis_label, xLeftOffset - canvas.stringWidth("999.99", font=pvalueScaleFont) - 10*zoom, \ + yZero - 150, font=pvalueLODFont, color=pid.black, angle=90) + + for i,item in enumerate(pvalueAxisList): + ypvalue = yZero - (float(i)/float(len(pvalueAxisList) - 1)) * pvalueHeightThresh + canvas.drawLine(xLeftOffset, ypvalue, xLeftOffset - 4, ypvalue, color=self.LRS_COLOR, width=1*zoom) + scaleStr = "%2.1f" % item + #added by NL 6-24-2011:Y-axis scale display + canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=pvalueScaleFont)-5, ypvalue+3, font=pvalueScaleFont, color=self.LRS_COLOR) + + ChrList=self.ChrList + startPosX = xLeftOffset + + for i, chr in enumerate(ChrList): + + if plinkResultDict.has_key(chr): + plinkresultList = plinkResultDict[chr] + + m = 0 + #add by NL 06-24-2011: for mahanttam plot + symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0) + # color for point in each chr + chrCount=len(ChrList) + chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1) + for j, item in enumerate(plinkresultList): + try : + mb=float(item[1])/1000000.0 + except: + mb=0 + + try : + pvalue =float(item[-1]) + except: + pvalue =1 + + try: + snpName = item[0] + except: + snpName='' + + formattedPvalue = -math.log10(pvalue) + + Xc = startPosX + (mb-startMb)*plotXScale + Yc = yZero - (formattedPvalue-pvalueMin)*pvalueHeightThresh/(tempPvalueMax - pvalueMin) + canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[i], font=symbolFont) + m += 1 + + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis + + def drawQTL(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + INTERCROSS = (self.genotype.type=="intercross") + + ChrLengthDistList = self.ChrLengthMbList + GraphInterval=self.GraphInterval + LRSHeightThresh = drawAreaHeight + AdditiveHeightThresh = drawAreaHeight/2 + DominanceHeightThresh = drawAreaHeight/2 + + #draw the LRS scale + #We first determine whether or not we are using a sliding scale. + #If so, we need to compute the maximum LRS value to determine where the max y-value should be, and call this LRSMax. + #LRSTop is then defined to be above the LRSMax by enough to add one additional LRSScale increment. + #if we are using a set-scale, then we set LRSTop to be the user's value, and LRSMax doesn't matter. + + if self.LRS_LOD == 'LOD': + lodm = self.LODFACTOR + else: + lodm = 1.0 + + if self.lrsMax <= 0: #sliding scale + LRSMax = max(map(max, self.qtlresults)).lrs + #genotype trait will give infinite LRS + LRSMax = min(LRSMax, webqtlConfig.MAXLRS) + LRSMax = max(self.significance, LRSMax) + else: + LRSMax = self.lrsMax*lodm + + if LRSMax/lodm > 100: + LRSScale = 20.0 + elif LRSMax/lodm > 20: + LRSScale = 5.0 + elif LRSMax/lodm > 7.5: + LRSScale = 2.5 + else: + LRSScale = 1.0 + + LRSAxisList = Plot.frange(LRSScale, LRSMax/lodm, LRSScale) + #make sure the user's value appears on the y-axis + #update by NL 6-21-2011: round the LOD value to 100 when LRSMax is equal to 460 + LRSAxisList.append(round(LRSMax/lodm)) + + #draw the "LRS" or "LOD" string to the left of the axis + LRSScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0) + LRSLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + yZero = yTopOffset + plotHeight + + #yAxis label display area + canvas.drawString(self.LRS_LOD, xLeftOffset - canvas.stringWidth("999.99", font=LRSScaleFont) - 10*zoom, \ + yZero - 150, font=LRSLODFont, color=pid.black, angle=90) + + for item in LRSAxisList: + yLRS = yZero - (item*lodm/LRSMax) * LRSHeightThresh + canvas.drawLine(xLeftOffset, yLRS, xLeftOffset - 4, yLRS, color=self.LRS_COLOR, width=1*zoom) + scaleStr = "%2.1f" % item + #added by NL 6-24-2011:Y-axis scale display + canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=LRSScaleFont)-5, yLRS+3, font=LRSScaleFont, color=self.LRS_COLOR) + + + #"Significant" and "Suggestive" Drawing Routine + # ======= Draw the thick lines for "Significant" and "Suggestive" ===== (crowell: I tried to make the SNPs draw over these lines, but piddle wouldn't have it...) + if self.permChecked and not self.multipleInterval: + significantY = yZero - self.significance*LRSHeightThresh/LRSMax + suggestiveY = yZero - self.suggestive*LRSHeightThresh/LRSMax + + + startPosX = xLeftOffset + for i, _chr in enumerate(self.genotype): + rightEdge = int(startPosX + self.ChrLengthDistList[i]*plotXScale - self.SUGGESTIVE_WIDTH/1.5) + #added by NL 6-24-2011:draw suggestive line (grey one) + canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, suggestiveY, rightEdge, suggestiveY, color=self.SUGGESTIVE_COLOR, + width=self.SUGGESTIVE_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) + #added by NL 6-24-2011:draw significant line (pink one) + canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, significantY, rightEdge, significantY, color=self.SIGNIFICANT_COLOR, + width=self.SIGNIFICANT_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) + sugg_coords = "%d, %d, %d, %d" % (startPosX, suggestiveY-2, rightEdge + 2*zoom, suggestiveY+2) + sig_coords = "%d, %d, %d, %d" % (startPosX, significantY-2, rightEdge + 2*zoom, significantY+2) + if self.LRS_LOD == 'LRS': + sugg_title = "Suggestive LRS = %0.2f" % self.suggestive + sig_title = "Significant LRS = %0.2f" % self.significance + else: + sugg_title = "Suggestive LOD = %0.2f" % (self.suggestive/4.61) + sig_title = "Significant LOD = %0.2f" % (self.significance/4.61) + Areas1 = HT.Area(shape='rect',coords=sugg_coords,title=sugg_title) + Areas2 = HT.Area(shape='rect',coords=sig_coords,title=sig_title) + gifmap.areas.append(Areas1) + gifmap.areas.append(Areas2) + + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + + if self.multipleInterval: + lrsEdgeWidth = 1 + else: + additiveMax = max(map(lambda X : abs(X.additive), self.qtlresults[0])) + if INTERCROSS: + dominanceMax = max(map(lambda X : abs(X.dominance), self.qtlresults[0])) + else: + dominanceMax = -1 + lrsEdgeWidth = 2 + for i, qtlresult in enumerate(self.qtlresults): + m = 0 + startPosX = xLeftOffset + thisLRSColor = self.colorCollection[i] + + #add by NL 06-24-2011: for mahanttam plot + symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0) + + for j, _chr in enumerate(self.genotype): + chrCount=len(self.genotype) + chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1) + LRSCoordXY = [] + AdditiveCoordXY = [] + DominanceCoordXY = [] + for k, _locus in enumerate(_chr): + if self.plotScale == 'physic': + Xc = startPosX + (_locus.Mb-startMb)*plotXScale + else: + Xc = startPosX + (_locus.cM-_chr[0].cM)*plotXScale + # updated by NL 06-18-2011: + # fix the over limit LRS graph issue since genotype trait may give infinite LRS; + # for any lrs is over than 460(LRS max in this system), it will be reset to 460 + if qtlresult[m].lrs> 460 or qtlresult[m].lrs=='inf': + Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSMax + else: + Yc = yZero - qtlresult[m].lrs*LRSHeightThresh/LRSMax + + LRSCoordXY.append((Xc, Yc)) + #add by NL 06-24-2011: for mahanttam plot + #self.significance/4.61 consider chr and LOD + # significantY = yZero - self.significance*LRSHeightThresh/LRSMax + # if Yc >significantY: + # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont) + # else: + # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont) + + # add by NL 06-27-2011: eliminate imputed value when locus name is equal to '-' + if (qtlresult[m].locus.name) and (qtlresult[m].locus.name!=' - '): + canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[j], font=symbolFont) + + if not self.multipleInterval and self.additiveChecked: + Yc = yZero - qtlresult[m].additive*AdditiveHeightThresh/additiveMax + AdditiveCoordXY.append((Xc, Yc)) + if not self.multipleInterval and INTERCROSS and self.additiveChecked: + Yc = yZero - qtlresult[m].dominance*DominanceHeightThresh/dominanceMax + DominanceCoordXY.append((Xc, Yc)) + m += 1 + + startPosX += (ChrLengthDistList[j]+GraphInterval)*plotXScale + + + ###draw additive scale + if not self.multipleInterval and self.additiveChecked: + additiveScaleFont=pid.Font(ttf="verdana",size=12*fontZoom,bold=0) + additiveScale = Plot.detScaleOld(0,additiveMax) + additiveStep = (additiveScale[1]-additiveScale[0])/additiveScale[2] + additiveAxisList = Plot.frange(0, additiveScale[1], additiveStep) + maxAdd = additiveScale[1] + addPlotScale = AdditiveHeightThresh/additiveMax + + additiveAxisList.append(additiveScale[1]) + for item in additiveAxisList: + additiveY = yZero - item*addPlotScale + canvas.drawLine(xLeftOffset + plotWidth,additiveY,xLeftOffset+4+ plotWidth,additiveY,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + scaleStr = "%2.3f" % item + canvas.drawString(scaleStr,xLeftOffset + plotWidth +6,additiveY+5,font=additiveScaleFont,color=self.ADDITIVE_COLOR_POSITIVE) + + canvas.drawLine(xLeftOffset+plotWidth,additiveY,xLeftOffset+plotWidth,yZero,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis + + def drawGraphBackgroundForPLINK(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None,plinkResultDict={} ): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #calculate plot scale + #XZ: all of these global variables should be passed from function signiture + ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + GraphInterval=self.GraphInterval + ChrList =self.ChrList + + #multiple chromosome view + plotXScale = plotWidth / ((len(ChrList)-1)*GraphInterval + drawRegionDistance) + + startPosX = xLeftOffset + chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0) + + for i, _chr in enumerate(ChrList): + + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + # NL:resize chr width for drawing + if float(ChrLengthDistList[i])<90: + ChrLengthDistList[i]=90 + #draw the shaded boxes and the sig/sug thick lines + canvas.drawRect(startPosX, yTopOffset, startPosX + ChrLengthDistList[i]*plotXScale, \ + yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor) + + chrNameWidth = canvas.stringWidth(_chr, font=chrLabelFont) + chrStartPix = startPosX + (ChrLengthDistList[i]*plotXScale -chrNameWidth)/2 + chrEndPix = startPosX + (ChrLengthDistList[i]*plotXScale +chrNameWidth)/2 + + canvas.drawString(_chr, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray) + COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) + + #add by NL 09-03-2010 + HREF = "javascript:changeView(%d,%s);" % (i,ChrLengthDistList) + Areas = HT.Area(shape='rect',coords=COORDS,href=HREF) + gifmap.areas.append(Areas) + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + return plotXScale + + + def drawGraphBackground(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None): + ##conditions + ##multiple Chromosome view + ##single Chromosome Physical + ##single Chromosome Genetic + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #calculate plot scale + if self.plotScale != 'physic': + self.ChrLengthDistList = self.ChrLengthCMList + drawRegionDistance = self.ChrLengthCMSum + else: + self.ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + + if self.selectedChr > -1: #single chromosome view + spacingAmt = plotWidth/13.5 + i = 0 + for startPix in Plot.frange(xLeftOffset, xLeftOffset+plotWidth, spacingAmt): + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + i += 1 + canvas.drawRect(startPix, yTopOffset, min(startPix+spacingAmt, xLeftOffset+plotWidth), \ + yTopOffset+plotHeight, edgeColor=theBackColor, fillColor=theBackColor) + + drawRegionDistance = self.ChrLengthDistList[self.selectedChr] + self.ChrLengthDistList = [drawRegionDistance] + if self.plotScale == 'physic': + plotXScale = plotWidth / (endMb-startMb) + else: + plotXScale = plotWidth / drawRegionDistance + + else: #multiple chromosome view + plotXScale = plotWidth / ((len(self.genotype)-1)*self.GraphInterval + drawRegionDistance) + + startPosX = xLeftOffset + chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0) + + for i, _chr in enumerate(self.genotype): + + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + + #draw the shaded boxes and the sig/sug thick lines + canvas.drawRect(startPosX, yTopOffset, startPosX + self.ChrLengthDistList[i]*plotXScale, \ + yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor) + + chrNameWidth = canvas.stringWidth(_chr.name, font=chrLabelFont) + chrStartPix = startPosX + (self.ChrLengthDistList[i]*plotXScale -chrNameWidth)/2 + chrEndPix = startPosX + (self.ChrLengthDistList[i]*plotXScale +chrNameWidth)/2 + + canvas.drawString(_chr.name, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray) + COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) + + #add by NL 09-03-2010 + HREF = "javascript:changeView(%d,%s);" % (i,self.ChrLengthMbList) + Areas = HT.Area(shape='rect',coords=COORDS,href=HREF) + gifmap.areas.append(Areas) + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + return plotXScale + + # XZ: The only difference of function drawXAxisForPLINK and function drawXAxis are the function name and the self.plotScale condition. + def drawXAxisForPLINK(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #Parameters + ChrLengthDistList = self.ChrLengthMbList + GraphInterval=self.GraphInterval + + NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks + X_MAJOR_TICK_THICKNESS = 2 + X_MINOR_TICK_THICKNESS = 1 + X_AXIS_THICKNESS = 1*zoom + + # ======= Alex: Draw the X-axis labels (megabase location) + MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0) + xMajorTickHeight = 15 # How high the tick extends below the axis + xMinorTickHeight = 5*zoom + xAxisTickMarkColor = pid.black + xAxisLabelColor = pid.black + fontHeight = 12*fontZoom # How tall the font that we're using is + spacingFromLabelToAxis = 20 + spacingFromLineToLabel = 3 + + if self.plotScale == 'physic': + strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + ###Physical single chromosome view + if self.selectedChr > -1: + graphMbWidth = endMb - startMb + XScale = Plot.detScale(startMb, endMb) + XStart, XEnd, XStep = XScale + if XStep < 8: + XStep *= 2 + spacingAmtX = spacingAmt = (XEnd-XStart)/XStep + + j = 0 + while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6: + j += 1 + spacingAmtX *= 10 + + formatStr = '%%2.%df' % j + + for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)): + if _Mb < startMb or _Mb > endMb: + continue + Xc = xLeftOffset + plotXScale*(_Mb - startMb) + if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark + canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark + labelStr = str(formatStr % _Mb) # What Mbase location to put on the label + strWidth = canvas.stringWidth(labelStr, font=MBLabelFont) + drawStringXc = (Xc - (strWidth / 2.0)) + canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0) + else: + canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark + # end else + + ###Physical genome wide view + else: + distScale = 0 + startPosX = xLeftOffset + for i, distLen in enumerate(ChrLengthDistList): + if distScale == 0: #universal scale in whole genome mapping + if distLen > 75: + distScale = 25 + elif distLen > 30: + distScale = 10 + else: + distScale = 5 + for tickdists in range(distScale, ceil(distLen), distScale): + canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom) + canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270) + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2, + strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black) + pass + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself + + def drawXAxis(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #Parameters + NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks + X_MAJOR_TICK_THICKNESS = 2 + X_MINOR_TICK_THICKNESS = 1 + X_AXIS_THICKNESS = 1*zoom + + # ======= Alex: Draw the X-axis labels (megabase location) + MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0) + xMajorTickHeight = 15 # How high the tick extends below the axis + xMinorTickHeight = 5*zoom + xAxisTickMarkColor = pid.black + xAxisLabelColor = pid.black + fontHeight = 12*fontZoom # How tall the font that we're using is + spacingFromLabelToAxis = 20 + spacingFromLineToLabel = 3 + + if self.plotScale == 'physic': + strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + ###Physical single chromosome view + if self.selectedChr > -1: + graphMbWidth = endMb - startMb + XScale = Plot.detScale(startMb, endMb) + XStart, XEnd, XStep = XScale + if XStep < 8: + XStep *= 2 + spacingAmtX = spacingAmt = (XEnd-XStart)/XStep + + j = 0 + while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6: + j += 1 + spacingAmtX *= 10 + + formatStr = '%%2.%df' % j + + for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)): + if _Mb < startMb or _Mb > endMb: + continue + Xc = xLeftOffset + plotXScale*(_Mb - startMb) + if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark + canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark + labelStr = str(formatStr % _Mb) # What Mbase location to put on the label + strWidth = canvas.stringWidth(labelStr, font=MBLabelFont) + drawStringXc = (Xc - (strWidth / 2.0)) + canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0) + else: + canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark + # end else + + ###Physical genome wide view + else: + distScale = 0 + startPosX = xLeftOffset + for i, distLen in enumerate(self.ChrLengthDistList): + if distScale == 0: #universal scale in whole genome mapping + if distLen > 75: + distScale = 25 + elif distLen > 30: + distScale = 10 + else: + distScale = 5 + for tickdists in range(distScale, ceil(distLen), distScale): + canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom) + canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270) + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2, + strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black) + pass + else: + ChrAInfo = [] + preLpos = -1 + distinctCount = 0.0 + if len(self.genotype) > 1: + for i, _chr in enumerate(self.genotype): + thisChr = [] + Locus0CM = _chr[0].cM + nLoci = len(_chr) + if nLoci <= 8: + for _locus in _chr: + if _locus.name != ' - ': + if _locus.cM != preLpos: + distinctCount += 1 + preLpos = _locus.cM + thisChr.append([_locus.name, _locus.cM-Locus0CM]) + else: + for j in (0, nLoci/4, nLoci/2, nLoci*3/4, -1): + while _chr[j].name == ' - ': + j += 1 + if _chr[j].cM != preLpos: + distinctCount += 1 + preLpos = _chr[j].cM + thisChr.append([_chr[j].name, _chr[j].cM-Locus0CM]) + ChrAInfo.append(thisChr) + else: + for i, _chr in enumerate(self.genotype): + thisChr = [] + Locus0CM = _chr[0].cM + for _locus in _chr: + if _locus.name != ' - ': + if _locus.cM != preLpos: + distinctCount += 1 + preLpos = _locus.cM + thisChr.append([_locus.name, _locus.cM-Locus0CM]) + ChrAInfo.append(thisChr) + + stepA = (plotWidth+0.0)/distinctCount + + LRectWidth = 10 + LRectHeight = 3 + offsetA = -stepA + lineColor = pid.lightblue + startPosX = xLeftOffset + for j, ChrInfo in enumerate(ChrAInfo): + preLpos = -1 + for i, item in enumerate(ChrInfo): + Lname,Lpos = item + if Lpos != preLpos: + offsetA += stepA + differ = 1 + else: + differ = 0 + preLpos = Lpos + Lpos *= plotXScale + if self.selectedChr > -1: + Zorder = i % 5 + else: + Zorder = 0 + if differ: + canvas.drawLine(startPosX+Lpos,yZero,xLeftOffset+offsetA,\ + yZero+25, color=lineColor) + canvas.drawLine(xLeftOffset+offsetA,yZero+25,xLeftOffset+offsetA,\ + yZero+40+Zorder*(LRectWidth+3),color=lineColor) + rectColor = pid.orange + else: + canvas.drawLine(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3,\ + xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),color=lineColor) + rectColor = pid.deeppink + canvas.drawRect(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),\ + xLeftOffset+offsetA-LRectHeight,yZero+40+Zorder*(LRectWidth+3)+LRectWidth,\ + edgeColor=rectColor,fillColor=rectColor,edgeWidth = 0) + COORDS="%d,%d,%d,%d"%(xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3),\ + xLeftOffset+offsetA,yZero+40+Zorder*(LRectWidth+3)+LRectWidth) + HREF="javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm,fd.RISet+"Geno", Lname) + Areas=HT.Area(shape='rect',coords=COORDS,href=HREF, title="Locus : " + Lname) + gifmap.areas.append(Areas) + ##piddle bug + if j == 0: + canvas.drawLine(startPosX,yZero,startPosX,yZero+40, color=lineColor) + startPosX += (self.ChrLengthDistList[j]+self.GraphInterval)*plotXScale + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself + + def getColorForMarker(self, chrCount,flag):# no change is needed + chrColorDict={} + for i in range(chrCount): + if flag==1: # display blue and lightblue intercross + chrColorDict[i]=pid.black + elif flag==0: + if (i%2==0): + chrColorDict[i]=pid.blue + else: + chrColorDict[i]=pid.lightblue + else:#display different color for different chr + if i in [0,8,16]: + chrColorDict[i]=pid.black + elif i in [1,9,17]: + chrColorDict[i]=pid.red + elif i in [2,10,18]: + chrColorDict[i]=pid.lightgreen + elif i in [3,11,19]: + chrColorDict[i]=pid.blue + elif i in [4,12]: + chrColorDict[i]=pid.lightblue + elif i in [5,13]: + chrColorDict[i]=pid.hotpink + elif i in [6,14]: + chrColorDict[i]=pid.gold + elif i in [7,15]: + chrColorDict[i]=pid.grey + + return chrColorDict + + + def drawProbeSetPosition(self, canvas, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + if len(self.traitList) != 1: + return + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + try: + Chr = self.traitList[0].chr # self.traitListChr =self.traitList[0].chr=_vals need to change to chrList and mbList + Mb = self.traitList[0].mb # self.traitListMb =self.traitList[0].mb=_vals + except: + return + + if self.plotScale == 'physic': + if self.selectedChr > -1: + if self.genotype[0].name != Chr or Mb < self.startMb or Mb > self.endMb: + return + else: + locPixel = xLeftOffset + (Mb-self.startMb)*plotXScale + else: + locPixel = xLeftOffset + for i, _chr in enumerate(self.genotype): + if _chr.name != Chr: + locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + else: + locPixel += Mb*plotXScale + break + else: + if self.selectedChr > -1: + if self.genotype[0].name != Chr: + return + else: + for i, _locus in enumerate(self.genotype[0]): + #the trait's position is on the left of the first genotype + if i==0 and _locus.Mb >= Mb: + locPixel=-1 + break + + #the trait's position is between two traits + if i > 0 and self.genotype[0][i-1].Mb < Mb and _locus.Mb >= Mb: + locPixel = xLeftOffset + plotXScale*(self.genotype[0][i-1].cM+(_locus.cM-self.genotype[0][i-1].cM)*(Mb -self.genotype[0][i-1].Mb)/(_locus.Mb-self.genotype[0][i-1].Mb)) + break + + #the trait's position is on the right of the last genotype + if i==len(self.genotype[0]) and Mb>=_locus.Mb: + locPixel = -1 + else: + locPixel = xLeftOffset + for i, _chr in enumerate(self.genotype): + if _chr.name != Chr: + locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + else: + locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale + break + if locPixel >= 0: + traitPixel = ((locPixel, yZero), (locPixel-6, yZero+12), (locPixel+6, yZero+12)) + canvas.drawPolygon(traitPixel, edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) + + if self.legendChecked: + startPosY = 15 + nCol = 2 + smallLabelFont = pid.Font(ttf="trebuc", size=12, bold=1) + leftOffset = xLeftOffset+(nCol-1)*200 + canvas.drawPolygon(((leftOffset+6, startPosY-6), (leftOffset, startPosY+6), (leftOffset+12, startPosY+6)), edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) + canvas.drawString("Sequence Site", (leftOffset+15), (startPosY+5), smallLabelFont, self.TOP_RIGHT_INFO_COLOR) + + # build dict based on plink result, key is chr, value is list of [snp,BP,pValue] + def getPlinkResultDict(self,outputFileName='',thresholdPvalue=-1,ChrOrderIdNameDict={}): + + ChrList =self.ChrList + plinkResultDict={} + + plinkResultfp = open("%s%s.qassoc"% (webqtlConfig.TMPDIR, outputFileName), "rb") + + headerLine=plinkResultfp.readline()# read header line + line = plinkResultfp.readline() + + valueList=[] # initialize value list, this list will include snp, bp and pvalue info + pValueList=[] + count=0 + + while line: + #convert line from str to list + lineList=self.buildLineList(line=line) + + # only keep the records whose chromosome name is in db + if ChrOrderIdNameDict.has_key(int(lineList[0])) and lineList[-1] and lineList[-1].strip()!='NA': + + chrName=ChrOrderIdNameDict[int(lineList[0])] + snp = lineList[1] + BP = lineList[2] + pValue = float(lineList[-1]) + pValueList.append(pValue) + + if plinkResultDict.has_key(chrName): + valueList=plinkResultDict[chrName] + + # pvalue range is [0,1] + if thresholdPvalue >=0 and thresholdPvalue<=1: + if pValue < thresholdPvalue: + valueList.append((snp,BP,pValue)) + count+=1 + + plinkResultDict[chrName]=valueList + valueList=[] + else: + if thresholdPvalue>=0 and thresholdPvalue<=1: + if pValue < thresholdPvalue: + valueList.append((snp,BP,pValue)) + count+=1 + + if valueList: + plinkResultDict[chrName]=valueList + + valueList=[] + + + line =plinkResultfp.readline() + else: + line=plinkResultfp.readline() + + if pValueList: + minPvalue= min(pValueList) + else: + minPvalue=0 + + return count,minPvalue,plinkResultDict + + + ###################################################### + # input: line: str,one line read from file + # function: convert line from str to list; + # output: lineList list + ####################################################### + def buildLineList(self,line=None): + + lineList = string.split(string.strip(line),' ')# irregular number of whitespaces between columns + lineList =[ item for item in lineList if item <>''] + lineList = map(string.strip, lineList) + + return lineList + + #added by NL: automatically generate pheno txt file for PLINK based on strainList passed from dataEditing page + def genPhenoTxtFileForPlink(self,phenoFileName='', RISetName='', probesetName='', valueDict={}): + pedFileStrainList=self.getStrainNameFromPedFile(RISetName=RISetName) + outputFile = open("%s%s.txt"%(webqtlConfig.TMPDIR,phenoFileName),"wb") + headerLine = 'FID\tIID\t%s\n'%probesetName + outputFile.write(headerLine) + + newValueList=[] + + #if valueDict does not include some strain, value will be set to -9999 as missing value + for item in pedFileStrainList: + try: + value=valueDict[item] + value=str(value).replace('value=','') + value=value.strip() + except: + value=-9999 + + newValueList.append(value) + + + newLine='' + for i, strain in enumerate(pedFileStrainList): + j=i+1 + value=newValueList[i] + newLine+='%s\t%s\t%s\n'%(strain, strain, value) + + if j%1000==0: + outputFile.write(newLine) + newLine='' + + if newLine: + outputFile.write(newLine) + + outputFile.close() + + # get strain name from ped file in order + def getStrainNameFromPedFile(self, RISetName=''): + pedFileopen= open("%splink/%s.ped"%(webqtlConfig.HTMLPATH, RISetName),"r") + line =pedFileopen.readline() + strainNameList=[] + + while line: + lineList=string.split(string.strip(line),'\t') + lineList=map(string.strip,lineList) + + strainName=lineList[0] + strainNameList.append(strainName) + + line =pedFileopen.readline() + + return strainNameList + + ################################################################ + # Generate Chr list, Chr OrderId and Retrieve Length Information + ################################################################ + def getChrNameOrderIdLength(self,RISet=''): + + try: + query = """ + Select + Chr_Length.Name,Chr_Length.OrderId,Length from Chr_Length, InbredSet + where + Chr_Length.SpeciesId = InbredSet.SpeciesId AND + InbredSet.Name = '%s' + Order by OrderId + """ % (RISet) + self.cursor.execute(query) + + results =self.cursor.fetchall() + ChrList=[] + ChrLengthMbList=[] + ChrNameOrderIdDict={} + ChrOrderIdNameDict={} + + for item in results: + ChrList.append(item[0]) + ChrNameOrderIdDict[item[0]]=item[1] # key is chr name, value is orderId + ChrOrderIdNameDict[item[1]]=item[0] # key is orderId, value is chr name + ChrLengthMbList.append(item[2]) + + except: + ChrList=[] + ChrNameOrderIdDict={} + ChrLengthMbList=[] + + return ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList diff --git a/wqflask/wqflask/marker_regression/__init__.py b/wqflask/wqflask/marker_regression/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py new file mode 100755 index 00000000..ed01a3fa --- /dev/null +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -0,0 +1,1648 @@ +from __future__ import absolute_import, print_function, division + +from base.trait import GeneralTrait +from base import data_set #import create_dataset + +from pprint import pformat as pf + +import time +import string +import math +#from math import * +#import piddle +import sys +import os +import httplib +import urllib + +from htmlgen import HTMLgen2 as HT +from utility import Plot +from wqflask.interval_analyst import GeneUtil +from base.trait import GeneralTrait +from base.data_set import create_dataset +from base.templatePage import templatePage +from utility import webqtlUtil +from base import webqtlConfig +from dbFunction import webqtlDatabaseFunction +from base.GeneralObject import GeneralObject + +import reaper +import cPickle +from utility.THCell import THCell +from utility.TDCell import TDCell + + +class MarkerRegression(object): + + #def __init__(self, start_vars): + # + # print("[mike] Now start_vars is:", pf(start_vars)) + # + # self.dataset = data_set.create_dataset(start_vars['dataset_name']) + # self.this_trait = GeneralTrait(dataset=self.dataset.name, + # name=start_vars['trait_id'], + # cellid=None) + # + # print("self.this_trait is: ", pf(self.this_trait)) + # print("self.dataset is: ", pf(self.dataset)) + + def __init__(self, start_vars): + #templatePage.__init__(self, fd) + + #if not self.openMysql(): + # return + + self.dataset = create_dataset(start_vars['dataset_name']) + + #self.initializeParameters(start_vars) + + #filename= webqtlUtil.genRandStr("Itvl_") + #ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrtLengthMbList= self.getChrNameOrderIdLength(RISet=fd.RISet) + + if False: # For PLINK + + traitInfoList = string.split(string.strip(fd.identification),':') + probesetName = string.strip(traitInfoList[-1]) + plinkOutputFileName= webqtlUtil.genRandStr("%s_%s_"%(fd.RISet,probesetName)) + + # get related values from fd.allTraitData; the format of 'allTraitValueDict'is {strainName1: value=-0.2...} + fd.readData() + allTraitValueDict = fd.allTraitData + + #automatically generate pheno txt file for PLINK + self.genPhenoTxtFileForPlink(phenoFileName=plinkOutputFileName,RISetName=fd.RISet,probesetName=probesetName, valueDict=allTraitValueDict) + # os.system full path is required for input and output files; specify missing value is -9999 + plink_command = '%splink/plink --noweb --ped %splink/%s.ped --no-fid --no-parents --no-sex --no-pheno --map %splink/%s.map --pheno %s/%s.txt --pheno-name %s --missing-phenotype -9999 --out %s%s --assoc ' % (webqtlConfig.HTMLPATH, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.HTMLPATH, fd.RISet, webqtlConfig.TMPDIR, plinkOutputFileName, probesetName, webqtlConfig.TMPDIR, plinkOutputFileName) + + os.system(plink_command) + + if fd.identification: + heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) + heading2.__setattr__("class","subtitle") + self.dict['title'] = '%s: Genome Association' % fd.identification + else: + heading2 = "" + self.dict['title'] = 'Genome Association' + + if fd.traitInfo: + symbol,chromosome,MB = string.split(fd.traitInfo,'\t') + heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) + else: + heading3 = "" + + heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) + heading.__setattr__("class","title") + + # header info part:Trait Data Entered for HLC Set & Trait ID: + headerdiv = HT.TR(HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee')) + + self.ChrList=ChrList # get chr name from '1' to 'X' + self.ChrLengthMbList = ChrLengthMbList + + # build plink result dict based on chr, key is chr name, value is in list type including Snpname, bp and pvalue info + plinkResultDict={} + count,minPvalue,plinkResultDict =self.getPlinkResultDict(outputFileName=plinkOutputFileName,thresholdPvalue=self.pValue,ChrOrderIdNameDict=ChrOrderIdNameDict) + + # if can not find results which are matched with assigned p-value, system info will show up + if count >0: + + #for genome association report table + reportTable="" + # sortable table object + resultstable,tblobj,bottomInfo = self.GenReportForPLINK(ChrNameOrderIdDict=ChrNameOrderIdDict, RISet=fd.RISet,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue,chrList=self.ChrList) + + # creat object for result table for sort function + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + sortby = ("Index", "up") + reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + + descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) + descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) + descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) + descriptionTable.append(bottomInfo) + + # get each chr's length + self.ChrLengthMbList = map(lambda x: x/1000000.0, self.ChrLengthMbList) # change unit from bp to mb + self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0)# get total length of all chrs + if self.ChrLengthMbList: + self.GraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval + else: + self.GraphInterval = 1 + + # for human data, there's no CM value + self.ChrLengthCMList = [] + self.ChrLengthCMSum = 0 + + # begin: common part with human data + intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) + gifmap = self.plotIntMappingForPLINK(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, plinkResultDict=plinkResultDict) + + intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') + intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') + + TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) + self.dict['body'] = str(headerdiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) + + else: + heading = "Genome Association" + detail = ['There is no association with marker that meets this criteria. Please provide a less stringend threshold. The minimun p-value is %s.'%minPvalue] + self.error(heading=heading,detail=detail) + return + + else: # QTLreaper result + #if not fd.genotype: + # fd.readData() + # + #fd.parentsf14regression = fd.formdata.getvalue('parentsf14regression') + #weightedRegression = fd.formdata.getvalue('applyVarianceSE') + + #if fd.parentsf14regression and fd.genotype_2: + # _genotype = fd.genotype_2 + #else: + genotype = self.dataset.group.read_genotype_file() + print("[black]:", genotype) + + _strains, _vals, _vars, N = fd.informativeStrains(_genotype.prgy, weightedRegression) + + if fd.identification: + heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) + heading2.__setattr__("class","subtitle") + self.dict['title'] = '%s: Genome Association' % fd.identification + else: + heading2 = "" + self.dict['title'] = 'Genome Association' + + if fd.traitInfo: + symbol,chromosome,MB = string.split(fd.traitInfo,'\t') + heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) + else: + heading3 = "" + + if N < webqtlConfig.KMININFORMATIVE: + heading = "Genome Association" + detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, fd.RISet)] + self.error(heading=heading,detail=detail) + return + else: + heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) + heading.__setattr__("class","title") + + datadiv = HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee') + resultstable,tblobj,bottomInfo = self.GenReport(ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars) + #resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars) + + # creat object for result table for sort function + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + sortby = ("Index", "up") + reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + + descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) + descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) + descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) + descriptionTable.append(bottomInfo) + + self.traitList=_vals + + ##########################plot####################### + + ################################################################ + # Generate Chr list and Retrieve Length Information + ################################################################ + self.genotype= _genotype + self.ChrList = [("All", -1)] + + for i, indChr in enumerate(self.genotype): + self.ChrList.append((indChr.name, i)) + + self.cursor.execute(""" + Select + Length from Chr_Length, InbredSet + where + Chr_Length.SpeciesId = InbredSet.SpeciesId AND + InbredSet.Name = '%s' AND + Chr_Length.Name in (%s) + Order by + OrderId + """ % (fd.RISet, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", "))) + + self.ChrLengthMbList = self.cursor.fetchall() + self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList) + self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) + if self.ChrLengthMbList: + self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval + else: + self.MbGraphInterval = 1 + + self.ChrLengthCMList = [] + for i, _chr in enumerate(self.genotype): + self.ChrLengthCMList.append(_chr[-1].cM - _chr[0].cM) + self.ChrLengthCMSum = reduce(lambda x, y:x+y, self.ChrLengthCMList, 0.0)# used for calculate plot scale + + self.GraphInterval = self.MbGraphInterval #Mb + + # begin: common part with human data + intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) + gifmap = self.plotIntMapping(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= "") + filename= webqtlUtil.genRandStr("Itvl_") + intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') + intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') + + ################################################################ + # footnote goes here + ################################################################ + btminfo = HT.Paragraph(Id="smallsize") #Small('More information about this graph is available here.') + + if (self.additiveChecked): + btminfo.append(HT.BR(), 'A positive additive coefficient (', HT.Font('green', color='green'), ' line) indicates that %s alleles increase trait values. In contrast, a negative additive coefficient (' % fd.ppolar, HT.Font('red', color='red'), ' line) indicates that %s alleles increase trait values.' % fd.mpolar) + + + TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) + + self.dict['body'] = str(datadiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) + + # end: common part with human data + + + + + # add by NL 10-2-2011 + def initializeParameters(self, fd): + """ + Initializes all of the MarkerRegressionPage class parameters, + acquiring most values from the formdata (fd) + """ + ################################### + # manhattam plot parameters + ################################### + + self.graphHeight = 600 + self.graphWidth = 1280 + self.plotScale = 'physic' + self.selectedChr = -1 + self.GRAPH_BACK_DARK_COLOR = pid.HexColor(0xF1F1F9) + self.GRAPH_BACK_LIGHT_COLOR = pid.HexColor(0xFBFBFF) + self.LRS_COLOR = pid.HexColor(0x0000FF) + self.LRS_LOD ='LRS' + self.lrsMax = float(fd.formdata.getvalue('lrsMax', 0)) + self.startMb = fd.formdata.getvalue('startMb', "-1") + self.endMb = fd.formdata.getvalue('endMb', "-1") + self.mappingMethodId = fd.formdata.getvalue('mappingMethodId', "0") + self.permChecked=True + self.multipleInterval=False + self.SIGNIFICANT_WIDTH = 5 + self.SUGGESTIVE_WIDTH = 5 + self.SIGNIFICANT_COLOR = pid.HexColor(0xEBC7C7) + self.SUGGESTIVE_COLOR = pid.gainsboro + self.colorCollection = [self.LRS_COLOR] + self.additiveChecked= True + self.ADDITIVE_COLOR_POSITIVE = pid.green + self.legendChecked =False + self.pValue=float(fd.formdata.getvalue('pValue',-1)) + + # allow user to input p-value greater than 1, + # in this case, the value will be treated as -lgP value. so the input value needs to be transferred to power of 10 format + if self.pValue >1: + self.pValue =10**-(self.pValue) + + try: + self.startMb = float(self.startMb) + self.endMb = float(self.endMb) + if self.startMb > self.endMb: + temp = self.startMb + self.startMb = self.endMb + self.endMb = temp + #minimal distance 10bp + if self.endMb - self.startMb < 0.00001: + self.endMb = self.startMb + 0.00001 + except: + self.startMb = self.endMb = -1 + + def GenReportForPLINK(self, ChrNameOrderIdDict={},RISet='',plinkResultDict= {},thresholdPvalue=-1,chrList=[]): + + 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + ######################################### + # Genome Association report + ######################################### + locusFormName = webqtlUtil.genRandStr("fm_") + locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \ + enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':RISet+"Geno",'CellID':'_', \ + 'RISet':RISet, 'incparentsf1':'on'} + for key in hddn.keys(): + locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + regressionHeading = HT.Paragraph('Genome Association Report') + regressionHeading.__setattr__("class","title") + + filename= webqtlUtil.genRandStr("GenomeAsscociation_") + fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb') + fpText.write('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue) + pValueInfo =HT.Paragraph('The loci meet the criteria of P-Value <= %3.6f.\n'%thresholdPvalue) + + textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn') + bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),Class="fs12 fwn"), colspan=3)) + + tblobj={} # build dict for genTableObj function; keys include header and body + tblobj_header = [] # value of key 'header' + tblobj_body=[] # value of key 'body' + reportHeaderRow=[] # header row list for tblobj_header (html part) + headerList=['Index','SNP Name','Chr','Mb','-log(P)'] + headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header + cellColorStyle = "fs13 b1 fwn c222" # style of the cells + + if headerList: + for ncol, item in enumerate(headerList): + reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol)) + #download file for table headers' names + fpText.write('SNP_Name\tChromosome\tMb\t-log(P)\n') + + tblobj_header.append(reportHeaderRow) + tblobj['header']=tblobj_header + + index=1 + for chr in chrList: + + if plinkResultDict.has_key(chr): + if chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[chr] + else: + chrOrderId=chr + + valueList=plinkResultDict[chr] + + for value in valueList: + reportBodyRow=[] # row list for tblobj_body (html part) + snpName=value[0] + bp=value[1] + mb=int(bp)/1000000.0 + + try: + pValue =float(value[2]) + except: + pValue =1 + formattedPvalue = -math.log10(pValue) + + formattedPvalue = webqtlUtil.SciFloat(formattedPvalue) + dbSnprs=snpName.replace('rs','') + SnpHref = HT.Href(text=snpName, url="http://www.ncbi.nlm.nih.gov/projects/SNP/snp_ref.cgi?rs=%s"%dbSnprs, target="_blank") + + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(HT.TD(SnpHref, Class=cellColorStyle,nowrap='ON'),snpName, snpName)) + reportBodyRow.append(TDCell(HT.TD(chr, Class=cellColorStyle, align="center",nowrap='ON'),chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%mb, Class=cellColorStyle, align="center",nowrap='ON'),mb, mb)) + reportBodyRow.append(TDCell(HT.TD(formattedPvalue, Class=cellColorStyle, align="center",nowrap='ON'),formattedPvalue, float(formattedPvalue))) + + fpText.write('%s\t%s\t%3.6f\t%s\n' % (snpName, str(chr), mb, formattedPvalue)) + index+=1 + + tblobj_body.append(reportBodyRow) + + tblobj['body']=tblobj_body + rv=HT.TR(HT.TD(regressionHeading,pValueInfo, locusForm, HT.P(), width='55%',valign='top', align='left',bgColor='#eeeeee')) + + return rv, tblobj,bottomInfo + + + def GenReport(self, ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars= []): + 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + #calculate QTL for each trait + self.qtlresults = [] + if webqtlUtil.ListNotNull(_vars): + qtlresults = _genotype.regression(strains = _strains, trait = _vals, variance = _vars) + LRSArray = _genotype.permutation(strains = _strains, trait = _vals, variance = _vars, nperm=fd.nperm) + else: + qtlresults = _genotype.regression(strains = _strains, trait = _vals) + LRSArray = _genotype.permutation(strains = _strains, trait = _vals,nperm=fd.nperm) + + self.qtlresults.append(qtlresults) + + filename= webqtlUtil.genRandStr("GenomeAsscociation_") + + # set suggestive, significant and highly significant LRS + if fd.suggestive == None: + fd.suggestive = LRSArray[int(fd.nperm*0.37-1)] + else: + fd.suggestive = float(fd.suggestive) + if fd.significance == None: + fd.significance = LRSArray[int(fd.nperm*0.95-1)] + else: + fd.significance = float(fd.significance) + + self.significance =fd.significance + self.suggestive = fd.suggestive + self.highlysignificant = LRSArray[int(fd.nperm*0.99-1)] + _dispAllLRS = 0 + if fd.formdata.getvalue('displayAllLRS'): + _dispAllLRS = 1 + qtlresults2 = [] + if _dispAllLRS: + filtered = qtlresults[:] + else: + filtered = filter(lambda x, y=fd.suggestive: x.lrs > y, qtlresults) + if len(filtered) == 0: + qtlresults2 = qtlresults[:] + qtlresults2.sort() + filtered = qtlresults2[-10:] + + ######################################### + # Permutation Graph + ######################################### + myCanvas = pid.PILCanvas(size=(400,300)) + #plotBar(myCanvas,10,10,390,290,LRSArray,XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test',identification=fd.identification) + Plot.plotBar(myCanvas, LRSArray, XLabel='LRS',YLabel='Frequency',title=' Histogram of Permutation Test') + filename= webqtlUtil.genRandStr("Reg_") + myCanvas.save(webqtlConfig.IMGDIR+filename, format='gif') + img=HT.Image('/image/'+filename+'.gif',border=0,alt='Histogram of Permutation Test') + + if fd.suggestive == None: + fd.suggestive = LRSArray[int(fd.nperm*0.37-1)] + else: + fd.suggestive = float(fd.suggestive) + if fd.significance == None: + fd.significance = LRSArray[int(fd.nperm*0.95-1)] + else: + fd.significance = float(fd.significance) + + permutationHeading = HT.Paragraph('Histogram of Permutation Test') + permutationHeading.__setattr__("class","title") + + permutation = HT.TableLite() + permutation.append(HT.TR(HT.TD(img))) + + + ######################################### + # Genome Association report + ######################################### + locusFormName = webqtlUtil.genRandStr("fm_") + locusForm = HT.Form(cgi = os.path.join(webqtlConfig.CGIDIR, webqtlConfig.SCRIPTFILE), \ + enctype='multipart/form-data', name=locusFormName, submit=HT.Input(type='hidden')) + hddn = {'FormID':'showDatabase','ProbeSetID':'_','database':fd.RISet+"Geno",'CellID':'_', \ + 'RISet':fd.RISet, 'incparentsf1':'on'} + for key in hddn.keys(): + locusForm.append(HT.Input(name=key, value=hddn[key], type='hidden')) + + regressionHeading = HT.Paragraph('Genome Association Report') + regressionHeading.__setattr__("class","title") + # report is the info part above report table + if qtlresults2 != []: + report = HT.Blockquote(HT.Font('No association ',color="#FF0000"),HT.Font('with a likelihood ratio statistic greater than %3.1f was found. Here are the top 10 LRSs.' % fd.suggestive,color="#000000")) + else: + report = HT.Blockquote('The following loci in the %s data set have associations with the above trait data.\n' % fd.RISet, HT.P()) + report.__setattr__("class","normalsize") + + fpText = open('%s.txt' % (webqtlConfig.TMPDIR+filename), 'wb') + fpText.write('Suggestive LRS =%3.2f\n'%self.suggestive) + fpText.write('Significant LRS =%3.2f\n'%self.significance) + fpText.write('Highly Significant LRS =%3.2f\n'%self.highlysignificant) + LRSInfo =HT.Paragraph('    Suggestive LRS =%3.2f\n'%fd.suggestive, HT.BR(), '    Significant LRS =%3.2f\n'%fd.significance,HT.BR(),'    Highly Significant LRS =%3.2f\n' % self.highlysignificant) + + textUrl = HT.Href(text = 'Download', url= '/tmp/'+filename+'.txt', target = "_blank", Class='fs12 fwn') + + bottomInfo = HT.TR(HT.TD(HT.Paragraph(textUrl, ' result in tab-delimited text format.', HT.BR(), HT.BR(),'LRS values marked with',HT.Font(' * ',color="red"), 'are greater than the significance threshold (specified by you or by permutation test). ' , HT.BR(), HT.BR(), HT.Strong('Additive Effect'), ' is half the difference in the mean phenotype of all cases that are homozygous for one parental allel at this marker minus the mean of all cases that are homozygous for the other parental allele at this marker. ','In the case of %s strains, for example,' % fd.RISet,' A positive additive effect indicates that %s alleles increase trait values. Negative additive effect indicates that %s alleles increase trait values.'% (fd.ppolar,fd.mpolar),Class="fs12 fwn"))) + + tblobj={} # build dict for genTableObj function; keys include header and body + tblobj_header = [] # value of key 'header' + tblobj_body=[] # value of key 'body' + reportHeaderRow=[] # header row list for tblobj_header (html part) + headerStyle="fs14 fwb ffl b1 cw cbrb" # style of the header + cellColorStyle = "fs13 b1 fwn c222" # style of the cells + + headerList=['Index','LRS','Chr','Mb','Locus','Additive Effect'] + for ncol, item in enumerate(headerList): + reportHeaderRow.append(THCell(HT.TD(item, Class=headerStyle, valign='bottom',nowrap='ON'),text=item, idx=ncol)) + + if fd.genotype.type == 'intercross': + ncol =len(headerList) + reportHeaderRow.append(THCell(HT.TD('Dominance Effect', Class=headerStyle, valign='bottom',nowrap='ON'),text='Dominance Effect', idx=ncol)) + + #download file for table headers' names + fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\tDominance Effect\n') + + index=1 + for ii in filtered: + #add by NL 06-20-2011: set LRS to 460 when LRS is infinite, + if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS: + LRS=webqtlConfig.MAXLRS #maximum LRS value + else: + LRS=ii.lrs + + if LRS > fd.significance: + lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle) + else: + lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle) + + if ii.locus.chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[ii.locus.chr] + else: + chrOrderId=ii.locus.chr + + reportBodyRow=[] # row list for tblobj_body (html part) + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(lrs,LRS, LRS)) + reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb)) + reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.dominance, Class=cellColorStyle, align="center",nowrap='ON'),ii.dominance, ii.dominance)) + + fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive, ii.dominance)) + index+=1 + tblobj_body.append(reportBodyRow) + else: + #download file for table headers' names + fpText.write('LRS\tChromosome\tMb\tLocus\tAdditive Effect\n') + + index=1 + for ii in filtered: + #add by NL 06-20-2011: set LRS to 460 when LRS is infinite, + if ii.lrs==float('inf') or ii.lrs>webqtlConfig.MAXLRS: + LRS=webqtlConfig.MAXLRS #maximum LRS value + else: + LRS=ii.lrs + + if LRS > fd.significance: + lrs = HT.TD(HT.Font('%3.3f*' % LRS, color='#FF0000'),Class=cellColorStyle) + else: + lrs = HT.TD('%3.3f' % LRS,Class=cellColorStyle) + + if ii.locus.chr in ChrNameOrderIdDict.keys(): + chrOrderId =ChrNameOrderIdDict[ii.locus.chr] + else: + chrOrderId=ii.locus.chr + + reportBodyRow=[] # row list for tblobj_body (html part) + selectCheck=HT.Input(type="checkbox", Class="checkbox", name="index",value=index, onClick="highlight(this)") + reportBodyRow.append(TDCell(HT.TD(str(index),selectCheck, align='right',Class=cellColorStyle,nowrap='ON'),str(index),index)) + reportBodyRow.append(TDCell(lrs,LRS, LRS)) + reportBodyRow.append(TDCell(HT.TD(ii.locus.chr, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.chr, chrOrderId)) + reportBodyRow.append(TDCell(HT.TD('%3.6f'%ii.locus.Mb, Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.Mb, ii.locus.Mb)) + reportBodyRow.append(TDCell(HT.TD(HT.Href(text=ii.locus.name, url = "javascript:showTrait('%s','%s');" % (locusFormName, ii.locus.name), Class='normalsize'), Class=cellColorStyle, align="center",nowrap='ON'),ii.locus.name, ii.locus.name)) + reportBodyRow.append(TDCell(HT.TD('%3.3f' % ii.additive, Class=cellColorStyle, align="center",nowrap='ON'),ii.additive, ii.additive)) + + fpText.write('%2.3f\t%s\t%3.6f\t%s\t%2.3f\n' % (LRS, ii.locus.chr, ii.locus.Mb, ii.locus.name, ii.additive)) + index+=1 + tblobj_body.append(reportBodyRow) + + tblobj_header.append(reportHeaderRow) + tblobj['header']=tblobj_header + tblobj['body']=tblobj_body + + rv=HT.TD(regressionHeading,LRSInfo,report, locusForm, HT.P(),width='55%',valign='top', align='left', bgColor='#eeeeee') + if fd.genotype.type == 'intercross': + bottomInfo.append(HT.BR(), HT.BR(), HT.Strong('Dominance Effect'),' is the difference between the mean trait value of cases heterozygous at a marker and the average mean for the two groups homozygous at this marker: e.g., BD - (BB+DD)/2]. A positive dominance effect indicates that the average phenotype of BD heterozygotes exceeds the mean of BB and DD homozygotes. No dominance deviation can be computed for a set of recombinant inbred strains or for a backcross.') + return rv,tblobj,bottomInfo + + return rv,tblobj,bottomInfo + + def plotIntMappingForPLINK(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = "",plinkResultDict={}): + #calculating margins + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + xLeftOffset = int(xLeftOffset*fontZoom) + xRightOffset = int(xRightOffset*fontZoom) + yBottomOffset = int(yBottomOffset*fontZoom) + + cWidth = canvas.size[0] + cHeight = canvas.size[1] + plotWidth = cWidth - xLeftOffset - xRightOffset + plotHeight = cHeight - yTopOffset - yBottomOffset + startPixelX = xLeftOffset + endPixelX = (xLeftOffset + plotWidth) + + #Drawing Area Height + drawAreaHeight = plotHeight + if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr + drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom + if self.geneChecked: + drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom + else: + if self.selectedChr > -1: + drawAreaHeight -= 20 + else:# for all chrs + drawAreaHeight -= 30 + + #Image map + gifmap = HT.Map(name='WebQTLImageMap') + + newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset) + # Draw the alternating-color background first and get plotXScale + plotXScale = self.drawGraphBackgroundForPLINK(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict) + + # Draw X axis + self.drawXAxisForPLINK(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + # Draw manhattam plot + self.drawManhattanPlotForPLINK(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb,plinkResultDict=plinkResultDict,thresholdPvalue=self.pValue) + + return gifmap + + + def plotIntMapping(self, fd, canvas, offset= (80, 120, 20, 80), zoom = 1, startMb = None, endMb = None, showLocusForm = ""): + #calculating margins + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + xLeftOffset = int(xLeftOffset*fontZoom) + xRightOffset = int(xRightOffset*fontZoom) + yBottomOffset = int(yBottomOffset*fontZoom) + + cWidth = canvas.size[0] + cHeight = canvas.size[1] + plotWidth = cWidth - xLeftOffset - xRightOffset + plotHeight = cHeight - yTopOffset - yBottomOffset + startPixelX = xLeftOffset + endPixelX = (xLeftOffset + plotWidth) + + #Drawing Area Height + drawAreaHeight = plotHeight + if self.plotScale == 'physic' and self.selectedChr > -1: # for single chr + drawAreaHeight -= self.ENSEMBL_BAND_HEIGHT + self.UCSC_BAND_HEIGHT+ self.WEBQTL_BAND_HEIGHT + 3*self.BAND_SPACING+ 10*zoom + if self.geneChecked: + drawAreaHeight -= self.NUM_GENE_ROWS*self.EACH_GENE_HEIGHT + 3*self.BAND_SPACING + 10*zoom + else:# for all chrs + if self.selectedChr > -1: + drawAreaHeight -= 20 + else: + drawAreaHeight -= 30 + + #Image map + gifmap = HT.Map(name='WebQTLImageMap') + + newoffset = (xLeftOffset, xRightOffset, yTopOffset, yBottomOffset) + # Draw the alternating-color background first and get plotXScale + plotXScale = self.drawGraphBackground(canvas, gifmap, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + + # Draw X axis + self.drawXAxis(fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + # Draw QTL curve + self.drawQTL(canvas, drawAreaHeight, gifmap, plotXScale, offset=newoffset, zoom= zoom, startMb=startMb, endMb = endMb) + + #draw legend + if self.multipleInterval: + self.drawMultiTraitName(fd, canvas, gifmap, showLocusForm, offset=newoffset) + elif self.legendChecked: + self.drawLegendPanel(fd, canvas, offset=newoffset) + else: + pass + + #draw position, no need to use a separate function + if fd.genotype.Mbmap: + self.drawProbeSetPosition(canvas, plotXScale, offset=newoffset) + + return gifmap + + + # functions for manhattam plot of markers + def drawManhattanPlotForPLINK(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None,plinkResultDict={},thresholdPvalue=-1): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + # INTERCROSS = (self.genotype.type=="intercross") + INTERCROSS ='' #?????? + + ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + GraphInterval=self.GraphInterval + pvalueHeightThresh = drawAreaHeight - 80 #ZS: Otherwise the plot gets very close to the chromosome labels + + #draw the pvalue scale + #We first determine whether or not we are using a sliding scale. + #If so, we need to compute the maximum pvalue value to determine where the max y-value should be, and call this pvalueMax. + #pvalueTop is then defined to be above the pvalueMax by enough to add one additional pvalueScale increment. + #if we are using a set-scale, then we set pvalueTop to be the user's value, and pvalueMax doesn't matter. + + # for human data we use p value instead of lrs + pValueList=[] + for key in plinkResultDict: + valueList = plinkResultDict[key] + for item in valueList: + pValue = item[-1] + pValueList.append(pValue) + + formattedPValueList=[] + for pValue in pValueList: + try: + pValue=float(pValue) + except: + pValue =1 + formattedpValue = -math.log10(pValue) + formattedPValueList.append(formattedpValue) + + #sliding scale + pvalueMax = max(formattedPValueList) + #pvalueMax =pvalueMax +1 + # no permutation result for plink func: GenReport() + pvalueMin = int(-math.log10(thresholdPvalue)) + + if pvalueMax> 100: + pvalueScale = 20.0 + elif pvalueMax > 20: + pvalueScale = 5.0 + elif pvalueMax > 7.5: + pvalueScale = 2.5 + else: + pvalueScale = 1.0 + + # the base line for x-axis is -log(thresholdPvalue) + pvalueAxisList = Plot.frange(pvalueMin, pvalueMax, pvalueScale) + #make sure the user's value appears on the y-axis + #ZS: There is no way to do this without making the position of the points not directly proportional to a given distance on the y-axis + #tempPvalueMax=round(pvalueMax) + tempPvalueMax = pvalueAxisList[len(pvalueAxisList)-1] + pvalueScale + pvalueAxisList.append(tempPvalueMax) + + #ZS: I don't understand this; the if statement will be true for any number that isn't exactly X.5. + #if abs(tempPvalueMax-pvalueMax) <0.5: + # tempPvalueMax=tempPvalueMax+1 + # pvalueAxisList.append(tempPvalueMax) + + #draw the "pvalue" string to the left of the axis + pvalueScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0) + pvalueLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + yZero = yTopOffset + plotHeight + + #yAxis label display area + yAxis_label ='-log(P)' + canvas.drawString(yAxis_label, xLeftOffset - canvas.stringWidth("999.99", font=pvalueScaleFont) - 10*zoom, \ + yZero - 150, font=pvalueLODFont, color=pid.black, angle=90) + + for i,item in enumerate(pvalueAxisList): + ypvalue = yZero - (float(i)/float(len(pvalueAxisList) - 1)) * pvalueHeightThresh + canvas.drawLine(xLeftOffset, ypvalue, xLeftOffset - 4, ypvalue, color=self.LRS_COLOR, width=1*zoom) + scaleStr = "%2.1f" % item + #added by NL 6-24-2011:Y-axis scale display + canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=pvalueScaleFont)-5, ypvalue+3, font=pvalueScaleFont, color=self.LRS_COLOR) + + ChrList=self.ChrList + startPosX = xLeftOffset + + for i, chr in enumerate(ChrList): + + if plinkResultDict.has_key(chr): + plinkresultList = plinkResultDict[chr] + + m = 0 + #add by NL 06-24-2011: for mahanttam plot + symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0) + # color for point in each chr + chrCount=len(ChrList) + chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1) + for j, item in enumerate(plinkresultList): + try : + mb=float(item[1])/1000000.0 + except: + mb=0 + + try : + pvalue =float(item[-1]) + except: + pvalue =1 + + try: + snpName = item[0] + except: + snpName='' + + formattedPvalue = -math.log10(pvalue) + + Xc = startPosX + (mb-startMb)*plotXScale + Yc = yZero - (formattedPvalue-pvalueMin)*pvalueHeightThresh/(tempPvalueMax - pvalueMin) + canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[i], font=symbolFont) + m += 1 + + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis + + def drawQTL(self, canvas, drawAreaHeight, gifmap, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + INTERCROSS = (self.genotype.type=="intercross") + + ChrLengthDistList = self.ChrLengthMbList + GraphInterval=self.GraphInterval + LRSHeightThresh = drawAreaHeight + AdditiveHeightThresh = drawAreaHeight/2 + DominanceHeightThresh = drawAreaHeight/2 + + #draw the LRS scale + #We first determine whether or not we are using a sliding scale. + #If so, we need to compute the maximum LRS value to determine where the max y-value should be, and call this LRSMax. + #LRSTop is then defined to be above the LRSMax by enough to add one additional LRSScale increment. + #if we are using a set-scale, then we set LRSTop to be the user's value, and LRSMax doesn't matter. + + if self.LRS_LOD == 'LOD': + lodm = self.LODFACTOR + else: + lodm = 1.0 + + if self.lrsMax <= 0: #sliding scale + LRSMax = max(map(max, self.qtlresults)).lrs + #genotype trait will give infinite LRS + LRSMax = min(LRSMax, webqtlConfig.MAXLRS) + LRSMax = max(self.significance, LRSMax) + else: + LRSMax = self.lrsMax*lodm + + if LRSMax/lodm > 100: + LRSScale = 20.0 + elif LRSMax/lodm > 20: + LRSScale = 5.0 + elif LRSMax/lodm > 7.5: + LRSScale = 2.5 + else: + LRSScale = 1.0 + + LRSAxisList = Plot.frange(LRSScale, LRSMax/lodm, LRSScale) + #make sure the user's value appears on the y-axis + #update by NL 6-21-2011: round the LOD value to 100 when LRSMax is equal to 460 + LRSAxisList.append(round(LRSMax/lodm)) + + #draw the "LRS" or "LOD" string to the left of the axis + LRSScaleFont=pid.Font(ttf="verdana", size=14*fontZoom, bold=0) + LRSLODFont=pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + yZero = yTopOffset + plotHeight + + #yAxis label display area + canvas.drawString(self.LRS_LOD, xLeftOffset - canvas.stringWidth("999.99", font=LRSScaleFont) - 10*zoom, \ + yZero - 150, font=LRSLODFont, color=pid.black, angle=90) + + for item in LRSAxisList: + yLRS = yZero - (item*lodm/LRSMax) * LRSHeightThresh + canvas.drawLine(xLeftOffset, yLRS, xLeftOffset - 4, yLRS, color=self.LRS_COLOR, width=1*zoom) + scaleStr = "%2.1f" % item + #added by NL 6-24-2011:Y-axis scale display + canvas.drawString(scaleStr, xLeftOffset-4-canvas.stringWidth(scaleStr, font=LRSScaleFont)-5, yLRS+3, font=LRSScaleFont, color=self.LRS_COLOR) + + + #"Significant" and "Suggestive" Drawing Routine + # ======= Draw the thick lines for "Significant" and "Suggestive" ===== (crowell: I tried to make the SNPs draw over these lines, but piddle wouldn't have it...) + if self.permChecked and not self.multipleInterval: + significantY = yZero - self.significance*LRSHeightThresh/LRSMax + suggestiveY = yZero - self.suggestive*LRSHeightThresh/LRSMax + + + startPosX = xLeftOffset + for i, _chr in enumerate(self.genotype): + rightEdge = int(startPosX + self.ChrLengthDistList[i]*plotXScale - self.SUGGESTIVE_WIDTH/1.5) + #added by NL 6-24-2011:draw suggestive line (grey one) + canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, suggestiveY, rightEdge, suggestiveY, color=self.SUGGESTIVE_COLOR, + width=self.SUGGESTIVE_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) + #added by NL 6-24-2011:draw significant line (pink one) + canvas.drawLine(startPosX+self.SUGGESTIVE_WIDTH/1.5, significantY, rightEdge, significantY, color=self.SIGNIFICANT_COLOR, + width=self.SIGNIFICANT_WIDTH*zoom, clipX=(xLeftOffset, xLeftOffset + plotWidth-2)) + sugg_coords = "%d, %d, %d, %d" % (startPosX, suggestiveY-2, rightEdge + 2*zoom, suggestiveY+2) + sig_coords = "%d, %d, %d, %d" % (startPosX, significantY-2, rightEdge + 2*zoom, significantY+2) + if self.LRS_LOD == 'LRS': + sugg_title = "Suggestive LRS = %0.2f" % self.suggestive + sig_title = "Significant LRS = %0.2f" % self.significance + else: + sugg_title = "Suggestive LOD = %0.2f" % (self.suggestive/4.61) + sig_title = "Significant LOD = %0.2f" % (self.significance/4.61) + Areas1 = HT.Area(shape='rect',coords=sugg_coords,title=sugg_title) + Areas2 = HT.Area(shape='rect',coords=sig_coords,title=sig_title) + gifmap.areas.append(Areas1) + gifmap.areas.append(Areas2) + + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + + if self.multipleInterval: + lrsEdgeWidth = 1 + else: + additiveMax = max(map(lambda X : abs(X.additive), self.qtlresults[0])) + if INTERCROSS: + dominanceMax = max(map(lambda X : abs(X.dominance), self.qtlresults[0])) + else: + dominanceMax = -1 + lrsEdgeWidth = 2 + for i, qtlresult in enumerate(self.qtlresults): + m = 0 + startPosX = xLeftOffset + thisLRSColor = self.colorCollection[i] + + #add by NL 06-24-2011: for mahanttam plot + symbolFont = pid.Font(ttf="fnt_bs", size=5,bold=0) + + for j, _chr in enumerate(self.genotype): + chrCount=len(self.genotype) + chrColorDict =self.getColorForMarker(chrCount=chrCount,flag=1) + LRSCoordXY = [] + AdditiveCoordXY = [] + DominanceCoordXY = [] + for k, _locus in enumerate(_chr): + if self.plotScale == 'physic': + Xc = startPosX + (_locus.Mb-startMb)*plotXScale + else: + Xc = startPosX + (_locus.cM-_chr[0].cM)*plotXScale + # updated by NL 06-18-2011: + # fix the over limit LRS graph issue since genotype trait may give infinite LRS; + # for any lrs is over than 460(LRS max in this system), it will be reset to 460 + if qtlresult[m].lrs> 460 or qtlresult[m].lrs=='inf': + Yc = yZero - webqtlConfig.MAXLRS*LRSHeightThresh/LRSMax + else: + Yc = yZero - qtlresult[m].lrs*LRSHeightThresh/LRSMax + + LRSCoordXY.append((Xc, Yc)) + #add by NL 06-24-2011: for mahanttam plot + #self.significance/4.61 consider chr and LOD + # significantY = yZero - self.significance*LRSHeightThresh/LRSMax + # if Yc >significantY: + # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont) + # else: + # canvas.drawString(":", Xc-canvas.stringWidth(":",font=symbolFont)/2+1,Yc+2,color=pid.black, font=symbolFont) + + # add by NL 06-27-2011: eliminate imputed value when locus name is equal to '-' + if (qtlresult[m].locus.name) and (qtlresult[m].locus.name!=' - '): + canvas.drawString("5", Xc-canvas.stringWidth("5",font=symbolFont)/2+1,Yc+2,color=chrColorDict[j], font=symbolFont) + + if not self.multipleInterval and self.additiveChecked: + Yc = yZero - qtlresult[m].additive*AdditiveHeightThresh/additiveMax + AdditiveCoordXY.append((Xc, Yc)) + if not self.multipleInterval and INTERCROSS and self.additiveChecked: + Yc = yZero - qtlresult[m].dominance*DominanceHeightThresh/dominanceMax + DominanceCoordXY.append((Xc, Yc)) + m += 1 + + startPosX += (ChrLengthDistList[j]+GraphInterval)*plotXScale + + + ###draw additive scale + if not self.multipleInterval and self.additiveChecked: + additiveScaleFont=pid.Font(ttf="verdana",size=12*fontZoom,bold=0) + additiveScale = Plot.detScaleOld(0,additiveMax) + additiveStep = (additiveScale[1]-additiveScale[0])/additiveScale[2] + additiveAxisList = Plot.frange(0, additiveScale[1], additiveStep) + maxAdd = additiveScale[1] + addPlotScale = AdditiveHeightThresh/additiveMax + + additiveAxisList.append(additiveScale[1]) + for item in additiveAxisList: + additiveY = yZero - item*addPlotScale + canvas.drawLine(xLeftOffset + plotWidth,additiveY,xLeftOffset+4+ plotWidth,additiveY,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + scaleStr = "%2.3f" % item + canvas.drawString(scaleStr,xLeftOffset + plotWidth +6,additiveY+5,font=additiveScaleFont,color=self.ADDITIVE_COLOR_POSITIVE) + + canvas.drawLine(xLeftOffset+plotWidth,additiveY,xLeftOffset+plotWidth,yZero,color=self.ADDITIVE_COLOR_POSITIVE, width=1*zoom) + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset, yTopOffset, color=self.LRS_COLOR, width=1*zoom) #the blue line running up the y axis + + def drawGraphBackgroundForPLINK(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None,plinkResultDict={} ): + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #calculate plot scale + #XZ: all of these global variables should be passed from function signiture + ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + GraphInterval=self.GraphInterval + ChrList =self.ChrList + + #multiple chromosome view + plotXScale = plotWidth / ((len(ChrList)-1)*GraphInterval + drawRegionDistance) + + startPosX = xLeftOffset + chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0) + + for i, _chr in enumerate(ChrList): + + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + # NL:resize chr width for drawing + if float(ChrLengthDistList[i])<90: + ChrLengthDistList[i]=90 + #draw the shaded boxes and the sig/sug thick lines + canvas.drawRect(startPosX, yTopOffset, startPosX + ChrLengthDistList[i]*plotXScale, \ + yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor) + + chrNameWidth = canvas.stringWidth(_chr, font=chrLabelFont) + chrStartPix = startPosX + (ChrLengthDistList[i]*plotXScale -chrNameWidth)/2 + chrEndPix = startPosX + (ChrLengthDistList[i]*plotXScale +chrNameWidth)/2 + + canvas.drawString(_chr, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray) + COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) + + #add by NL 09-03-2010 + HREF = "javascript:changeView(%d,%s);" % (i,ChrLengthDistList) + Areas = HT.Area(shape='rect',coords=COORDS,href=HREF) + gifmap.areas.append(Areas) + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + return plotXScale + + + def drawGraphBackground(self, canvas, gifmap, offset= (80, 120, 80, 50), zoom = 1, startMb = None, endMb = None): + ##conditions + ##multiple Chromosome view + ##single Chromosome Physical + ##single Chromosome Genetic + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #calculate plot scale + if self.plotScale != 'physic': + self.ChrLengthDistList = self.ChrLengthCMList + drawRegionDistance = self.ChrLengthCMSum + else: + self.ChrLengthDistList = self.ChrLengthMbList + drawRegionDistance = self.ChrLengthMbSum + + if self.selectedChr > -1: #single chromosome view + spacingAmt = plotWidth/13.5 + i = 0 + for startPix in Plot.frange(xLeftOffset, xLeftOffset+plotWidth, spacingAmt): + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + i += 1 + canvas.drawRect(startPix, yTopOffset, min(startPix+spacingAmt, xLeftOffset+plotWidth), \ + yTopOffset+plotHeight, edgeColor=theBackColor, fillColor=theBackColor) + + drawRegionDistance = self.ChrLengthDistList[self.selectedChr] + self.ChrLengthDistList = [drawRegionDistance] + if self.plotScale == 'physic': + plotXScale = plotWidth / (endMb-startMb) + else: + plotXScale = plotWidth / drawRegionDistance + + else: #multiple chromosome view + plotXScale = plotWidth / ((len(self.genotype)-1)*self.GraphInterval + drawRegionDistance) + + startPosX = xLeftOffset + chrLabelFont=pid.Font(ttf="verdana",size=24*fontZoom,bold=0) + + for i, _chr in enumerate(self.genotype): + + if (i % 2 == 0): + theBackColor = self.GRAPH_BACK_DARK_COLOR + else: + theBackColor = self.GRAPH_BACK_LIGHT_COLOR + + #draw the shaded boxes and the sig/sug thick lines + canvas.drawRect(startPosX, yTopOffset, startPosX + self.ChrLengthDistList[i]*plotXScale, \ + yTopOffset+plotHeight, edgeColor=pid.gainsboro,fillColor=theBackColor) + + chrNameWidth = canvas.stringWidth(_chr.name, font=chrLabelFont) + chrStartPix = startPosX + (self.ChrLengthDistList[i]*plotXScale -chrNameWidth)/2 + chrEndPix = startPosX + (self.ChrLengthDistList[i]*plotXScale +chrNameWidth)/2 + + canvas.drawString(_chr.name, chrStartPix, yTopOffset +20,font = chrLabelFont,color=pid.dimgray) + COORDS = "%d,%d,%d,%d" %(chrStartPix, yTopOffset, chrEndPix,yTopOffset +20) + + #add by NL 09-03-2010 + HREF = "javascript:changeView(%d,%s);" % (i,self.ChrLengthMbList) + Areas = HT.Area(shape='rect',coords=COORDS,href=HREF) + gifmap.areas.append(Areas) + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + return plotXScale + + # XZ: The only difference of function drawXAxisForPLINK and function drawXAxis are the function name and the self.plotScale condition. + def drawXAxisForPLINK(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #Parameters + ChrLengthDistList = self.ChrLengthMbList + GraphInterval=self.GraphInterval + + NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks + X_MAJOR_TICK_THICKNESS = 2 + X_MINOR_TICK_THICKNESS = 1 + X_AXIS_THICKNESS = 1*zoom + + # ======= Alex: Draw the X-axis labels (megabase location) + MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0) + xMajorTickHeight = 15 # How high the tick extends below the axis + xMinorTickHeight = 5*zoom + xAxisTickMarkColor = pid.black + xAxisLabelColor = pid.black + fontHeight = 12*fontZoom # How tall the font that we're using is + spacingFromLabelToAxis = 20 + spacingFromLineToLabel = 3 + + if self.plotScale == 'physic': + strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + ###Physical single chromosome view + if self.selectedChr > -1: + graphMbWidth = endMb - startMb + XScale = Plot.detScale(startMb, endMb) + XStart, XEnd, XStep = XScale + if XStep < 8: + XStep *= 2 + spacingAmtX = spacingAmt = (XEnd-XStart)/XStep + + j = 0 + while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6: + j += 1 + spacingAmtX *= 10 + + formatStr = '%%2.%df' % j + + for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)): + if _Mb < startMb or _Mb > endMb: + continue + Xc = xLeftOffset + plotXScale*(_Mb - startMb) + if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark + canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark + labelStr = str(formatStr % _Mb) # What Mbase location to put on the label + strWidth = canvas.stringWidth(labelStr, font=MBLabelFont) + drawStringXc = (Xc - (strWidth / 2.0)) + canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0) + else: + canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark + # end else + + ###Physical genome wide view + else: + distScale = 0 + startPosX = xLeftOffset + for i, distLen in enumerate(ChrLengthDistList): + if distScale == 0: #universal scale in whole genome mapping + if distLen > 75: + distScale = 25 + elif distLen > 30: + distScale = 10 + else: + distScale = 5 + for tickdists in range(distScale, ceil(distLen), distScale): + canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom) + canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270) + startPosX += (ChrLengthDistList[i]+GraphInterval)*plotXScale + + megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2, + strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black) + pass + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself + + def drawXAxis(self, fd, canvas, drawAreaHeight, gifmap, plotXScale, showLocusForm, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + #Parameters + NUM_MINOR_TICKS = 5 # Number of minor ticks between major ticks + X_MAJOR_TICK_THICKNESS = 2 + X_MINOR_TICK_THICKNESS = 1 + X_AXIS_THICKNESS = 1*zoom + + # ======= Alex: Draw the X-axis labels (megabase location) + MBLabelFont = pid.Font(ttf="verdana", size=12*fontZoom, bold=0) + xMajorTickHeight = 15 # How high the tick extends below the axis + xMinorTickHeight = 5*zoom + xAxisTickMarkColor = pid.black + xAxisLabelColor = pid.black + fontHeight = 12*fontZoom # How tall the font that we're using is + spacingFromLabelToAxis = 20 + spacingFromLineToLabel = 3 + + if self.plotScale == 'physic': + strYLoc = yZero + spacingFromLabelToAxis + canvas.fontHeight(MBLabelFont) + ###Physical single chromosome view + if self.selectedChr > -1: + graphMbWidth = endMb - startMb + XScale = Plot.detScale(startMb, endMb) + XStart, XEnd, XStep = XScale + if XStep < 8: + XStep *= 2 + spacingAmtX = spacingAmt = (XEnd-XStart)/XStep + + j = 0 + while abs(spacingAmtX -int(spacingAmtX)) >= spacingAmtX/100.0 and j < 6: + j += 1 + spacingAmtX *= 10 + + formatStr = '%%2.%df' % j + + for counter, _Mb in enumerate(Plot.frange(XStart, XEnd, spacingAmt / NUM_MINOR_TICKS)): + if _Mb < startMb or _Mb > endMb: + continue + Xc = xLeftOffset + plotXScale*(_Mb - startMb) + if counter % NUM_MINOR_TICKS == 0: # Draw a MAJOR mark, not just a minor tick mark + canvas.drawLine(Xc, yZero, Xc, yZero+xMajorTickHeight, color=xAxisTickMarkColor, width=X_MAJOR_TICK_THICKNESS) # Draw the MAJOR tick mark + labelStr = str(formatStr % _Mb) # What Mbase location to put on the label + strWidth = canvas.stringWidth(labelStr, font=MBLabelFont) + drawStringXc = (Xc - (strWidth / 2.0)) + canvas.drawString(labelStr, drawStringXc, strYLoc, font=MBLabelFont, color=xAxisLabelColor, angle=0) + else: + canvas.drawLine(Xc, yZero, Xc, yZero+xMinorTickHeight, color=xAxisTickMarkColor, width=X_MINOR_TICK_THICKNESS) # Draw the MINOR tick mark + # end else + + ###Physical genome wide view + else: + distScale = 0 + startPosX = xLeftOffset + for i, distLen in enumerate(self.ChrLengthDistList): + if distScale == 0: #universal scale in whole genome mapping + if distLen > 75: + distScale = 25 + elif distLen > 30: + distScale = 10 + else: + distScale = 5 + for tickdists in range(distScale, ceil(distLen), distScale): + canvas.drawLine(startPosX + tickdists*plotXScale, yZero, startPosX + tickdists*plotXScale, yZero + 7, color=pid.black, width=1*zoom) + canvas.drawString(str(tickdists), startPosX+tickdists*plotXScale, yZero + 10*zoom, color=pid.black, font=MBLabelFont, angle=270) + startPosX += (self.ChrLengthDistList[i]+self.GraphInterval)*plotXScale + + megabaseLabelFont = pid.Font(ttf="verdana", size=14*zoom*1.5, bold=0) + canvas.drawString("Megabases", xLeftOffset + (plotWidth -canvas.stringWidth("Megabases", font=megabaseLabelFont))/2, + strYLoc + canvas.fontHeight(MBLabelFont) + 5*zoom, font=megabaseLabelFont, color=pid.black) + pass + else: + ChrAInfo = [] + preLpos = -1 + distinctCount = 0.0 + if len(self.genotype) > 1: + for i, _chr in enumerate(self.genotype): + thisChr = [] + Locus0CM = _chr[0].cM + nLoci = len(_chr) + if nLoci <= 8: + for _locus in _chr: + if _locus.name != ' - ': + if _locus.cM != preLpos: + distinctCount += 1 + preLpos = _locus.cM + thisChr.append([_locus.name, _locus.cM-Locus0CM]) + else: + for j in (0, nLoci/4, nLoci/2, nLoci*3/4, -1): + while _chr[j].name == ' - ': + j += 1 + if _chr[j].cM != preLpos: + distinctCount += 1 + preLpos = _chr[j].cM + thisChr.append([_chr[j].name, _chr[j].cM-Locus0CM]) + ChrAInfo.append(thisChr) + else: + for i, _chr in enumerate(self.genotype): + thisChr = [] + Locus0CM = _chr[0].cM + for _locus in _chr: + if _locus.name != ' - ': + if _locus.cM != preLpos: + distinctCount += 1 + preLpos = _locus.cM + thisChr.append([_locus.name, _locus.cM-Locus0CM]) + ChrAInfo.append(thisChr) + + stepA = (plotWidth+0.0)/distinctCount + + LRectWidth = 10 + LRectHeight = 3 + offsetA = -stepA + lineColor = pid.lightblue + startPosX = xLeftOffset + for j, ChrInfo in enumerate(ChrAInfo): + preLpos = -1 + for i, item in enumerate(ChrInfo): + Lname,Lpos = item + if Lpos != preLpos: + offsetA += stepA + differ = 1 + else: + differ = 0 + preLpos = Lpos + Lpos *= plotXScale + if self.selectedChr > -1: + Zorder = i % 5 + else: + Zorder = 0 + if differ: + canvas.drawLine(startPosX+Lpos,yZero,xLeftOffset+offsetA,\ + yZero+25, color=lineColor) + canvas.drawLine(xLeftOffset+offsetA,yZero+25,xLeftOffset+offsetA,\ + yZero+40+Zorder*(LRectWidth+3),color=lineColor) + rectColor = pid.orange + else: + canvas.drawLine(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3)-3,\ + xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),color=lineColor) + rectColor = pid.deeppink + canvas.drawRect(xLeftOffset+offsetA, yZero+40+Zorder*(LRectWidth+3),\ + xLeftOffset+offsetA-LRectHeight,yZero+40+Zorder*(LRectWidth+3)+LRectWidth,\ + edgeColor=rectColor,fillColor=rectColor,edgeWidth = 0) + COORDS="%d,%d,%d,%d"%(xLeftOffset+offsetA-LRectHeight, yZero+40+Zorder*(LRectWidth+3),\ + xLeftOffset+offsetA,yZero+40+Zorder*(LRectWidth+3)+LRectWidth) + HREF="javascript:showDatabase3('%s','%s','%s','');" % (showLocusForm,fd.RISet+"Geno", Lname) + Areas=HT.Area(shape='rect',coords=COORDS,href=HREF, title="Locus : " + Lname) + gifmap.areas.append(Areas) + ##piddle bug + if j == 0: + canvas.drawLine(startPosX,yZero,startPosX,yZero+40, color=lineColor) + startPosX += (self.ChrLengthDistList[j]+self.GraphInterval)*plotXScale + + canvas.drawLine(xLeftOffset, yZero, xLeftOffset+plotWidth, yZero, color=pid.black, width=X_AXIS_THICKNESS) # Draw the X axis itself + + def getColorForMarker(self, chrCount,flag):# no change is needed + chrColorDict={} + for i in range(chrCount): + if flag==1: # display blue and lightblue intercross + chrColorDict[i]=pid.black + elif flag==0: + if (i%2==0): + chrColorDict[i]=pid.blue + else: + chrColorDict[i]=pid.lightblue + else:#display different color for different chr + if i in [0,8,16]: + chrColorDict[i]=pid.black + elif i in [1,9,17]: + chrColorDict[i]=pid.red + elif i in [2,10,18]: + chrColorDict[i]=pid.lightgreen + elif i in [3,11,19]: + chrColorDict[i]=pid.blue + elif i in [4,12]: + chrColorDict[i]=pid.lightblue + elif i in [5,13]: + chrColorDict[i]=pid.hotpink + elif i in [6,14]: + chrColorDict[i]=pid.gold + elif i in [7,15]: + chrColorDict[i]=pid.grey + + return chrColorDict + + + def drawProbeSetPosition(self, canvas, plotXScale, offset= (40, 120, 80, 10), zoom = 1, startMb = None, endMb = None): + if len(self.traitList) != 1: + return + + xLeftOffset, xRightOffset, yTopOffset, yBottomOffset = offset + plotWidth = canvas.size[0] - xLeftOffset - xRightOffset + plotHeight = canvas.size[1] - yTopOffset - yBottomOffset + yZero = canvas.size[1] - yBottomOffset + fontZoom = zoom + if zoom == 2: + fontZoom = 1.5 + + try: + Chr = self.traitList[0].chr # self.traitListChr =self.traitList[0].chr=_vals need to change to chrList and mbList + Mb = self.traitList[0].mb # self.traitListMb =self.traitList[0].mb=_vals + except: + return + + if self.plotScale == 'physic': + if self.selectedChr > -1: + if self.genotype[0].name != Chr or Mb < self.startMb or Mb > self.endMb: + return + else: + locPixel = xLeftOffset + (Mb-self.startMb)*plotXScale + else: + locPixel = xLeftOffset + for i, _chr in enumerate(self.genotype): + if _chr.name != Chr: + locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + else: + locPixel += Mb*plotXScale + break + else: + if self.selectedChr > -1: + if self.genotype[0].name != Chr: + return + else: + for i, _locus in enumerate(self.genotype[0]): + #the trait's position is on the left of the first genotype + if i==0 and _locus.Mb >= Mb: + locPixel=-1 + break + + #the trait's position is between two traits + if i > 0 and self.genotype[0][i-1].Mb < Mb and _locus.Mb >= Mb: + locPixel = xLeftOffset + plotXScale*(self.genotype[0][i-1].cM+(_locus.cM-self.genotype[0][i-1].cM)*(Mb -self.genotype[0][i-1].Mb)/(_locus.Mb-self.genotype[0][i-1].Mb)) + break + + #the trait's position is on the right of the last genotype + if i==len(self.genotype[0]) and Mb>=_locus.Mb: + locPixel = -1 + else: + locPixel = xLeftOffset + for i, _chr in enumerate(self.genotype): + if _chr.name != Chr: + locPixel += (self.ChrLengthDistList[i] + self.GraphInterval)*plotXScale + else: + locPixel += (Mb*(_chr[-1].cM-_chr[0].cM)/self.ChrLengthCMList[i])*plotXScale + break + if locPixel >= 0: + traitPixel = ((locPixel, yZero), (locPixel-6, yZero+12), (locPixel+6, yZero+12)) + canvas.drawPolygon(traitPixel, edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) + + if self.legendChecked: + startPosY = 15 + nCol = 2 + smallLabelFont = pid.Font(ttf="trebuc", size=12, bold=1) + leftOffset = xLeftOffset+(nCol-1)*200 + canvas.drawPolygon(((leftOffset+6, startPosY-6), (leftOffset, startPosY+6), (leftOffset+12, startPosY+6)), edgeColor=pid.black, fillColor=self.TRANSCRIPT_LOCATION_COLOR, closed=1) + canvas.drawString("Sequence Site", (leftOffset+15), (startPosY+5), smallLabelFont, self.TOP_RIGHT_INFO_COLOR) + + # build dict based on plink result, key is chr, value is list of [snp,BP,pValue] + def getPlinkResultDict(self,outputFileName='',thresholdPvalue=-1,ChrOrderIdNameDict={}): + + ChrList =self.ChrList + plinkResultDict={} + + plinkResultfp = open("%s%s.qassoc"% (webqtlConfig.TMPDIR, outputFileName), "rb") + + headerLine=plinkResultfp.readline()# read header line + line = plinkResultfp.readline() + + valueList=[] # initialize value list, this list will include snp, bp and pvalue info + pValueList=[] + count=0 + + while line: + #convert line from str to list + lineList=self.buildLineList(line=line) + + # only keep the records whose chromosome name is in db + if ChrOrderIdNameDict.has_key(int(lineList[0])) and lineList[-1] and lineList[-1].strip()!='NA': + + chrName=ChrOrderIdNameDict[int(lineList[0])] + snp = lineList[1] + BP = lineList[2] + pValue = float(lineList[-1]) + pValueList.append(pValue) + + if plinkResultDict.has_key(chrName): + valueList=plinkResultDict[chrName] + + # pvalue range is [0,1] + if thresholdPvalue >=0 and thresholdPvalue<=1: + if pValue < thresholdPvalue: + valueList.append((snp,BP,pValue)) + count+=1 + + plinkResultDict[chrName]=valueList + valueList=[] + else: + if thresholdPvalue>=0 and thresholdPvalue<=1: + if pValue < thresholdPvalue: + valueList.append((snp,BP,pValue)) + count+=1 + + if valueList: + plinkResultDict[chrName]=valueList + + valueList=[] + + + line =plinkResultfp.readline() + else: + line=plinkResultfp.readline() + + if pValueList: + minPvalue= min(pValueList) + else: + minPvalue=0 + + return count,minPvalue,plinkResultDict + + + ###################################################### + # input: line: str,one line read from file + # function: convert line from str to list; + # output: lineList list + ####################################################### + def buildLineList(self,line=None): + + lineList = string.split(string.strip(line),' ')# irregular number of whitespaces between columns + lineList =[ item for item in lineList if item <>''] + lineList = map(string.strip, lineList) + + return lineList + + #added by NL: automatically generate pheno txt file for PLINK based on strainList passed from dataEditing page + def genPhenoTxtFileForPlink(self,phenoFileName='', RISetName='', probesetName='', valueDict={}): + pedFileStrainList=self.getStrainNameFromPedFile(RISetName=RISetName) + outputFile = open("%s%s.txt"%(webqtlConfig.TMPDIR,phenoFileName),"wb") + headerLine = 'FID\tIID\t%s\n'%probesetName + outputFile.write(headerLine) + + newValueList=[] + + #if valueDict does not include some strain, value will be set to -9999 as missing value + for item in pedFileStrainList: + try: + value=valueDict[item] + value=str(value).replace('value=','') + value=value.strip() + except: + value=-9999 + + newValueList.append(value) + + + newLine='' + for i, strain in enumerate(pedFileStrainList): + j=i+1 + value=newValueList[i] + newLine+='%s\t%s\t%s\n'%(strain, strain, value) + + if j%1000==0: + outputFile.write(newLine) + newLine='' + + if newLine: + outputFile.write(newLine) + + outputFile.close() + + # get strain name from ped file in order + def getStrainNameFromPedFile(self, RISetName=''): + pedFileopen= open("%splink/%s.ped"%(webqtlConfig.HTMLPATH, RISetName),"r") + line =pedFileopen.readline() + strainNameList=[] + + while line: + lineList=string.split(string.strip(line),'\t') + lineList=map(string.strip,lineList) + + strainName=lineList[0] + strainNameList.append(strainName) + + line =pedFileopen.readline() + + return strainNameList + + ################################################################# + ## Generate Chr list, Chr OrderId and Retrieve Length Information + ################################################################# + #def getChrNameOrderIdLength(self,RISet=''): + # + # try: + # query = """ + # Select + # Chr_Length.Name,Chr_Length.OrderId,Length from Chr_Length, InbredSet + # where + # Chr_Length.SpeciesId = InbredSet.SpeciesId AND + # InbredSet.Name = '%s' + # Order by OrderId + # """ % (RISet) + # self.cursor.execute(query) + # + # results =self.cursor.fetchall() + # ChrList=[] + # ChrLengthMbList=[] + # ChrNameOrderIdDict={} + # ChrOrderIdNameDict={} + # + # for item in results: + # ChrList.append(item[0]) + # ChrNameOrderIdDict[item[0]]=item[1] # key is chr name, value is orderId + # ChrOrderIdNameDict[item[1]]=item[0] # key is orderId, value is chr name + # ChrLengthMbList.append(item[2]) + # + # except: + # ChrList=[] + # ChrNameOrderIdDict={} + # ChrLengthMbList=[] + # + # return ChrList,ChrNameOrderIdDict,ChrOrderIdNameDict,ChrLengthMbList -- cgit v1.2.3 From 2520342c689233a82b70b5328a044add87169d84 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Fri, 4 Jan 2013 17:09:27 -0600 Subject: Correct results are being returned from reaper for the marker regression page --- misc/notes.txt | 13 +- misc/todo.txt | 3 +- .../wqflask/marker_regression/marker_regression.py | 255 ++++++++++++--------- .../wqflask/templates/show_trait_edit_data.html | 4 +- .../templates/show_trait_mapping_tools.html | 13 +- 5 files changed, 173 insertions(+), 115 deletions(-) diff --git a/misc/notes.txt b/misc/notes.txt index b0c0762c..306cadeb 100644 --- a/misc/notes.txt +++ b/misc/notes.txt @@ -57,12 +57,6 @@ unset SSH_ASKPASS =========================================== -Python stuff: - -Classes should always inherit "object" - -=========================================== - htop: Gives information on processes, cpu/memory load, etc dstat: Also gives various system information, resource usage, etc df: Reports file system disk space usage @@ -78,4 +72,11 @@ ps -ax - View processes kill (process #) +=========================================== + +Python stuff: + +Classes should always inherit "object" +To iterate through dictionary items: for X, Y in MyDictionary.items(): + diff --git a/misc/todo.txt b/misc/todo.txt index 60655a71..1d781b13 100644 --- a/misc/todo.txt +++ b/misc/todo.txt @@ -1,3 +1,2 @@ -- Check about using trait id instead of trait name in queries in data_set.py - +- Ask Rob about potentially recoding qtlreaper - Ask Rob about Probe/cellid traits \ No newline at end of file diff --git a/wqflask/wqflask/marker_regression/marker_regression.py b/wqflask/wqflask/marker_regression/marker_regression.py index ed01a3fa..30860376 100755 --- a/wqflask/wqflask/marker_regression/marker_regression.py +++ b/wqflask/wqflask/marker_regression/marker_regression.py @@ -52,7 +52,36 @@ class MarkerRegression(object): #if not self.openMysql(): # return + print("start_vars are: ", pf(start_vars)) + self.dataset = create_dataset(start_vars['dataset_name']) + self.num_perm = int(start_vars['num_perm']) + + # Passed in by the form (user might have edited) + #samples = start_vars['allsamples'].split() + + self.samples = [] # Want only ones with values + self.vals = [] + self.variances = [] + + self.dataset.group.read_genotype_file() + self.genotype = self.dataset.group.genotype + + for sample in self.dataset.group.samplelist: + value = start_vars['value:' + sample] + variance = start_vars['variance:' + sample] + if variance.strip().lower() == 'x': + variance = 0 + else: + variance = float(variance) + if value.strip().lower() != 'x': + self.samples.append(str(sample)) + self.vals.append(float(value)) + self.variances.append(variance) + + print("self.samples is:", pf(self.samples)) + print("self.vals is:", pf(self.vals)) + print("self.variances is:", pf(self.variances)) #self.initializeParameters(start_vars) @@ -162,111 +191,114 @@ class MarkerRegression(object): #if fd.parentsf14regression and fd.genotype_2: # _genotype = fd.genotype_2 #else: - genotype = self.dataset.group.read_genotype_file() - print("[black]:", genotype) + #print("[black]:", self.genotype) - _strains, _vals, _vars, N = fd.informativeStrains(_genotype.prgy, weightedRegression) + #_strains, _vals, _vars, N = fd.informativeStrains(_genotype.prgy, weightedRegression) - if fd.identification: - heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) - heading2.__setattr__("class","subtitle") - self.dict['title'] = '%s: Genome Association' % fd.identification - else: - heading2 = "" - self.dict['title'] = 'Genome Association' - - if fd.traitInfo: - symbol,chromosome,MB = string.split(fd.traitInfo,'\t') - heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) - else: - heading3 = "" - - if N < webqtlConfig.KMININFORMATIVE: - heading = "Genome Association" - detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, fd.RISet)] - self.error(heading=heading,detail=detail) - return - else: - heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) - heading.__setattr__("class","title") - - datadiv = HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee') - resultstable,tblobj,bottomInfo = self.GenReport(ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars) - #resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars) - - # creat object for result table for sort function - objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') - cPickle.dump(tblobj, objfile) - objfile.close() + #if fd.identification: + # heading2 = HT.Paragraph('Trait ID: %s' % fd.identification) + # heading2.__setattr__("class","subtitle") + # self.dict['title'] = '%s: Genome Association' % fd.identification + #else: + # heading2 = "" + # self.dict['title'] = 'Genome Association' - sortby = ("Index", "up") - reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + #if fd.traitInfo: + # symbol, chromosome, MB = string.split(fd.traitInfo,'\t') + # heading3 = HT.Paragraph('[ ',HT.Strong(HT.Italic('%s' % symbol,id="green")),' on Chr %s @ %s Mb ]' % (chromosome,MB)) + #else: + # heading3 = "" - descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) - descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) - descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) - descriptionTable.append(bottomInfo) + ### Todo in 2013: Don't allow marker regression in show trait page when number of samples + ### with values < 5 - self.traitList=_vals - - ##########################plot####################### - - ################################################################ - # Generate Chr list and Retrieve Length Information - ################################################################ - self.genotype= _genotype - self.ChrList = [("All", -1)] - - for i, indChr in enumerate(self.genotype): - self.ChrList.append((indChr.name, i)) - - self.cursor.execute(""" - Select - Length from Chr_Length, InbredSet - where - Chr_Length.SpeciesId = InbredSet.SpeciesId AND - InbredSet.Name = '%s' AND - Chr_Length.Name in (%s) - Order by - OrderId - """ % (fd.RISet, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", "))) - - self.ChrLengthMbList = self.cursor.fetchall() - self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList) - self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) - if self.ChrLengthMbList: - self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval - else: - self.MbGraphInterval = 1 + #if N < webqtlConfig.KMININFORMATIVE: + # heading = "Genome Association" + # detail = ['Fewer than %d strain data were entered for %s data set. No mapping attempted.' % (webqtlConfig.KMININFORMATIVE, fd.RISet)] + # self.error(heading=heading,detail=detail) + # return + #else: + # heading = HT.Paragraph('Trait Data Entered for %s Set' % fd.RISet) + # heading.__setattr__("class","title") + + #datadiv = HT.TD(heading, heading2,heading3, width='45%',valign='top', align='left', bgColor='#eeeeee') + #resultstable,tblobj,bottomInfo = self.GenReport(ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars) + resultstable, tblobj, bottomInfo = self.gen_data() + #resultstable = self.GenReport(fd, _genotype, _strains, _vals, _vars) + + # creat object for result table for sort function + objfile = open('%s.obj' % (webqtlConfig.TMPDIR+filename), 'wb') + cPickle.dump(tblobj, objfile) + objfile.close() + + sortby = ("Index", "up") + reportTable =HT.Div(webqtlUtil.genTableObj(tblobj=tblobj, file=filename, sortby=sortby, tableID = "sortable", addIndex = "0"), Id="sortable") + + descriptionTable = HT.TableLite(border=0, cellpadding=0, cellspacing=0) + descriptionTable.append(HT.TR(HT.TD(reportTable, colspan=3))) + descriptionTable.append(HT.TR(HT.TD(HT.BR(),HT.BR()))) + descriptionTable.append(bottomInfo) + + self.traitList=_vals + + ##########################plot####################### + + ################################################################ + # Generate Chr list and Retrieve Length Information + ################################################################ + self.genotype= _genotype + self.ChrList = [("All", -1)] + + for i, indChr in enumerate(self.genotype): + self.ChrList.append((indChr.name, i)) + + self.cursor.execute(""" + Select + Length from Chr_Length, InbredSet + where + Chr_Length.SpeciesId = InbredSet.SpeciesId AND + InbredSet.Name = '%s' AND + Chr_Length.Name in (%s) + Order by + OrderId + """ % (fd.RISet, string.join(map(lambda X: "'%s'" % X[0], self.ChrList[1:]), ", "))) + + self.ChrLengthMbList = self.cursor.fetchall() + self.ChrLengthMbList = map(lambda x: x[0]/1000000.0, self.ChrLengthMbList) + self.ChrLengthMbSum = reduce(lambda x, y:x+y, self.ChrLengthMbList, 0.0) + if self.ChrLengthMbList: + self.MbGraphInterval = self.ChrLengthMbSum/(len(self.ChrLengthMbList)*12) #Empirical Mb interval + else: + self.MbGraphInterval = 1 - self.ChrLengthCMList = [] - for i, _chr in enumerate(self.genotype): - self.ChrLengthCMList.append(_chr[-1].cM - _chr[0].cM) - self.ChrLengthCMSum = reduce(lambda x, y:x+y, self.ChrLengthCMList, 0.0)# used for calculate plot scale + self.ChrLengthCMList = [] + for i, _chr in enumerate(self.genotype): + self.ChrLengthCMList.append(_chr[-1].cM - _chr[0].cM) + self.ChrLengthCMSum = reduce(lambda x, y:x+y, self.ChrLengthCMList, 0.0)# used for calculate plot scale - self.GraphInterval = self.MbGraphInterval #Mb + self.GraphInterval = self.MbGraphInterval #Mb - # begin: common part with human data - intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) - gifmap = self.plotIntMapping(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= "") - filename= webqtlUtil.genRandStr("Itvl_") - intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') - intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') + # begin: common part with human data + intCanvas = pid.PILCanvas(size=(self.graphWidth,self.graphHeight)) + gifmap = self.plotIntMapping(fd, intCanvas, startMb = self.startMb, endMb = self.endMb, showLocusForm= "") + filename= webqtlUtil.genRandStr("Itvl_") + intCanvas.save(os.path.join(webqtlConfig.IMGDIR, filename), format='png') + intImg=HT.Image('/image/'+filename+'.png', border=0, usemap='#WebQTLImageMap') - ################################################################ - # footnote goes here - ################################################################ - btminfo = HT.Paragraph(Id="smallsize") #Small('More information about this graph is available here.') + ################################################################ + # footnote goes here + ################################################################ + btminfo = HT.Paragraph(Id="smallsize") #Small('More information about this graph is available here.') - if (self.additiveChecked): - btminfo.append(HT.BR(), 'A positive additive coefficient (', HT.Font('green', color='green'), ' line) indicates that %s alleles increase trait values. In contrast, a negative additive coefficient (' % fd.ppolar, HT.Font('red', color='red'), ' line) indicates that %s alleles increase trait values.' % fd.mpolar) + if (self.additiveChecked): + btminfo.append(HT.BR(), 'A positive additive coefficient (', HT.Font('green', color='green'), ' line) indicates that %s alleles increase trait values. In contrast, a negative additive coefficient (' % fd.ppolar, HT.Font('red', color='red'), ' line) indicates that %s alleles increase trait values.' % fd.mpolar) - TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) + TD_LR = HT.TR(HT.TD(HT.Blockquote(gifmap,intImg, HT.P()), bgColor='#eeeeee', height = 200)) - self.dict['body'] = str(datadiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) + self.dict['body'] = str(datadiv)+str(TD_LR)+str(resultstable)+str(HT.TR(HT.TD(descriptionTable))) - # end: common part with human data + # end: common part with human data @@ -410,18 +442,37 @@ class MarkerRegression(object): return rv, tblobj,bottomInfo - def GenReport(self, ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars= []): - 'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + #def GenReport(self, ChrNameOrderIdDict,fd, _genotype, _strains, _vals, _vars= []): + def gen_data(self): + """Todo: Fill this in here""" + #'Create an HTML division which reports any loci which are significantly associated with the submitted trait data.' + #calculate QTL for each trait - self.qtlresults = [] - if webqtlUtil.ListNotNull(_vars): - qtlresults = _genotype.regression(strains = _strains, trait = _vals, variance = _vars) - LRSArray = _genotype.permutation(strains = _strains, trait = _vals, variance = _vars, nperm=fd.nperm) - else: - qtlresults = _genotype.regression(strains = _strains, trait = _vals) - LRSArray = _genotype.permutation(strains = _strains, trait = _vals,nperm=fd.nperm) - - self.qtlresults.append(qtlresults) + #self.qtlresults = [] + #if webqtlUtil.ListNotNull(_vars): + + #strains = + #vals = + #variances = + + #if any(self.variances): + # self.qtl_results = self.genotype.regression(strains = self.samples, + # trait = self.vals, + # variance = self.variances) + # self.lrs_array = self.genotype.permutation(strains = self.samples, + # trait = self.vals, + # variance = self.variances, + # nperm = self.num_perm) + #else: + self.qtl_results = self.genotype.regression(strains = self.samples, + trait = self.vals) + self.lrs_array = self.genotype.permutation(strains = self.samples, + trait = self.vals, + nperm=self.num_perm) + + print("[yellow] self.__dict__ is:", pf(self.__dict__)) + + #self.qtlresults.append(qtlresults) filename= webqtlUtil.genRandStr("GenomeAsscociation_") diff --git a/wqflask/wqflask/templates/show_trait_edit_data.html b/wqflask/wqflask/templates/show_trait_edit_data.html index 9023b34d..84c606b9 100644 --- a/wqflask/wqflask/templates/show_trait_edit_data.html +++ b/wqflask/wqflask/templates/show_trait_edit_data.html @@ -120,7 +120,7 @@ {# Todo: Add IDs #}
      - - Chromosome
      @@ -30,7 +30,7 @@
      - +
      @@ -125,7 +125,7 @@ No
      - +
      @@ -134,6 +134,13 @@
      +
      + +
      + +
      +
      +
      -
      -
      Aliases
      -
      {{ this_trait.alias_fmt }}
      - -
      Location
      -
      {{ this_trait.location_fmt }}
      - -
      Database
      -
      - - {{ dataset.name }} - -
      - - {% if this_trait.probe_set_specificity %} -
      - - BLAT Specifity - -
      -
      {{ "%.1f" % (this_trait.probe_set_specificity) }}
      - {% endif %} - {% if this_trait.probe_set_blat_score %} -
      BLAT Score
      -
      {{ "%i" % (this_trait.probe_set_blat_score) }}
      - {% endif %} -
      -- cgit v1.2.3 From 1685d588ecfb13a1a5c0f5aa10018e7ddbab7244 Mon Sep 17 00:00:00 2001 From: Zachary Sloan Date: Wed, 9 Jan 2013 14:58:57 -0600 Subject: jqplot added --- .../wqflask/static/packages/jqplot/MIT-LICENSE.txt | 21 + wqflask/wqflask/static/packages/jqplot/README.txt | 77 + .../static/packages/jqplot/additional-methods.js | 437 + .../packages/jqplot/additional-methods.min.js | 4 + wqflask/wqflask/static/packages/jqplot/changes.txt | 395 + .../wqflask/static/packages/jqplot/copyright.txt | 56 + .../jqplot/docs/files/MIT-LICENSE-txt.html | 39 + .../packages/jqplot/docs/files/changes-txt.html | 39 + .../packages/jqplot/docs/files/gpl-2-0-txt.html | 39 + .../jqplot/docs/files/images/background.jpg | Bin 0 -> 1101 bytes .../jqplot/docs/files/images/basicline.png | Bin 0 -> 17024 bytes .../jqplot/docs/files/images/basiclogaxis.png | Bin 0 -> 19902 bytes .../jqplot/docs/files/images/basiclogoptions.png | Bin 0 -> 17207 bytes .../jqplot/docs/files/images/basicoptions.png | Bin 0 -> 19864 bytes .../packages/jqplot/docs/files/images/dualaxis.png | Bin 0 -> 29672 bytes .../packages/jqplot/docs/files/images/logo.jpg | Bin 0 -> 14632 bytes .../packages/jqplot/docs/files/images/navdocs.png | Bin 0 -> 996 bytes .../jqplot/docs/files/images/navdocsover.png | Bin 0 -> 1006 bytes .../jqplot/docs/files/images/navdownload.png | Bin 0 -> 1236 bytes .../jqplot/docs/files/images/navdownloadover.png | Bin 0 -> 1265 bytes .../jqplot/docs/files/images/navexamples.png | Bin 0 -> 1308 bytes .../jqplot/docs/files/images/navexamplesover.png | Bin 0 -> 1332 bytes .../packages/jqplot/docs/files/images/navhome.png | Bin 0 -> 858 bytes .../jqplot/docs/files/images/navhomeover.png | Bin 0 -> 886 bytes .../packages/jqplot/docs/files/images/new.png | Bin 0 -> 13750 bytes .../packages/jqplot/docs/files/images/sample3.png | Bin 0 -> 44781 bytes .../packages/jqplot/docs/files/images/samplesm.png | Bin 0 -> 20874 bytes .../jqplot/docs/files/jqPlotCssStyling-txt.html | 39 + .../jqplot/docs/files/jqPlotOptions-txt.html | 292 + .../docs/files/jqplot-axisLabelRenderer-js.html | 47 + .../docs/files/jqplot-axisTickRenderer-js.html | 73 + .../docs/files/jqplot-canvasGridRenderer-js.html | 39 + .../packages/jqplot/docs/files/jqplot-core-js.html | 389 + .../docs/files/jqplot-divTitleRenderer-js.html | 39 + .../jqplot/docs/files/jqplot-lineRenderer-js.html | 69 + .../docs/files/jqplot-linearAxisRenderer-js.html | 61 + .../docs/files/jqplot-markerRenderer-js.html | 65 + .../docs/files/jqplot-shadowRenderer-js.html | 61 + .../jqplot/docs/files/jqplot-shapeRenderer-js.html | 65 + .../jqplot/docs/files/jqplot-themeEngine-js.html | 191 + .../jqplot/docs/files/jqplot-toImage-js.html | 39 + .../jqplot/docs/files/optionsTutorial-txt.html | 120 + .../plugins/jqplot-BezierCurveRenderer-js.html | 45 + .../docs/files/plugins/jqplot-barRenderer-js.html | 69 + .../files/plugins/jqplot-blockRenderer-js.html | 53 + .../files/plugins/jqplot-bubbleRenderer-js.html | 71 + .../plugins/jqplot-canvasAxisLabelRenderer-js.html | 63 + .../plugins/jqplot-canvasAxisTickRenderer-js.html | 79 + .../files/plugins/jqplot-canvasOverlay-js.html | 113 + .../plugins/jqplot-categoryAxisRenderer-js.html | 46 + .../docs/files/plugins/jqplot-ciParser-js.html | 39 + .../docs/files/plugins/jqplot-cursor-js.html | 93 + .../files/plugins/jqplot-dateAxisRenderer-js.html | 101 + .../files/plugins/jqplot-donutRenderer-js.html | 98 + .../docs/files/plugins/jqplot-dragable-js.html | 45 + .../plugins/jqplot-enhancedLegendRenderer-js.html | 51 + .../files/plugins/jqplot-funnelRenderer-js.html | 87 + .../docs/files/plugins/jqplot-highlighter-js.html | 80 + .../files/plugins/jqplot-logAxisRenderer-js.html | 47 + .../files/plugins/jqplot-mekkoAxisRenderer-js.html | 49 + .../files/plugins/jqplot-mekkoRenderer-js.html | 62 + .../plugins/jqplot-meterGaugeRenderer-js.html | 103 + .../docs/files/plugins/jqplot-ohlcRenderer-js.html | 65 + .../docs/files/plugins/jqplot-pieRenderer-js.html | 93 + .../docs/files/plugins/jqplot-pointLabels-js.html | 72 + .../plugins/jqplot-pyramidAxisRenderer-js.html | 49 + .../plugins/jqplot-pyramidGridRenderer-js.html | 39 + .../files/plugins/jqplot-pyramidRenderer-js.html | 55 + .../docs/files/plugins/jqplot-trendline-js.html | 67 + .../packages/jqplot/docs/files/usage-txt.html | 58 + .../wqflask/static/packages/jqplot/docs/index.html | 1 + .../static/packages/jqplot/docs/index/Classes.html | 70 + .../static/packages/jqplot/docs/index/Files.html | 34 + .../packages/jqplot/docs/index/Functions.html | 70 + .../static/packages/jqplot/docs/index/General.html | 42 + .../packages/jqplot/docs/index/General2.html | 42 + .../packages/jqplot/docs/index/General3.html | 42 + .../packages/jqplot/docs/index/General4.html | 46 + .../packages/jqplot/docs/index/General5.html | 50 + .../packages/jqplot/docs/index/General6.html | 34 + .../packages/jqplot/docs/index/General7.html | 58 + .../static/packages/jqplot/docs/index/Hooks.html | 46 + .../packages/jqplot/docs/index/Properties.html | 42 + .../packages/jqplot/docs/index/Properties2.html | 42 + .../packages/jqplot/docs/index/Properties3.html | 46 + .../packages/jqplot/docs/index/Properties4.html | 50 + .../packages/jqplot/docs/index/Properties5.html | 34 + .../packages/jqplot/docs/index/Properties6.html | 58 + .../static/packages/jqplot/docs/javascript/main.js | 836 ++ .../packages/jqplot/docs/javascript/searchdata.js | 182 + .../packages/jqplot/docs/search/ClassesA.html | 20 + .../packages/jqplot/docs/search/ClassesD.html | 20 + .../packages/jqplot/docs/search/ClassesG.html | 20 + .../packages/jqplot/docs/search/ClassesH.html | 20 + .../packages/jqplot/docs/search/ClassesJ.html | 20 + .../packages/jqplot/docs/search/ClassesL.html | 20 + .../packages/jqplot/docs/search/ClassesS.html | 20 + .../jqplot/docs/search/ClassesSymbols.html | 20 + .../packages/jqplot/docs/search/ClassesT.html | 20 + .../packages/jqplot/docs/search/ClassesV.html | 20 + .../static/packages/jqplot/docs/search/FilesJ.html | 20 + .../packages/jqplot/docs/search/FunctionsC.html | 20 + .../packages/jqplot/docs/search/FunctionsD.html | 20 + .../packages/jqplot/docs/search/FunctionsG.html | 20 + .../packages/jqplot/docs/search/FunctionsI.html | 20 + .../packages/jqplot/docs/search/FunctionsM.html | 20 + .../packages/jqplot/docs/search/FunctionsN.html | 20 + .../packages/jqplot/docs/search/FunctionsQ.html | 20 + .../packages/jqplot/docs/search/FunctionsR.html | 20 + .../packages/jqplot/docs/search/FunctionsS.html | 20 + .../packages/jqplot/docs/search/FunctionsZ.html | 20 + .../packages/jqplot/docs/search/GeneralA.html | 20 + .../packages/jqplot/docs/search/GeneralB.html | 20 + .../packages/jqplot/docs/search/GeneralC.html | 20 + .../packages/jqplot/docs/search/GeneralD.html | 20 + .../packages/jqplot/docs/search/GeneralE.html | 20 + .../packages/jqplot/docs/search/GeneralF.html | 20 + .../packages/jqplot/docs/search/GeneralG.html | 20 + .../packages/jqplot/docs/search/GeneralH.html | 20 + .../packages/jqplot/docs/search/GeneralI.html | 20 + .../packages/jqplot/docs/search/GeneralJ.html | 20 + .../packages/jqplot/docs/search/GeneralL.html | 20 + .../packages/jqplot/docs/search/GeneralM.html | 20 + .../packages/jqplot/docs/search/GeneralN.html | 20 + .../packages/jqplot/docs/search/GeneralO.html | 20 + .../packages/jqplot/docs/search/GeneralP.html | 20 + .../packages/jqplot/docs/search/GeneralQ.html | 20 + .../packages/jqplot/docs/search/GeneralR.html | 20 + .../packages/jqplot/docs/search/GeneralS.html | 20 + .../jqplot/docs/search/GeneralSymbols.html | 20 + .../packages/jqplot/docs/search/GeneralT.html | 20 + .../packages/jqplot/docs/search/GeneralU.html | 20 + .../packages/jqplot/docs/search/GeneralV.html | 20 + .../packages/jqplot/docs/search/GeneralW.html | 20 + .../packages/jqplot/docs/search/GeneralX.html | 20 + .../packages/jqplot/docs/search/GeneralY.html | 20 + .../packages/jqplot/docs/search/GeneralZ.html | 20 + .../static/packages/jqplot/docs/search/HooksA.html | 20 + .../static/packages/jqplot/docs/search/HooksE.html | 20 + .../static/packages/jqplot/docs/search/HooksJ.html | 20 + .../static/packages/jqplot/docs/search/HooksP.html | 20 + .../packages/jqplot/docs/search/NoResults.html | 15 + .../packages/jqplot/docs/search/PropertiesA.html | 20 + .../packages/jqplot/docs/search/PropertiesB.html | 20 + .../packages/jqplot/docs/search/PropertiesC.html | 20 + .../packages/jqplot/docs/search/PropertiesD.html | 20 + .../packages/jqplot/docs/search/PropertiesE.html | 20 + .../packages/jqplot/docs/search/PropertiesF.html | 20 + .../packages/jqplot/docs/search/PropertiesG.html | 20 + .../packages/jqplot/docs/search/PropertiesH.html | 20 + .../packages/jqplot/docs/search/PropertiesI.html | 20 + .../packages/jqplot/docs/search/PropertiesL.html | 20 + .../packages/jqplot/docs/search/PropertiesM.html | 20 + .../packages/jqplot/docs/search/PropertiesN.html | 20 + .../packages/jqplot/docs/search/PropertiesO.html | 20 + .../packages/jqplot/docs/search/PropertiesP.html | 20 + .../packages/jqplot/docs/search/PropertiesR.html | 20 + .../packages/jqplot/docs/search/PropertiesS.html | 20 + .../packages/jqplot/docs/search/PropertiesT.html | 20 + .../packages/jqplot/docs/search/PropertiesU.html | 20 + .../packages/jqplot/docs/search/PropertiesV.html | 20 + .../packages/jqplot/docs/search/PropertiesW.html | 20 + .../packages/jqplot/docs/search/PropertiesX.html | 20 + .../packages/jqplot/docs/search/PropertiesY.html | 20 + .../packages/jqplot/docs/search/PropertiesZ.html | 20 + .../static/packages/jqplot/docs/styles/1.css | 767 ++ .../static/packages/jqplot/docs/styles/2.css | 174 + .../static/packages/jqplot/docs/styles/main.css | 2 + .../static/packages/jqplot/examples/KCPsample4.csv | 25 + .../static/packages/jqplot/examples/ages.json | 5 + .../packages/jqplot/examples/ajax-loader.gif | Bin 0 -> 3208 bytes .../static/packages/jqplot/examples/area.html | 229 + .../packages/jqplot/examples/axisLabelTests.html | 157 + .../jqplot/examples/axisLabelsRotatedText.html | 229 + .../jqplot/examples/axisScalingForceTickAt.html | 242 + .../packages/jqplot/examples/bandedLine.html | 310 + .../packages/jqplot/examples/bar-charts.html | 219 + .../packages/jqplot/examples/barLineAnimated.html | 165 + .../static/packages/jqplot/examples/barTest.html | 299 + .../packages/jqplot/examples/bezierCurve.html | 125 + .../static/packages/jqplot/examples/blockPlot.html | 199 + .../packages/jqplot/examples/bubble-plots.html | 213 + .../packages/jqplot/examples/bubbleChart.html | 264 + .../jqplot/examples/candlestick-charts.html | 209 + .../packages/jqplot/examples/candlestick.html | 322 + .../packages/jqplot/examples/canvas-overlay.html | 231 + .../packages/jqplot/examples/colorpicker/README | 140 + .../packages/jqplot/examples/colorpicker/TODO | 14 + .../examples/colorpicker/images/bar-alpha.png | Bin 0 -> 2195 bytes .../examples/colorpicker/images/bar-opacity.png | Bin 0 -> 134 bytes .../examples/colorpicker/images/bar-pointer.png | Bin 0 -> 198 bytes .../jqplot/examples/colorpicker/images/bar.png | Bin 0 -> 382 bytes .../examples/colorpicker/images/map-opacity.png | Bin 0 -> 139 bytes .../examples/colorpicker/images/map-pointer.png | Bin 0 -> 344 bytes .../jqplot/examples/colorpicker/images/map.png | Bin 0 -> 78245 bytes .../colorpicker/images/preview-opacity.png | Bin 0 -> 135 bytes .../examples/colorpicker/images/ui-colorpicker.png | Bin 0 -> 494 bytes .../jqplot/examples/colorpicker/index.html | 85 + .../examples/colorpicker/jquery.colorpicker.css | 129 + .../examples/colorpicker/jquery.colorpicker.js | 1654 +++ .../jqplot/examples/cursor-highlighter.html | 137 + .../examples/customHighlighterCursorTrendline.html | 104 + .../packages/jqplot/examples/dashboardWidget.html | 212 + .../packages/jqplot/examples/dashedLines.html | 227 + .../packages/jqplot/examples/data-renderers.html | 144 + .../static/packages/jqplot/examples/date-axes.html | 107 + .../jqplot/examples/dateAxisLogAxisZooming.html | 101 + .../packages/jqplot/examples/dateAxisRenderer.html | 292 + .../static/packages/jqplot/examples/example.js | 114 + .../static/packages/jqplot/examples/example.min.js | 1 + .../static/packages/jqplot/examples/examples.css | 140 + .../packages/jqplot/examples/examples.min.css | 1 + .../packages/jqplot/examples/fillBetweenLines.html | 134 + .../jqplot/examples/hiddenPlotsInTabs.html | 225 + .../packages/jqplot/examples/images/logo.jpg | Bin 0 -> 14632 bytes .../jqplot/examples/images/ui-colorpicker.png | Bin 0 -> 494 bytes .../static/packages/jqplot/examples/index.html | 108 + .../images/ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes .../images/ui-bg_flat_75_ffffff_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 119 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes .../smoothness/images/ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes .../smoothness/images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes .../smoothness/images/ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes .../smoothness/images/ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes .../smoothness/images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes .../jquery-ui/css/smoothness/jquery-ui.css | 568 + .../jquery-ui/css/smoothness/jquery-ui.min.css | 1 + .../ui-bg_diagonals-thick_18_b81900_40x40.png | Bin 0 -> 260 bytes .../ui-bg_diagonals-thick_20_666666_40x40.png | Bin 0 -> 251 bytes .../images/ui-bg_flat_10_000000_40x100.png | Bin 0 -> 178 bytes .../images/ui-bg_glass_100_f6f6f6_1x400.png | Bin 0 -> 104 bytes .../images/ui-bg_glass_100_fdf5ce_1x400.png | Bin 0 -> 125 bytes .../images/ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes .../images/ui-bg_gloss-wave_35_f6a828_500x100.png | Bin 0 -> 3762 bytes .../ui-bg_highlight-soft_100_eeeeee_1x100.png | Bin 0 -> 90 bytes .../ui-bg_highlight-soft_75_ffe45c_1x100.png | Bin 0 -> 129 bytes .../images/ui-icons_228ef1_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ef8c08_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffd27a_256x240.png | Bin 0 -> 4369 bytes .../images/ui-icons_ffffff_256x240.png | Bin 0 -> 4369 bytes .../css/ui-lightness/jquery-ui-1.9pre.css | 612 + .../css/ui-lightness/jquery-ui-1.9pre.min.css | 10 + .../jquery-ui/css/ui-lightness/jquery-ui.css | 568 + .../jquery-ui/css/ui-lightness/jquery-ui.min.css | 1 + .../examples/jquery-ui/js/jquery-ui-1.9pre.min.js | 473 + .../jqplot/examples/jquery-ui/js/jquery-ui.js | 11767 +++++++++++++++++++ .../jqplot/examples/jquery-ui/js/jquery-ui.min.js | 791 ++ .../examples/jquery-ui/js/jquery.effects.blind.js | 80 + .../jquery-ui/js/jquery.effects.blind.min.js | 14 + .../examples/jquery-ui/js/jquery.effects.core.js | 890 ++ .../jquery-ui/js/jquery.effects.core.min.js | 32 + .../packages/jqplot/examples/jquery.print.js | 103 + .../jqplot/examples/jquery.printElement.min.js | 28 + .../static/packages/jqplot/examples/jsondata.txt | 1 + .../static/packages/jqplot/examples/kcp.print.js | 136 + .../static/packages/jqplot/examples/kcp_area.html | 284 + .../static/packages/jqplot/examples/kcp_area2.html | 217 + .../static/packages/jqplot/examples/kcp_area2.json | 2 + .../static/packages/jqplot/examples/kcp_cdf.html | 351 + .../static/packages/jqplot/examples/kcp_engel.html | 256 + .../packages/jqplot/examples/kcp_lorenz.html | 528 + .../static/packages/jqplot/examples/kcp_pdf.html | 387 + .../packages/jqplot/examples/kcp_pyramid.html | 590 + .../packages/jqplot/examples/kcp_pyramid2.html | 578 + .../jqplot/examples/kcp_pyramid_by_age.html | 859 ++ .../jqplot/examples/kcp_pyramid_by_age.php | 862 ++ .../packages/jqplot/examples/kcp_quintiles.html | 663 ++ .../packages/jqplot/examples/line-charts.html | 193 + .../packages/jqplot/examples/mekkoCharts.html | 269 + .../packages/jqplot/examples/meritOrder.html | 103 + .../packages/jqplot/examples/meterGauge.html | 179 + .../jqplot/examples/multipleBarColors.html | 131 + .../static/packages/jqplot/examples/nav.inc | 40 + .../packages/jqplot/examples/pie-donut-charts.html | 160 + .../static/packages/jqplot/examples/pieTest.html | 187 + .../static/packages/jqplot/examples/pieTest2.js | 80 + .../static/packages/jqplot/examples/pieTest4.html | 258 + .../packages/jqplot/examples/point-labels.html | 193 + .../static/packages/jqplot/examples/quintiles.json | 348 + .../packages/jqplot/examples/resizablePlot.html | 196 + .../jqplot/examples/rotated-tick-labels.html | 216 + .../jqplot/examples/rotatedTickLabelsZoom.html | 118 + .../packages/jqplot/examples/selectorSyntax.html | 157 + .../packages/jqplot/examples/smoothedLine.html | 137 + .../jqplot/examples/syntaxhighlighter/LGPL-LICENSE | 165 + .../jqplot/examples/syntaxhighlighter/MIT-LICENSE | 20 + .../syntaxhighlighter/scripts/shAutoloader.js | 17 + .../syntaxhighlighter/scripts/shAutoloader.min.js | 1 + .../syntaxhighlighter/scripts/shBrushJScript.js | 52 + .../scripts/shBrushJScript.min.js | 1 + .../syntaxhighlighter/scripts/shBrushXml.js | 69 + .../syntaxhighlighter/scripts/shBrushXml.min.js | 1 + .../examples/syntaxhighlighter/scripts/shCore.js | 17 + .../syntaxhighlighter/scripts/shCore.min.js | 1 + .../examples/syntaxhighlighter/styles/shCore.css | 226 + .../syntaxhighlighter/styles/shCore.min.css | 1 + .../syntaxhighlighter/styles/shCoreDefault.css | 328 + .../syntaxhighlighter/styles/shCoreDefault.min.css | 1 + .../syntaxhighlighter/styles/shThemeDefault.css | 117 + .../styles/shThemeDefault.min.css | 1 + .../syntaxhighlighter/styles/shThemejqPlot.css | 138 + .../syntaxhighlighter/styles/shThemejqPlot.min.css | 1 + .../static/packages/jqplot/examples/theming.html | 519 + .../static/packages/jqplot/examples/topbanner.inc | 9 + .../static/packages/jqplot/examples/waterfall.html | 162 + .../packages/jqplot/examples/waterfall2.html | 231 + .../static/packages/jqplot/examples/yahooData.js | 1807 +++ .../packages/jqplot/examples/yahooData.min.js | 1 + .../static/packages/jqplot/examples/zoom1.html | 149 + .../packages/jqplot/examples/zoomOptions.html | 176 + .../static/packages/jqplot/examples/zoomProxy.html | 161 + .../static/packages/jqplot/examples/zooming.html | 209 + wqflask/wqflask/static/packages/jqplot/excanvas.js | 1438 +++ .../wqflask/static/packages/jqplot/excanvas.min.js | 57 + wqflask/wqflask/static/packages/jqplot/gpl-2.0.txt | 280 + .../static/packages/jqplot/jqPlotCssStyling.txt | 53 + .../static/packages/jqplot/jqPlotOptions.txt | 276 + .../static/packages/jqplot/jquery.jqplot.css | 259 + .../static/packages/jqplot/jquery.jqplot.js | 11381 ++++++++++++++++++ .../static/packages/jqplot/jquery.jqplot.min.css | 1 + .../static/packages/jqplot/jquery.jqplot.min.js | 57 + wqflask/wqflask/static/packages/jqplot/jquery.js | 9046 ++++++++++++++ .../wqflask/static/packages/jqplot/jquery.min.js | 4 + .../static/packages/jqplot/jquery.validate.js | 1248 ++ .../static/packages/jqplot/jquery.validate.min.js | 4 + .../static/packages/jqplot/optionsTutorial.txt | 240 + .../jqplot/plugins/jqplot.BezierCurveRenderer.js | 313 + .../plugins/jqplot.BezierCurveRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.barRenderer.js | 797 ++ .../jqplot/plugins/jqplot.barRenderer.min.js | 57 + .../jqplot/plugins/jqplot.blockRenderer.js | 235 + .../jqplot/plugins/jqplot.blockRenderer.min.js | 57 + .../jqplot/plugins/jqplot.bubbleRenderer.js | 759 ++ .../jqplot/plugins/jqplot.bubbleRenderer.min.js | 57 + .../plugins/jqplot.canvasAxisLabelRenderer.js | 203 + .../plugins/jqplot.canvasAxisLabelRenderer.min.js | 57 + .../plugins/jqplot.canvasAxisTickRenderer.js | 243 + .../plugins/jqplot.canvasAxisTickRenderer.min.js | 57 + .../jqplot/plugins/jqplot.canvasOverlay.js | 865 ++ .../jqplot/plugins/jqplot.canvasOverlay.min.js | 57 + .../jqplot/plugins/jqplot.canvasTextRenderer.js | 449 + .../plugins/jqplot.canvasTextRenderer.min.js | 57 + .../jqplot/plugins/jqplot.categoryAxisRenderer.js | 673 ++ .../plugins/jqplot.categoryAxisRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.ciParser.js | 116 + .../packages/jqplot/plugins/jqplot.ciParser.min.js | 57 + .../packages/jqplot/plugins/jqplot.cursor.js | 1108 ++ .../packages/jqplot/plugins/jqplot.cursor.min.js | 57 + .../jqplot/plugins/jqplot.dateAxisRenderer.js | 737 ++ .../jqplot/plugins/jqplot.dateAxisRenderer.min.js | 57 + .../jqplot/plugins/jqplot.donutRenderer.js | 805 ++ .../jqplot/plugins/jqplot.donutRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.dragable.js | 225 + .../packages/jqplot/plugins/jqplot.dragable.min.js | 57 + .../plugins/jqplot.enhancedLegendRenderer.js | 305 + .../plugins/jqplot.enhancedLegendRenderer.min.js | 57 + .../jqplot/plugins/jqplot.funnelRenderer.js | 943 ++ .../jqplot/plugins/jqplot.funnelRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.highlighter.js | 465 + .../jqplot/plugins/jqplot.highlighter.min.js | 57 + .../static/packages/jqplot/plugins/jqplot.json2.js | 475 + .../packages/jqplot/plugins/jqplot.json2.min.js | 57 + .../jqplot/plugins/jqplot.logAxisRenderer.js | 529 + .../jqplot/plugins/jqplot.logAxisRenderer.min.js | 57 + .../jqplot/plugins/jqplot.mekkoAxisRenderer.js | 611 + .../jqplot/plugins/jqplot.mekkoAxisRenderer.min.js | 57 + .../jqplot/plugins/jqplot.mekkoRenderer.js | 437 + .../jqplot/plugins/jqplot.mekkoRenderer.min.js | 57 + .../jqplot/plugins/jqplot.meterGaugeRenderer.js | 1030 ++ .../plugins/jqplot.meterGaugeRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.mobile.js | 45 + .../packages/jqplot/plugins/jqplot.mobile.min.js | 57 + .../packages/jqplot/plugins/jqplot.ohlcRenderer.js | 373 + .../jqplot/plugins/jqplot.ohlcRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.pieRenderer.js | 904 ++ .../jqplot/plugins/jqplot.pieRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.pointLabels.js | 379 + .../jqplot/plugins/jqplot.pointLabels.min.js | 57 + .../jqplot/plugins/jqplot.pyramidAxisRenderer.js | 728 ++ .../plugins/jqplot.pyramidAxisRenderer.min.js | 57 + .../jqplot/plugins/jqplot.pyramidGridRenderer.js | 429 + .../plugins/jqplot.pyramidGridRenderer.min.js | 57 + .../jqplot/plugins/jqplot.pyramidRenderer.js | 514 + .../jqplot/plugins/jqplot.pyramidRenderer.min.js | 57 + .../packages/jqplot/plugins/jqplot.trendline.js | 223 + .../jqplot/plugins/jqplot.trendline.min.js | 57 + wqflask/wqflask/static/packages/jqplot/usage.txt | 126 + 392 files changed, 87659 insertions(+) create mode 100644 wqflask/wqflask/static/packages/jqplot/MIT-LICENSE.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/README.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/additional-methods.js create mode 100644 wqflask/wqflask/static/packages/jqplot/additional-methods.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/changes.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/copyright.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/MIT-LICENSE-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/changes-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/gpl-2-0-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/background.jpg create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/basicline.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/basiclogaxis.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/basiclogoptions.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/basicoptions.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/dualaxis.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/logo.jpg create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navdocs.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navdocsover.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navdownload.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navdownloadover.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navexamples.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navexamplesover.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navhome.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/navhomeover.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/new.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/sample3.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/images/samplesm.png create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqPlotCssStyling-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqPlotOptions-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-axisLabelRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-axisTickRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-canvasGridRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-core-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-divTitleRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-lineRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-linearAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-markerRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-shadowRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-shapeRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-themeEngine-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/jqplot-toImage-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/optionsTutorial-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-BezierCurveRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-barRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-blockRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-bubbleRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-canvasAxisLabelRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-canvasAxisTickRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-canvasOverlay-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-categoryAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-ciParser-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-cursor-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-dateAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-donutRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-dragable-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-enhancedLegendRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-funnelRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-highlighter-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-logAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-mekkoAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-mekkoRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-meterGaugeRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-ohlcRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-pieRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-pointLabels-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-pyramidAxisRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-pyramidGridRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-pyramidRenderer-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/plugins/jqplot-trendline-js.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/files/usage-txt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Classes.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Files.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Functions.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General2.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General3.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General4.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General5.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General6.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/General7.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Hooks.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties2.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties3.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties4.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties5.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/index/Properties6.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/javascript/main.js create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/javascript/searchdata.js create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesA.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesD.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesG.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesH.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesJ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesL.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesS.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesSymbols.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesT.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/ClassesV.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FilesJ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsC.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsD.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsG.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsI.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsM.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsN.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsQ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsR.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsS.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/FunctionsZ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralA.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralB.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralC.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralD.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralE.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralF.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralG.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralH.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralI.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralJ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralL.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralM.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralN.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralO.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralP.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralQ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralR.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralS.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralSymbols.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralT.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralU.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralV.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralW.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralX.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralY.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/GeneralZ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/HooksA.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/HooksE.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/HooksJ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/HooksP.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/NoResults.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesA.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesB.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesC.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesD.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesE.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesF.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesG.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesH.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesI.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesL.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesM.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesN.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesO.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesP.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesR.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesS.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesT.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesU.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesV.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesW.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesX.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesY.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/search/PropertiesZ.html create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/styles/1.css create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/styles/2.css create mode 100644 wqflask/wqflask/static/packages/jqplot/docs/styles/main.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/KCPsample4.csv create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/ages.json create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/ajax-loader.gif create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/area.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/axisLabelTests.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/axisLabelsRotatedText.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/axisScalingForceTickAt.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/bandedLine.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/bar-charts.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/barLineAnimated.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/barTest.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/bezierCurve.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/blockPlot.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/bubble-plots.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/bubbleChart.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/candlestick-charts.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/candlestick.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/canvas-overlay.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/README create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/TODO create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/bar-alpha.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/bar-opacity.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/bar-pointer.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/bar.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/map-opacity.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/map-pointer.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/map.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/preview-opacity.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/images/ui-colorpicker.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/index.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/jquery.colorpicker.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/colorpicker/jquery.colorpicker.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/cursor-highlighter.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/customHighlighterCursorTrendline.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/dashboardWidget.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/dashedLines.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/data-renderers.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/date-axes.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/dateAxisLogAxisZooming.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/dateAxisRenderer.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/example.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/example.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/examples.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/examples.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/fillBetweenLines.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/hiddenPlotsInTabs.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/images/logo.jpg create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/images/ui-colorpicker.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/index.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui-1.9pre.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery.print.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jquery.printElement.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/jsondata.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp.print.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_area.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_area2.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_area2.json create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_cdf.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_engel.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_lorenz.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_pdf.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_pyramid.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_pyramid2.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_pyramid_by_age.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_pyramid_by_age.php create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/kcp_quintiles.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/line-charts.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/mekkoCharts.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/meritOrder.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/meterGauge.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/multipleBarColors.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/nav.inc create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/pie-donut-charts.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/pieTest.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/pieTest2.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/pieTest4.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/point-labels.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/quintiles.json create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/resizablePlot.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/rotated-tick-labels.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/rotatedTickLabelsZoom.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/selectorSyntax.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/smoothedLine.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/LGPL-LICENSE create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/MIT-LICENSE create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shAutoloader.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shAutoloader.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shBrushJScript.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shBrushJScript.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shBrushXml.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shBrushXml.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shCore.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/scripts/shCore.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shCore.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shCore.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shCoreDefault.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shCoreDefault.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shThemeDefault.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shThemeDefault.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shThemejqPlot.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/syntaxhighlighter/styles/shThemejqPlot.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/theming.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/topbanner.inc create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/waterfall.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/waterfall2.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/yahooData.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/yahooData.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/zoom1.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/zoomOptions.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/zoomProxy.html create mode 100644 wqflask/wqflask/static/packages/jqplot/examples/zooming.html create mode 100644 wqflask/wqflask/static/packages/jqplot/excanvas.js create mode 100644 wqflask/wqflask/static/packages/jqplot/excanvas.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/gpl-2.0.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/jqPlotCssStyling.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/jqPlotOptions.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.jqplot.css create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.jqplot.js create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.jqplot.min.css create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.jqplot.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.js create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.validate.js create mode 100644 wqflask/wqflask/static/packages/jqplot/jquery.validate.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/optionsTutorial.txt create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.BezierCurveRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.BezierCurveRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.barRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.barRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.blockRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.blockRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.bubbleRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.bubbleRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasAxisLabelRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasAxisTickRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasAxisTickRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasOverlay.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasTextRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.canvasTextRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.categoryAxisRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.categoryAxisRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.ciParser.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.ciParser.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.cursor.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.cursor.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.dateAxisRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.dateAxisRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.donutRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.donutRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.dragable.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.dragable.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.enhancedLegendRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.enhancedLegendRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.funnelRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.funnelRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.highlighter.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.highlighter.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.json2.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.json2.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.logAxisRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.logAxisRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mekkoAxisRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mekkoAxisRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mekkoRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mekkoRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.meterGaugeRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.meterGaugeRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mobile.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.mobile.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.ohlcRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.ohlcRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pieRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pieRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pointLabels.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pointLabels.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidAxisRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidAxisRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidGridRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidGridRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidRenderer.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.pyramidRenderer.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.trendline.js create mode 100644 wqflask/wqflask/static/packages/jqplot/plugins/jqplot.trendline.min.js create mode 100644 wqflask/wqflask/static/packages/jqplot/usage.txt diff --git a/wqflask/wqflask/static/packages/jqplot/MIT-LICENSE.txt b/wqflask/wqflask/static/packages/jqplot/MIT-LICENSE.txt new file mode 100644 index 00000000..647db23f --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/MIT-LICENSE.txt @@ -0,0 +1,21 @@ +Title: MIT License + +Copyright (c) 2009-2012 Chris Leonello + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/README.txt b/wqflask/wqflask/static/packages/jqplot/README.txt new file mode 100644 index 00000000..4932a00c --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/README.txt @@ -0,0 +1,77 @@ +Title: jqPlot Readme + +Pure JavaScript plotting plugin for jQuery. + +To learn how to use jqPlot, start with the Basic Usage Instructions below. Then read the +usage.txt and jqPlotOptions.txt files included with the distribution. + +The jqPlot home page is at . + +Downloads can be found at . + +The mailing list is at . + +Examples and unit tests are at . + +Documentation is at . + +The project page and source code are at . + +Bugs, issues, feature requests: . + +Basic Usage Instructions: + +jqPlot requires jQuery (1.4+ required for certain features). jQuery 1.4.4 is included in +the distribution. To use jqPlot include jQuery, the jqPlot jQuery plugin, the jqPlot css file and +optionally the excanvas script to support IE version prior to IE 9 in your web page: + +> +> +> +> + +For usage instructions, see in usage.txt. For available options, see + in jqPlotOptions.txt. + +Building from source: + +If you've cloned the repository, you can build a distribution from source. +You need to have ant installed. You can simply +type "ant" from the jqplot directory to build the default "all" target. +There are 6 pertinent targets: clean, dist, min, docs, compress and all. Use: + +> ant -p + +to get a description of the various build targets. + +Legal Notices: + +Copyright (c) 2009-2010 Chris Leonello +jqPlot is currently available for use in all personal or commercial projects +under both the MIT and GPL version 2.0 licenses. This means that you can +choose the license that best suits your project and use it accordingly. + +Although not required, the author would appreciate an email letting him +know of any substantial use of jqPlot. You can reach the author at: +chris at jqplot or see http://www.jqplot.com/info.php . + +If you are feeling kind and generous, consider supporting the project by +making a donation at: http://www.jqplot.com/donate.php . + +jqPlot includes date instance methods and printf/sprintf functions by other authors: + +Date instance methods: + + author Ken Snyder (ken d snyder at gmail dot com) + date 2008-09-10 + version 2.0.2 (http://kendsnyder.com/sandbox/date/) + license Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) + +JavaScript printf/sprintf functions. + + version 2007.04.27 + author Ash Searle + http://hexmen.com/blog/2007/03/printf-sprintf/ + http://hexmen.com/js/sprintf.js + The author (Ash Searle) has placed this code in the public domain: + "This code is unrestricted: you are free to use it however you like." diff --git a/wqflask/wqflask/static/packages/jqplot/additional-methods.js b/wqflask/wqflask/static/packages/jqplot/additional-methods.js new file mode 100644 index 00000000..801d0b7f --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/additional-methods.js @@ -0,0 +1,437 @@ +/*! jQuery Validation Plugin - v1.10.0 - 9/7/2012 +* https://github.com/jzaefferer/jquery-validation +* Copyright (c) 2012 Jörn Zaefferer; Licensed MIT, GPL */ + +/*! + * jQuery Validation Plugin 1.10.0 + * + * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ + * http://docs.jquery.com/Plugins/Validation + * + * Copyright (c) 2006 - 2011 Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ + +(function() { + + function stripHtml(value) { + // remove html tags and space chars + return value.replace(/<.[^<>]*?>/g, ' ').replace(/ | /gi, ' ') + // remove punctuation + .replace(/[.(),;:!?%#$'"_+=\/-]*/g,''); + } + jQuery.validator.addMethod("maxWords", function(value, element, params) { + return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length <= params; + }, jQuery.validator.format("Please enter {0} words or less.")); + + jQuery.validator.addMethod("minWords", function(value, element, params) { + return this.optional(element) || stripHtml(value).match(/\b\w+\b/g).length >= params; + }, jQuery.validator.format("Please enter at least {0} words.")); + + jQuery.validator.addMethod("rangeWords", function(value, element, params) { + var valueStripped = stripHtml(value); + var regex = /\b\w+\b/g; + return this.optional(element) || valueStripped.match(regex).length >= params[0] && valueStripped.match(regex).length <= params[1]; + }, jQuery.validator.format("Please enter between {0} and {1} words.")); + +})(); + +jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) { + return this.optional(element) || /^[a-z\-.,()'\"\s]+$/i.test(value); +}, "Letters or punctuation only please"); + +jQuery.validator.addMethod("alphanumeric", function(value, element) { + return this.optional(element) || /^\w+$/i.test(value); +}, "Letters, numbers, and underscores only please"); + +jQuery.validator.addMethod("lettersonly", function(value, element) { + return this.optional(element) || /^[a-z]+$/i.test(value); +}, "Letters only please"); + +jQuery.validator.addMethod("nowhitespace", function(value, element) { + return this.optional(element) || /^\S+$/i.test(value); +}, "No white space please"); + +jQuery.validator.addMethod("ziprange", function(value, element) { + return this.optional(element) || /^90[2-5]\d\{2\}-\d{4}$/.test(value); +}, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"); + +jQuery.validator.addMethod("zipcodeUS", function(value, element) { + return this.optional(element) || /\d{5}-\d{4}$|^\d{5}$/.test(value) +}, "The specified US ZIP Code is invalid"); + +jQuery.validator.addMethod("integer", function(value, element) { + return this.optional(element) || /^-?\d+$/.test(value); +}, "A positive or negative non-decimal number please"); + +/** + * Return true, if the value is a valid vehicle identification number (VIN). + * + * Works with all kind of text inputs. + * + * @example + * @desc Declares a required input element whose value must be a valid vehicle identification number. + * + * @name jQuery.validator.methods.vinUS + * @type Boolean + * @cat Plugins/Validate/Methods + */ +jQuery.validator.addMethod("vinUS", function(v) { + if (v.length != 17) { + return false; + } + var i, n, d, f, cd, cdv; + var LL = ["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"]; + var VL = [1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9]; + var FL = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2]; + var rs = 0; + for(i = 0; i < 17; i++){ + f = FL[i]; + d = v.slice(i,i+1); + if (i == 8) { + cdv = d; + } + if (!isNaN(d)) { + d *= f; + } else { + for (n = 0; n < LL.length; n++) { + if (d.toUpperCase() === LL[n]) { + d = VL[n]; + d *= f; + if (isNaN(cdv) && n == 8) { + cdv = LL[n]; + } + break; + } + } + } + rs += d; + } + cd = rs % 11; + if (cd == 10) { + cd = "X"; + } + if (cd == cdv) { + return true; + } + return false; +}, "The specified vehicle identification number (VIN) is invalid."); + +/** + * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. + * + * @example jQuery.validator.methods.date("01/01/1900") + * @result true + * + * @example jQuery.validator.methods.date("01/13/1990") + * @result false + * + * @example jQuery.validator.methods.date("01.01.1900") + * @result false + * + * @example + * @desc Declares an optional input element whose value must be a valid date. + * + * @name jQuery.validator.methods.dateITA + * @type Boolean + * @cat Plugins/Validate/Methods + */ +jQuery.validator.addMethod("dateITA", function(value, element) { + var check = false; + var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/; + if( re.test(value)){ + var adata = value.split('/'); + var gg = parseInt(adata[0],10); + var mm = parseInt(adata[1],10); + var aaaa = parseInt(adata[2],10); + var xdata = new Date(aaaa,mm-1,gg); + if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) ) + check = true; + else + check = false; + } else + check = false; + return this.optional(element) || check; +}, "Please enter a correct date"); + +jQuery.validator.addMethod("dateNL", function(value, element) { + return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value); +}, "Vul hier een geldige datum in."); + +jQuery.validator.addMethod("time", function(value, element) { + return this.optional(element) || /^([0-1]\d|2[0-3]):([0-5]\d)$/.test(value); +}, "Please enter a valid time, between 00:00 and 23:59"); +jQuery.validator.addMethod("time12h", function(value, element) { + return this.optional(element) || /^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$/i.test(value); +}, "Please enter a valid time, between 00:00 am and 12:00 pm"); + +/** + * matches US phone number format + * + * where the area code may not start with 1 and the prefix may not start with 1 + * allows '-' or ' ' as a separator and allows parens around area code + * some people may want to put a '1' in front of their number + * + * 1(212)-999-2345 or + * 212 999 2344 or + * 212-999-0983 + * + * but not + * 111-123-5434 + * and not + * 212 123 4567 + */ +jQuery.validator.addMethod("phoneUS", function(phone_number, element) { + phone_number = phone_number.replace(/\s+/g, ""); + return this.optional(element) || phone_number.length > 9 && + phone_number.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/); +}, "Please specify a valid phone number"); + +jQuery.validator.addMethod('phoneUK', function(phone_number, element) { + phone_number = phone_number.replace(/\(|\)|\s+|-/g,''); + return this.optional(element) || phone_number.length > 9 && + phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:(?:\d{5}\)?\s?\d{4,5})|(?:\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3}))|(?:\d{3}\)?\s?\d{3}\s?\d{3,4})|(?:\d{2}\)?\s?\d{4}\s?\d{4}))$/); +}, 'Please specify a valid phone number'); + +jQuery.validator.addMethod('mobileUK', function(phone_number, element) { + phone_number = phone_number.replace(/\s+|-/g,''); + return this.optional(element) || phone_number.length > 9 && + phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/); +}, 'Please specify a valid mobile number'); + +//Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers +jQuery.validator.addMethod('phonesUK', function(phone_number, element) { + phone_number = phone_number.replace(/\s+|-/g,''); + return this.optional(element) || phone_number.length > 9 && + phone_number.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/); +}, 'Please specify a valid uk phone number'); +// On the above three UK functions, do the following server side processing: +// Compare with ^((?:00\s?|\+)(44)\s?)?\(?0?(?:\)\s?)?([1-9]\d{1,4}\)?[\d\s]+) +// Extract $2 and set $prefix to '+44' if $2 is '44' otherwise set $prefix to '0' +// Extract $3 and remove spaces and parentheses. Phone number is combined $2 and $3. +// A number of very detailed GB telephone number RegEx patterns can also be found at: +// http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_UK_Telephone_Numbers + +//Matches UK postcode. based on http://snipplr.com/view/3152/postcode-validation/ +jQuery.validator.addMethod('postcodeUK', function(postcode, element) { + postcode = (postcode.toUpperCase()).replace(/\s+/g,''); + return this.optional(element) || postcode.match(/^([^QZ][^IJZ]{0,1}\d{1,2})(\d[^CIKMOV]{2})$/) || postcode.match(/^([^QV]\d[ABCDEFGHJKSTUW])(\d[^CIKMOV]{2})$/) || postcode.match(/^([^QV][^IJZ]\d[ABEHMNPRVWXY])(\d[^CIKMOV]{2})$/) || postcode.match(/^(GIR)(0AA)$/) || postcode.match(/^(BFPO)(\d{1,4})$/) || postcode.match(/^(BFPO)(C\/O\d{1,3})$/); +}, 'Please specify a valid postcode'); + +// TODO check if value starts with <, otherwise don't try stripping anything +jQuery.validator.addMethod("strippedminlength", function(value, element, param) { + return jQuery(value).text().length >= param; +}, jQuery.validator.format("Please enter at least {0} characters")); + +// same as email, but TLD is optional +jQuery.validator.addMethod("email2", function(value, element, param) { + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); +}, jQuery.validator.messages.email); + +// same as url, but TLD is optional +jQuery.validator.addMethod("url2", function(value, element, param) { + return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); +}, jQuery.validator.messages.url); + +// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator +// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 +// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) +jQuery.validator.addMethod("creditcardtypes", function(value, element, param) { + if (/[^0-9-]+/.test(value)) { + return false; + } + + value = value.replace(/\D/g, ""); + + var validTypes = 0x0000; + + if (param.mastercard) + validTypes |= 0x0001; + if (param.visa) + validTypes |= 0x0002; + if (param.amex) + validTypes |= 0x0004; + if (param.dinersclub) + validTypes |= 0x0008; + if (param.enroute) + validTypes |= 0x0010; + if (param.discover) + validTypes |= 0x0020; + if (param.jcb) + validTypes |= 0x0040; + if (param.unknown) + validTypes |= 0x0080; + if (param.all) + validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; + + if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard + return value.length == 16; + } + if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa + return value.length == 16; + } + if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex + return value.length == 15; + } + if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub + return value.length == 14; + } + if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute + return value.length == 15; + } + if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover + return value.length == 16; + } + if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb + return value.length == 16; + } + if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb + return value.length == 15; + } + if (validTypes & 0x0080) { //unknown + return true; + } + return false; +}, "Please enter a valid credit card number."); + +jQuery.validator.addMethod("ipv4", function(value, element, param) { + return this.optional(element) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(value); +}, "Please enter a valid IP v4 address."); + +jQuery.validator.addMethod("ipv6", function(value, element, param) { + return this.optional(element) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(value); +}, "Please enter a valid IP v6 address."); + +/** +* Return true if the field value matches the given format RegExp +* +* @example jQuery.validator.methods.pattern("AR1004",element,/^AR\d{4}$/) +* @result true +* +* @example jQuery.validator.methods.pattern("BR1004",element,/^AR\d{4}$/) +* @result false +* +* @name jQuery.validator.methods.pattern +* @type Boolean +* @cat Plugins/Validate/Methods +*/ +jQuery.validator.addMethod("pattern", function(value, element, param) { + if (this.optional(element)) { + return true; + } + if (typeof param === 'string') { + param = new RegExp('^(?:' + param + ')$'); + } + return param.test(value); +}, "Invalid format."); + + +/* + * Lets you say "at least X inputs that match selector Y must be filled." + * + * The end result is that neither of these inputs: + * + * + * + * + * ...will validate unless at least one of them is filled. + * + * partnumber: {require_from_group: [1,".productinfo"]}, + * description: {require_from_group: [1,".productinfo"]} + * + */ +jQuery.validator.addMethod("require_from_group", function(value, element, options) { + var validator = this; + var selector = options[1]; + var validOrNot = $(selector, element.form).filter(function() { + return validator.elementValue(this); + }).length >= options[0]; + + if(!$(element).data('being_validated')) { + var fields = $(selector, element.form); + fields.data('being_validated', true); + fields.valid(); + fields.data('being_validated', false); + } + return validOrNot; +}, jQuery.format("Please fill at least {0} of these fields.")); + +/* + * Lets you say "either at least X inputs that match selector Y must be filled, + * OR they must all be skipped (left blank)." + * + * The end result, is that none of these inputs: + * + * + * + * + * + * ...will validate unless either at least two of them are filled, + * OR none of them are. + * + * partnumber: {skip_or_fill_minimum: [2,".productinfo"]}, + * description: {skip_or_fill_minimum: [2,".productinfo"]}, + * color: {skip_or_fill_minimum: [2,".productinfo"]} + * + */ +jQuery.validator.addMethod("skip_or_fill_minimum", function(value, element, options) { + var validator = this; + + numberRequired = options[0]; + selector = options[1]; + var numberFilled = $(selector, element.form).filter(function() { + return validator.elementValue(this); + }).length; + var valid = numberFilled >= numberRequired || numberFilled === 0; + + if(!$(element).data('being_validated')) { + var fields = $(selector, element.form); + fields.data('being_validated', true); + fields.valid(); + fields.data('being_validated', false); + } + return valid; +}, jQuery.format("Please either skip these fields or fill at least {0} of them.")); + +// Accept a value from a file input based on a required mimetype +jQuery.validator.addMethod("accept", function(value, element, param) { + // Split mime on commas incase we have multiple types we can accept + var typeParam = typeof param === "string" ? param.replace(/,/g, '|') : "image/*", + optionalValue = this.optional(element), + i, file; + + // Element is optional + if(optionalValue) { + return optionalValue; + } + + if($(element).attr("type") === "file") { + // If we are using a wildcard, make it regex friendly + typeParam = typeParam.replace("*", ".*"); + + // Check if the element has a FileList before checking each file + if(element.files && element.files.length) { + for(i = 0; i < element.files.length; i++) { + file = element.files[i]; + + // Grab the mimtype from the loaded file, verify it matches + if(!file.type.match(new RegExp( ".?(" + typeParam + ")$", "i"))) { + return false; + } + } + } + } + + // Either return true because we've validated each file, or because the + // browser does not support element.files and the FileList feature + return true; +}, jQuery.format("Please enter a value with a valid mimetype.")); + +// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept +jQuery.validator.addMethod("extension", function(value, element, param) { + param = typeof param === "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; + return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); +}, jQuery.format("Please enter a value with a valid extension.")); diff --git a/wqflask/wqflask/static/packages/jqplot/additional-methods.min.js b/wqflask/wqflask/static/packages/jqplot/additional-methods.min.js new file mode 100644 index 00000000..60533e43 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/additional-methods.min.js @@ -0,0 +1,4 @@ +/*! jQuery Validation Plugin - v1.10.0 - 9/7/2012 +* https://github.com/jzaefferer/jquery-validation +* Copyright (c) 2012 Jörn Zaefferer; Licensed MIT, GPL */ +(function(){function a(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'"_+=\/-]*/g,"")}jQuery.validator.addMethod("maxWords",function(b,c,d){return this.optional(c)||a(b).match(/\b\w+\b/g).length<=d},jQuery.validator.format("Please enter {0} words or less.")),jQuery.validator.addMethod("minWords",function(b,c,d){return this.optional(c)||a(b).match(/\b\w+\b/g).length>=d},jQuery.validator.format("Please enter at least {0} words.")),jQuery.validator.addMethod("rangeWords",function(b,c,d){var e=a(b),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},jQuery.validator.format("Please enter between {0} and {1} words."))})(),jQuery.validator.addMethod("letterswithbasicpunc",function(a,b){return this.optional(b)||/^[a-z\-.,()'\"\s]+$/i.test(a)},"Letters or punctuation only please"),jQuery.validator.addMethod("alphanumeric",function(a,b){return this.optional(b)||/^\w+$/i.test(a)},"Letters, numbers, and underscores only please"),jQuery.validator.addMethod("lettersonly",function(a,b){return this.optional(b)||/^[a-z]+$/i.test(a)},"Letters only please"),jQuery.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),jQuery.validator.addMethod("ziprange",function(a,b){return this.optional(b)||/^90[2-5]\d\{2\}-\d{4}$/.test(a)},"Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"),jQuery.validator.addMethod("zipcodeUS",function(a,b){return this.optional(b)||/\d{5}-\d{4}$|^\d{5}$/.test(a)},"The specified US ZIP Code is invalid"),jQuery.validator.addMethod("integer",function(a,b){return this.optional(b)||/^-?\d+$/.test(a)},"A positive or negative non-decimal number please"),jQuery.validator.addMethod("vinUS",function(a){if(a.length!=17)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){e=j[b],d=a.slice(b,b+1),b==8&&(g=d);if(!isNaN(d))d*=e;else for(c=0;c9&&a.match(/^(\+?1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/)},"Please specify a valid phone number"),jQuery.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:(?:\d{5}\)?\s?\d{4,5})|(?:\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3}))|(?:\d{3}\)?\s?\d{3}\s?\d{3,4})|(?:\d{2}\)?\s?\d{4}\s?\d{4}))$/)},"Please specify a valid phone number"),jQuery.validator.addMethod("mobileUK",function(a,b){return a=a.replace(/\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[45789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),jQuery.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[45789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),jQuery.validator.addMethod("postcodeUK",function(a,b){return a=a.toUpperCase().replace(/\s+/g,""),this.optional(b)||a.match(/^([^QZ][^IJZ]{0,1}\d{1,2})(\d[^CIKMOV]{2})$/)||a.match(/^([^QV]\d[ABCDEFGHJKSTUW])(\d[^CIKMOV]{2})$/)||a.match(/^([^QV][^IJZ]\d[ABEHMNPRVWXY])(\d[^CIKMOV]{2})$/)||a.match(/^(GIR)(0AA)$/)||a.match(/^(BFPO)(\d{1,4})$/)||a.match(/^(BFPO)(C\/O\d{1,3})$/)},"Please specify a valid postcode"),jQuery.validator.addMethod("strippedminlength",function(a,b,c){return jQuery(a).text().length>=c},jQuery.validator.format("Please enter at least {0} characters")),jQuery.validator.addMethod("email2",function(a,b,c){return this.optional(b)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(a)},jQuery.validator.messages.email),jQuery.validator.addMethod("url2",function(a,b,c){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},jQuery.validator.messages.url),jQuery.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),d&1&&/^(5[12345])/.test(a)?a.length==16:d&2&&/^(4)/.test(a)?a.length==16:d&4&&/^(3[47])/.test(a)?a.length==15:d&8&&/^(3(0[012345]|[68]))/.test(a)?a.length==14:d&16&&/^(2(014|149))/.test(a)?a.length==15:d&32&&/^(6011)/.test(a)?a.length==16:d&64&&/^(3)/.test(a)?a.length==16:d&64&&/^(2131|1800)/.test(a)?a.length==15:d&128?!0:!1},"Please enter a valid credit card number."),jQuery.validator.addMethod("ipv4",function(a,b,c){return this.optional(b)||/^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test(a)},"Please enter a valid IP v4 address."),jQuery.validator.addMethod("ipv6",function(a,b,c){return this.optional(b)||/^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test(a)},"Please enter a valid IP v6 address."),jQuery.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:(typeof c=="string"&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),jQuery.validator.addMethod("require_from_group",function(a,b,c){var d=this,e=c[1],f=$(e,b.form).filter(function(){return d.elementValue(this)}).length>=c[0];if(!$(b).data("being_validated")){var g=$(e,b.form);g.data("being_validated",!0),g.valid(),g.data("being_validated",!1)}return f},jQuery.format("Please fill at least {0} of these fields.")),jQuery.validator.addMethod("skip_or_fill_minimum",function(a,b,c){var d=this;numberRequired=c[0],selector=c[1];var e=$(selector,b.form).filter(function(){return d.elementValue(this)}).length,f=e>=numberRequired||e===0;if(!$(b).data("being_validated")){var g=$(selector,b.form);g.data("being_validated",!0),g.valid(),g.data("being_validated",!1)}return f},jQuery.format("Please either skip these fields or fill at least {0} of them.")),jQuery.validator.addMethod("accept",function(a,b,c){var d=typeof c=="string"?c.replace(/,/g,"|"):"image/*",e=this.optional(b),f,g;if(e)return e;if($(b).attr("type")==="file"){d=d.replace("*",".*");if(b.files&&b.files.length)for(f=0;f
      1 ? ' colspan="' + cell.pos[2] + '"' : '') + + (cell.pos[3] > 1 ? ' rowspan="' + cell.pos[3] + '"' : '') + + (classes.length > 0 ? ' class="' + classes.join(' ') + '"' : '') + + ' valign="top">
      ' + html + '
      '; + }, + + _effectGeneric: function (show, slide, fade, callback) { + var self = this; + + if ($.effects && $.effects[self.options.showAnim]) { + self.dialog[show](self.options.showAnim, self.options.showOptions, self.options.duration, callback); + } else { + self.dialog[(self.options.showAnim === 'slideDown' ? + slide + : (self.options.showAnim === 'fadeIn' ? + fade + : show))]((self.options.showAnim ? self.options.duration : null), callback); + if (!self.options.showAnim || !self.options.duration) { + callback(); + } + } + }, + + _effectShow: function (callback) { + this._effectGeneric('show', 'slideDown', 'fadeIn', callback); + }, + + _effectHide: function (callback) { + this._effectGeneric('hide', 'slideUp', 'fadeOut', callback); + }, + + open: function () { + if (!this.opened) { + this._generate(); + + var offset = this.element.offset(), + x = offset.left, + y = offset.top + this.element.outerHeight(); + x -= Math.max(0, (x + this.dialog.width()) - $(window).width() + 20); + y -= Math.max(0, (y + this.dialog.height()) - $(window).height() + 20); + this.dialog.css({'left': x, 'top': y}); + + this._effectShow(); + this.opened = true; + } + }, + + close: function () { + var self = this; + + this._setAltField(); + + self.currentColor = $.extend({}, self.color); + self.changed = false; + + // tear down the interface + self._effectHide(function () { + self.dialog.empty(); + self.generated = false; + + self.opened = false; + self._callback(self.options.onClose); + }); + }, + + _callback: function (f) { + var self = this; + + if (f instanceof Function) { + f(self.color.toCSS(), { + r: self.color.r, + g: self.color.g, + b: self.color.b, + a: self.color.a + }, self); + } + }, + + _generateAllParts: function () { + $.each(this.parts, function (index, part) { + part.generate(); + }); + }, + + _initAllParts: function () { + $.each(this.parts, function (index, part) { + part.init(); + }); + }, + + _change: function () { + this.changed = true; + + switch (this.options.limit) { + case 'websafe': + this.color.limit(6); + break; + + case 'nibble': + this.color.limit(16); + break; + + case 'binary': + this.color.limit(2); + break; + } + + // update colors + if (!this.inline) { + if (!this.color.equals(this._parseHex(this.element.val()))) { + this.element.val(this.color.toHex()); + } + + if (this.image && this.options.buttonColorize) { + this.image.css('background-color', this.color.toCSS()); + } + + if (this.options.altOnChange) { + this._setAltField(); + } + } + + // callback + this._callback(this.options.onSelect); + + $.each(this.parts, function (index, part) { + part.repaint(); + }); + }, + + _intToHex: function (dec) { + var result = dec.toString(16); + if (result.length === 1) { + result = ('0' + result); + } + return result.toLowerCase(); + }, + + // This will be deprecated by jQueryUI 1.9 widget + _hoverable: function (e) { + e.hover(function () { + e.addClass("ui-state-hover"); + }, function () { + e.removeClass("ui-state-hover"); + }); + }, + + // This will be deprecated by jQueryUI 1.9 widget + _focusable: function (e) { + e.focus(function () { + e.addClass("ui-state-focus"); + }).blur(function () { + e.removeClass("ui-state-focus"); + }); + }, + + _parts: { + header: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + return '
      ' + + '' + inst.options.title + '' + + '' + + '
      '; + }; + + this.init = function () { + e = $(_html()).prependTo(inst.dialog); + var close = $('.ui-dialog-titlebar-close', e); + inst._hoverable(close); + inst._focusable(close); + + close.click( function() { + inst.close() + }); + }; + + this.repaint = function () { + }; + + this.generate = function () { + this.repaint(); + }; + }, + + map: function (inst) { + var self = this, + e = null, + _mousedown, _mouseup, _mousemove, _html; + + _mousedown = function (event) { + if (!inst.opened) { + return; + } + + var div = $('#ui-colorpicker-map-layer-pointer', e), + offset = div.offset(), + width = div.width(), + height = div.height(), + x = event.pageX - offset.left, + y = event.pageY - offset.top; + + if (x >= 0 && x < width && y >= 0 && y < height) { + event.stopImmediatePropagation(); + event.preventDefault(); + $(document).unbind('mousedown', _mousedown); + $(document).bind('mouseup', _mouseup); + $(document).bind('mousemove', _mousemove); + _mousemove(event); + } + }; + + _mouseup = function (event) { + event.stopImmediatePropagation(); + event.preventDefault(); + $(document).unbind('mouseup', _mouseup); + $(document).unbind('mousemove', _mousemove); + $(document).bind('mousedown', _mousedown); + }; + + _mousemove = function (event) { + event.stopImmediatePropagation(); + event.preventDefault(); + + if (event.pageX === self.x && event.pageY === self.y) { + return; + } + self.x = event.pageX; + self.y = event.pageY; + + var div = $('#ui-colorpicker-map-layer-pointer', e), + offset = div.offset(), + width = div.width(), + height = div.height(), + x = event.pageX - offset.left, + y = event.pageY - offset.top; + + x = Math.max(0, Math.min(x / width, 1)); + y = Math.max(0, Math.min(y / height, 1)); + + // interpret values + switch (inst.mode) { + case 'h': + inst.color.s = x; + inst.color.v = 1 - y; + inst.color.updateRGB(); + break; + + case 's': + case 'a': + inst.color.h = x; + inst.color.v = 1 - y; + inst.color.updateRGB(); + break; + + case 'v': + inst.color.h = x; + inst.color.s = 1 - y; + inst.color.updateRGB(); + break; + + case 'r': + inst.color.b = x; + inst.color.g = 1 - y; + inst.color.updateHSV(); + break; + + case 'g': + inst.color.b = x; + inst.color.r = 1 - y; + inst.color.updateHSV(); + break; + + case 'b': + inst.color.r = x; + inst.color.g = 1 - y; + inst.color.updateHSV(); + break; + } + + inst._change(); + }; + + _html = function () { + var html = '
      ' + + ' ' + + ' ' + + (inst.options.alpha ? ' ' : '') + + '
      '; + return html; + }; + + this.generate = function () { + switch (inst.mode) { + case 'h': + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 0', 'opacity': ''}).show(); + $('#ui-colorcasepicker-map-layer-2', e).hide(); + break; + + case 's': + case 'a': + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 -260px', 'opacity': ''}).show(); + $('#ui-colorpicker-map-layer-2', e).css({'background-position': '0 -520px', 'opacity': ''}).show(); + break; + + case 'v': + $(e).css('background-color', 'black'); + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 -780px', 'opacity': ''}).show(); + $('#ui-colorpicker-map-layer-2', e).hide(); + break; + + case 'r': + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 -1040px', 'opacity': ''}).show(); + $('#ui-colorpicker-map-layer-2', e).css({'background-position': '0 -1300px', 'opacity': ''}).show(); + break; + + case 'g': + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 -1560px', 'opacity': ''}).show(); + $('#ui-colorpicker-map-layer-2', e).css({'background-position': '0 -1820px', 'opacity': ''}).show(); + break; + + case 'b': + $('#ui-colorpicker-map-layer-1', e).css({'background-position': '0 -2080px', 'opacity': ''}).show(); + $('#ui-colorpicker-map-layer-2', e).css({'background-position': '0 -2340px', 'opacity': ''}).show(); + break; + } + self.repaint(); + }; + + this.repaint = function () { + var div = $('#ui-colorpicker-map-layer-pointer', e), + x = 0, + y = 0; + + switch (inst.mode) { + case 'h': + x = inst.color.s * div.width(); + y = (1 - inst.color.v) * div.width(); + $(e).css('background-color', inst.color.normClone().toCSS()); + break; + + case 's': + case 'a': + x = inst.color.h * div.width(); + y = (1 - inst.color.v) * div.width(); + $('#ui-colorpicker-map-layer-2', e).css('opacity', 1 - inst.color.s); + break; + + case 'v': + x = inst.color.h * div.width(); + y = (1 - inst.color.s) * div.width(); + $('#ui-colorpicker-map-layer-1', e).css('opacity', inst.color.v); + break; + + case 'r': + x = inst.color.b * div.width(); + y = (1 - inst.color.g) * div.width(); + $('#ui-colorpicker-map-layer-2', e).css('opacity', inst.color.r); + break; + + case 'g': + x = inst.color.b * div.width(); + y = (1 - inst.color.r) * div.width(); + $('#ui-colorpicker-map-layer-2', e).css('opacity', inst.color.g); + break; + + case 'b': + x = inst.color.r * div.width(); + y = (1 - inst.color.g) * div.width(); + $('#ui-colorpicker-map-layer-2', e).css('opacity', inst.color.b); + break; + } + + if (inst.options.alpha) { + $('#ui-colorpicker-map-layer-alpha', e).css('opacity', 1 - inst.color.a); + } + + $('#ui-colorpicker-map-pointer', e).css({ + 'left': x - 7, + 'top': y - 7 + }); + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-map-container', inst.dialog)); + + e.bind('mousedown', _mousedown); + }; + }, + + bar: function (inst) { + var self = this, + e = null, + _mousedown, _mouseup, _mousemove, _html; + + _mousedown = function (event) { + if (!inst.opened) { + return; + } + + var div = $('#ui-colorpicker-bar-layer-pointer', e), + offset = div.offset(), + width = div.width(), + height = div.height(), + x = event.pageX - offset.left, + y = event.pageY - offset.top; + + if (x >= 0 && x < width && y >= 0 && y < height) { + event.stopImmediatePropagation(); + event.preventDefault(); + $(document).unbind('mousedown', _mousedown); + $(document).bind('mouseup', _mouseup); + $(document).bind('mousemove', _mousemove); + _mousemove(event); + } + }; + + _mouseup = function (event) { + event.stopImmediatePropagation(); + event.preventDefault(); + $(document).unbind('mouseup', _mouseup); + $(document).unbind('mousemove', _mousemove); + $(document).bind('mousedown', _mousedown); + }; + + _mousemove = function (event) { + event.stopImmediatePropagation(); + event.preventDefault(); + + if (event.pageY === self.y) { + return; + } + self.y = event.pageY; + + var div = $('#ui-colorpicker-bar-layer-pointer', e), + offset = div.offset(), + height = div.height(), + y = event.pageY - offset.top; + + y = Math.max(0, Math.min(y / height, 1)); + + // interpret values + switch (inst.mode) { + case 'h': + inst.color.h = 1 - y; + inst.color.updateRGB(); + break; + + case 's': + inst.color.s = 1 - y; + inst.color.updateRGB(); + break; + + case 'v': + inst.color.v = 1 - y; + inst.color.updateRGB(); + break; + + case 'r': + inst.color.r = 1 - y; + inst.color.updateHSV(); + break; + + case 'g': + inst.color.g = 1 - y; + inst.color.updateHSV(); + break; + + case 'b': + inst.color.b = 1 - y; + inst.color.updateHSV(); + break; + + case 'a': + inst.color.a = 1 - y; + break; + } + + inst._change(); + }; + + _html = function () { + var html = '
      ' + + ' ' + + ' ' + + ' ' + + ' '; + + if (inst.options.alpha) { + html += ' ' + + ' '; + } + + html += '
      '; + + return html; + }; + + this.generate = function () { + switch (inst.mode) { + case 'h': + case 's': + case 'v': + case 'r': + case 'g': + case 'b': + $('#ui-colorpicker-bar-layer-alpha', e).show(); + $('#ui-colorpicker-bar-layer-alphabar', e).hide(); + break; + + case 'a': + $('#ui-colorpicker-bar-layer-alpha', e).hide(); + $('#ui-colorpicker-bar-layer-alphabar', e).show(); + break; + } + + switch (inst.mode) { + case 'h': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 0', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).hide(); + $('#ui-colorpicker-bar-layer-3', e).hide(); + $('#ui-colorpicker-bar-layer-4', e).hide(); + break; + + case 's': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 -260px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).css({'background-position': '0 -520px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-3', e).hide(); + $('#ui-colorpicker-bar-layer-4', e).hide(); + break; + + case 'v': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 -520px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).hide(); + $('#ui-colorpicker-bar-layer-3', e).hide(); + $('#ui-colorpicker-bar-layer-4', e).hide(); + break; + + case 'r': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 -1560px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).css({'background-position': '0 -1300px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-3', e).css({'background-position': '0 -780px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-4', e).css({'background-position': '0 -1040px', 'opacity': ''}).show(); + break; + + case 'g': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 -2600px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).css({'background-position': '0 -2340px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-3', e).css({'background-position': '0 -1820px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-4', e).css({'background-position': '0 -2080px', 'opacity': ''}).show(); + break; + + case 'b': + $('#ui-colorpicker-bar-layer-1', e).css({'background-position': '0 -3640px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-2', e).css({'background-position': '0 -3380px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-3', e).css({'background-position': '0 -2860px', 'opacity': ''}).show(); + $('#ui-colorpicker-bar-layer-4', e).css({'background-position': '0 -3120px', 'opacity': ''}).show(); + break; + + case 'a': + $('#ui-colorpicker-bar-layer-1', e).hide(); + $('#ui-colorpicker-bar-layer-2', e).hide(); + $('#ui-colorpicker-bar-layer-3', e).hide(); + $('#ui-colorpicker-bar-layer-4', e).hide(); + break; + } + self.repaint(); + }; + + this.repaint = function () { + var div = $('#ui-colorpicker-bar-layer-pointer', e), + y = 0; + + switch (inst.mode) { + case 'h': + y = (1 - inst.color.h) * div.height(); + break; + + case 's': + y = (1 - inst.color.s) * div.height(); + $('#ui-colorpicker-bar-layer-2', e).css('opacity', 1 - inst.color.v); + $(e).css('background-color', inst.color.normClone().toCSS()); + break; + + case 'v': + y = (1 - inst.color.v) * div.height(); + $(e).css('background-color', inst.color.normClone().toCSS()); + break; + + case 'r': + y = (1 - inst.color.r) * div.height(); + $('#ui-colorpicker-bar-layer-2', e).css('opacity', Math.max(0, (inst.color.b - inst.color.g))); + $('#ui-colorpicker-bar-layer-3', e).css('opacity', Math.max(0, (inst.color.g - inst.color.b))); + $('#ui-colorpicker-bar-layer-4', e).css('opacity', Math.min(inst.color.b, inst.color.g)); + break; + + case 'g': + y = (1 - inst.color.g) * div.height(); + $('#ui-colorpicker-bar-layer-2', e).css('opacity', Math.max(0, (inst.color.b - inst.color.r))); + $('#ui-colorpicker-bar-layer-3', e).css('opacity', Math.max(0, (inst.color.r - inst.color.b))); + $('#ui-colorpicker-bar-layer-4', e).css('opacity', Math.min(inst.color.r, inst.color.b)); + break; + + case 'b': + y = (1 - inst.color.b) * div.height(); + $('#ui-colorpicker-bar-layer-2', e).css('opacity', Math.max(0, (inst.color.r - inst.color.g))); + $('#ui-colorpicker-bar-layer-3', e).css('opacity', Math.max(0, (inst.color.g - inst.color.r))); + $('#ui-colorpicker-bar-layer-4', e).css('opacity', Math.min(inst.color.r, inst.color.g)); + break; + + case 'a': + y = (1 - inst.color.a) * div.height(); + $(e).css('background-color', inst.color.normClone().toCSS()); + break; + } + + if (inst.mode !== 'a') { + $('#ui-colorpicker-bar-layer-alpha', e).css('opacity', 1 - inst.color.a); + } + + $('#ui-colorpicker-bar-pointer', e).css('top', y - 3); + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-bar-container', inst.dialog)); + + e.bind('mousedown', _mousedown); + }; + }, + + inputs: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + var html = '
      '; + + if (inst.options.hsv) { + html += '
      °
      ' + + '
      %
      ' + + '
      %
      '; + } + + if (inst.options.rgb) { + html += '
      ' + + '
      ' + + '
      '; + } + + if (inst.options.alpha) { + html += '
      %
      '; + } + + return html + '
      '; + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-inputs-container', inst.dialog)); + + $('.ui-colorpicker-mode', e).click(function () { + inst.mode = $(this).val(); + inst._generateAllParts(); + }); + + $('.ui-colorpicker-number', e).bind('change input keyup', function () { + inst.color.r = $('#ui-colorpicker-r .ui-colorpicker-number', e).val() / 255; + inst.color.g = $('#ui-colorpicker-g .ui-colorpicker-number', e).val() / 255; + inst.color.b = $('#ui-colorpicker-b .ui-colorpicker-number', e).val() / 255; + inst.color.a = $('#ui-colorpicker-a .ui-colorpicker-number', e).val() / 100; + inst.color.h = $('#ui-colorpicker-h .ui-colorpicker-number', e).val() / 360; + inst.color.s = $('#ui-colorpicker-s .ui-colorpicker-number', e).val() / 100; + inst.color.v = $('#ui-colorpicker-v .ui-colorpicker-number', e).val() / 100; + + if ($(this).hasClass('ui-colorpicker-number-hsv')) { + inst.color.updateRGB(); + } else if ($(this).hasClass('ui-colorpicker-number-rgb')) { + inst.color.updateHSV(); + } + + inst._change(); + }); + }; + + this.repaint = function () { + var c = $.extend(inst.color); + c.h *= 360; + c.s *= 100; + c.v *= 100; + c.r *= 255; + c.g *= 255; + c.b *= 255; + c.a *= 100; + + $.each(c, function (index, value) { + var v = Math.round(value); + if (!$('#ui-colorpicker-' + index + ' .ui-colorpicker-number', e).is(':focus') + && $('#ui-colorpicker-' + index + ' .ui-colorpicker-number', e).val() !== v) { + $('#ui-colorpicker-' + index + ' .ui-colorpicker-number', e).val(v); + } + }); + }; + + this.generate = function () { + $('.ui-colorpicker-mode', e).each(function () { + $(this).attr('checked', $(this).val() === inst.mode); + }); + this.repaint(); + }; + }, + + preview: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + return '
      ' + + '' + + '
      ' + + '
      ' + + '
      ' + + '
      '; + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-preview-container', inst.dialog)); + + $('#ui-colorpicker-preview-initial', e).click(function () { + inst.color = $.extend({}, inst.currentColor); + inst._change(); + }); + + }; + + this.repaint = function () { + $('#ui-colorpicker-preview-initial', e).css('background-color', inst.currentColor.toCSS()).attr('title', inst.currentColor.toHex()); + $('#ui-colorpicker-preview-initial-alpha', e).css('opacity', 1 - inst.currentColor.a); + $('#ui-colorpicker-preview-current', e).css('background-color', inst.color.toCSS()).attr('title', inst.color.toHex()); + $('#ui-colorpicker-preview-current-alpha', e).css('opacity', 1 - inst.color.a); + }; + + this.generate = function () { + if (inst.options.alpha) { + $('#ui-colorpicker-preview-initial-alpha, #ui-colorpicker-preview-current-alpha', e).show(); + } else { + $('#ui-colorpicker-preview-initial-alpha, #ui-colorpicker-preview-current-alpha', e).hide(); + } + + this.repaint(); + }; + }, + + hex: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + var html = ''; + + if (inst.options.alpha) { + html += ''; + } + + html += ''; + + return '
      ' + html + '
      '; + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-hex-container', inst.dialog)); + + $('#ui-colorpicker-hex-input', e).bind('change keyup', function () { + var rgb = inst._parseHex($(this).val()); + inst.color.r = rgb[0]; + inst.color.g = rgb[1]; + inst.color.b = rgb[2]; + inst.color.updateHSV(); + inst._change(); + }); + + $('#ui-colorpicker-hex-alpha', e).bind('change keyup', function () { + inst.color.a = parseInt($('#ui-colorpicker-hex-alpha', e).val(), 16); + inst._change(); + }); + }; + + this.repaint = function () { + if (!$('#ui-colorpicker-hex-input', e).is(':focus')) { + $('#ui-colorpicker-hex-input', e).val(inst.color.toHex(true)); + } + + if (!$('#ui-colorpicker-hex-alpha', e).is(':focus')) { + $('#ui-colorpicker-hex-alpha', e).val(inst._intToHex(inst.color.a * 255)); + } + }; + + this.generate = function () { + this.repaint(); + }; + }, + + swatches: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + var html = ''; + + $.each(inst.options.swatches, function (name, color) { + var hex = inst._intToHex(color[0]) + inst._intToHex(color[1]) + inst._intToHex(color[2]); + html += '
      '; + }); + + return '
      ' + html + '
      '; + }; + + this.init = function () { + e = $(_html()).appendTo($('#ui-colorpicker-swatches-container', inst.dialog)); + + $('.ui-colorpicker-swatch', e).click(function () { + var rgb = inst._parseColor($(this).css('background-color')); + inst.color = (rgb === false ? new inst.Color() : new inst.Color(rgb[0], rgb[1], rgb[2])); + inst._change(); + }); + }; + + this.repaint = function () { + // Not affected by changing color; + }; + + this.generate = function () { + // Not affected by changing color; + }; + }, + + footer: function (inst) { + var self = this, + e = null, + _html; + + _html = function () { + return '
      ' + + (inst.options.alpha ? '' : '') + + (inst.inline ? '' : '
      ' + + '' + + '
      ') + + '
      '; + }; + + this.init = function () { + e = $(_html()).appendTo(inst.dialog); + + $('.ui-colorpicker-close', e).button().click(function () { + inst.close(); + }); + + if (inst.options.alpha) { + $('.ui-colorpicker-transparent', e).button().click(function () { + inst.color.a = 0; + inst._change(); + }); + } + }; + + this.repaint = function () {}; + + this.generate = function () {}; + } + }, + + _parseHex: function (color) { + var name = $.trim(color).toLowerCase(), + c, + m; + + if (_colors[name]) { + c = _colors[name]; + return [c[0] / 255, c[1] / 255, c[2] / 255]; + } + + // {#}rrggbb + m = /^#?([a-fA-F0-9]{0,6})/.exec(color); + if (m) { + c = parseInt(m[1], 16); + return [((c >> 16) & 0xFF) / 255, + ((c >> 8) & 0xFF) / 255, + (c & 0xFF) / 255]; + } + }, + + _parseColor: function (color) { + var m; + + // rgba(r,g,b,a) + m = /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/.exec(color); + if (m) { + return [ + m[1] / 255, + m[2] / 255, + m[3] / 255, + m[4] / 255 + ]; + } + + // rgba(r%,g%,b%,a%) + m = /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/.exec(color); + if (m) { + return [ + m[1] / 100, + m[2] / 100, + m[3] / 100, + m[4] / 100 + ]; + } + + // #rrggbb + m = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color); + if (m) { + return [ + parseInt(m[1], 16) / 255, + parseInt(m[2], 16) / 255, + parseInt(m[3], 16) / 255 + ]; + } + + // #rgb + m = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color); + if (m) { + return [ + parseInt(m[1] + m[1], 16) / 255, + parseInt(m[2] + m[2], 16) / 255, + parseInt(m[3] + m[3], 16) / 255 + ]; + } + + return this._parseHex(color); + }, + + Color: function () { + var a, args = arguments; + + this.updateRGB = function () { + this.h = Math.max(0, Math.min(this.h, 1)); + this.s = Math.max(0, Math.min(this.s, 1)); + this.v = Math.max(0, Math.min(this.v, 1)); + + if (this.s === 0) { + this.r = this.g = this.b = this.v; + } else { + var var_h = this.h === 1 ? 0 : this.h * 6, + var_i = Math.floor(var_h), + var_1 = this.v * (1 - this.s), + var_2 = this.v * (1 - this.s * (var_h - var_i)), + var_3 = this.v * (1 - this.s * (1 - (var_h - var_i))); + + if (var_i === 0) { + this.r = this.v; + this.g = var_3; + this.b = var_1; + } else if (var_i === 1) { + this.r = var_2; + this.g = this.v; + this.b = var_1; + } else if (var_i === 2) { + this.r = var_1; + this.g = this.v; + this.b = var_3; + } else if (var_i === 3) { + this.r = var_1; + this.g = var_2; + this.b = this.v; + } else if (var_i === 4) { + this.r = var_3; + this.g = var_1; + this.b = this.v; + } else { + this.r = this.v; + this.g = var_1; + this.b = var_2; + } + } + return this; + }; + + this.updateHSV = function () { + var minVal, maxVal, delta, del_R, del_G, del_B; + this.r = Math.max(0, Math.min(this.r, 1)); + this.g = Math.max(0, Math.min(this.g, 1)); + this.b = Math.max(0, Math.min(this.b, 1)); + + minVal = Math.min(this.r, this.g, this.b); + maxVal = Math.max(this.r, this.g, this.b); + delta = maxVal - minVal; + + this.v = maxVal; + + if (delta === 0) { + this.h = 0; + this.s = 0; + } else { + this.s = delta / maxVal; + del_R = (((maxVal - this.r) / 6) + (delta / 2)) / delta; + del_G = (((maxVal - this.g) / 6) + (delta / 2)) / delta; + del_B = (((maxVal - this.b) / 6) + (delta / 2)) / delta; + + if (this.r === maxVal) { + this.h = del_B - del_G; + } else if (this.g === maxVal) { + this.h = (1 / 3) + del_R - del_B; + } else if (this.b === maxVal) { + this.h = (2 / 3) + del_G - del_R; + } + + if (this.h < 0) { + this.h += 1; + } else if (this.h > 1) { + this.h -= 1; + } + } + return this; + }; + + this._hexify = function (number) { + // return Math.round(number).toString(16); + var digits = '0123456789abcdef', + lsd = number % 16, + msd = (number - lsd) / 16, + hexified = digits.charAt(msd) + digits.charAt(lsd); + return hexified; + }; + + this.toHex = function () { + return this._hexify(this.r * 255) + this._hexify(this.g * 255) + this._hexify(this.b * 255); + }; + + this.toCSS = function () { + return '#' + this.toHex(); + }; + + this.toHexAlpha = function () { + return this._hexify(this.a * 255); + }; + + this.normClone = function () { + return $.extend({}, this, {s: 1, v: 1}).updateRGB(); + }; + + this.equals = function (rgb) { + return rgb[0] === this.r + && rgb[1] === this.g + && rgb[2] === this.b; + }; + + this.limit = function (steps) { + steps -= 1; + this.r = Math.round(this.r * steps) / steps; + this.g = Math.round(this.g * steps) / steps; + this.b = Math.round(this.b * steps) / steps; + this.updateHSV(); + }; + + for (a = 0; a < args.length; a += 1) { + args[a] = Math.max(0, Math.min(args[a], 1)); + } + + if (args.length === 0) { + this.r = 0; + this.g = 0; + this.b = 0; + this.a = 1; + this.h = 0; + this.s = 0; + this.v = 0; + } else if (args.length === 3) { + // r,g,b + this.r = args[0] || 0; + this.g = args[1] || 0; + this.b = args[2] || 0; + this.a = 1; + this.updateHSV(); + } else if (args.length === 7) { + // r,g,b,a,h,s,v + this.r = args[0] || 0; + this.g = args[1] || 0; + this.b = args[2] || 0; + this.a = args[3] || 0; + this.h = args[4] || 0; + this.s = args[5] || 0; + this.v = args[6] || 0; + } + } + }); + +}(jQuery)); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/cursor-highlighter.html b/wqflask/wqflask/static/packages/jqplot/examples/cursor-highlighter.html new file mode 100644 index 00000000..ef35aebf --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/cursor-highlighter.html @@ -0,0 +1,137 @@ + + + + + + Data Point Highlighting, Tooltips and Cursor Tracking + + + + + + + + + + + + + +
      + + + + + + +

      The Highlighter plugin will highlight data points near the mouse and display an optional tooltip with the data point value. By default, the tooltip values will be formatted with the same formatter as used to display the axes tick values. The text format can be customized with an optional sprintf style format string.

      + +
      + +
      
      +
      +

      The Cursor plugin changes the mouse cursor when it enters the graph area and displays an optional tooltip with the mouse position. The tooltip can be in a fixed location, or it can follow the mouse. The pointer style, set to "crosshair" by default, can also be customized. Tooltip values are formatted similar to the Highlighter plugin. By default they use the axes formatters, but can be customized with a sprintf format string.

      + +
      + +
      
      +
      +
      +  
      +
      +
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +
      +    
      +    
      +    
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/customHighlighterCursorTrendline.html b/wqflask/wqflask/static/packages/jqplot/examples/customHighlighterCursorTrendline.html new file mode 100644 index 00000000..d5ed6ce4 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/customHighlighterCursorTrendline.html @@ -0,0 +1,104 @@ + + + + + + Highlighting, Dragging Points, Cursor and Trend Lines. + + + + + + + + + + + + + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/dashboardWidget.html b/wqflask/wqflask/static/packages/jqplot/examples/dashboardWidget.html new file mode 100644 index 00000000..d57f1de3 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/dashboardWidget.html @@ -0,0 +1,212 @@ + + + + + + Animated Dashboard Sample - Filled Line with Log Axis + + + + + + + + + + + + + +
      + + + + + + + + + +
      +
      Hi Powered Data
      +
      +
      +
      +
      + +
      
      +
      +    
      +
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +    
      +    
      +    
      +    
      +    
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/dashedLines.html b/wqflask/wqflask/static/packages/jqplot/examples/dashedLines.html new file mode 100644 index 00000000..d1bf48fb --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/dashedLines.html @@ -0,0 +1,227 @@ + + + + + + Dashed Lines with Smoothing + + + + + + + + + + + + + +
      + + + + + + + + + +
      + +
      + +
      + +
      + +
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/data-renderers.html b/wqflask/wqflask/static/packages/jqplot/examples/data-renderers.html new file mode 100644 index 00000000..ba835d58 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/data-renderers.html @@ -0,0 +1,144 @@ + + + + + + AJAX and JSON Data Loading via Data Renderers + + + + + + + + + + + + + +
      + + + + + + +

      Data renderers allow jqPlot to pull data from any external source (e.g. a function implementing an AJAX call). Simply assign the external source to the "dataRenderer" plot option. The only requirement on data renderers is that it must return a valid jqPlot data array.

      + +
      + +
      
      +
      +
      +

      Data renderers get passed options by the plot. The signiture for a data renderer is:

      + + +
      +function(userData, plotObject, options) {
      +  ...
      +  return data;
      +}
      +
      + + +

      Where userData is whatever data was passed into the plot, plotObject is a reference back to the plot itself, and options are any options passed into the plots "dataRendererOption" option. The following example shows a more complicated example which uses ajax pulls data from an external json data source.

      + +
      + +
      
      +
      +
      +
      +
      +  
      +
      +
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +
      +    
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/date-axes.html b/wqflask/wqflask/static/packages/jqplot/examples/date-axes.html new file mode 100644 index 00000000..4fa3f620 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/date-axes.html @@ -0,0 +1,107 @@ + + + + + + Date Axes + + + + + + + + + + + + + +
      + + + + + +

      Date axes support is provided through the dateAxisRenderer plugin. Date axes expand javascripts native date handling capabilities. This allow dates to be input in almost any unambiguous form, not just in milliseconds!

      + +

      Note, although jqPlot will parse most any human readable date, it is safest to use javascript time stamps when possible. Also, it is best to specify a date and time and not just a date alone. This is due to inconsistent browser handling of local time vs. UTC with bare dates.

      + +
      + +
      
      +
      +

      Date Axes also provide powerful formatting features. This allows custom formatter strings to be used to format axis tick labels precisely the way you want.

      + +
      + +
      
      +  
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +
      +    
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/dateAxisLogAxisZooming.html b/wqflask/wqflask/static/packages/jqplot/examples/dateAxisLogAxisZooming.html new file mode 100644 index 00000000..81f0f1c7 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/dateAxisLogAxisZooming.html @@ -0,0 +1,101 @@ + + + + + + Zooming with Date and Log Axes + + + + + + + + + + + + + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/dateAxisRenderer.html b/wqflask/wqflask/static/packages/jqplot/examples/dateAxisRenderer.html new file mode 100644 index 00000000..b0b72fba --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/dateAxisRenderer.html @@ -0,0 +1,292 @@ + + + + + + Date Axes + + + + + + + + + + + + + +
      + + + + + + +

      Date axis renderer with default settings. Ticks are given wider spacing by default since date axes typically have longer tick labels.

      +
      +

      Date axis recognizes rotated tick labels. It will space ticks a little closer when labels are rotated.

      +
      +

      If you want more or less ticks, specify the "numberTicks" options. Date axes will try to produce the desired number of ticks, but may adjust to get a nice interval.

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/example.js b/wqflask/wqflask/static/packages/jqplot/examples/example.js new file mode 100644 index 00000000..ff85cd20 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/example.js @@ -0,0 +1,114 @@ +$(document).ready(function(){ + if (!$.jqplot._noCodeBlock) { + $('script.code').each(function(index) { + if ($('pre.code').eq(index).length ) { + $('pre.code').eq(index).text($(this).html()); + } + else { + // var str = $(this).text(); + // $('div.jqplot-target').eq(index).after($('
      '+str+'
      ')); + var pre = $('
      ');
      +                $('div.jqplot-target').eq(index).after(pre);
      +                pre.text($(this).html());
      +                pre = null;
      +            }
      +        });
      +
      +        $('script.common').each(function(index) {
      +            $('pre.common').eq(index).text($(this).html());
      +        });
      +
      +        var elstr='';
      +        if ($('script.include, link.include').length > 0) {
      +
      +            if ($('pre.include').length == 0) {
      +                var temp = [
      +                    '
      ', + '

      The charts on this page depend on the following files:

      ', + '
      ',
      +                    '
      ' + ]; + + temp = $(temp.join('\n')); + $('div.example-content').append(temp); + temp = null; + } + + + $('script.include').each(function(index) { + if (elstr !== '') { + elstr += '\n'; + } + elstr += ''; + }); + + $('link.include').each(function(index) { + if (elstr !== '') { + elstr += '\n'; + } + elstr += ''; + }) + + $('pre.include').text(elstr); + } + + else { + $('pre.include').remove(); + $('div.include').remove(); + } + } + + if (!$.jqplot.use_excanvas) { + $('div.jqplot-target').each(function(){ + var outerDiv = $(document.createElement('div')); + var header = $(document.createElement('div')); + var div = $(document.createElement('div')); + + outerDiv.append(header); + outerDiv.append(div); + + outerDiv.addClass('jqplot-image-container'); + header.addClass('jqplot-image-container-header'); + div.addClass('jqplot-image-container-content'); + + header.html('Right Click to Save Image As...'); + + var close = $(document.createElement('a')); + close.addClass('jqplot-image-container-close'); + close.html('Close'); + close.attr('href', '#'); + close.click(function() { + $(this).parents('div.jqplot-image-container').hide(500); + }) + header.append(close); + + $(this).after(outerDiv); + outerDiv.hide(); + + outerDiv = header = div = close = null; + + if (!$.jqplot._noToImageButton) { + var btn = $(document.createElement('button')); + btn.text('View Plot Image'); + btn.addClass('jqplot-image-button'); + btn.bind('click', {chart: $(this)}, function(evt) { + var imgelem = evt.data.chart.jqplotToImageElem(); + var div = $(this).nextAll('div.jqplot-image-container').first(); + div.children('div.jqplot-image-container-content').empty(); + div.children('div.jqplot-image-container-content').append(imgelem); + div.show(500); + div = null; + }); + + $(this).after(btn); + btn.after('
      '); + btn = null; + } + }); + } + + SyntaxHighlighter.defaults['toolbar'] = true; + SyntaxHighlighter.all(); + + $(document).unload(function() {$('*').unbind(); }); +}); \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/example.min.js b/wqflask/wqflask/static/packages/jqplot/examples/example.min.js new file mode 100644 index 00000000..132e2295 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/example.min.js @@ -0,0 +1 @@ +$(document).ready(function(){if(!$.jqplot._noCodeBlock){$("script.code").each(function(c){if($("pre.code").eq(c).length){$("pre.code").eq(c).text($(this).html())}else{var d=$('
      ');$("div.jqplot-target").eq(c).after(d);d.text($(this).html());d=null}});$("script.common").each(function(c){$("pre.common").eq(c).text($(this).html())});var b="";if($("script.include, link.include").length>0){if($("pre.include").length==0){var a=['
      ','

      The charts on this page depend on the following files:

      ','
      ',"
      "];a=$(a.join("\n"));$("div.example-content").append(a);a=null}$("script.include").each(function(c){if(b!==""){b+="\n"}b+=' + + + + + +
      + + + + + + + + + +
      + +

      Enter 2 series to fill between:

      + + + + + + + +
      
      +
      +
      +    
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/hiddenPlotsInTabs.html b/wqflask/wqflask/static/packages/jqplot/examples/hiddenPlotsInTabs.html new file mode 100644 index 00000000..1a508baa --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/hiddenPlotsInTabs.html @@ -0,0 +1,225 @@ + + + + + + Hidden Plots + + + + + + + + + + + + + +
      + + + + + + + + +

      This page demonstrates placing plots within jQuery UI widgets. Tab 2 and tab 3 contain plots. Using a combination of alternate sizing specification and the jqplot "replot" method the plots are properly displayed when their containers are shown.

      + +

      The alternate sizing specifications for setting plot height and width are needed because a hidden element (or child of a hidden element) has no size. The first example in tab 2 uses custom "data-height" and "data-width" attributes on the plot target element. The second example uses "width" and "height" properties specified on the options object passed into the $.jqplot() function.

      + +

      The default plot size is 300px wide by 400px high. The default setting can be overridden by specifying different values to the $.jqplot.config.defaultHeight and $.jqplot.config.defaultWidth properties. Height and width values are taken in this order of precedence: +

      + +
        +
      1. The css properties of the plot target if available (not available with display:none;).
      2. +
      3. Options object passed into the $.jqplot() function.
      4. +
      5. Custom data-height and data-width attributes on the plot target.
      6. +
      7. The config defaults.
      8. +
      + +
      + +
      + Tabs 2 and 3 have plots. Since tabs 2 and 3 are initially inactive, their contents (and the plots) are initially hidden. +
      + +
      +

      This plot was in an initially hidden container. It's hieght and width are set by the "data-height" and "data-width" properties of the plot container.

      +
      +
      + +
      +

      This plot is in an initially hidden container. It's height and width are set by the 'height' and 'width' properties of the options object passed into the plot constructor.

      +
      +
      + +
      + +

      In the accordion below, section 2 contains a plot. Sizing plots in hidden accordion sections is very similar to sizing in a tab widget. Because of the default animation on accordions, however, the plot will not draw itself until the entire accordion panel is shown.

      + +
      + +

      Section 1

      +
      + Here is section 1 there is no plot. Section 2 has a plot that will display once the section is completely shown. +
      + +

      Section 2

      +
      +

      + This plot also has it's height and width set with the data-height and data-width attributes. Note, if you want the accordion widget to properly size itself before the plot is shown, you must also specify a css height and width on the plot target. +

      +
      +
      + +
      + +

      Code for generating the plots follows. It is critical to bind the callback to the UI widgets "show" or "change" method which calls the plots "replot" method. Without this, the plot won't properly redraw itself when it's container becomes visible.

      + +

      + Note in the ui.index and plot._drawCount properties in the tabsshow callback. ui.index gives the index of the activated tab. plot._drawCount keeps track of how many times the plot was visibly drawn (or redrawn/replotted). Generally, replot only needs to be called the first time the plot is visibly drawn, hence the check for plot._drawCount === 0. +

      + +
      
      +
      + 
      +
      +
      +
      +
      +
      +
      +    
      +    
      +    
      +    
      +
      +
      +
      +  
      +  
      +  
      +  
      +   
      +  
      +
      +
      +
      +
      +	
      + + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/images/logo.jpg b/wqflask/wqflask/static/packages/jqplot/examples/images/logo.jpg new file mode 100644 index 00000000..a12fffcd Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/images/logo.jpg differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/images/ui-colorpicker.png b/wqflask/wqflask/static/packages/jqplot/examples/images/ui-colorpicker.png new file mode 100644 index 00000000..e244c689 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/images/ui-colorpicker.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/index.html b/wqflask/wqflask/static/packages/jqplot/examples/index.html new file mode 100644 index 00000000..2947604a --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/index.html @@ -0,0 +1,108 @@ + + + + + + jqPlot Sample Charts + + + + + + + + + + + + + + + + + + + + + +
      + + + + + diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 00000000..5b5dab2a Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 00000000..ac8b229a Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 00000000..ad3d6346 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 00000000..42ccba26 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 00000000..5a46b47c Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 00000000..86c2baa6 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 00000000..4443fdc1 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 00000000..7c9fa6c6 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png new file mode 100644 index 00000000..b273ff11 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_222222_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 00000000..09d1cdc8 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_2e83ff_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png new file mode 100644 index 00000000..59bd45b9 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_454545_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png new file mode 100644 index 00000000..6d02426c Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_888888_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 00000000..2ab019b7 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/images/ui-icons_cd0a0a_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.css new file mode 100644 index 00000000..0f1a7e77 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.css @@ -0,0 +1,568 @@ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* + * jQuery UI Resizable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.16 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.min.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.min.css new file mode 100644 index 00000000..08821f53 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/smoothness/jquery-ui.min.css @@ -0,0 +1 @@ +.ui-helper-hidden{display:none;}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none;}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.ui-helper-clearfix{display:inline-block;}/* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix{height:1%;}.ui-helper-clearfix{display:block;}/* end clearfix */ .ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0);}.ui-state-disabled{cursor:default!important;}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%;}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em;}.ui-widget .ui-widget{font-size:1em;}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em;}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222;}.ui-widget-content a{color:#222;}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold;}.ui-widget-header a{color:#222;}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555;}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none;}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-hover a,.ui-state-hover a:hover{color:#212121;text-decoration:none;}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none;}.ui-widget :active{outline:none;}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636;}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636;}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a;}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a;}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a;}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold;}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal;}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none;}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png);}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png);}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png);}.ui-icon-carat-1-n{background-position:0 0;}.ui-icon-carat-1-ne{background-position:-16px 0;}.ui-icon-carat-1-e{background-position:-32px 0;}.ui-icon-carat-1-se{background-position:-48px 0;}.ui-icon-carat-1-s{background-position:-64px 0;}.ui-icon-carat-1-sw{background-position:-80px 0;}.ui-icon-carat-1-w{background-position:-96px 0;}.ui-icon-carat-1-nw{background-position:-112px 0;}.ui-icon-carat-2-n-s{background-position:-128px 0;}.ui-icon-carat-2-e-w{background-position:-144px 0;}.ui-icon-triangle-1-n{background-position:0 -16px;}.ui-icon-triangle-1-ne{background-position:-16px -16px;}.ui-icon-triangle-1-e{background-position:-32px -16px;}.ui-icon-triangle-1-se{background-position:-48px -16px;}.ui-icon-triangle-1-s{background-position:-64px -16px;}.ui-icon-triangle-1-sw{background-position:-80px -16px;}.ui-icon-triangle-1-w{background-position:-96px -16px;}.ui-icon-triangle-1-nw{background-position:-112px -16px;}.ui-icon-triangle-2-n-s{background-position:-128px -16px;}.ui-icon-triangle-2-e-w{background-position:-144px -16px;}.ui-icon-arrow-1-n{background-position:0 -32px;}.ui-icon-arrow-1-ne{background-position:-16px -32px;}.ui-icon-arrow-1-e{background-position:-32px -32px;}.ui-icon-arrow-1-se{background-position:-48px -32px;}.ui-icon-arrow-1-s{background-position:-64px -32px;}.ui-icon-arrow-1-sw{background-position:-80px -32px;}.ui-icon-arrow-1-w{background-position:-96px -32px;}.ui-icon-arrow-1-nw{background-position:-112px -32px;}.ui-icon-arrow-2-n-s{background-position:-128px -32px;}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px;}.ui-icon-arrow-2-e-w{background-position:-160px -32px;}.ui-icon-arrow-2-se-nw{background-position:-176px -32px;}.ui-icon-arrowstop-1-n{background-position:-192px -32px;}.ui-icon-arrowstop-1-e{background-position:-208px -32px;}.ui-icon-arrowstop-1-s{background-position:-224px -32px;}.ui-icon-arrowstop-1-w{background-position:-240px -32px;}.ui-icon-arrowthick-1-n{background-position:0 -48px;}.ui-icon-arrowthick-1-ne{background-position:-16px -48px;}.ui-icon-arrowthick-1-e{background-position:-32px -48px;}.ui-icon-arrowthick-1-se{background-position:-48px -48px;}.ui-icon-arrowthick-1-s{background-position:-64px -48px;}.ui-icon-arrowthick-1-sw{background-position:-80px -48px;}.ui-icon-arrowthick-1-w{background-position:-96px -48px;}.ui-icon-arrowthick-1-nw{background-position:-112px -48px;}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px;}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px;}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px;}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px;}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px;}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px;}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px;}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px;}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px;}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px;}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px;}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px;}.ui-icon-arrowreturn-1-w{background-position:-64px -64px;}.ui-icon-arrowreturn-1-n{background-position:-80px -64px;}.ui-icon-arrowreturn-1-e{background-position:-96px -64px;}.ui-icon-arrowreturn-1-s{background-position:-112px -64px;}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px;}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px;}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px;}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px;}.ui-icon-arrow-4{background-position:0 -80px;}.ui-icon-arrow-4-diag{background-position:-16px -80px;}.ui-icon-extlink{background-position:-32px -80px;}.ui-icon-newwin{background-position:-48px -80px;}.ui-icon-refresh{background-position:-64px -80px;}.ui-icon-shuffle{background-position:-80px -80px;}.ui-icon-transfer-e-w{background-position:-96px -80px;}.ui-icon-transferthick-e-w{background-position:-112px -80px;}.ui-icon-folder-collapsed{background-position:0 -96px;}.ui-icon-folder-open{background-position:-16px -96px;}.ui-icon-document{background-position:-32px -96px;}.ui-icon-document-b{background-position:-48px -96px;}.ui-icon-note{background-position:-64px -96px;}.ui-icon-mail-closed{background-position:-80px -96px;}.ui-icon-mail-open{background-position:-96px -96px;}.ui-icon-suitcase{background-position:-112px -96px;}.ui-icon-comment{background-position:-128px -96px;}.ui-icon-person{background-position:-144px -96px;}.ui-icon-print{background-position:-160px -96px;}.ui-icon-trash{background-position:-176px -96px;}.ui-icon-locked{background-position:-192px -96px;}.ui-icon-unlocked{background-position:-208px -96px;}.ui-icon-bookmark{background-position:-224px -96px;}.ui-icon-tag{background-position:-240px -96px;}.ui-icon-home{background-position:0 -112px;}.ui-icon-flag{background-position:-16px -112px;}.ui-icon-calendar{background-position:-32px -112px;}.ui-icon-cart{background-position:-48px -112px;}.ui-icon-pencil{background-position:-64px -112px;}.ui-icon-clock{background-position:-80px -112px;}.ui-icon-disk{background-position:-96px -112px;}.ui-icon-calculator{background-position:-112px -112px;}.ui-icon-zoomin{background-position:-128px -112px;}.ui-icon-zoomout{background-position:-144px -112px;}.ui-icon-search{background-position:-160px -112px;}.ui-icon-wrench{background-position:-176px -112px;}.ui-icon-gear{background-position:-192px -112px;}.ui-icon-heart{background-position:-208px -112px;}.ui-icon-star{background-position:-224px -112px;}.ui-icon-link{background-position:-240px -112px;}.ui-icon-cancel{background-position:0 -128px;}.ui-icon-plus{background-position:-16px -128px;}.ui-icon-plusthick{background-position:-32px -128px;}.ui-icon-minus{background-position:-48px -128px;}.ui-icon-minusthick{background-position:-64px -128px;}.ui-icon-close{background-position:-80px -128px;}.ui-icon-closethick{background-position:-96px -128px;}.ui-icon-key{background-position:-112px -128px;}.ui-icon-lightbulb{background-position:-128px -128px;}.ui-icon-scissors{background-position:-144px -128px;}.ui-icon-clipboard{background-position:-160px -128px;}.ui-icon-copy{background-position:-176px -128px;}.ui-icon-contact{background-position:-192px -128px;}.ui-icon-image{background-position:-208px -128px;}.ui-icon-video{background-position:-224px -128px;}.ui-icon-script{background-position:-240px -128px;}.ui-icon-alert{background-position:0 -144px;}.ui-icon-info{background-position:-16px -144px;}.ui-icon-notice{background-position:-32px -144px;}.ui-icon-help{background-position:-48px -144px;}.ui-icon-check{background-position:-64px -144px;}.ui-icon-bullet{background-position:-80px -144px;}.ui-icon-radio-off{background-position:-96px -144px;}.ui-icon-radio-on{background-position:-112px -144px;}.ui-icon-pin-w{background-position:-128px -144px;}.ui-icon-pin-s{background-position:-144px -144px;}.ui-icon-play{background-position:0 -160px;}.ui-icon-pause{background-position:-16px -160px;}.ui-icon-seek-next{background-position:-32px -160px;}.ui-icon-seek-prev{background-position:-48px -160px;}.ui-icon-seek-end{background-position:-64px -160px;}.ui-icon-seek-start{background-position:-80px -160px;}.ui-icon-seek-first{background-position:-80px -160px;}.ui-icon-stop{background-position:-96px -160px;}.ui-icon-eject{background-position:-112px -160px;}.ui-icon-volume-off{background-position:-128px -160px;}.ui-icon-volume-on{background-position:-144px -160px;}.ui-icon-power{background-position:0 -176px;}.ui-icon-signal-diag{background-position:-16px -176px;}.ui-icon-signal{background-position:-32px -176px;}.ui-icon-battery-0{background-position:-48px -176px;}.ui-icon-battery-1{background-position:-64px -176px;}.ui-icon-battery-2{background-position:-80px -176px;}.ui-icon-battery-3{background-position:-96px -176px;}.ui-icon-circle-plus{background-position:0 -192px;}.ui-icon-circle-minus{background-position:-16px -192px;}.ui-icon-circle-close{background-position:-32px -192px;}.ui-icon-circle-triangle-e{background-position:-48px -192px;}.ui-icon-circle-triangle-s{background-position:-64px -192px;}.ui-icon-circle-triangle-w{background-position:-80px -192px;}.ui-icon-circle-triangle-n{background-position:-96px -192px;}.ui-icon-circle-arrow-e{background-position:-112px -192px;}.ui-icon-circle-arrow-s{background-position:-128px -192px;}.ui-icon-circle-arrow-w{background-position:-144px -192px;}.ui-icon-circle-arrow-n{background-position:-160px -192px;}.ui-icon-circle-zoomin{background-position:-176px -192px;}.ui-icon-circle-zoomout{background-position:-192px -192px;}.ui-icon-circle-check{background-position:-208px -192px;}.ui-icon-circlesmall-plus{background-position:0 -208px;}.ui-icon-circlesmall-minus{background-position:-16px -208px;}.ui-icon-circlesmall-close{background-position:-32px -208px;}.ui-icon-squaresmall-plus{background-position:-48px -208px;}.ui-icon-squaresmall-minus{background-position:-64px -208px;}.ui-icon-squaresmall-close{background-position:-80px -208px;}.ui-icon-grip-dotted-vertical{background-position:0 -224px;}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px;}.ui-icon-grip-solid-vertical{background-position:-32px -224px;}.ui-icon-grip-solid-horizontal{background-position:-48px -224px;}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px;}.ui-icon-grip-diagonal-se{background-position:-80px -224px;}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px;}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.30;filter:Alpha(Opacity=30);}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.30;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;}.ui-resizable{position:relative;}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block;}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none;}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0;}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0;}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%;}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%;}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px;}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px;}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px;}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px;}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black;}.ui-accordion{width:100%;}.ui-accordion .ui-accordion-header{cursor:pointer;position:relative;margin-top:1px;zoom:1;}.ui-accordion .ui-accordion-li-fix{display:inline;}.ui-accordion .ui-accordion-header-active{border-bottom:0!important;}.ui-accordion .ui-accordion-header a{display:block;font-size:1em;padding:.5em .5em .5em .7em;}.ui-accordion-icons .ui-accordion-header a{padding-left:2.2em;}.ui-accordion .ui-accordion-header .ui-icon{position:absolute;left:.5em;top:50%;margin-top:-8px;}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;margin-top:-2px;position:relative;top:1px;margin-bottom:2px;overflow:auto;display:none;zoom:1;}.ui-accordion .ui-accordion-content-active{display:block;}.ui-autocomplete{position:absolute;cursor:default;}* html .ui-autocomplete{width:1px;}.ui-menu{list-style:none;padding:2px;margin:0;display:block;float:left;}.ui-menu .ui-menu{margin-top:-3px;}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;float:left;clear:left;width:100%;}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:.2em .4em;line-height:1.5;zoom:1;}.ui-menu .ui-menu-item a.ui-state-hover,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px;}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:visible;}.ui-button-icon-only{width:2.2em;}button.ui-button-icon-only{width:2.4em;}.ui-button-icons-only{width:3.4em;}button.ui-button-icons-only{width:3.7em;}.ui-button .ui-button-text{display:block;line-height:1.4;}.ui-button-text-only .ui-button-text{padding:.4em 1em;}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px;}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em;}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em;}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em;}input.ui-button{padding:.4em 1em;}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px;}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px;}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em;}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-buttonset{margin-right:7px;}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em;}button.ui-button::-moz-focus-inner{border:0;padding:0;}.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden;}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative;}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0;}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px;}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px;}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0;}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1;}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em;}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right;}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer;}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px;}.ui-draggable .ui-dialog-titlebar{cursor:move;}.ui-slider{position:relative;text-align:left;}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0;}.ui-slider-horizontal{height:.8em;}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em;}.ui-slider-horizontal .ui-slider-range{top:0;height:100%;}.ui-slider-horizontal .ui-slider-range-min{left:0;}.ui-slider-horizontal .ui-slider-range-max{right:0;}.ui-slider-vertical{width:.8em;height:100px;}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em;}.ui-slider-vertical .ui-slider-range{left:0;width:100%;}.ui-slider-vertical .ui-slider-range-min{bottom:0;}.ui-slider-vertical .ui-slider-range-max{top:0;}.ui-tabs{position:relative;padding:.2em;zoom:1;}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0;}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:1px;margin:0 .2em 1px 0;border-bottom:0!important;padding:0;white-space:nowrap;}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none;}.ui-tabs .ui-tabs-nav li.ui-tabs-selected{margin-bottom:0;padding-bottom:1px;}.ui-tabs .ui-tabs-nav li.ui-tabs-selected a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-state-processing a{cursor:text;}.ui-tabs .ui-tabs-nav li a,.ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a{cursor:pointer;}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none;}.ui-tabs .ui-tabs-hide{display:none!important;}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none;}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0;}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em;}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px;}.ui-datepicker .ui-datepicker-prev{left:2px;}.ui-datepicker .ui-datepicker-next{right:2px;}.ui-datepicker .ui-datepicker-prev-hover{left:1px;}.ui-datepicker .ui-datepicker-next-hover{right:1px;}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px;}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;}.ui-datepicker select.ui-datepicker-month-year{width:100%;}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%;}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em;}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0;}.ui-datepicker td{border:0;padding:1px;}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none;}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0;}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible;}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left;}.ui-datepicker.ui-datepicker-multi{width:auto;}.ui-datepicker-multi .ui-datepicker-group{float:left;}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em;}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%;}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%;}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%;}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left;}.ui-datepicker-row-break{clear:both;width:100%;font-size:0;}.ui-datepicker-rtl{direction:rtl;}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto;}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto;}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right;}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left;}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right;}.ui-datepicker-rtl .ui-datepicker-group{float:right;}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-cover{display:none;display:block;position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px;}.ui-progressbar{height:2em;text-align:left;}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%;} \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png new file mode 100644 index 00000000..954e22db Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png new file mode 100644 index 00000000..64ece570 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png new file mode 100644 index 00000000..abdc0108 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png new file mode 100644 index 00000000..9b383f4d Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png new file mode 100644 index 00000000..a23baad2 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 00000000..42ccba26 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png new file mode 100644 index 00000000..39d5824d Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png new file mode 100644 index 00000000..f1273672 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png new file mode 100644 index 00000000..359397ac Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png new file mode 100644 index 00000000..a641a371 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_228ef1_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png new file mode 100644 index 00000000..85e63e9f Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ef8c08_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png new file mode 100644 index 00000000..e117effa Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffd27a_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png new file mode 100644 index 00000000..42f8f992 Binary files /dev/null and b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/images/ui-icons_ffffff_256x240.png differ diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.css new file mode 100644 index 00000000..cd66d537 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.css @@ -0,0 +1,612 @@ +/* + * jQuery UI CSS Framework 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +/* + * jQuery UI Accordion 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-heading { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-heading { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ +/* + * jQuery UI Button 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Datepicker 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Dialog 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Menu 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu li.ui-state-disabled { font-weight: normal; padding: .0em .4em; margin: .4em 0 .2em; line-height: 1.5; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } +/* + * jQuery UI Menubar 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ +.ui-menubar { list-style: none; margin: 0; padding-left: 0; } + +.ui-menubar-item { float: left; } + +.ui-menubar .ui-button { float: left; font-weight: normal; border-top-width: 0 !important; border-bottom-width: 0 !important; margin: 0; outline: none; } +.ui-menubar .ui-menubar-link { border-right: 1px dashed transparent; border-left: 1px dashed transparent; } + +.ui-menubar .ui-menu { width: 200px; position: absolute; z-index: 9999; } +/* + * jQuery UI Progressbar 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* + * jQuery UI Resizable 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Slider 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Spinner 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Spinner#theming + */ +.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; z-index: 100; text-align: center; vertical-align: middle; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +span.ui-spinner { background: none; } +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} +/* + * jQuery UI Tabs 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +/* + * jQuery UI Tooltip 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tooltip#theming + */ +.ui-tooltip { + padding:8px; + position:absolute; + z-index:9999; + -o-box-shadow: 0 0 5px #aaa; + -moz-box-shadow: 0 0 5px #aaa; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width:2px; } +/* + * jQuery UI CSS Framework 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/ + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1.1em/*{fsDefault}*/; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif/*{ffDefault}*/; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ url(images/ui-bg_flat_75_ffffff_40x100.png)/*{bgImgUrlContent}*/ 50%/*{bgContentXPos}*/ 50%/*{bgContentYPos}*/ repeat-x/*{bgContentRepeat}*/; color: #222222/*{fcContent}*/; } +.ui-widget-content a { color: #222222/*{fcContent}*/; } +.ui-widget-header { border: 1px solid #aaaaaa/*{borderColorHeader}*/; background: #cccccc/*{bgColorHeader}*/ url(images/ui-bg_highlight-soft_75_cccccc_1x100.png)/*{bgImgUrlHeader}*/ 50%/*{bgHeaderXPos}*/ 50%/*{bgHeaderYPos}*/ repeat-x/*{bgHeaderRepeat}*/; color: #222222/*{fcHeader}*/; font-weight: bold; } +.ui-widget-header a { color: #222222/*{fcHeader}*/; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3/*{borderColorDefault}*/; background: #e6e6e6/*{bgColorDefault}*/ url(images/ui-bg_glass_75_e6e6e6_1x400.png)/*{bgImgUrlDefault}*/ 50%/*{bgDefaultXPos}*/ 50%/*{bgDefaultYPos}*/ repeat-x/*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #555555/*{fcDefault}*/; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555/*{fcDefault}*/; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999/*{borderColorHover}*/; background: #dadada/*{bgColorHover}*/ url(images/ui-bg_glass_75_dadada_1x400.png)/*{bgImgUrlHover}*/ 50%/*{bgHoverXPos}*/ 50%/*{bgHoverYPos}*/ repeat-x/*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcHover}*/; } +.ui-state-hover a, .ui-state-hover a:hover { color: #212121/*{fcHover}*/; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa/*{borderColorActive}*/; background: #ffffff/*{bgColorActive}*/ url(images/ui-bg_glass_65_ffffff_1x400.png)/*{bgImgUrlActive}*/ 50%/*{bgActiveXPos}*/ 50%/*{bgActiveYPos}*/ repeat-x/*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #212121/*{fcActive}*/; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121/*{fcActive}*/; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1/*{borderColorHighlight}*/; background: #fbf9ee/*{bgColorHighlight}*/ url(images/ui-bg_glass_55_fbf9ee_1x400.png)/*{bgImgUrlHighlight}*/ 50%/*{bgHighlightXPos}*/ 50%/*{bgHighlightYPos}*/ repeat-x/*{bgHighlightRepeat}*/; color: #363636/*{fcHighlight}*/; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636/*{fcHighlight}*/; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a/*{borderColorError}*/; background: #fef1ec/*{bgColorError}*/ url(images/ui-bg_glass_95_fef1ec_1x400.png)/*{bgImgUrlError}*/ 50%/*{bgErrorXPos}*/ 50%/*{bgErrorYPos}*/ repeat-x/*{bgErrorRepeat}*/; color: #cd0a0a/*{fcError}*/; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a/*{fcError}*/; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a/*{fcError}*/; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsContent}*/; } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png)/*{iconsHeader}*/; } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png)/*{iconsDefault}*/; } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsHover}*/; } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png)/*{iconsActive}*/; } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png)/*{iconsHighlight}*/; } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png)/*{iconsError}*/; } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px/*{cornerRadius}*/; -webkit-border-top-left-radius: 4px/*{cornerRadius}*/; -khtml-border-top-left-radius: 4px/*{cornerRadius}*/; border-top-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px/*{cornerRadius}*/; -webkit-border-top-right-radius: 4px/*{cornerRadius}*/; -khtml-border-top-right-radius: 4px/*{cornerRadius}*/; border-top-right-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px/*{cornerRadius}*/; -webkit-border-bottom-left-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-left-radius: 4px/*{cornerRadius}*/; border-bottom-left-radius: 4px/*{cornerRadius}*/; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px/*{cornerRadius}*/; -webkit-border-bottom-right-radius: 4px/*{cornerRadius}*/; -khtml-border-bottom-right-radius: 4px/*{cornerRadius}*/; border-bottom-right-radius: 4px/*{cornerRadius}*/; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlOverlay}*/ 50%/*{bgOverlayXPos}*/ 50%/*{bgOverlayYPos}*/ repeat-x/*{bgOverlayRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityOverlay}*/; } +.ui-widget-shadow { margin: -8px/*{offsetTopShadow}*/ 0 0 -8px/*{offsetLeftShadow}*/; padding: 8px/*{thicknessShadow}*/; background: #aaaaaa/*{bgColorShadow}*/ url(images/ui-bg_flat_0_aaaaaa_40x100.png)/*{bgImgUrlShadow}*/ 50%/*{bgShadowXPos}*/ 50%/*{bgShadowYPos}*/ repeat-x/*{bgShadowRepeat}*/; opacity: .3;filter:Alpha(Opacity=30)/*{opacityShadow}*/; -moz-border-radius: 8px/*{cornerRadiusShadow}*/; -khtml-border-radius: 8px/*{cornerRadiusShadow}*/; -webkit-border-radius: 8px/*{cornerRadiusShadow}*/; border-radius: 8px/*{cornerRadiusShadow}*/; } \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.min.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.min.css new file mode 100644 index 00000000..56a9be11 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui-1.9pre.min.css @@ -0,0 +1,10 @@ +/* + * jQuery UI CSS Framework 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ +.ui-helper-hidden{display:none;}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none;}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.ui-helper-clearfix{display:inline-block;}/* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix{height:1%;}.ui-helper-clearfix{display:block;}/* end clearfix */ .ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0);}.ui-state-disabled{cursor:default!important;}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%;}.ui-accordion{width:100%;}.ui-accordion .ui-accordion-header{cursor:pointer;position:relative;margin-top:1px;zoom:1;}.ui-accordion .ui-accordion-header-active{border-bottom:0!important;}.ui-accordion .ui-accordion-heading{display:block;font-size:1em;padding:.5em .5em .5em .7em;}.ui-accordion-icons .ui-accordion-heading{padding-left:2.2em;}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px;}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;margin-top:-2px;position:relative;top:1px;margin-bottom:2px;overflow:auto;display:none;zoom:1;}.ui-accordion .ui-accordion-content-active{display:block;}.ui-autocomplete{position:absolute;cursor:default;}* html .ui-autocomplete{width:1px;}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:visible;}.ui-button-icon-only{width:2.2em;}button.ui-button-icon-only{width:2.4em;}.ui-button-icons-only{width:3.4em;}button.ui-button-icons-only{width:3.7em;}.ui-button .ui-button-text{display:block;line-height:1.4;}.ui-button-text-only .ui-button-text{padding:.4em 1em;}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px;}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em;}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em;}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em;}input.ui-button{padding:.4em 1em;}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px;}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px;}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em;}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-buttonset{margin-right:7px;}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em;}button.ui-button::-moz-focus-inner{border:0;padding:0;}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none;}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0;}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em;}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px;}.ui-datepicker .ui-datepicker-prev{left:2px;}.ui-datepicker .ui-datepicker-next{right:2px;}.ui-datepicker .ui-datepicker-prev-hover{left:1px;}.ui-datepicker .ui-datepicker-next-hover{right:1px;}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px;}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;}.ui-datepicker select.ui-datepicker-month-year{width:100%;}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%;}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em;}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0;}.ui-datepicker td{border:0;padding:1px;}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none;}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0;}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible;}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left;}.ui-datepicker.ui-datepicker-multi{width:auto;}.ui-datepicker-multi .ui-datepicker-group{float:left;}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em;}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%;}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%;}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%;}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left;}.ui-datepicker-row-break{clear:both;width:100%;font-size:0;}.ui-datepicker-rtl{direction:rtl;}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto;}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto;}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right;}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left;}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right;}.ui-datepicker-rtl .ui-datepicker-group{float:right;}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-cover{display:none;display:block;position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px;}.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden;}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative;}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0;}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px;}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px;}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0;}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1;}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em;}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right;}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer;}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px;}.ui-draggable .ui-dialog-titlebar{cursor:move;}.ui-menu{list-style:none;padding:2px;margin:0;display:block;outline:none;}.ui-menu .ui-menu{margin-top:-3px;position:absolute;}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;width:100%;}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:2px .4em;line-height:1.5;zoom:1;font-weight:normal;}.ui-menu .ui-menu-item a.ui-state-focus,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px;}.ui-menu li.ui-state-disabled{font-weight:normal;padding:.0em .4em;margin:.4em 0 .2em;line-height:1.5;}.ui-menu-icons{position:relative;}.ui-menu-icons .ui-menu-item a{position:relative;padding-left:2em;}.ui-menu .ui-icon{position:absolute;top:.2em;left:.2em;}.ui-menu .ui-menu-icon{position:static;float:right;}.ui-menubar{list-style:none;margin:0;padding-left:0;}.ui-menubar-item{float:left;}.ui-menubar .ui-button{float:left;font-weight:normal;border-top-width:0!important;border-bottom-width:0!important;margin:0;outline:none;}.ui-menubar .ui-menubar-link{border-right:1px dashed transparent;border-left:1px dashed transparent;}.ui-menubar .ui-menu{width:200px;position:absolute;z-index:9999;}.ui-progressbar{height:2em;text-align:left;overflow:hidden;}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%;}.ui-resizable{position:relative;}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block;}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none;}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0;}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0;}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%;}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%;}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px;}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px;}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px;}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px;}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black;}.ui-slider{position:relative;text-align:left;}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0;}.ui-slider-horizontal{height:.8em;}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em;}.ui-slider-horizontal .ui-slider-range{top:0;height:100%;}.ui-slider-horizontal .ui-slider-range-min{left:0;}.ui-slider-horizontal .ui-slider-range-max{right:0;}.ui-slider-vertical{width:.8em;height:100px;}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em;}.ui-slider-vertical .ui-slider-range{left:0;width:100%;}.ui-slider-vertical .ui-slider-range-min{bottom:0;}.ui-slider-vertical .ui-slider-range-max{top:0;}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle;}.ui-spinner-input{border:none;background:none;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px;}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;z-index:100;text-align:center;vertical-align:middle;position:absolute;cursor:default;display:block;overflow:hidden;right:0;}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none;}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0;}.ui-spinner-up{top:0;}.ui-spinner-down{bottom:0;}span.ui-spinner{background:none;}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px;}.ui-tabs{position:relative;padding:.2em;zoom:1;}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0;}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom:0!important;padding:0;white-space:nowrap;}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none;}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px;}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text;}.ui-tabs .ui-tabs-nav li a,.ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer;}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none;}.ui-tooltip{padding:8px;position:absolute;z-index:9999;-o-box-shadow:0 0 5px #aaa;-moz-box-shadow:0 0 5px #aaa;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa;}* html .ui-tooltip{background-image:none;}body .ui-tooltip{border-width:2px;}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em;}.ui-widget .ui-widget{font-size:1em;}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em;}.ui-widget-content{border:1px solid #aaa;background:#fff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x;color:#222;}.ui-widget-content a{color:#222;}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:bold;}.ui-widget-header a{color:#222;}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#555;}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none;}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-hover a,.ui-state-hover a:hover{color:#212121;text-decoration:none;}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:normal;color:#212121;}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none;}.ui-widget :active{outline:none;}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636;}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636;}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a;}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a;}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a;}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold;}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal;}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none;}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png);}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png);}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png);}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png);}.ui-icon-carat-1-n{background-position:0 0;}.ui-icon-carat-1-ne{background-position:-16px 0;}.ui-icon-carat-1-e{background-position:-32px 0;}.ui-icon-carat-1-se{background-position:-48px 0;}.ui-icon-carat-1-s{background-position:-64px 0;}.ui-icon-carat-1-sw{background-position:-80px 0;}.ui-icon-carat-1-w{background-position:-96px 0;}.ui-icon-carat-1-nw{background-position:-112px 0;}.ui-icon-carat-2-n-s{background-position:-128px 0;}.ui-icon-carat-2-e-w{background-position:-144px 0;}.ui-icon-triangle-1-n{background-position:0 -16px;}.ui-icon-triangle-1-ne{background-position:-16px -16px;}.ui-icon-triangle-1-e{background-position:-32px -16px;}.ui-icon-triangle-1-se{background-position:-48px -16px;}.ui-icon-triangle-1-s{background-position:-64px -16px;}.ui-icon-triangle-1-sw{background-position:-80px -16px;}.ui-icon-triangle-1-w{background-position:-96px -16px;}.ui-icon-triangle-1-nw{background-position:-112px -16px;}.ui-icon-triangle-2-n-s{background-position:-128px -16px;}.ui-icon-triangle-2-e-w{background-position:-144px -16px;}.ui-icon-arrow-1-n{background-position:0 -32px;}.ui-icon-arrow-1-ne{background-position:-16px -32px;}.ui-icon-arrow-1-e{background-position:-32px -32px;}.ui-icon-arrow-1-se{background-position:-48px -32px;}.ui-icon-arrow-1-s{background-position:-64px -32px;}.ui-icon-arrow-1-sw{background-position:-80px -32px;}.ui-icon-arrow-1-w{background-position:-96px -32px;}.ui-icon-arrow-1-nw{background-position:-112px -32px;}.ui-icon-arrow-2-n-s{background-position:-128px -32px;}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px;}.ui-icon-arrow-2-e-w{background-position:-160px -32px;}.ui-icon-arrow-2-se-nw{background-position:-176px -32px;}.ui-icon-arrowstop-1-n{background-position:-192px -32px;}.ui-icon-arrowstop-1-e{background-position:-208px -32px;}.ui-icon-arrowstop-1-s{background-position:-224px -32px;}.ui-icon-arrowstop-1-w{background-position:-240px -32px;}.ui-icon-arrowthick-1-n{background-position:0 -48px;}.ui-icon-arrowthick-1-ne{background-position:-16px -48px;}.ui-icon-arrowthick-1-e{background-position:-32px -48px;}.ui-icon-arrowthick-1-se{background-position:-48px -48px;}.ui-icon-arrowthick-1-s{background-position:-64px -48px;}.ui-icon-arrowthick-1-sw{background-position:-80px -48px;}.ui-icon-arrowthick-1-w{background-position:-96px -48px;}.ui-icon-arrowthick-1-nw{background-position:-112px -48px;}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px;}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px;}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px;}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px;}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px;}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px;}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px;}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px;}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px;}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px;}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px;}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px;}.ui-icon-arrowreturn-1-w{background-position:-64px -64px;}.ui-icon-arrowreturn-1-n{background-position:-80px -64px;}.ui-icon-arrowreturn-1-e{background-position:-96px -64px;}.ui-icon-arrowreturn-1-s{background-position:-112px -64px;}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px;}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px;}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px;}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px;}.ui-icon-arrow-4{background-position:0 -80px;}.ui-icon-arrow-4-diag{background-position:-16px -80px;}.ui-icon-extlink{background-position:-32px -80px;}.ui-icon-newwin{background-position:-48px -80px;}.ui-icon-refresh{background-position:-64px -80px;}.ui-icon-shuffle{background-position:-80px -80px;}.ui-icon-transfer-e-w{background-position:-96px -80px;}.ui-icon-transferthick-e-w{background-position:-112px -80px;}.ui-icon-folder-collapsed{background-position:0 -96px;}.ui-icon-folder-open{background-position:-16px -96px;}.ui-icon-document{background-position:-32px -96px;}.ui-icon-document-b{background-position:-48px -96px;}.ui-icon-note{background-position:-64px -96px;}.ui-icon-mail-closed{background-position:-80px -96px;}.ui-icon-mail-open{background-position:-96px -96px;}.ui-icon-suitcase{background-position:-112px -96px;}.ui-icon-comment{background-position:-128px -96px;}.ui-icon-person{background-position:-144px -96px;}.ui-icon-print{background-position:-160px -96px;}.ui-icon-trash{background-position:-176px -96px;}.ui-icon-locked{background-position:-192px -96px;}.ui-icon-unlocked{background-position:-208px -96px;}.ui-icon-bookmark{background-position:-224px -96px;}.ui-icon-tag{background-position:-240px -96px;}.ui-icon-home{background-position:0 -112px;}.ui-icon-flag{background-position:-16px -112px;}.ui-icon-calendar{background-position:-32px -112px;}.ui-icon-cart{background-position:-48px -112px;}.ui-icon-pencil{background-position:-64px -112px;}.ui-icon-clock{background-position:-80px -112px;}.ui-icon-disk{background-position:-96px -112px;}.ui-icon-calculator{background-position:-112px -112px;}.ui-icon-zoomin{background-position:-128px -112px;}.ui-icon-zoomout{background-position:-144px -112px;}.ui-icon-search{background-position:-160px -112px;}.ui-icon-wrench{background-position:-176px -112px;}.ui-icon-gear{background-position:-192px -112px;}.ui-icon-heart{background-position:-208px -112px;}.ui-icon-star{background-position:-224px -112px;}.ui-icon-link{background-position:-240px -112px;}.ui-icon-cancel{background-position:0 -128px;}.ui-icon-plus{background-position:-16px -128px;}.ui-icon-plusthick{background-position:-32px -128px;}.ui-icon-minus{background-position:-48px -128px;}.ui-icon-minusthick{background-position:-64px -128px;}.ui-icon-close{background-position:-80px -128px;}.ui-icon-closethick{background-position:-96px -128px;}.ui-icon-key{background-position:-112px -128px;}.ui-icon-lightbulb{background-position:-128px -128px;}.ui-icon-scissors{background-position:-144px -128px;}.ui-icon-clipboard{background-position:-160px -128px;}.ui-icon-copy{background-position:-176px -128px;}.ui-icon-contact{background-position:-192px -128px;}.ui-icon-image{background-position:-208px -128px;}.ui-icon-video{background-position:-224px -128px;}.ui-icon-script{background-position:-240px -128px;}.ui-icon-alert{background-position:0 -144px;}.ui-icon-info{background-position:-16px -144px;}.ui-icon-notice{background-position:-32px -144px;}.ui-icon-help{background-position:-48px -144px;}.ui-icon-check{background-position:-64px -144px;}.ui-icon-bullet{background-position:-80px -144px;}.ui-icon-radio-on{background-position:-96px -144px;}.ui-icon-radio-off{background-position:-112px -144px;}.ui-icon-pin-w{background-position:-128px -144px;}.ui-icon-pin-s{background-position:-144px -144px;}.ui-icon-play{background-position:0 -160px;}.ui-icon-pause{background-position:-16px -160px;}.ui-icon-seek-next{background-position:-32px -160px;}.ui-icon-seek-prev{background-position:-48px -160px;}.ui-icon-seek-end{background-position:-64px -160px;}.ui-icon-seek-start{background-position:-80px -160px;}.ui-icon-seek-first{background-position:-80px -160px;}.ui-icon-stop{background-position:-96px -160px;}.ui-icon-eject{background-position:-112px -160px;}.ui-icon-volume-off{background-position:-128px -160px;}.ui-icon-volume-on{background-position:-144px -160px;}.ui-icon-power{background-position:0 -176px;}.ui-icon-signal-diag{background-position:-16px -176px;}.ui-icon-signal{background-position:-32px -176px;}.ui-icon-battery-0{background-position:-48px -176px;}.ui-icon-battery-1{background-position:-64px -176px;}.ui-icon-battery-2{background-position:-80px -176px;}.ui-icon-battery-3{background-position:-96px -176px;}.ui-icon-circle-plus{background-position:0 -192px;}.ui-icon-circle-minus{background-position:-16px -192px;}.ui-icon-circle-close{background-position:-32px -192px;}.ui-icon-circle-triangle-e{background-position:-48px -192px;}.ui-icon-circle-triangle-s{background-position:-64px -192px;}.ui-icon-circle-triangle-w{background-position:-80px -192px;}.ui-icon-circle-triangle-n{background-position:-96px -192px;}.ui-icon-circle-arrow-e{background-position:-112px -192px;}.ui-icon-circle-arrow-s{background-position:-128px -192px;}.ui-icon-circle-arrow-w{background-position:-144px -192px;}.ui-icon-circle-arrow-n{background-position:-160px -192px;}.ui-icon-circle-zoomin{background-position:-176px -192px;}.ui-icon-circle-zoomout{background-position:-192px -192px;}.ui-icon-circle-check{background-position:-208px -192px;}.ui-icon-circlesmall-plus{background-position:0 -208px;}.ui-icon-circlesmall-minus{background-position:-16px -208px;}.ui-icon-circlesmall-close{background-position:-32px -208px;}.ui-icon-squaresmall-plus{background-position:-48px -208px;}.ui-icon-squaresmall-minus{background-position:-64px -208px;}.ui-icon-squaresmall-close{background-position:-80px -208px;}.ui-icon-grip-dotted-vertical{background-position:0 -224px;}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px;}.ui-icon-grip-solid-vertical{background-position:-32px -224px;}.ui-icon-grip-solid-horizontal{background-position:-48px -224px;}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px;}.ui-icon-grip-diagonal-se{background-position:-80px -224px;}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px;}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30);-moz-border-radius:8px;-khtml-border-radius:8px;-webkit-border-radius:8px;border-radius:8px;} \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.css new file mode 100644 index 00000000..5547c7b9 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.css @@ -0,0 +1,568 @@ +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* + * jQuery UI CSS Framework 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; } +.ui-widget-content a { color: #333333; } +.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; } +.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); } +.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -khtml-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* + * jQuery UI Resizable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizable#theming + */ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectable#theming + */ +.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +/* + * jQuery UI Accordion 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion#theming + */ +/* IE/Win - Fix animation bug - #4615 */ +.ui-accordion { width: 100%; } +.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } +.ui-accordion .ui-accordion-li-fix { display: inline; } +.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } +.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } +.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } +.ui-accordion .ui-accordion-content-active { display: block; } +/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete#theming + */ +.ui-autocomplete { position: absolute; cursor: default; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* + * jQuery UI Menu 1.8.16 + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu#theming + */ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; + float: left; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button#theming + */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog#theming + */ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* + * jQuery UI Slider 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider#theming + */ +.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; } +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker#theming + */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar#theming + */ +.ui-progressbar { height:2em; text-align: left; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.min.css b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.min.css new file mode 100644 index 00000000..78f7d3d0 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/css/ui-lightness/jquery-ui.min.css @@ -0,0 +1 @@ +.ui-helper-hidden{display:none;}.ui-helper-hidden-accessible{position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px);}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none;}.ui-helper-clearfix:after{content:".";display:block;height:0;clear:both;visibility:hidden;}.ui-helper-clearfix{display:inline-block;}/* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix{height:1%;}.ui-helper-clearfix{display:block;}/* end clearfix */ .ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0);}.ui-state-disabled{cursor:default!important;}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;}.ui-widget-overlay{position:absolute;top:0;left:0;width:100%;height:100%;}.ui-widget{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1.1em;}.ui-widget .ui-widget{font-size:1em;}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Trebuchet MS,Tahoma,Verdana,Arial,sans-serif;font-size:1em;}.ui-widget-content{border:1px solid #ddd;background:#eee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x;color:#333;}.ui-widget-content a{color:#333;}.ui-widget-header{border:1px solid #e78f08;background:#f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x;color:#fff;font-weight:bold;}.ui-widget-header a{color:#fff;}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #ccc;background:#f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#1c94c4;}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#1c94c4;text-decoration:none;}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #fbcb09;background:#fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#c77405;}.ui-state-hover a,.ui-state-hover a:hover{color:#c77405;text-decoration:none;}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #fbd850;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:bold;color:#eb8f00;}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#eb8f00;text-decoration:none;}.ui-widget :active{outline:none;}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fed22f;background:#ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x;color:#363636;}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636;}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat;color:#fff;}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff;}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff;}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold;}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal;}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none;}.ui-icon{width:16px;height:16px;background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png);}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_ffffff_256x240.png);}.ui-state-default .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png);}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png);}.ui-state-active .ui-icon{background-image:url(images/ui-icons_ef8c08_256x240.png);}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_228ef1_256x240.png);}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_ffd27a_256x240.png);}.ui-icon-carat-1-n{background-position:0 0;}.ui-icon-carat-1-ne{background-position:-16px 0;}.ui-icon-carat-1-e{background-position:-32px 0;}.ui-icon-carat-1-se{background-position:-48px 0;}.ui-icon-carat-1-s{background-position:-64px 0;}.ui-icon-carat-1-sw{background-position:-80px 0;}.ui-icon-carat-1-w{background-position:-96px 0;}.ui-icon-carat-1-nw{background-position:-112px 0;}.ui-icon-carat-2-n-s{background-position:-128px 0;}.ui-icon-carat-2-e-w{background-position:-144px 0;}.ui-icon-triangle-1-n{background-position:0 -16px;}.ui-icon-triangle-1-ne{background-position:-16px -16px;}.ui-icon-triangle-1-e{background-position:-32px -16px;}.ui-icon-triangle-1-se{background-position:-48px -16px;}.ui-icon-triangle-1-s{background-position:-64px -16px;}.ui-icon-triangle-1-sw{background-position:-80px -16px;}.ui-icon-triangle-1-w{background-position:-96px -16px;}.ui-icon-triangle-1-nw{background-position:-112px -16px;}.ui-icon-triangle-2-n-s{background-position:-128px -16px;}.ui-icon-triangle-2-e-w{background-position:-144px -16px;}.ui-icon-arrow-1-n{background-position:0 -32px;}.ui-icon-arrow-1-ne{background-position:-16px -32px;}.ui-icon-arrow-1-e{background-position:-32px -32px;}.ui-icon-arrow-1-se{background-position:-48px -32px;}.ui-icon-arrow-1-s{background-position:-64px -32px;}.ui-icon-arrow-1-sw{background-position:-80px -32px;}.ui-icon-arrow-1-w{background-position:-96px -32px;}.ui-icon-arrow-1-nw{background-position:-112px -32px;}.ui-icon-arrow-2-n-s{background-position:-128px -32px;}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px;}.ui-icon-arrow-2-e-w{background-position:-160px -32px;}.ui-icon-arrow-2-se-nw{background-position:-176px -32px;}.ui-icon-arrowstop-1-n{background-position:-192px -32px;}.ui-icon-arrowstop-1-e{background-position:-208px -32px;}.ui-icon-arrowstop-1-s{background-position:-224px -32px;}.ui-icon-arrowstop-1-w{background-position:-240px -32px;}.ui-icon-arrowthick-1-n{background-position:0 -48px;}.ui-icon-arrowthick-1-ne{background-position:-16px -48px;}.ui-icon-arrowthick-1-e{background-position:-32px -48px;}.ui-icon-arrowthick-1-se{background-position:-48px -48px;}.ui-icon-arrowthick-1-s{background-position:-64px -48px;}.ui-icon-arrowthick-1-sw{background-position:-80px -48px;}.ui-icon-arrowthick-1-w{background-position:-96px -48px;}.ui-icon-arrowthick-1-nw{background-position:-112px -48px;}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px;}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px;}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px;}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px;}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px;}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px;}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px;}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px;}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px;}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px;}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px;}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px;}.ui-icon-arrowreturn-1-w{background-position:-64px -64px;}.ui-icon-arrowreturn-1-n{background-position:-80px -64px;}.ui-icon-arrowreturn-1-e{background-position:-96px -64px;}.ui-icon-arrowreturn-1-s{background-position:-112px -64px;}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px;}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px;}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px;}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px;}.ui-icon-arrow-4{background-position:0 -80px;}.ui-icon-arrow-4-diag{background-position:-16px -80px;}.ui-icon-extlink{background-position:-32px -80px;}.ui-icon-newwin{background-position:-48px -80px;}.ui-icon-refresh{background-position:-64px -80px;}.ui-icon-shuffle{background-position:-80px -80px;}.ui-icon-transfer-e-w{background-position:-96px -80px;}.ui-icon-transferthick-e-w{background-position:-112px -80px;}.ui-icon-folder-collapsed{background-position:0 -96px;}.ui-icon-folder-open{background-position:-16px -96px;}.ui-icon-document{background-position:-32px -96px;}.ui-icon-document-b{background-position:-48px -96px;}.ui-icon-note{background-position:-64px -96px;}.ui-icon-mail-closed{background-position:-80px -96px;}.ui-icon-mail-open{background-position:-96px -96px;}.ui-icon-suitcase{background-position:-112px -96px;}.ui-icon-comment{background-position:-128px -96px;}.ui-icon-person{background-position:-144px -96px;}.ui-icon-print{background-position:-160px -96px;}.ui-icon-trash{background-position:-176px -96px;}.ui-icon-locked{background-position:-192px -96px;}.ui-icon-unlocked{background-position:-208px -96px;}.ui-icon-bookmark{background-position:-224px -96px;}.ui-icon-tag{background-position:-240px -96px;}.ui-icon-home{background-position:0 -112px;}.ui-icon-flag{background-position:-16px -112px;}.ui-icon-calendar{background-position:-32px -112px;}.ui-icon-cart{background-position:-48px -112px;}.ui-icon-pencil{background-position:-64px -112px;}.ui-icon-clock{background-position:-80px -112px;}.ui-icon-disk{background-position:-96px -112px;}.ui-icon-calculator{background-position:-112px -112px;}.ui-icon-zoomin{background-position:-128px -112px;}.ui-icon-zoomout{background-position:-144px -112px;}.ui-icon-search{background-position:-160px -112px;}.ui-icon-wrench{background-position:-176px -112px;}.ui-icon-gear{background-position:-192px -112px;}.ui-icon-heart{background-position:-208px -112px;}.ui-icon-star{background-position:-224px -112px;}.ui-icon-link{background-position:-240px -112px;}.ui-icon-cancel{background-position:0 -128px;}.ui-icon-plus{background-position:-16px -128px;}.ui-icon-plusthick{background-position:-32px -128px;}.ui-icon-minus{background-position:-48px -128px;}.ui-icon-minusthick{background-position:-64px -128px;}.ui-icon-close{background-position:-80px -128px;}.ui-icon-closethick{background-position:-96px -128px;}.ui-icon-key{background-position:-112px -128px;}.ui-icon-lightbulb{background-position:-128px -128px;}.ui-icon-scissors{background-position:-144px -128px;}.ui-icon-clipboard{background-position:-160px -128px;}.ui-icon-copy{background-position:-176px -128px;}.ui-icon-contact{background-position:-192px -128px;}.ui-icon-image{background-position:-208px -128px;}.ui-icon-video{background-position:-224px -128px;}.ui-icon-script{background-position:-240px -128px;}.ui-icon-alert{background-position:0 -144px;}.ui-icon-info{background-position:-16px -144px;}.ui-icon-notice{background-position:-32px -144px;}.ui-icon-help{background-position:-48px -144px;}.ui-icon-check{background-position:-64px -144px;}.ui-icon-bullet{background-position:-80px -144px;}.ui-icon-radio-off{background-position:-96px -144px;}.ui-icon-radio-on{background-position:-112px -144px;}.ui-icon-pin-w{background-position:-128px -144px;}.ui-icon-pin-s{background-position:-144px -144px;}.ui-icon-play{background-position:0 -160px;}.ui-icon-pause{background-position:-16px -160px;}.ui-icon-seek-next{background-position:-32px -160px;}.ui-icon-seek-prev{background-position:-48px -160px;}.ui-icon-seek-end{background-position:-64px -160px;}.ui-icon-seek-start{background-position:-80px -160px;}.ui-icon-seek-first{background-position:-80px -160px;}.ui-icon-stop{background-position:-96px -160px;}.ui-icon-eject{background-position:-112px -160px;}.ui-icon-volume-off{background-position:-128px -160px;}.ui-icon-volume-on{background-position:-144px -160px;}.ui-icon-power{background-position:0 -176px;}.ui-icon-signal-diag{background-position:-16px -176px;}.ui-icon-signal{background-position:-32px -176px;}.ui-icon-battery-0{background-position:-48px -176px;}.ui-icon-battery-1{background-position:-64px -176px;}.ui-icon-battery-2{background-position:-80px -176px;}.ui-icon-battery-3{background-position:-96px -176px;}.ui-icon-circle-plus{background-position:0 -192px;}.ui-icon-circle-minus{background-position:-16px -192px;}.ui-icon-circle-close{background-position:-32px -192px;}.ui-icon-circle-triangle-e{background-position:-48px -192px;}.ui-icon-circle-triangle-s{background-position:-64px -192px;}.ui-icon-circle-triangle-w{background-position:-80px -192px;}.ui-icon-circle-triangle-n{background-position:-96px -192px;}.ui-icon-circle-arrow-e{background-position:-112px -192px;}.ui-icon-circle-arrow-s{background-position:-128px -192px;}.ui-icon-circle-arrow-w{background-position:-144px -192px;}.ui-icon-circle-arrow-n{background-position:-160px -192px;}.ui-icon-circle-zoomin{background-position:-176px -192px;}.ui-icon-circle-zoomout{background-position:-192px -192px;}.ui-icon-circle-check{background-position:-208px -192px;}.ui-icon-circlesmall-plus{background-position:0 -208px;}.ui-icon-circlesmall-minus{background-position:-16px -208px;}.ui-icon-circlesmall-close{background-position:-32px -208px;}.ui-icon-squaresmall-plus{background-position:-48px -208px;}.ui-icon-squaresmall-minus{background-position:-64px -208px;}.ui-icon-squaresmall-close{background-position:-80px -208px;}.ui-icon-grip-dotted-vertical{background-position:0 -224px;}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px;}.ui-icon-grip-solid-vertical{background-position:-32px -224px;}.ui-icon-grip-solid-horizontal{background-position:-48px -224px;}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px;}.ui-icon-grip-diagonal-se{background-position:-80px -224px;}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{-moz-border-radius-topleft:4px;-webkit-border-top-left-radius:4px;-khtml-border-top-left-radius:4px;border-top-left-radius:4px;}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{-moz-border-radius-topright:4px;-webkit-border-top-right-radius:4px;-khtml-border-top-right-radius:4px;border-top-right-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{-moz-border-radius-bottomleft:4px;-webkit-border-bottom-left-radius:4px;-khtml-border-bottom-left-radius:4px;border-bottom-left-radius:4px;}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{-moz-border-radius-bottomright:4px;-webkit-border-bottom-right-radius:4px;-khtml-border-bottom-right-radius:4px;border-bottom-right-radius:4px;}.ui-widget-overlay{background:#666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat;opacity:.50;filter:Alpha(Opacity=50);}.ui-widget-shadow{margin:-5px 0 0 -5px;padding:5px;background:#000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x;opacity:.20;filter:Alpha(Opacity=20);-moz-border-radius:5px;-khtml-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;}.ui-resizable{position:relative;}.ui-resizable-handle{position:absolute;font-size:.1px;z-index:99999;display:block;}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none;}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0;}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0;}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%;}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%;}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px;}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px;}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px;}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px;}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black;}.ui-accordion{width:100%;}.ui-accordion .ui-accordion-header{cursor:pointer;position:relative;margin-top:1px;zoom:1;}.ui-accordion .ui-accordion-li-fix{display:inline;}.ui-accordion .ui-accordion-header-active{border-bottom:0!important;}.ui-accordion .ui-accordion-header a{display:block;font-size:1em;padding:.5em .5em .5em .7em;}.ui-accordion-icons .ui-accordion-header a{padding-left:2.2em;}.ui-accordion .ui-accordion-header .ui-icon{position:absolute;left:.5em;top:50%;margin-top:-8px;}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;margin-top:-2px;position:relative;top:1px;margin-bottom:2px;overflow:auto;display:none;zoom:1;}.ui-accordion .ui-accordion-content-active{display:block;}.ui-autocomplete{position:absolute;cursor:default;}* html .ui-autocomplete{width:1px;}.ui-menu{list-style:none;padding:2px;margin:0;display:block;float:left;}.ui-menu .ui-menu{margin-top:-3px;}.ui-menu .ui-menu-item{margin:0;padding:0;zoom:1;float:left;clear:left;width:100%;}.ui-menu .ui-menu-item a{text-decoration:none;display:block;padding:.2em .4em;line-height:1.5;zoom:1;}.ui-menu .ui-menu-item a.ui-state-hover,.ui-menu .ui-menu-item a.ui-state-active{font-weight:normal;margin:-1px;}.ui-button{display:inline-block;position:relative;padding:0;margin-right:.1em;text-decoration:none!important;cursor:pointer;text-align:center;zoom:1;overflow:visible;}.ui-button-icon-only{width:2.2em;}button.ui-button-icon-only{width:2.4em;}.ui-button-icons-only{width:3.4em;}button.ui-button-icons-only{width:3.7em;}.ui-button .ui-button-text{display:block;line-height:1.4;}.ui-button-text-only .ui-button-text{padding:.4em 1em;}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px;}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em;}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em;}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em;}input.ui-button{padding:.4em 1em;}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px;}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px;}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em;}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em;}.ui-buttonset{margin-right:7px;}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em;}button.ui-button::-moz-focus-inner{border:0;padding:0;}.ui-dialog{position:absolute;padding:.2em;width:300px;overflow:hidden;}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative;}.ui-dialog .ui-dialog-title{float:left;margin:.1em 16px .1em 0;}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:19px;margin:-10px 0 0 0;padding:1px;height:18px;}.ui-dialog .ui-dialog-titlebar-close span{display:block;margin:1px;}.ui-dialog .ui-dialog-titlebar-close:hover,.ui-dialog .ui-dialog-titlebar-close:focus{padding:0;}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto;zoom:1;}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin:.5em 0 0 0;padding:.3em 1em .5em .4em;}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right;}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer;}.ui-dialog .ui-resizable-se{width:14px;height:14px;right:3px;bottom:3px;}.ui-draggable .ui-dialog-titlebar{cursor:move;}.ui-slider{position:relative;text-align:left;}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0;}.ui-slider-horizontal{height:.8em;}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em;}.ui-slider-horizontal .ui-slider-range{top:0;height:100%;}.ui-slider-horizontal .ui-slider-range-min{left:0;}.ui-slider-horizontal .ui-slider-range-max{right:0;}.ui-slider-vertical{width:.8em;height:100px;}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em;}.ui-slider-vertical .ui-slider-range{left:0;width:100%;}.ui-slider-vertical .ui-slider-range-min{bottom:0;}.ui-slider-vertical .ui-slider-range-max{top:0;}.ui-tabs{position:relative;padding:.2em;zoom:1;}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0;}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:1px;margin:0 .2em 1px 0;border-bottom:0!important;padding:0;white-space:nowrap;}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none;}.ui-tabs .ui-tabs-nav li.ui-tabs-selected{margin-bottom:0;padding-bottom:1px;}.ui-tabs .ui-tabs-nav li.ui-tabs-selected a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-state-processing a{cursor:text;}.ui-tabs .ui-tabs-nav li a,.ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a{cursor:pointer;}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none;}.ui-tabs .ui-tabs-hide{display:none!important;}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none;}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0;}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em;}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px;}.ui-datepicker .ui-datepicker-prev{left:2px;}.ui-datepicker .ui-datepicker-next{right:2px;}.ui-datepicker .ui-datepicker-prev-hover{left:1px;}.ui-datepicker .ui-datepicker-next-hover{right:1px;}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px;}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center;}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0;}.ui-datepicker select.ui-datepicker-month-year{width:100%;}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:49%;}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em;}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0;}.ui-datepicker td{border:0;padding:1px;}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none;}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0;}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible;}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left;}.ui-datepicker.ui-datepicker-multi{width:auto;}.ui-datepicker-multi .ui-datepicker-group{float:left;}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em;}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%;}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%;}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%;}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0;}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left;}.ui-datepicker-row-break{clear:both;width:100%;font-size:0;}.ui-datepicker-rtl{direction:rtl;}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto;}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto;}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto;}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right;}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left;}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current{float:right;}.ui-datepicker-rtl .ui-datepicker-group{float:right;}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px;}.ui-datepicker-cover{display:none;display:block;position:absolute;z-index:-1;filter:mask();top:-4px;left:-4px;width:200px;height:200px;}.ui-progressbar{height:2em;text-align:left;}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%;} \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui-1.9pre.min.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui-1.9pre.min.js new file mode 100644 index 00000000..5ca2642d --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui-1.9pre.min.js @@ -0,0 +1,473 @@ +/*! + * jQuery UI 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(a,g){function d(e,f){var i=e.nodeName.toLowerCase();if("area"===i){i=e.parentNode;var b=i.name;if(!e.href||!b||i.nodeName.toLowerCase()!=="map")return false;i=a("img[usemap=#"+b+"]")[0];return!!i&&c(i)}return(/input|select|textarea|button|object/.test(i)?!e.disabled:"a"==i?e.href||f:f)&&c(e)}function c(e){return!a(e).parents().andSelf().filter(function(){return a.curCSS(this,"visibility")==="hidden"||a.expr.filters.hidden(this)}).length}a.ui=a.ui||{};if(!a.ui.version){a.extend(a.ui,{version:"1.9pre", +keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});a.fn.extend({_focus:a.fn.focus,focus:function(e,f){return typeof e==="number"?this.each(function(){var i=this;setTimeout(function(){a(i).focus(); +f&&f.call(i)},e)}):this._focus.apply(this,arguments)},scrollParent:function(){var e;e=a.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(a.curCSS(this,"position",1))&&/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this,"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(a.curCSS(this,"overflow",1)+a.curCSS(this, +"overflow-y",1)+a.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!e.length?a(document):e},zIndex:function(e){if(e!==g)return this.css("zIndex",e);if(this.length){e=a(this[0]);for(var f;e.length&&e[0]!==document;){f=e.css("position");if(f==="absolute"||f==="relative"||f==="fixed"){f=parseInt(e.css("zIndex"),10);if(!isNaN(f)&&f!==0)return f}e=e.parent()}}return 0},disableSelection:function(){return this.bind((a.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection", +function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});a.each(["Width","Height"],function(e,f){function i(l,j,m,n){a.each(b,function(){j-=parseFloat(a.curCSS(l,"padding"+this,true))||0;if(m)j-=parseFloat(a.curCSS(l,"border"+this+"Width",true))||0;if(n)j-=parseFloat(a.curCSS(l,"margin"+this,true))||0});return j}var b=f==="Width"?["Left","Right"]:["Top","Bottom"],h=f.toLowerCase(),k={innerWidth:a.fn.innerWidth,innerHeight:a.fn.innerHeight,outerWidth:a.fn.outerWidth, +outerHeight:a.fn.outerHeight};a.fn["inner"+f]=function(l){if(l===g)return k["inner"+f].call(this);return this.each(function(){a(this).css(h,i(this,l)+"px")})};a.fn["outer"+f]=function(l,j){if(typeof l!=="number")return k["outer"+f].call(this,l);return this.each(function(){a(this).css(h,i(this,l,true,j)+"px")})}});a.extend(a.expr[":"],{data:function(e,f,i){return!!a.data(e,i[3])},focusable:function(e){return d(e,!isNaN(a.attr(e,"tabindex")))},tabbable:function(e){var f=a.attr(e,"tabindex"),i=isNaN(f); +return(i||f>=0)&&d(e,!i)}});a(function(){var e=document.body,f=e.appendChild(f=document.createElement("div"));a.extend(f.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});a.support.minHeight=f.offsetHeight===100;a.support.selectstart="onselectstart"in f;e.removeChild(f).style.display="none"});a.extend(a.ui,{plugin:{add:function(e,f,i){e=a.ui[e].prototype;for(var b in i){e.plugins[b]=e.plugins[b]||[];e.plugins[b].push([f,i[b]])}},call:function(e,f,i){if((f=e.plugins[f])&&e.element[0].parentNode)for(var b= +0;b0)return true;e[i]=1;b=e[i]>0;e[i]=0;return b},isOverAxis:function(e,f,i){return e>f&&e", +options:{disabled:false,create:null},_createWidget:function(e,f){f=a(f||this.defaultElement||this)[0];this.element=a(f);this.options=a.widget.extend({},this.options,this._getCreateOptions(),e);this.bindings=a();this.hoverable=a();this.focusable=a();if(f!==this){a.data(f,this.widgetName,this);this._bind({remove:"destroy"})}this._create();this._trigger("create");this._init()},_getCreateOptions:a.noop,_create:a.noop,_init:a.noop,destroy:function(){this._destroy();this.element.unbind("."+this.widgetName).removeData(this.widgetName); +this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled");this.bindings.unbind("."+this.widgetName);this.hoverable.removeClass("ui-state-hover");this.focusable.removeClass("ui-state-focus")},_destroy:a.noop,widget:function(){return this.element},option:function(e,f){var i=e,b,h,k;if(arguments.length===0)return a.widget.extend({},this.options);if(typeof e==="string"){i={};b=e.split(".");e=b.shift();if(b.length){h=i[e]=a.widget.extend({}, +this.options[e]);for(k=0;k=9)&&!d.button)return this._mouseUp(d);if(this._mouseStarted){this._mouseDrag(d);return d.preventDefault()}if(this._mouseDistanceMet(d)&&this._mouseDelayMet(d))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,d)!==false)?this._mouseDrag(d):this._mouseUp(d);return!this._mouseStarted},_mouseUp:function(d){a(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName, +this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;d.target==this._mouseDownEvent.target&&a.data(d.target,this.widgetName+".preventClickEvent",true);this._mouseStop(d)}return false},_mouseDistanceMet:function(d){return Math.max(Math.abs(this._mouseDownEvent.pageX-d.pageX),Math.abs(this._mouseDownEvent.pageY-d.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +(function(a){a.widget("ui.draggable",a.ui.mouse,{version:"1.9pre",widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== +"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(g){var d= +this.options;if(this.helper||d.disabled||a(g.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(g);if(!this.handle)return false;a(d.iframeFix===true?"iframe":d.iframeFix).each(function(){a('
      ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(a(this).offset()).appendTo("body")});return true},_mouseStart:function(g){var d=this.options;this.helper= +this._createHelper(g);this._cacheHelperProportions();if(a.ui.ddmanager)a.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:g.pageX-this.offset.left,top:g.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); +this.originalPosition=this.position=this._generatePosition(g);this.originalPageX=g.pageX;this.originalPageY=g.pageY;d.cursorAt&&this._adjustOffsetFromHelper(d.cursorAt);d.containment&&this._setContainment();if(this._trigger("start",g)===false){this._clear();return false}this._cacheHelperProportions();a.ui.ddmanager&&!d.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,g);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(g,true);a.ui.ddmanager&&a.ui.ddmanager.dragStart(this,g);return true}, +_mouseDrag:function(g,d){this.position=this._generatePosition(g);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();if(this._trigger("drag",g,c)===false){this._mouseUp({});return false}this.position=c.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";a.ui.ddmanager&&a.ui.ddmanager.drag(this,g);return false},_mouseStop:function(g){var d= +false;if(a.ui.ddmanager&&!this.options.dropBehaviour)d=a.ui.ddmanager.drop(this,g);if(this.dropped){d=this.dropped;this.dropped=false}if(!this.element[0]||!this.element[0].parentNode)return false;if(this.options.revert=="invalid"&&!d||this.options.revert=="valid"&&d||this.options.revert===true||a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d)){var c=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){c._trigger("stop",g)!== +false&&c._clear()})}else this._trigger("stop",g)!==false&&this._clear();return false},_mouseUp:function(g){this.options.iframeFix===true&&a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});a.ui.ddmanager&&a.ui.ddmanager.dragStop(this,g);return a.ui.mouse.prototype._mouseUp.call(this,g)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(g){var d=!this.options.handle||!a(this.options.handle,this.element).length? +true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==g.target)d=true});return d},_createHelper:function(g){var d=this.options;g=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[g])):d.helper=="clone"?this.element.clone().removeAttr("id"):this.element;g.parents("body").length||g.appendTo(d.appendTo=="parent"?this.element[0].parentNode:d.appendTo);g[0]!=this.element[0]&&!/(fixed|absolute)/.test(g.css("position"))&&g.css("position","absolute");return g}, +_adjustOffsetFromHelper:function(g){if(typeof g=="string")g=g.split(" ");if(a.isArray(g))g={left:+g[0],top:+g[1]||0};if("left"in g)this.offset.click.left=g.left+this.margins.left;if("right"in g)this.offset.click.left=this.helperProportions.width-g.right+this.margins.left;if("top"in g)this.offset.click.top=g.top+this.margins.top;if("bottom"in g)this.offset.click.top=this.helperProportions.height-g.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var g= +this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0])){g.left+=this.scrollParent.scrollLeft();g.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)g={top:0,left:0};return{top:g.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:g.left+(parseInt(this.offsetParent.css("borderLeftWidth"), +10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var g=this.element.position();return{top:g.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:g.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), +10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var g=this.options;if(g.containment=="parent")g.containment=this.helper[0].parentNode;if(g.containment=="document"||g.containment=="window")this.containment=[g.containment=="document"?0:a(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,g.containment=="document"?0:a(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, +(g.containment=="document"?0:a(window).scrollLeft())+a(g.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(g.containment=="document"?0:a(window).scrollTop())+(a(g.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(g.containment)&&g.containment.constructor!=Array){g=a(g.containment);var d=g[0];if(d){g.offset();var c=a(d).css("overflow")!= +"hidden";this.containment=[(parseInt(a(d).css("borderLeftWidth"),10)||0)+(parseInt(a(d).css("paddingLeft"),10)||0),(parseInt(a(d).css("borderTopWidth"),10)||0)+(parseInt(a(d).css("paddingTop"),10)||0),(c?Math.max(d.scrollWidth,d.offsetWidth):d.offsetWidth)-(parseInt(a(d).css("borderLeftWidth"),10)||0)-(parseInt(a(d).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(d.scrollHeight,d.offsetHeight):d.offsetHeight)-(parseInt(a(d).css("borderTopWidth"), +10)||0)-(parseInt(a(d).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=g}}else if(g.containment.constructor==Array)this.containment=g.containment},_convertPositionTo:function(g,d){if(!d)d=this.position;var c=g=="absolute"?1:-1,e=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(e[0].tagName);return{top:d.top+ +this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:e.scrollTop())*c),left:d.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&a.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:e.scrollLeft())*c)}},_generatePosition:function(g){var d=this.options,c=this.cssPosition=="absolute"&& +!(this.scrollParent[0]!=document&&a.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,e=/(html|body)/i.test(c[0].tagName),f=g.pageX,i=g.pageY;if(this.originalPosition){var b;if(this.containment){if(this.relative_container){b=this.relative_container.offset();b=[this.containment[0]+b.left,this.containment[1]+b.top,this.containment[2]+b.left,this.containment[3]+b.top]}else b=this.containment;if(g.pageX-this.offset.click.leftb[2])f=b[2]+this.offset.click.left;if(g.pageY-this.offset.click.top>b[3])i=b[3]+this.offset.click.top}if(d.grid){i=d.grid[1]?this.originalPageY+Math.round((i-this.originalPageY)/d.grid[1])*d.grid[1]:this.originalPageY;i=b?!(i-this.offset.click.topb[3])?i:!(i-this.offset.click.topb[2])?f:!(f-this.offset.click.left=0;l--){var j=c.snapElements[l].left,m=j+c.snapElements[l].width,n=c.snapElements[l].top,o=n+c.snapElements[l].height;if(j-f=l&&i<=j||b>=l&&b<=j||ij)&&(e>=h&&e<=k||f>=h&&f<=k||ek);default:return false}}; +a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(g,d){var c=a.ui.ddmanager.droppables[g.options.scope]||[],e=d?d.type:null,f=(g.currentItem||g.element).find(":data(droppable)").andSelf(),i=0;a:for(;i').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=e.handles||(!a(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var f=this.handles.split(",");this.handles={};for(var i=0;i');/sw|se|ne|nw/.test(b)&&h.css({zIndex:++e.zIndex});"se"==b&&h.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[b]=".ui-resizable-"+b;this.element.append(h)}}this._renderAxis=function(k){k=k||this.element;for(var l in this.handles){if(this.handles[l].constructor== +String)this.handles[l]=a(this.handles[l],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=a(this.handles[l],this.element),m=0;m=/sw|ne|nw|se|n|s/.test(l)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(l)?"Top":/se|sw|s/.test(l)?"Bottom":/^e$/.test(l)?"Right":"Left"].join("");k.css(j,m);this._proportionallyResize()}a(this.handles[l])}};this._renderAxis(this.element);this._handles=a(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!c.resizing){if(this.className)var k=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);c.axis=k&&k[1]?k[1]:"se"}});if(e.autoHide){this._handles.hide();a(this.element).addClass("ui-resizable-autohide").hover(function(){if(!e.disabled){a(this).removeClass("ui-resizable-autohide");c._handles.show()}},function(){if(!e.disabled)if(!c.resizing){a(this).addClass("ui-resizable-autohide");c._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); +var c=function(f){a(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){c(this.element);var e=this.element;e.after(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);c(this.originalElement);return this},_mouseCapture:function(c){var e= +false,f;for(f in this.handles)if(a(this.handles[f])[0]==c.target)e=true;return!this.options.disabled&&e},_mouseStart:function(c){var e=this.options,f=this.element.position(),i=this.element;this.resizing=true;this.documentScroll={top:a(document).scrollTop(),left:a(document).scrollLeft()};if(i.is(".ui-draggable")||/absolute/.test(i.css("position")))i.css({position:"absolute",top:f.top,left:f.left});a.browser.opera&&/relative/.test(i.css("position"))&&i.css({position:"relative",top:"auto",left:"auto"}); +this._renderProxy();f=g(this.helper.css("left"));var b=g(this.helper.css("top"));if(e.containment){f+=a(e.containment).scrollLeft()||0;b+=a(e.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:f,top:b};this.size=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalSize=this._helper?{width:i.outerWidth(),height:i.outerHeight()}:{width:i.width(),height:i.height()};this.originalPosition={left:f,top:b};this.sizeDiff= +{width:i.outerWidth()-i.width(),height:i.outerHeight()-i.height()};this.originalMousePosition={left:c.pageX,top:c.pageY};this.aspectRatio=typeof e.aspectRatio=="number"?e.aspectRatio:this.originalSize.width/this.originalSize.height||1;e=a(".ui-resizable-"+this.axis).css("cursor");a("body").css("cursor",e=="auto"?this.axis+"-resize":e);i.addClass("ui-resizable-resizing");this._propagate("start",c);return true},_mouseDrag:function(c){var e=this.helper,f=this.originalMousePosition,i=this._change[this.axis]; +if(!i)return false;f=i.apply(this,[c,c.pageX-f.left||0,c.pageY-f.top||0]);this._updateVirtualBoundaries(c.shiftKey);if(this._aspectRatio||c.shiftKey)f=this._updateRatio(f,c);f=this._respectSize(f,c);this._propagate("resize",c);e.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(f);this._trigger("resize",c,this.ui());return false}, +_mouseStop:function(c){this.resizing=false;var e=this.options;if(this._helper){var f=this._proportionallyResizeElements,i=f.length&&/textarea/i.test(f[0].nodeName);f=i&&a.ui.hasScroll(f[0],"left")?0:this.sizeDiff.height;i=i?0:this.sizeDiff.width;i={width:this.helper.width()-i,height:this.helper.height()-f};f=parseInt(this.element.css("left"),10)+(this.position.left-this.originalPosition.left)||null;var b=parseInt(this.element.css("top"),10)+(this.position.top-this.originalPosition.top)||null;e.animate|| +this.element.css(a.extend(i,{top:b,left:f}));this.helper.height(this.size.height);this.helper.width(this.size.width);this._helper&&!e.animate&&this._proportionallyResize()}a("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",c);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(c){var e=this.options,f,i,b;e={minWidth:d(e.minWidth)?e.minWidth:0,maxWidth:d(e.maxWidth)?e.maxWidth:Infinity,minHeight:d(e.minHeight)?e.minHeight: +0,maxHeight:d(e.maxHeight)?e.maxHeight:Infinity};if(this._aspectRatio||c){c=e.minHeight*this.aspectRatio;i=e.minWidth/this.aspectRatio;f=e.maxHeight*this.aspectRatio;b=e.maxWidth/this.aspectRatio;if(c>e.minWidth)e.minWidth=c;if(i>e.minHeight)e.minHeight=i;if(fc.width,k=d(c.height)&&e.minHeight&&e.minHeight>c.height;if(h)c.width=e.minWidth;if(k)c.height=e.minHeight;if(i)c.width=e.maxWidth;if(b)c.height=e.maxHeight;var l=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,m=/sw|nw|w/.test(f);f=/nw|ne|n/.test(f);if(h&&m)c.left=l-e.minWidth;if(i&&m)c.left=l-e.maxWidth;if(k&&f)c.top=j-e.minHeight;if(b&&f)c.top=j-e.maxHeight;if((e=!c.width&&!c.height)&&!c.left&&c.top)c.top=null; +else if(e&&!c.top&&c.left)c.left=null;return c},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c=this.helper||this.element,e=0;e');var e=a.browser.msie&&a.browser.version<7,f=e?1:0;e=e?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ +e,height:this.element.outerHeight()+e,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++c.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(c,e){return{width:this.originalSize.width+e}},w:function(c,e){return{left:this.originalPosition.left+e,width:this.originalSize.width-e}},n:function(c,e,f){return{top:this.originalPosition.top+f,height:this.originalSize.height-f}},s:function(c,e,f){return{height:this.originalSize.height+ +f}},se:function(c,e,f){return a.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[c,e,f]))},sw:function(c,e,f){return a.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[c,e,f]))},ne:function(c,e,f){return a.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[c,e,f]))},nw:function(c,e,f){return a.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[c,e,f]))}},_propagate:function(c,e){a.ui.plugin.call(this,c,[e,this.ui()]); +c!="resize"&&this._trigger(c,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});a.ui.plugin.add("resizable","alsoResize",{start:function(){var c=a(this).data("resizable").options,e=function(f){a(f).each(function(){var i=a(this);i.data("resizable-alsoresize",{width:parseInt(i.width(),10),height:parseInt(i.height(),10), +left:parseInt(i.css("left"),10),top:parseInt(i.css("top"),10),position:i.css("position")})})};if(typeof c.alsoResize=="object"&&!c.alsoResize.parentNode)if(c.alsoResize.length){c.alsoResize=c.alsoResize[0];e(c.alsoResize)}else a.each(c.alsoResize,function(f){e(f)});else e(c.alsoResize)},resize:function(c,e){var f=a(this).data("resizable"),i=f.options,b=f.originalSize,h=f.originalPosition,k={height:f.size.height-b.height||0,width:f.size.width-b.width||0,top:f.position.top-h.top||0,left:f.position.left- +h.left||0},l=function(j,m){a(j).each(function(){var n=a(this),o=a(this).data("resizable-alsoresize"),p={},q=m&&m.length?m:n.parents(e.originalElement[0]).length?["width","height"]:["width","height","top","left"];a.each(q,function(u,s){var r=(o[s]||0)+(k[s]||0);if(r&&r>=0)p[s]=r||null});if(a.browser.opera&&/relative/.test(n.css("position"))){f._revertToRelativePosition=true;n.css({position:"absolute",top:"auto",left:"auto"})}n.css(p)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?a.each(i.alsoResize, +function(j,m){l(j,m)}):l(i.alsoResize)},stop:function(){var c=a(this).data("resizable"),e=c.options,f=function(i){a(i).each(function(){var b=a(this);b.css({position:b.data("resizable-alsoresize").position})})};if(c._revertToRelativePosition){c._revertToRelativePosition=false;typeof e.alsoResize=="object"&&!e.alsoResize.nodeType?a.each(e.alsoResize,function(i){f(i)}):f(e.alsoResize)}a(this).removeData("resizable-alsoresize")}});a.ui.plugin.add("resizable","animate",{stop:function(c){var e=a(this).data("resizable"), +f=e.options,i=e._proportionallyResizeElements,b=i.length&&/textarea/i.test(i[0].nodeName),h=b&&a.ui.hasScroll(i[0],"left")?0:e.sizeDiff.height;b={width:e.size.width-(b?0:e.sizeDiff.width),height:e.size.height-h};h=parseInt(e.element.css("left"),10)+(e.position.left-e.originalPosition.left)||null;var k=parseInt(e.element.css("top"),10)+(e.position.top-e.originalPosition.top)||null;e.element.animate(a.extend(b,k&&h?{top:k,left:h}:{}),{duration:f.animateDuration,easing:f.animateEasing,step:function(){var l= +{width:parseInt(e.element.css("width"),10),height:parseInt(e.element.css("height"),10),top:parseInt(e.element.css("top"),10),left:parseInt(e.element.css("left"),10)};i&&i.length&&a(i[0]).css({width:l.width,height:l.height});e._updateCache(l);e._propagate("resize",c)}})}});a.ui.plugin.add("resizable","containment",{start:function(){var c=a(this).data("resizable"),e=c.element,f=c.options.containment;if(e=f instanceof a?f.get(0):/parent/.test(f)?e.parent().get(0):f){c.containerElement=a(e);if(/document/.test(f)|| +f==document){c.containerOffset={left:0,top:0};c.containerPosition={left:0,top:0};c.parentData={element:a(document),left:0,top:0,width:a(document).width(),height:a(document).height()||document.body.parentNode.scrollHeight}}else{var i=a(e),b=[];a(["Top","Right","Left","Bottom"]).each(function(l,j){b[l]=g(i.css("padding"+j))});c.containerOffset=i.offset();c.containerPosition=i.position();c.containerSize={height:i.innerHeight()-b[3],width:i.innerWidth()-b[1]};f=c.containerOffset;var h=c.containerSize.height, +k=c.containerSize.width;k=a.ui.hasScroll(e,"left")?e.scrollWidth:k;h=a.ui.hasScroll(e)?e.scrollHeight:h;c.parentData={element:e,left:f.left,top:f.top,width:k,height:h}}}},resize:function(c){var e=a(this).data("resizable"),f=e.options,i=e.containerOffset,b=e.position;c=e._aspectRatio||c.shiftKey;var h={top:0,left:0},k=e.containerElement;if(k[0]!=document&&/static/.test(k.css("position")))h=i;if(b.left<(e._helper?i.left:0)){e.size.width+=e._helper?e.position.left-i.left:e.position.left-h.left;if(c)e.size.height= +e.size.width/f.aspectRatio;e.position.left=f.helper?i.left:0}if(b.top<(e._helper?i.top:0)){e.size.height+=e._helper?e.position.top-i.top:e.position.top;if(c)e.size.width=e.size.height*f.aspectRatio;e.position.top=e._helper?i.top:0}e.offset.left=e.parentData.left+e.position.left;e.offset.top=e.parentData.top+e.position.top;f=Math.abs((e._helper?e.offset.left-h.left:e.offset.left-h.left)+e.sizeDiff.width);i=Math.abs((e._helper?e.offset.top-h.top:e.offset.top-i.top)+e.sizeDiff.height);b=e.containerElement.get(0)== +e.element.parent().get(0);h=/relative|absolute/.test(e.containerElement.css("position"));if(b&&h)f-=e.parentData.left;if(f+e.size.width>=e.parentData.width){e.size.width=e.parentData.width-f;if(c)e.size.height=e.size.width/e.aspectRatio}if(i+e.size.height>=e.parentData.height){e.size.height=e.parentData.height-i;if(c)e.size.width=e.size.height*e.aspectRatio}},stop:function(){var c=a(this).data("resizable"),e=c.options,f=c.containerOffset,i=c.containerPosition,b=c.containerElement,h=a(c.helper),k= +h.offset(),l=h.outerWidth()-c.sizeDiff.width;h=h.outerHeight()-c.sizeDiff.height;c._helper&&!e.animate&&/relative/.test(b.css("position"))&&a(this).css({left:k.left-i.left-f.left,width:l,height:h});c._helper&&!e.animate&&/static/.test(b.css("position"))&&a(this).css({left:k.left-i.left-f.left,width:l,height:h})}});a.ui.plugin.add("resizable","ghost",{start:function(){var c=a(this).data("resizable"),e=c.options,f=c.size;c.ghost=c.originalElement.clone();c.ghost.css({opacity:0.25,display:"block",position:"relative", +height:f.height,width:f.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof e.ghost=="string"?e.ghost:"");c.ghost.appendTo(c.helper)},resize:function(){var c=a(this).data("resizable");c.ghost&&c.ghost.css({position:"relative",height:c.size.height,width:c.size.width})},stop:function(){var c=a(this).data("resizable");c.ghost&&c.helper&&c.helper.get(0).removeChild(c.ghost.get(0))}});a.ui.plugin.add("resizable","grid",{resize:function(){var c=a(this).data("resizable"),e=c.options, +f=c.size,i=c.originalSize,b=c.originalPosition,h=c.axis;e.grid=typeof e.grid=="number"?[e.grid,e.grid]:e.grid;var k=Math.round((f.width-i.width)/(e.grid[0]||1))*(e.grid[0]||1);e=Math.round((f.height-i.height)/(e.grid[1]||1))*(e.grid[1]||1);if(/^(se|s|e)$/.test(h)){c.size.width=i.width+k;c.size.height=i.height+e}else if(/^(ne)$/.test(h)){c.size.width=i.width+k;c.size.height=i.height+e;c.position.top=b.top-e}else{if(/^(sw)$/.test(h)){c.size.width=i.width+k;c.size.height=i.height+e}else{c.size.width= +i.width+k;c.size.height=i.height+e;c.position.top=b.top-e}c.position.left=b.left-k}}});var g=function(c){return parseInt(c,10)||0},d=function(c){return!isNaN(parseInt(c,10))}})(jQuery); +(function(a){a.widget("ui.selectable",a.ui.mouse,{version:"1.9pre",options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var g=this;this.element.addClass("ui-selectable");this.dragged=false;var d;this.refresh=function(){d=a(g.options.filter,g.element[0]);d.each(function(){var c=a(this),e=c.offset();a.data(this,"selectable-item",{element:this,$element:c,left:e.left,top:e.top,right:e.left+c.outerWidth(),bottom:e.top+c.outerHeight(),startselected:false, +selected:c.hasClass("ui-selected"),selecting:c.hasClass("ui-selecting"),unselecting:c.hasClass("ui-unselecting")})})};this.refresh();this.selectees=d.addClass("ui-selectee");this._mouseInit();this.helper=a("
      ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(g){var d= +this;this.opos=[g.pageX,g.pageY];if(!this.options.disabled){var c=this.options;this.selectees=a(c.filter,this.element[0]);this._trigger("start",g);a(c.appendTo).append(this.helper);this.helper.css({left:g.clientX,top:g.clientY,width:0,height:0});c.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var e=a.data(this,"selectable-item");e.startselected=true;if(!g.metaKey){e.$element.removeClass("ui-selected");e.selected=false;e.$element.addClass("ui-unselecting");e.unselecting= +true;d._trigger("unselecting",g,{unselecting:e.element})}});a(g.target).parents().andSelf().each(function(){var e=a.data(this,"selectable-item");if(e){var f=!g.metaKey||!e.$element.hasClass("ui-selected");e.$element.removeClass(f?"ui-unselecting":"ui-selected").addClass(f?"ui-selecting":"ui-unselecting");e.unselecting=!f;e.selecting=f;(e.selected=f)?d._trigger("selecting",g,{selecting:e.element}):d._trigger("unselecting",g,{unselecting:e.element});return false}})}},_mouseDrag:function(g){var d=this; +this.dragged=true;if(!this.options.disabled){var c=this.options,e=this.opos[0],f=this.opos[1],i=g.pageX,b=g.pageY;if(e>i){var h=i;i=e;e=h}if(f>b){h=b;b=f;f=h}this.helper.css({left:e,top:f,width:i-e,height:b-f});this.selectees.each(function(){var k=a.data(this,"selectable-item");if(!(!k||k.element==d.element[0])){var l=false;if(c.tolerance=="touch")l=!(k.left>i||k.rightb||k.bottome&&k.rightf&&k.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var g=this.options;this.containerCache= +{};this.element.addClass("ui-sortable");this.refresh();this.floating=this.items.length?g.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled");this._mouseDestroy();for(var g=this.items.length-1;g>=0;g--)this.items[g].item.removeData(this.widgetName+"-item");return this},_setOption:function(g, +d){if(g==="disabled"){this.options[g]=d;this.widget().toggleClass("ui-sortable-disabled",!!d)}else a.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(g,d){var c=this;if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(g);var e=null,f=this;a(g.target).parents().each(function(){if(a.data(this,c.widgetName+"-item")==f){e=a(this);return false}});if(a.data(g.target,c.widgetName+"-item")==f)e=a(g.target);if(!e)return false; +if(this.options.handle&&!d){var i=false;a(this.options.handle,e).find("*").andSelf().each(function(){if(this==g.target)i=true});if(!i)return false}this.currentItem=e;this._removeCurrentsFromItems();return true},_mouseStart:function(g,d,c){d=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(g);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top- +this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:g.pageX-this.offset.left,top:g.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(g);this.originalPageX=g.pageX;this.originalPageY=g.pageY;d.cursorAt&&this._adjustOffsetFromHelper(d.cursorAt);this.domPosition={prev:this.currentItem.prev()[0], +parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();d.containment&&this._setContainment();if(d.cursor){if(a("body").css("cursor"))this._storedCursor=a("body").css("cursor");a("body").css("cursor",d.cursor)}if(d.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",d.opacity)}if(d.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex", +d.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",g,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",g,this._uiHash(this));if(a.ui.ddmanager)a.ui.ddmanager.current=this;a.ui.ddmanager&&!d.dropBehaviour&&a.ui.ddmanager.prepareOffsets(this,g);this.dragging=true;this.helper.addClass("ui-sortable-helper"); +this._mouseDrag(g);return true},_mouseDrag:function(g){this.position=this._generatePosition(g);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var d=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-g.pageY=0;d--){c=this.items[d];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!a.contains(this.placeholder[0],e)&&(this.options.type== +"semi-dynamic"?!a.contains(this.element[0],e):1)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(g,c);else break;this._trigger("change",g,this._uiHash());break}}this._contactContainers(g);a.ui.ddmanager&&a.ui.ddmanager.drag(this,g);this._trigger("sort",g,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(g,d){if(g){a.ui.ddmanager&&!this.options.dropBehaviour&&a.ui.ddmanager.drop(this,g);if(this.options.revert){var c= +this,e=c.placeholder.offset();c.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(g)})}else this._clear(g,d);return false}},cancel:function(){if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"? +this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var g=this.containers.length-1;g>=0;g--){this.containers[g]._trigger("deactivate",null,this._uiHash(this));if(this.containers[g].containerCache.over){this.containers[g]._trigger("out",null,this._uiHash(this));this.containers[g].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&& +this.helper&&this.helper[0].parentNode&&this.helper.remove();a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?a(this.domPosition.prev).after(this.currentItem):a(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(g){var d=this._getItemsAsjQuery(g&&g.connected),c=[];g=g||{};a(d).each(function(){var e=(a(g.item||this).attr(g.attribute||"id")||"").match(g.expression||/(.+)[-=_](.+)/);if(e)c.push((g.key||e[1]+"[]")+"="+ +(g.key&&g.expression?e[1]:e[2]))});!c.length&&g.key&&c.push(g.key+"=");return c.join("&")},toArray:function(g){var d=this._getItemsAsjQuery(g&&g.connected),c=[];g=g||{};d.each(function(){c.push(a(g.item||this).attr(g.attribute||"id")||"")});return c},_intersectsWith:function(g){var d=this.positionAbs.left,c=d+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,i=g.left,b=i+g.width,h=g.top,k=h+g.height,l=this.offset.click.top,j=this.offset.click.left;return this.options.tolerance== +"pointer"||this.options.forcePointerForContainers||this.options.tolerance!="pointer"&&this.helperProportions[this.floating?"width":"height"]>g[this.floating?"width":"height"]?e+l>h&&e+li&&d+j0?"down":"up")},_getDragHorizontalDirection:function(){var g=this.positionAbs.left-this.lastPositionAbs.left;return g!=0&&(g>0?"right":"left")},refresh:function(g){this._refreshItems(g);this.refreshPositions();return this},_connectWith:function(){var g=this.options;return g.connectWith.constructor==String?[g.connectWith]: +g.connectWith},_getItemsAsjQuery:function(g){var d=[],c=[],e=this._connectWith();if(e&&g)for(g=e.length-1;g>=0;g--)for(var f=a(e[g]),i=f.length-1;i>=0;i--){var b=a.data(f[i],this.widgetName);if(b&&b!=this&&!b.options.disabled)c.push([a.isFunction(b.options.items)?b.options.items.call(b.element):a(b.options.items,b.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),b])}c.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}): +a(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(g=c.length-1;g>=0;g--)c[g][0].each(function(){d.push(this)});return a(d)},_removeCurrentsFromItems:function(){for(var g=this.currentItem.find(":data("+this.widgetName+"-item)"),d=0;d=0;f--)for(var i=a(e[f]),b=i.length-1;b>=0;b--){var h=a.data(i[b],this.widgetName);if(h&&h!=this&&!h.options.disabled){c.push([a.isFunction(h.options.items)?h.options.items.call(h.element[0],g,{item:this.currentItem}):a(h.options.items,h.element),h]);this.containers.push(h)}}for(f=c.length-1;f>=0;f--){g=c[f][1];e=c[f][0];b=0;for(i=e.length;b< +i;b++){h=a(e[b]);h.data(this.widgetName+"-item",g);d.push({item:h,instance:g,width:0,height:0,left:0,top:0})}}},refreshPositions:function(g){if(this.offsetParent&&this.helper)this.offset.parent=this._getParentOffset();for(var d=this.items.length-1;d>=0;d--){var c=this.items[d];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?a(this.options.toleranceElement,c.item):c.item;if(!g){c.width=e.outerWidth();c.height=e.outerHeight()}e= +e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(d=this.containers.length-1;d>=0;d--){e=this.containers[d].element.offset();this.containers[d].containerCache.left=e.left;this.containers[d].containerCache.top=e.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}return this},_createPlaceholder:function(g){var d= +g||this,c=d.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f=a(document.createElement(d.currentItem[0].nodeName)).addClass(e||d.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,i){if(!(e&&!c.forcePlaceholderSize)){i.height()||i.height(d.currentItem.innerHeight()-parseInt(d.currentItem.css("paddingTop")||0,10)-parseInt(d.currentItem.css("paddingBottom")|| +0,10));i.width()||i.width(d.currentItem.innerWidth()-parseInt(d.currentItem.css("paddingLeft")||0,10)-parseInt(d.currentItem.css("paddingRight")||0,10))}}}}d.placeholder=a(c.placeholder.element.call(d.element,d.currentItem));d.currentItem.after(d.placeholder);c.placeholder.update(d,d.placeholder)},_contactContainers:function(g){for(var d=null,c=null,e=this.containers.length-1;e>=0;e--)if(!a.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(d&& +a.contains(this.containers[e].element[0],d.element[0]))){d=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out",g,this._uiHash(this));this.containers[e].containerCache.over=0}if(d)if(this.containers.length===1){this.containers[c]._trigger("over",g,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){d=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],i=this.items.length- +1;i>=0;i--)if(a.contains(this.containers[c].element[0],this.items[i].item[0])){var b=this.items[i][this.containers[c].floating?"left":"top"];if(Math.abs(b-f) +this.containment[2])f=this.containment[2]+this.offset.click.left;if(g.pageY-this.offset.click.top>this.containment[3])i=this.containment[3]+this.offset.click.top}if(d.grid){i=this.originalPageY+Math.round((i-this.originalPageY)/d.grid[1])*d.grid[1];i=this.containment?!(i-this.offset.click.topthis.containment[3])?i:!(i-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(a.contains(this.containers[e].element[0],this.currentItem[0])&&!d){c.push(function(f){return function(i){f._trigger("receive",i,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(i){f._trigger("update", +i,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){d||c.push(function(f){return function(i){f._trigger("deactivate",i,this._uiHash(this))}}.call(this,this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(i){f._trigger("out",i,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&a("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity", +this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!d){this._trigger("beforeStop",g,this._uiHash());for(e=0;e").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), +n={width:l.width(),height:l.height()},o=document.activeElement;l.wrap(m);if(l[0]===o||a.contains(l[0],o))a(o).focus();m=l.parent();if(l.css("position")==="static"){m.css({position:"relative"});l.css({position:"relative"})}else{a.extend(j,{position:l.css("position"),zIndex:l.css("z-index")});a.each(["top","left","bottom","right"],function(p,q){j[q]=l.css(q);if(isNaN(parseInt(j[q],10)))j[q]="auto"});l.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}l.css(n);return m.css(j).show()}, +removeWrapper:function(l){var j=document.activeElement;if(l.parent().is(".ui-effects-wrapper")){l.parent().replaceWith(l);if(l[0]===j||a.contains(l[0],j))a(j).focus()}return l},setTransition:function(l,j,m,n){n=n||{};a.each(j,function(o,p){var q=l.cssUnit(p);if(q[0]>0)n[p]=q[0]*m+q[1]});return n}});a.fn.extend({effect:function(){function l(q){function u(){a.isFunction(r)&&r.call(s[0]);a.isFunction(q)&&q()}var s=a(this),r=j.complete,t=j.mode;(s.is(":hidden")?t==="hide":t==="show")?u():o.call(s[0], +j,u)}var j=e.apply(this,arguments),m=j.mode,n=j.queue,o=a.effects.effect[j.effect],p=!o&&i&&a.effects[j.effect];if(a.fx.off||!(o||p))return m?this[m](j.duration,j.complete):this.each(function(){j.complete&&j.complete.call(this)});return o?n===false?this.each(l):this.queue(n||"fx",l):p.call(this,{options:j,duration:j.duration,callback:j.complete,mode:j.mode})},_show:a.fn.show,show:function(l){if(f(l))return this._show.apply(this,arguments);else{var j=e.apply(this,arguments);j.mode="show";return this.effect.call(this, +j)}},_hide:a.fn.hide,hide:function(l){if(f(l))return this._hide.apply(this,arguments);else{var j=e.apply(this,arguments);j.mode="hide";return this.effect.call(this,j)}},__toggle:a.fn.toggle,toggle:function(l){if(f(l)||typeof l==="boolean"||a.isFunction(l))return this.__toggle.apply(this,arguments);else{var j=e.apply(this,arguments);j.mode="toggle";return this.effect.call(this,j)}},cssUnit:function(l){var j=this.css(l),m=[];a.each(["em","px","%","pt"],function(n,o){if(j.indexOf(o)>0)m=[parseFloat(j), +o]});return m}});a.easing.jswing=a.easing.swing;a.extend(a.easing,{def:"easeOutQuad",swing:function(l,j,m,n,o){return a.easing[a.easing.def](l,j,m,n,o)},easeInQuad:function(l,j,m,n,o){return n*(j/=o)*j+m},easeOutQuad:function(l,j,m,n,o){return-n*(j/=o)*(j-2)+m},easeInOutQuad:function(l,j,m,n,o){if((j/=o/2)<1)return n/2*j*j+m;return-n/2*(--j*(j-2)-1)+m},easeInCubic:function(l,j,m,n,o){return n*(j/=o)*j*j+m},easeOutCubic:function(l,j,m,n,o){return n*((j=j/o-1)*j*j+1)+m},easeInOutCubic:function(l,j, +m,n,o){if((j/=o/2)<1)return n/2*j*j*j+m;return n/2*((j-=2)*j*j+2)+m},easeInQuart:function(l,j,m,n,o){return n*(j/=o)*j*j*j+m},easeOutQuart:function(l,j,m,n,o){return-n*((j=j/o-1)*j*j*j-1)+m},easeInOutQuart:function(l,j,m,n,o){if((j/=o/2)<1)return n/2*j*j*j*j+m;return-n/2*((j-=2)*j*j*j-2)+m},easeInQuint:function(l,j,m,n,o){return n*(j/=o)*j*j*j*j+m},easeOutQuint:function(l,j,m,n,o){return n*((j=j/o-1)*j*j*j*j+1)+m},easeInOutQuint:function(l,j,m,n,o){if((j/=o/2)<1)return n/2*j*j*j*j*j+m;return n/2* +((j-=2)*j*j*j*j+2)+m},easeInSine:function(l,j,m,n,o){return-n*Math.cos(j/o*(Math.PI/2))+n+m},easeOutSine:function(l,j,m,n,o){return n*Math.sin(j/o*(Math.PI/2))+m},easeInOutSine:function(l,j,m,n,o){return-n/2*(Math.cos(Math.PI*j/o)-1)+m},easeInExpo:function(l,j,m,n,o){return j==0?m:n*Math.pow(2,10*(j/o-1))+m},easeOutExpo:function(l,j,m,n,o){return j==o?m+n:n*(-Math.pow(2,-10*j/o)+1)+m},easeInOutExpo:function(l,j,m,n,o){if(j==0)return m;if(j==o)return m+n;if((j/=o/2)<1)return n/2*Math.pow(2,10*(j-1))+ +m;return n/2*(-Math.pow(2,-10*--j)+2)+m},easeInCirc:function(l,j,m,n,o){return-n*(Math.sqrt(1-(j/=o)*j)-1)+m},easeOutCirc:function(l,j,m,n,o){return n*Math.sqrt(1-(j=j/o-1)*j)+m},easeInOutCirc:function(l,j,m,n,o){if((j/=o/2)<1)return-n/2*(Math.sqrt(1-j*j)-1)+m;return n/2*(Math.sqrt(1-(j-=2)*j)+1)+m},easeInElastic:function(l,j,m,n,o){l=1.70158;var p=o*0.3,q=n;if(j==0)return m;if((j/=o)==1)return m+n;if(q1&&q.splice.apply(q,[1,0].concat(q.splice(u,l+1)));c.dequeue()}})(jQuery); +(function(a){a.effects.effect.clip=function(g,d){var c=a(this),e=["position","top","bottom","left","right","height","width"],f=a.effects.setMode(c,g.mode||"hide")==="show",i=(g.direction||"vertical")==="vertical",b=i?"height":"width";i=i?"top":"left";var h={},k,l;a.effects.save(c,e);c.show();k=a.effects.createWrapper(c).css({overflow:"hidden"});k=c[0].tagName==="IMG"?k:c;l=k[b]();if(f){k.css(b,0);k.css(i,l/2)}h[b]=f?l:0;h[i]=f?0:l/2;k.animate(h,{queue:false,duration:g.duration,easing:g.easing,complete:function(){f|| +c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d()}})}})(jQuery); +(function(a){a.effects.effect.drop=function(g,d){var c=a(this),e=["position","top","bottom","left","right","opacity","height","width"],f=a.effects.setMode(c,g.mode||"hide"),i=f==="show",b=g.direction||"left",h=b==="up"||b==="down"?"top":"left";b=b==="up"||b==="left"?"pos":"neg";var k={opacity:i?1:0},l;a.effects.save(c,e);c.show();a.effects.createWrapper(c);l=g.distance||c[h=="top"?"outerHeight":"outerWidth"]({margin:true})/2;if(i)c.css("opacity",0).css(h,b=="pos"?-l:l);k[h]=(i?b==="pos"?"+=":"-=": +b==="pos"?"-=":"+=")+l;c.animate(k,{queue:false,duration:g.duration,easing:g.easing,complete:function(){f=="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d()}})}})(jQuery); +(function(a){a.effects.effect.explode=function(g,d){function c(){j.push(this);if(j.length==e*f){i.css({visibility:"visible"});a(j).remove();b||i.hide();d()}}var e=g.pieces?Math.round(Math.sqrt(g.pieces)):3,f=e,i=a(this),b=a.effects.setMode(i,g.mode||"hide")==="show",h=i.show().css("visibility","hidden").offset(),k=Math.ceil(i.outerWidth()/f),l=Math.ceil(i.outerHeight()/e),j=[],m,n,o,p,q,u;for(m=0;m").css({position:"absolute", +visibility:"visible",left:-n*k,top:-m*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:k,height:l,left:o+(b?q*k:0),top:p+(b?u*l:0),opacity:b?0:1}).animate({left:o+(b?0:q*k),top:p+(b?0:u*l),opacity:b?1:0},g.duration||500,g.easing,c)}}}})(jQuery); +(function(a){a.effects.effect.fade=function(g,d){var c=a(this),e=a.effects.setMode(c,g.mode||"toggle")==="hide";c.show();c.animate({opacity:e?0:1},{queue:false,duration:g.duration,easing:g.easing,complete:function(){e&&c.hide();d()}})}})(jQuery); +(function(a){a.effects.effect.fold=function(g,d){var c=a(this),e=["position","top","bottom","left","right","height","width"],f=a.effects.setMode(c,g.mode||"hide"),i=f==="show",b=f==="hide";f=g.size||15;var h=/([0-9]+)%/.exec(f),k=!!g.horizFirst,l=i!=k,j=l?["width","height"]:["height","width"],m=g.duration/2,n,o={},p={};a.effects.save(c,e);c.show();n=a.effects.createWrapper(c).css({overflow:"hidden"});l=l?[n.width(),n.height()]:[n.height(),n.width()];if(h)f=parseInt(h[1],10)/100*l[b?0:1];if(i)n.css(k? +{height:0,width:f}:{height:f,width:0});o[j[0]]=i?l[0]:f;p[j[1]]=i?l[1]:0;n.animate(o,m,g.easing).animate(p,m,g.easing,function(){b&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d()})}})(jQuery); +(function(a){a.effects.effect.highlight=function(g,d){var c=a(this),e=["backgroundImage","backgroundColor","opacity"],f=a.effects.setMode(c,g.mode||"show"),i={backgroundColor:c.css("backgroundColor")};if(f==="hide")i.opacity=0;a.effects.save(c,e);c.show().css({backgroundImage:"none",backgroundColor:g.color||"#ffff99"}).animate(i,{queue:false,duration:g.duration,easing:g.easing,complete:function(){f==="hide"&&c.hide();a.effects.restore(c,e);d()}})}})(jQuery); +(function(a){a.effects.effect.pulsate=function(g,d){var c=a(this),e=a.effects.setMode(c,g.mode||"show"),f=e==="show",i=e==="hide";e=(g.times||5)*2+(f||e==="hide"?1:0);var b=g.duration/e,h=0,k=c.queue(),l=k.length;if(f||!c.is(":visible")){c.css("opacity",0).show();h=1}for(f=1;f1&&k.splice.apply(k,[1,0].concat(k.splice(l,e+1)));c.dequeue()}})(jQuery); +(function(a){a.effects.effect.puff=function(g,d){var c=a(this),e=a.effects.setMode(c,g.mode||"hide"),f=e==="hide",i=parseInt(g.percent,10)||150,b=i/100,h={height:c.height(),width:c.width()};a.extend(g,{effect:"scale",queue:false,fade:true,mode:e,complete:d,percent:f?i:100,from:f?h:{height:h.height*b,width:h.width*b}});c.effect(g)};a.effects.effect.scale=function(g,d){var c=a(this),e=a.extend(true,{},g),f=a.effects.setMode(c,g.mode||"effect"),i=parseInt(g.percent,10)||(parseInt(g.percent,10)==0?0: +f=="hide"?0:100),b=g.direction||"both",h=g.origin,k={height:c.height(),width:c.width(),outerHeight:c.outerHeight(),outerWidth:c.outerWidth()};i={y:b!="horizontal"?i/100:1,x:b!="vertical"?i/100:1};e.effect="size";e.queue=false;e.complete=d;if(f!="effect"){e.origin=h||["middle","center"];e.restore=true}e.from=g.from||(f=="show"?{height:0,width:0}:k);e.to={height:k.height*i.y,width:k.width*i.x,outerHeight:k.outerHeight*i.y,outerWidth:k.outerWidth*i.x};if(e.fade){if(f=="show"){e.from.opacity=0;e.to.opacity= +1}if(f=="hide"){e.from.opacity=1;e.to.opacity=0}}c.effect(e)};a.effects.effect.size=function(g,d){var c=a(this),e=["position","top","bottom","left","right","width","height","overflow","opacity"],f=["position","top","bottom","left","right","overflow","opacity"],i=["width","height","overflow"],b=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],k=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],l=a.effects.setMode(c,g.mode||"effect"),j=g.restore|| +l!=="effect",m=g.scale||"both",n=g.origin||["middle","center"],o,p,q,u=c.css("position"),s=c.css("bottom")!=="auto"?"bottom":"top";originalHorizontalPositioning=c.css("right")!=="auto"?"right":"left";l==="show"&&c.show();o={height:c.height(),width:c.width(),outerHeight:c.outerHeight(),outerWidth:c.outerWidth()};c.from=g.from||o;c.to=g.to||o;q={from:{y:c.from.height/o.height,x:c.from.width/o.width},to:{y:c.to.height/o.height,x:c.to.width/o.width}};if(m=="box"||m=="both"){if(q.from.y!==q.to.y){e=e.concat(h); +c.from=a.effects.setTransition(c,h,q.from.y,c.from);c.to=a.effects.setTransition(c,h,q.to.y,c.to)}if(q.from.x!==q.to.x){e=e.concat(k);c.from=a.effects.setTransition(c,k,q.from.x,c.from);c.to=a.effects.setTransition(c,k,q.to.x,c.to)}}if(m=="content"||m=="both")if(q.from.y!==q.to.y){e=e.concat(b);c.from=a.effects.setTransition(c,b,q.from.y,c.from);c.to=a.effects.setTransition(c,b,q.to.y,c.to)}a.effects.save(c,j?e:f);c.show();a.effects.createWrapper(c);c.css("overflow","hidden").css(c.from);if(n){p= +a.effects.getBaseline(n,o);c.from.top=(o.outerHeight-c.outerHeight())*p.y;c.from.left=(o.outerWidth-c.outerWidth())*p.x;c.to.top=(o.outerHeight-c.to.outerHeight)*p.y;c.to.left=(o.outerWidth-c.to.outerWidth)*p.x}c.css(c.from);if(m=="content"||m=="both"){h=h.concat(["marginTop","marginBottom"]).concat(b);k=k.concat(["marginLeft","marginRight"]);i=e.concat(h).concat(k);c.find("*[width]").each(function(){var r=a(this),t={height:r.height(),width:r.width()};j&&a.effects.save(r,i);r.from={height:t.height* +q.from.y,width:t.width*q.from.x};r.to={height:t.height*q.to.y,width:t.width*q.to.x};if(q.from.y!=q.to.y){r.from=a.effects.setTransition(r,h,q.from.y,r.from);r.to=a.effects.setTransition(r,h,q.to.y,r.to)}if(q.from.x!=q.to.x){r.from=a.effects.setTransition(r,k,q.from.x,r.from);r.to=a.effects.setTransition(r,k,q.to.x,r.to)}r.css(r.from);r.animate(r.to,g.duration,g.easing,function(){j&&a.effects.restore(r,i)})})}c.animate(c.to,{queue:false,duration:g.duration,easing:g.easing,complete:function(){c.to.opacity=== +0&&c.css("opacity",c.from.opacity);l=="hide"&&c.hide();a.effects.restore(c,j?e:f);j||(u==="static"?c.css({position:"relative",top:c.to.top,left:c.to.left}):a.each([s,originalHorizontalPositioning],function(r,t){c.css(t,function(v,w){var x=parseInt(w,10),C=r?c.to.left:c.to.top,A=r?c.to.outerWidth-c.from.outerWidth:c.to.outerHeight-c.from.outerHeight,y=n[r]===t,D=n[r]==="middle"||n[r]==="center";if(w==="auto")return C+"px";if(!(t=="left"||t=="top"))if(u==="relative")C*=-1;else D||(C-=A*(y?-1:1));return x+ +C+"px"})}));a.effects.removeWrapper(c);d()}})}})(jQuery); +(function(a){a.effects.effect.shake=function(g,d){var c=a(this),e=["position","top","bottom","left","right","height","width"],f=a.effects.setMode(c,g.mode||"effect"),i=g.direction||"left",b=g.distance||20,h=g.times||3,k=h*2+1,l=g.duration,j=i=="up"||i=="down"?"top":"left",m=i=="up"||i=="left";i={};var n={},o={},p=c.queue(),q=p.length;a.effects.save(c,e);c.show();a.effects.createWrapper(c);i[j]=(m?"-=":"+=")+b;n[j]=(m?"+=":"-=")+b*2;o[j]=(m?"-=":"+=")+b*2;c.animate(i,l,g.easing);for(b=1;b1&&p.splice.apply(p,[1,0].concat(p.splice(q,k+1)));c.dequeue()}})(jQuery); +(function(a){a.effects.effect.slide=function(g,d){var c=a(this),e=["position","top","bottom","left","right","width","height"],f=a.effects.setMode(c,g.mode||"show"),i=f==="show",b=g.direction||"left",h=b=="up"||b=="down"?"top":"left";b=b=="up"||b=="left";var k,l={};a.effects.save(c,e);c.show();k=g.distance||c[h==="top"?"outerHeight":"outerWidth"]({margin:true});a.effects.createWrapper(c).css({overflow:"hidden"});if(i)c.css(h,b?isNaN(k)?"-"+k:-k:k);l[h]=(i?b?"+=":"-=":b?"-=":"+=")+k;c.animate(l,{queue:false, +duration:g.duration,easing:g.easing,complete:function(){f==="hide"&&c.hide();a.effects.restore(c,e);a.effects.removeWrapper(c);d()}})}})(jQuery); +(function(a){a.effects.effect.transfer=function(g,d){var c=a(this),e=a(g.to),f=e.css("position")==="fixed",i=a("body"),b=f?i.scrollTop():0;i=f?i.scrollLeft():0;var h=e.offset();e={top:h.top-b,left:h.left-i,height:e.innerHeight(),width:e.innerWidth()};h=c.offset();var k=a('
      ').appendTo(document.body).addClass(g.className).css({top:h.top-b,left:h.left-i,height:c.innerHeight(),width:c.innerWidth(),position:f?"fixed":"absolute"}).animate(e,g.duration,g.easing,function(){k.remove(); +d()})}})(jQuery); +(function(a){a.widget("ui.accordion",{version:"1.9pre",options:{active:0,animated:"slide",collapsible:false,event:"click",header:"> li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var g=this.options;this.lastToggle={};this.element.addClass("ui-accordion ui-widget ui-helper-reset");this.headers=this.element.find(g.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all");this._hoverable(this.headers); +this._focusable(this.headers);this.headers.find(":first-child").addClass("ui-accordion-heading");this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");if(!g.collapsible&&g.active===false)g.active=0;if(g.active<0)g.active+=this.headers.length;this.active=this._findActive(g.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");this.active.next().addClass("ui-accordion-content-active");this._createIcons(); +this.refresh();this.element.attr("role","tablist");this.headers.attr("role","tab").bind("keydown.accordion",a.proxy(this,"_keydown")).next().attr("role","tabpanel");this.headers.not(this.active).attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();this.active.length?this.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):this.headers.eq(0).attr("tabIndex",0);a.browser.safari||this.headers.find("a").attr("tabIndex",-1);this._setupEvents(g.event)},_createIcons:function(){var g= +this.options.icons;if(g){a("").addClass("ui-accordion-header-icon ui-icon "+g.header).prependTo(this.headers);this.active.children(".ui-accordion-header-icon").removeClass(g.header).addClass(g.activeHeader);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-accordion-header-icon").remove();this.element.removeClass("ui-accordion-icons")},_destroy:function(){this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex").find("a").removeAttr("tabIndex").end().find(".ui-accordion-heading").removeClass("ui-accordion-heading"); +this._destroyIcons();var g=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");this.options.heightStyle!=="content"&&g.css("height","")},_setOption:function(g,d){if(g==="active")this._activate(d);else{if(g==="event"){this.options.event&&this.headers.unbind(this.options.event+".accordion",this._eventHandler);this._setupEvents(d)}this._super("_setOption", +g,d);g==="collapsible"&&!d&&this.options.active===false&&this._activate(0);if(g==="icons"){this._destroyIcons();d&&this._createIcons()}g==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-accordion-disabled ui-state-disabled",!!d)}},_keydown:function(g){if(!(this.options.disabled||g.altKey||g.ctrlKey)){var d=a.ui.keyCode,c=this.headers.length,e=this.headers.index(g.target),f=false;switch(g.keyCode){case d.RIGHT:case d.DOWN:f=this.headers[(e+1)%c];break;case d.LEFT:case d.UP:f=this.headers[(e- +1+c)%c];break;case d.SPACE:case d.ENTER:this._eventHandler(g)}if(f){a(g.target).attr("tabIndex",-1);a(f).attr("tabIndex",0);f.focus();g.preventDefault()}}},refresh:function(){var g=this.options,d=this.element.parent(),c,e;if(g.heightStyle==="fill"){if(!a.support.minHeight){e=d.css("overflow");d.css("overflow","hidden")}c=d.height();this.element.siblings(":visible").each(function(){var f=a(this),i=f.css("position");i==="absolute"||i==="fixed"||(c-=f.outerHeight(true))});e&&d.css("overflow",e);this.headers.each(function(){c-= +a(this).outerHeight(true)});this.headers.next().each(function(){a(this).height(Math.max(0,c-a(this).innerHeight()+a(this).height()))}).css("overflow","auto")}else if(g.heightStyle==="auto"){c=0;this.headers.next().each(function(){c=Math.max(c,a(this).height("").height())}).height(c)}return this},_activate:function(g){g=this._findActive(g)[0];if(g!==this.active[0]){g=g||this.active[0];this._eventHandler({target:g,currentTarget:g,preventDefault:a.noop})}},_findActive:function(g){return typeof g==="number"? +this.headers.eq(g):a()},_setupEvents:function(g){g&&this.headers.bind(g.split(" ").join(".accordion ")+".accordion",a.proxy(this,"_eventHandler"))},_eventHandler:function(g){var d=this.options,c=this.active,e=a(g.currentTarget),f=e[0]===c[0],i=f&&d.collapsible,b=i?a():e.next(),h=c.next();b={oldHeader:c,oldContent:h,newHeader:i?a():e,newContent:b};g.preventDefault();if(!(d.disabled||f&&!d.collapsible||this._trigger("beforeActivate",g,b)===false)){d.active=i?false:this.headers.index(e);this.active= +f?a():e;this._toggle(b);c.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-accordion-header-icon").removeClass(d.icons.activeHeader).addClass(d.icons.header);if(!f){e.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-accordion-header-icon").removeClass(d.icons.header).addClass(d.icons.activeHeader);e.next().addClass("ui-accordion-content-active")}}},_toggle:function(g){function d(){c._completed(g)} +var c=this,e=c.options,f=g.newContent,i=g.oldContent;if(e.animated){var b=a.ui.accordion.animations;e=e.animated;var h;if(!b[e]){h={easing:a.easing[e]?e:"slide",duration:700};e="slide"}b[e]({widget:c,toShow:f,toHide:i,prevShow:c.lastToggle.toShow,prevHide:c.lastToggle.toHide,complete:d,down:f.length&&(!i.length||f.index()",options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var d=this,c=this.element[0].ownerDocument,e,f;this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"];this.element.addClass("ui-autocomplete-input").attr("autocomplete", +"off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(i){if(d.options.disabled||d.element.prop("readOnly"))f=e=true;else{f=e=false;var b=a.ui.keyCode;switch(i.keyCode){case b.PAGE_UP:e=true;d._move("previousPage",i);break;case b.PAGE_DOWN:e=true;d._move("nextPage",i);break;case b.UP:e=true;d._move("previous",i);i.preventDefault();break;case b.DOWN:e=true;d._move("next",i);i.preventDefault();break;case b.ENTER:case b.NUMPAD_ENTER:if(d.menu.active){e= +true;i.preventDefault()}case b.TAB:if(!d.menu.active)break;d.menu.select(i);break;case b.ESCAPE:if(d.menu.element.is(":visible")){d._value(d.term);d.close(i)}break;default:d._searchTimeout(i)}}}).bind("keypress.autocomplete",function(i){if(e){e=false;i.preventDefault()}else{var b=a.ui.keyCode;switch(i.keyCode){case b.PAGE_UP:d._move("previousPage",i);break;case b.PAGE_DOWN:d._move("nextPage",i);break;case b.UP:d._move("previous",i);i.preventDefault();break;case b.DOWN:d._move("next",i);i.preventDefault()}}}).bind("input.autocomplete", +function(i){if(f){f=false;i.preventDefault()}else d._searchTimeout(i)}).bind("focus.autocomplete",function(){if(!d.options.disabled){d.selectedItem=null;d.previous=d._value()}}).bind("blur.autocomplete",function(i){if(!d.options.disabled){clearTimeout(d.searching);d.closing=setTimeout(function(){d.close(i);d._change(i)},150)}});this._initSource();this.response=function(){return d._response.apply(d,arguments)};this.menu=a("
        ").addClass("ui-autocomplete").appendTo(a(this.options.appendTo||"body", +c)[0]).mousedown(function(i){var b=d.menu.element[0];a(i.target).closest(".ui-menu-item").length||setTimeout(function(){a(document).one("mousedown",function(h){h.target!==d.element[0]&&h.target!==b&&!a.contains(b,h.target)&&d.close()})},1);setTimeout(function(){clearTimeout(d.closing)},13)}).menu({input:a(),focus:function(i,b){var h=b.item.data("item.autocomplete");false!==d._trigger("focus",i,{item:h})&&/^key/.test(i.originalEvent.type)&&d._value(h.value)},select:function(i,b){var h=b.item.data("item.autocomplete"), +k=d.previous;if(d.element[0]!==c.activeElement){d.element.focus();d.previous=k;setTimeout(function(){d.previous=k;d.selectedItem=h},1)}false!==d._trigger("select",i,{item:h})&&d._value(h.value);d.term=d._value();d.close(i);d.selectedItem=h}}).zIndex(this.element.zIndex()+1).hide().data("menu");a.fn.bgiframe&&this.menu.element.bgiframe()},_destroy:function(){clearTimeout(this.searching);this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"); +this.menu.element.remove()},_setOption:function(d,c){this._super("_setOption",d,c);d==="source"&&this._initSource();if(d==="appendTo")this.menu.element.appendTo(a(c||"body",this.element[0].ownerDocument)[0]);d==="disabled"&&c&&this.xhr&&this.xhr.abort()},_initSource:function(){var d=this,c,e;if(a.isArray(this.options.source)){c=this.options.source;this.source=function(f,i){i(a.ui.autocomplete.filter(c,f.term))}}else if(typeof this.options.source==="string"){e=this.options.source;this.source=function(f, +i){d.xhr&&d.xhr.abort();d.xhr=a.ajax({url:e,data:f,dataType:"json",autocompleteRequest:++g,success:function(b){this.autocompleteRequest===g&&i(b)},error:function(){this.autocompleteRequest===g&&i([])}})}}else this.source=this.options.source},_searchTimeout:function(d){var c=this;clearTimeout(c.searching);c.searching=setTimeout(function(){if(c.term!==c._value()){c.selectedItem=null;c.search(null,d)}},c.options.delay)},search:function(d,c){d=d!=null?d:this._value();this.term=this._value();if(d.length< +this.options.minLength)return this.close(c);clearTimeout(this.closing);if(this._trigger("search",c)!==false)return this._search(d)},_search:function(d){this.pending++;this.element.addClass("ui-autocomplete-loading");this.source({term:d},this.response)},_response:function(d){if(d)d=this._normalize(d);this._trigger("response",null,{content:d});if(!this.options.disabled&&d&&d.length){this._suggest(d);this._trigger("open")}else this.close();this.pending--;this.pending||this.element.removeClass("ui-autocomplete-loading")}, +close:function(d){clearTimeout(this.closing);if(this.menu.element.is(":visible")){this.menu.element.hide();this.menu.blur();this._trigger("close",d)}},_change:function(d){this.previous!==this._value()&&this._trigger("change",d,{item:this.selectedItem})},_normalize:function(d){if(d.length&&d[0].label&&d[0].value)return d;return a.map(d,function(c){if(typeof c==="string")return{label:c,value:c};return a.extend({label:c.label||c.value,value:c.value||c.label},c)})},_suggest:function(d){var c=this.menu.element.empty().zIndex(this.element.zIndex()+ +1);this._renderMenu(c,d);this.menu.blur();this.menu.refresh();c.show();this._resizeMenu();c.position(a.extend({of:this.element},this.options.position));this.options.autoFocus&&this.menu.next(new a.Event("mouseover"))},_resizeMenu:function(){var d=this.menu.element;d.outerWidth(Math.max(d.width("").outerWidth(),this.element.outerWidth()))},_renderMenu:function(d,c){var e=this;a.each(c,function(f,i){e._renderItem(d,i)})},_renderItem:function(d,c){return a("
      • ").data("item.autocomplete",c).append(a("").text(c.label)).appendTo(d)}, +_move:function(d,c){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(d)||this.menu.last()&&/^next/.test(d)){this._value(this.term);this.menu.blur()}else this.menu[d](c);else this.search(null,c)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)}});a.extend(a.ui.autocomplete,{escapeRegex:function(d){return d.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(d,c){var e=RegExp(a.ui.autocomplete.escapeRegex(c), +"i");return a.grep(d,function(f){return e.test(f.label||f.value||f)})}})})(jQuery); +(function(a){var g,d,c,e,f=function(){var b=a(this).find(":ui-button");setTimeout(function(){b.button("refresh")},1)},i=function(b){var h=b.name,k=b.form,l=a([]);if(h)l=k?a(k).find("[name='"+h+"']"):a("[name='"+h+"']",b.ownerDocument).filter(function(){return!this.form});return l};a.widget("ui.button",{version:"1.9pre",defaultElement:"').addClass(this._triggerClass).html(j==""?k:a("").attr({src:j,alt:k,title:k})));b[l?"before":"after"](h.trigger);h.trigger.click(function(){a.datepicker._datepickerShowing&&a.datepicker._lastInput==b[0]?a.datepicker._hideDatepicker(): +a.datepicker._showDatepicker(b[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var h=new Date(2009,11,20),k=this._get(b,"dateFormat");if(k.match(/[DM]/)){var l=function(j){for(var m=0,n=0,o=0;om){m=j[o].length;n=o}return n};h.setMonth(l(this._get(b,k.match(/MM/)?"monthNames":"monthNamesShort")));h.setDate(l(this._get(b,k.match(/DD/)?"dayNames":"dayNamesShort"))+20-h.getDay())}b.input.attr("size",this._formatDate(b,h).length)}},_inlineDatepicker:function(b, +h){var k=a(b);if(!k.hasClass(this.markerClassName)){k.addClass(this.markerClassName).append(h.dpDiv).bind("setData.datepicker",function(l,j,m){h.settings[j]=m}).bind("getData.datepicker",function(l,j){return this._get(h,j)});a.data(b,"datepicker",h);this._setDate(h,this._getDefaultDate(h),true);this._updateDatepicker(h);this._updateAlternate(h);h.settings.disabled&&this._disableDatepicker(b);h.dpDiv.css("display","block")}},_dialogDatepicker:function(b,h,k,l,j){b=this._dialogInst;if(!b){this.uuid+= +1;this._dialogInput=a('');this._dialogInput.keydown(this._doKeyDown);a("body").append(this._dialogInput);b=this._dialogInst=this._newInst(this._dialogInput,false);b.settings={};a.data(this._dialogInput[0],"datepicker",b)}e(b.settings,l||{});h=h&&h.constructor==Date?this._formatDate(b,h):h;this._dialogInput.val(h);this._pos=j?j.length?j:[j.pageX,j.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ +2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");b.settings.onSelect=k;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);a.blockUI&&a.blockUI(this.dpDiv);a.data(this._dialogInput[0],"datepicker",b);return this},_destroyDatepicker:function(b){var h= +a(b),k=a.data(b,"datepicker");if(h.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();a.removeData(b,"datepicker");if(l=="input"){k.append.remove();k.trigger.remove();h.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(l=="div"||l=="span")h.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(b){var h=a(b),k=a.data(b,"datepicker");if(h.hasClass(this.markerClassName)){var l= +b.nodeName.toLowerCase();if(l=="input"){b.disabled=false;k.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(l=="div"||l=="span"){h=h.children("."+this._inlineClass);h.children().removeClass("ui-state-disabled");h.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",false)}this._disabledInputs=a.map(this._disabledInputs,function(j){return j==b?null:j})}},_disableDatepicker:function(b){var h=a(b),k=a.data(b, +"datepicker");if(h.hasClass(this.markerClassName)){var l=b.nodeName.toLowerCase();if(l=="input"){b.disabled=true;k.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(l=="div"||l=="span"){h=h.children("."+this._inlineClass);h.children().addClass("ui-state-disabled");h.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",true)}this._disabledInputs=a.map(this._disabledInputs,function(j){return j==b? +null:j});this._disabledInputs[this._disabledInputs.length]=b}},_isDisabledDatepicker:function(b){if(!b)return false;for(var h=0;h-1}},_doKeyUp:function(b){b=a.datepicker._getInst(b.target);if(b.input.val()!=b.lastVal)try{if(a.datepicker.parseDate(a.datepicker._get(b,"dateFormat"),b.input?b.input.val():null,a.datepicker._getFormatConfig(b))){a.datepicker._setDateFromField(b);a.datepicker._updateAlternate(b);a.datepicker._updateDatepicker(b)}}catch(h){a.datepicker.log(h)}return true},_showDatepicker:function(b){b=b.target||b;if(b.nodeName.toLowerCase()!= +"input")b=a("input",b.parentNode)[0];if(!(a.datepicker._isDisabledDatepicker(b)||a.datepicker._lastInput==b)){var h=a.datepicker._getInst(b);if(a.datepicker._curInst&&a.datepicker._curInst!=h){a.datepicker._curInst.dpDiv.stop(true,true);h&&a.datepicker._datepickerShowing&&a.datepicker._hideDatepicker(a.datepicker._curInst.input[0])}var k=a.datepicker._get(h,"beforeShow");k=k?k.apply(b,[b,h]):{};if(k!==false){e(h.settings,k);h.lastVal=null;a.datepicker._lastInput=b;a.datepicker._setDateFromField(h); +if(a.datepicker._inDialog)b.value="";if(!a.datepicker._pos){a.datepicker._pos=a.datepicker._findPos(b);a.datepicker._pos[1]+=b.offsetHeight}var l=false;a(b).parents().each(function(){l|=a(this).css("position")=="fixed";return!l});if(l&&a.browser.opera){a.datepicker._pos[0]-=document.documentElement.scrollLeft;a.datepicker._pos[1]-=document.documentElement.scrollTop}k={left:a.datepicker._pos[0],top:a.datepicker._pos[1]};a.datepicker._pos=null;h.dpDiv.empty();h.dpDiv.css({position:"absolute",display:"block", +top:"-1000px"});a.datepicker._updateDatepicker(h);k=a.datepicker._checkOffset(h,k,l);h.dpDiv.css({position:a.datepicker._inDialog&&a.blockUI?"static":l?"fixed":"absolute",display:"none",left:k.left+"px",top:k.top+"px"});if(!h.inline){k=a.datepicker._get(h,"showAnim");var j=a.datepicker._get(h,"duration"),m=function(){var n=h.dpDiv.find("iframe.ui-datepicker-cover");if(n.length){var o=a.datepicker._getBorders(h.dpDiv);n.css({left:-o[0],top:-o[1],width:h.dpDiv.outerWidth(),height:h.dpDiv.outerHeight()})}}; +h.dpDiv.zIndex(a(b).zIndex()+1);a.datepicker._datepickerShowing=true;if(a.effects&&(a.effects.effect[k]||a.effects[k]))h.dpDiv.show(k,a.datepicker._get(h,"showOptions"),j,m);else h.dpDiv[k||"show"](k?j:null,m);if(!k||!j)m();h.input.is(":visible")&&!h.input.is(":disabled")&&h.input.focus();a.datepicker._curInst=h}}}},_updateDatepicker:function(b){this.maxRows=4;var h=a.datepicker._getBorders(b.dpDiv);i=b;b.dpDiv.empty().append(this._generateHTML(b));var k=b.dpDiv.find("iframe.ui-datepicker-cover"); +k.length&&k.css({left:-h[0],top:-h[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()});b.dpDiv.find("."+this._dayOverClass+" a").mouseover();h=this._getNumberOfMonths(b);k=h[1];b.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");k>1&&b.dpDiv.addClass("ui-datepicker-multi-"+k).css("width",17*k+"em");b.dpDiv[(h[0]!=1||h[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");b.dpDiv[(this._get(b,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"); +b==a.datepicker._curInst&&a.datepicker._datepickerShowing&&b.input&&b.input.is(":visible")&&!b.input.is(":disabled")&&b.input[0]!=document.activeElement&&b.input.focus();if(b.yearshtml){var l=b.yearshtml;setTimeout(function(){l===b.yearshtml&&b.yearshtml&&b.dpDiv.find("select.ui-datepicker-year:first").replaceWith(b.yearshtml);l=b.yearshtml=null},0)}},_getBorders:function(b){var h=function(k){return{thin:1,medium:2,thick:3}[k]||k};return[parseFloat(h(b.css("border-left-width"))),parseFloat(h(b.css("border-top-width")))]}, +_checkOffset:function(b,h,k){var l=b.dpDiv.outerWidth(),j=b.dpDiv.outerHeight(),m=b.input?b.input.outerWidth():0,n=b.input?b.input.outerHeight():0,o=document.documentElement.clientWidth+a(document).scrollLeft(),p=document.documentElement.clientHeight+a(document).scrollTop();h.left-=this._get(b,"isRTL")?l-m:0;h.left-=k&&h.left==b.input.offset().left?a(document).scrollLeft():0;h.top-=k&&h.top==b.input.offset().top+n?a(document).scrollTop():0;h.left-=Math.min(h.left,h.left+l>o&&o>l?Math.abs(h.left+l- +o):0);h.top-=Math.min(h.top,h.top+j>p&&p>j?Math.abs(j+n):0);return h},_findPos:function(b){for(var h=this._get(this._getInst(b),"isRTL");b&&(b.type=="hidden"||b.nodeType!=1||a.expr.filters.hidden(b));)b=b[h?"previousSibling":"nextSibling"];b=a(b).offset();return[b.left,b.top]},_hideDatepicker:function(b){var h=this._curInst;if(!(!h||b&&h!=a.data(b,"datepicker")))if(this._datepickerShowing){b=this._get(h,"showAnim");var k=this._get(h,"duration"),l=function(){a.datepicker._tidyDialog(h);this._curInst= +null};if(a.effects&&(a.effects.effect[b]||a.effects[b]))h.dpDiv.hide(b,a.datepicker._get(h,"showOptions"),k,l);else h.dpDiv[b=="slideDown"?"slideUp":b=="fadeIn"?"fadeOut":"hide"](b?k:null,l);b||l();this._datepickerShowing=false;if(b=this._get(h,"onClose"))b.apply(h.input?h.input[0]:null,[h.input?h.input.val():"",h]);this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(a.blockUI){a.unblockUI();a("body").append(this.dpDiv)}}this._inDialog=false}}, +_tidyDialog:function(b){b.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")},_checkExternalClick:function(b){if(a.datepicker._curInst){b=a(b.target);var h=a.datepicker._getInst(b[0]);if(b[0].id!=a.datepicker._mainDivId&&b.parents("#"+a.datepicker._mainDivId).length==0&&!b.hasClass(a.datepicker.markerClassName)&&!b.hasClass(a.datepicker._triggerClass)&&a.datepicker._datepickerShowing&&!(a.datepicker._inDialog&&a.blockUI)||b.hasClass(a.datepicker.markerClassName)&&a.datepicker._curInst!= +h)a.datepicker._hideDatepicker()}},_adjustDate:function(b,h,k){b=a(b);var l=this._getInst(b[0]);if(!this._isDisabledDatepicker(b[0])){this._adjustInstDate(l,h+(k=="M"?this._get(l,"showCurrentAtPos"):0),k);this._updateDatepicker(l)}},_gotoToday:function(b){b=a(b);var h=this._getInst(b[0]);if(this._get(h,"gotoCurrent")&&h.currentDay){h.selectedDay=h.currentDay;h.drawMonth=h.selectedMonth=h.currentMonth;h.drawYear=h.selectedYear=h.currentYear}else{var k=new Date;h.selectedDay=k.getDate();h.drawMonth= +h.selectedMonth=k.getMonth();h.drawYear=h.selectedYear=k.getFullYear()}this._notifyChange(h);this._adjustDate(b)},_selectMonthYear:function(b,h,k){b=a(b);var l=this._getInst(b[0]);l["selected"+(k=="M"?"Month":"Year")]=l["draw"+(k=="M"?"Month":"Year")]=parseInt(h.options[h.selectedIndex].value,10);this._notifyChange(l);this._adjustDate(b)},_selectDay:function(b,h,k,l){var j=a(b);if(!(a(l).hasClass(this._unselectableClass)||this._isDisabledDatepicker(j[0]))){j=this._getInst(j[0]);j.selectedDay=j.currentDay= +a("a",l).html();j.selectedMonth=j.currentMonth=h;j.selectedYear=j.currentYear=k;this._selectDate(b,this._formatDate(j,j.currentDay,j.currentMonth,j.currentYear))}},_clearDate:function(b){b=a(b);this._getInst(b[0]);this._selectDate(b,"")},_selectDate:function(b,h){var k=this._getInst(a(b)[0]);h=h!=null?h:this._formatDate(k);k.input&&k.input.val(h);this._updateAlternate(k);var l=this._get(k,"onSelect");if(l)l.apply(k.input?k.input[0]:null,[h,k]);else k.input&&k.input.trigger("change");if(k.inline)this._updateDatepicker(k); +else{this._hideDatepicker();this._lastInput=k.input[0];typeof k.input[0]!="object"&&k.input.focus();this._lastInput=null}},_updateAlternate:function(b){var h=this._get(b,"altField");if(h){var k=this._get(b,"altFormat")||this._get(b,"dateFormat"),l=this._getDate(b),j=this.formatDate(k,l,this._getFormatConfig(b));a(h).each(function(){a(this).val(j)})}},noWeekends:function(b){b=b.getDay();return[b>0&&b<6,""]},iso8601Week:function(b){b=new Date(b.getTime());b.setDate(b.getDate()+4-(b.getDay()||7));var h= +b.getTime();b.setMonth(0);b.setDate(1);return Math.floor(Math.round((h-b)/864E5)/7)+1},parseDate:function(b,h,k){if(b==null||h==null)throw"Invalid arguments";h=typeof h=="object"?h.toString():h+"";if(h=="")return null;var l=(k?k.shortYearCutoff:null)||this._defaults.shortYearCutoff;l=typeof l!="string"?l:(new Date).getFullYear()%100+parseInt(l,10);for(var j=(k?k.dayNamesShort:null)||this._defaults.dayNamesShort,m=(k?k.dayNames:null)||this._defaults.dayNames,n=(k?k.monthNamesShort:null)||this._defaults.monthNamesShort, +o=(k?k.monthNames:null)||this._defaults.monthNames,p=k=-1,q=-1,u=-1,s=false,r=function(y){(y=C+1-1){p=1;q=u;do{l=this._getDaysInMonth(k,p-1); +if(q<=l)break;p++;q-=l}while(1)}A=this._daylightSavingAdjust(new Date(k,p-1,q));if(A.getFullYear()!=k||A.getMonth()+1!=p||A.getDate()!=q)throw"Invalid date";return A},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*864E9,formatDate:function(b,h,k){if(!h)return""; +var l=(k?k.dayNamesShort:null)||this._defaults.dayNamesShort,j=(k?k.dayNames:null)||this._defaults.dayNames,m=(k?k.monthNamesShort:null)||this._defaults.monthNamesShort;k=(k?k.monthNames:null)||this._defaults.monthNames;var n=function(r){(r=s+112?b.getHours()+2:0);return b},_setDate:function(b,h,k){var l=!h,j=b.selectedMonth,m=b.selectedYear;h=this._restrictMinMax(b,this._determineDate(b,h,new Date));b.selectedDay=b.currentDay=h.getDate();b.drawMonth=b.selectedMonth=b.currentMonth=h.getMonth();b.drawYear=b.selectedYear=b.currentYear=h.getFullYear();if((j!=b.selectedMonth||m!=b.selectedYear)&& +!k)this._notifyChange(b);this._adjustInstDate(b);if(b.input)b.input.val(l?"":this._formatDate(b))},_getDate:function(b){return!b.currentYear||b.input&&b.input.val()==""?null:this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay))},_generateHTML:function(b){var h=new Date;h=this._daylightSavingAdjust(new Date(h.getFullYear(),h.getMonth(),h.getDate()));var k=this._get(b,"isRTL"),l=this._get(b,"showButtonPanel"),j=this._get(b,"hideIfNoPrevNext"),m=this._get(b,"navigationAsDateFormat"), +n=this._getNumberOfMonths(b),o=this._get(b,"showCurrentAtPos"),p=this._get(b,"stepMonths"),q=n[0]!=1||n[1]!=1,u=this._daylightSavingAdjust(!b.currentDay?new Date(9999,9,9):new Date(b.currentYear,b.currentMonth,b.currentDay)),s=this._getMinMaxDate(b,"min"),r=this._getMinMaxDate(b,"max");o=b.drawMonth-o;var t=b.drawYear;if(o<0){o+=12;t--}if(r){var v=this._daylightSavingAdjust(new Date(r.getFullYear(),r.getMonth()-n[0]*n[1]+1,r.getDate()));for(v=s&&v +v;){o--;if(o<0){o=11;t--}}}b.drawMonth=o;b.drawYear=t;v=this._get(b,"prevText");v=!m?v:this.formatDate(v,this._daylightSavingAdjust(new Date(t,o-p,1)),this._getFormatConfig(b));v=this._canAdjustMonth(b,-1,t,o)?''+v+"":j?"":''+v+"";var w=this._get(b,"nextText");w=!m?w:this.formatDate(w,this._daylightSavingAdjust(new Date(t,o+p,1)),this._getFormatConfig(b));j=this._canAdjustMonth(b,+1,t,o)?''+w+"":j?"":''+w+"";p=this._get(b,"currentText");w=this._get(b,"gotoCurrent")&&b.currentDay?u:h;p=!m?p:this.formatDate(p,w,this._getFormatConfig(b));m=!b.inline?'":"";l=l?'
        '+(k?m:"")+(this._isInRange(b, +w)?'":"")+(k?"":m)+"
        ":"";m=parseInt(this._get(b,"firstDay"),10);m=isNaN(m)?0:m;p=this._get(b,"showWeek");w=this._get(b,"dayNames");this._get(b,"dayNamesShort");var x=this._get(b,"dayNamesMin"),C=this._get(b,"monthNames"),A=this._get(b,"monthNamesShort"),y=this._get(b,"beforeShowDay"),D=this._get(b,"showOtherMonths"), +J=this._get(b,"selectOtherMonths");this._get(b,"calculateWeek");for(var I=this._getDefaultDate(b),H="",E=0;E1)switch(M){case 0:F+=" ui-datepicker-group-first";B=" ui-corner-"+(k?"right":"left");break;case n[1]-1:F+=" ui-datepicker-group-last";B=" ui-corner-"+(k?"left":"right");break;default:F+=" ui-datepicker-group-middle"; +B=""}F+='">'}F+='
        '+(/all|left/.test(B)&&E==0?k?j:v:"")+(/all|right/.test(B)&&E==0?k?v:j:"")+this._generateMonthYearHeader(b,o,t,s,r,E>0||M>0,C,A)+'
        ';var G=p?'":"";for(B=0;B<7;B++){var z=(B+m)%7;G+="=5?' class="ui-datepicker-week-end"':"")+'>'+x[z]+""}F+= +G+"";G=this._getDaysInMonth(t,o);if(t==b.selectedYear&&o==b.selectedMonth)b.selectedDay=Math.min(b.selectedDay,G);B=(this._getFirstDayOfMonth(t,o)-m+7)%7;G=Math.ceil((B+G)/7);this.maxRows=G=q?this.maxRows>G?this.maxRows:G:G;z=this._daylightSavingAdjust(new Date(t,o,1-B));for(var Q=0;Q";var R=!p?"":'";for(B=0;B<7;B++){var N=y?y.apply(b.input?b.input[0]:null,[z]):[true,""],L=z.getMonth()!= +o,O=L&&!J||!N[0]||s&&zr;R+='";z.setDate(z.getDate()+1);z=this._daylightSavingAdjust(z)}F+=R+""}o++;if(o>11){o=0;t++}F+="
        '+this._get(b,"weekHeader")+"
        '+this._get(b,"calculateWeek")(z)+""+(L&&!D?" ":O?''+z.getDate()+"":''+z.getDate()+"")+"
        "+(q?""+ +(n[0]>0&&M==n[1]-1?'
        ':""):"");K+=F}H+=K}H+=l+(a.browser.msie&&parseInt(a.browser.version,10)<7&&!b.inline?'':"");b._keyEvent=false;return H},_generateMonthYearHeader:function(b,h,k,l,j,m,n,o){var p=this._get(b,"changeMonth"),q=this._get(b,"changeYear"),u=this._get(b,"showMonthAfterYear"),s='
        ',r="";if(m||!p)r+=''+ +n[h]+"";else{n=l&&l.getFullYear()==k;var t=j&&j.getFullYear()==k;r+='"}u||(s+=r+(m||!(p&&q)?" ":""));if(!b.yearshtml){b.yearshtml="";if(m||!q)s+=''+k+"";else{o=this._get(b, +"yearRange").split(":");var w=(new Date).getFullYear();n=function(x){x=x.match(/c[+-].*/)?k+parseInt(x.substring(1),10):x.match(/[+-].*/)?w+parseInt(x,10):parseInt(x,10);return isNaN(x)?w:x};h=n(o[0]);o=Math.max(h,n(o[1]||""));h=l?Math.max(h,l.getFullYear()):h;o=j?Math.min(o,j.getFullYear()):o;for(b.yearshtml+='";s+=b.yearshtml;b.yearshtml=null}}s+=this._get(b,"yearSuffix");if(u)s+=(m||!(p&&q)?" ":"")+r;s+="
        ";return s},_adjustInstDate:function(b,h,k){var l=b.drawYear+(k=="Y"?h:0),j=b.drawMonth+(k=="M"?h:0);h=Math.min(b.selectedDay,this._getDaysInMonth(l,j))+(k=="D"?h:0);l=this._restrictMinMax(b,this._daylightSavingAdjust(new Date(l,j,h)));b.selectedDay=l.getDate();b.drawMonth=b.selectedMonth=l.getMonth();b.drawYear=b.selectedYear=l.getFullYear();if(k== +"M"||k=="Y")this._notifyChange(b)},_restrictMinMax:function(b,h){var k=this._getMinMaxDate(b,"min"),l=this._getMinMaxDate(b,"max");k=k&&hl?l:k},_notifyChange:function(b){var h=this._get(b,"onChangeMonthYear");if(h)h.apply(b.input?b.input[0]:null,[b.selectedYear,b.selectedMonth+1,b])},_getNumberOfMonths:function(b){b=this._get(b,"numberOfMonths");return b==null?[1,1]:typeof b=="number"?[1,b]:b},_getMinMaxDate:function(b,h){return this._determineDate(b,this._get(b,h+"Date"),null)}, +_getDaysInMonth:function(b,h){return 32-this._daylightSavingAdjust(new Date(b,h,32)).getDate()},_getFirstDayOfMonth:function(b,h){return(new Date(b,h,1)).getDay()},_canAdjustMonth:function(b,h,k,l){var j=this._getNumberOfMonths(b);k=this._daylightSavingAdjust(new Date(k,l+(h<0?h:j[0]*j[1]),1));h<0&&k.setDate(this._getDaysInMonth(k.getFullYear(),k.getMonth()));return this._isInRange(b,k)},_isInRange:function(b,h){var k=this._getMinMaxDate(b,"min"),l=this._getMinMaxDate(b,"max");return(!k||h.getTime()>= +k.getTime())&&(!l||h.getTime()<=l.getTime())},_getFormatConfig:function(b){var h=this._get(b,"shortYearCutoff");h=typeof h!="string"?h:(new Date).getFullYear()%100+parseInt(h,10);return{shortYearCutoff:h,dayNamesShort:this._get(b,"dayNamesShort"),dayNames:this._get(b,"dayNames"),monthNamesShort:this._get(b,"monthNamesShort"),monthNames:this._get(b,"monthNames")}},_formatDate:function(b,h,k,l){if(!h){b.currentDay=b.selectedDay;b.currentMonth=b.selectedMonth;b.currentYear=b.selectedYear}h=h?typeof h== +"object"?h:this._daylightSavingAdjust(new Date(l,k,h)):this._daylightSavingAdjust(new Date(b.currentYear,b.currentMonth,b.currentDay));return this.formatDate(this._get(b,"dateFormat"),h,this._getFormatConfig(b))}});a.fn.datepicker=function(b){if(!this.length)return this;if(!a.datepicker.initialized){a(document).mousedown(a.datepicker._checkExternalClick).find("body").append(a.datepicker.dpDiv);a.datepicker.initialized=true}var h=Array.prototype.slice.call(arguments,1);if(typeof b=="string"&&(b=="isDisabled"|| +b=="getDate"||b=="widget"))return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(h));if(b=="option"&&arguments.length==2&&typeof arguments[1]=="string")return a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this[0]].concat(h));return this.each(function(){typeof b=="string"?a.datepicker["_"+b+"Datepicker"].apply(a.datepicker,[this].concat(h)):a.datepicker._attachDatepicker(this,b)})};a.datepicker=new d;a.datepicker.initialized=false;a.datepicker.uuid=(new Date).getTime(); +a.datepicker.version="1.9pre";window["DP_jQuery_"+f]=a})(jQuery); +(function(a,g){var d={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},c={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true};a.widget("ui.dialog",{version:"1.9pre",options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var f=a(this).css(e).offset().top; +f<0&&a(this).css("top",e.top-f)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var e=this,f=e.options,i=f.title||" ",b=a.ui.dialog.getTitleId(e.element),h=(e.uiDialog=a("
        ")).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+f.dialogClass).css({display:"none",outline:0,zIndex:f.zIndex}).attr("tabIndex", +-1).keydown(function(j){if(f.closeOnEscape&&!j.isDefaultPrevented()&&j.keyCode&&j.keyCode===a.ui.keyCode.ESCAPE){e.close(j);j.preventDefault()}}).attr({role:"dialog","aria-labelledby":b}).mousedown(function(j){e.moveToTop(false,j)}).appendTo("body");e.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(h);var k=(e.uiDialogTitlebar=a("
        ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(h),l=a("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role", +"button").click(function(j){j.preventDefault();e.close(j)}).appendTo(k);(e.uiDialogTitlebarCloseText=a("")).addClass("ui-icon ui-icon-closethick").text(f.closeText).appendTo(l);a("").addClass("ui-dialog-title").attr("id",b).html(i).prependTo(k);k.find("*").add(k).disableSelection();this._hoverable(l);this._focusable(l);f.draggable&&a.fn.draggable&&e._makeDraggable();f.resizable&&a.fn.resizable&&e._makeResizable();e._createButtons(f.buttons);e._isOpen=false;a.fn.bgiframe&&h.bgiframe()}, +_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){this.overlay&&this.overlay.destroy();this.uiDialog.hide();this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body");this.uiDialog.remove();this.originalTitle&&this.element.attr("title",this.originalTitle)},widget:function(){return this.uiDialog},close:function(e){if(!this._isOpen)return f;var f=this,i,b;if(false!==f._trigger("beforeClose",e)){f._isOpen=false;f.overlay&&f.overlay.destroy();f.uiDialog.unbind("keypress.ui-dialog"); +if(f.options.hide)f.uiDialog.hide(f.options.hide,function(){f._trigger("close",e)});else{f.uiDialog.hide();f._trigger("close",e)}a.ui.dialog.overlay.resize();if(f.options.modal){i=0;a(".ui-dialog").each(function(){if(this!==f.uiDialog[0]){b=a(this).css("z-index");isNaN(b)||(i=Math.max(i,b))}});a.ui.dialog.maxZ=i}return f}},isOpen:function(){return this._isOpen},moveToTop:function(e,f){var i=this.options;if(i.modal&&!e||!i.stack&&!i.modal)return this._trigger("focus",f);if(i.zIndex>a.ui.dialog.maxZ)a.ui.dialog.maxZ= +i.zIndex;if(this.overlay){a.ui.dialog.maxZ+=1;a.ui.dialog.overlay.maxZ=a.ui.dialog.maxZ;this.overlay.$el.css("z-index",a.ui.dialog.overlay.maxZ)}i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()};a.ui.dialog.maxZ+=1;this.uiDialog.css("z-index",a.ui.dialog.maxZ);this.element.attr(i);this._trigger("focus",f);return this},open:function(){if(!this._isOpen){var e=this.options,f=this.uiDialog;this._size();this._position(e.position);f.show(e.show);this.overlay=e.modal?new a.ui.dialog.overlay(this): +null;this.moveToTop(true);e.modal&&f.bind("keydown.ui-dialog",function(i){if(i.keyCode===a.ui.keyCode.TAB){var b=a(":tabbable",this),h=b.filter(":first");b=b.filter(":last");if(i.target===b[0]&&!i.shiftKey){h.focus(1);return false}else if(i.target===h[0]&&i.shiftKey){b.focus(1);return false}}});e=this.element.find(":tabbable");if(!e.length){e=f.find(".ui-dialog-buttonpane :tabbable");e.length||(e=f)}e.eq(0).focus();this._isOpen=true;this._trigger("open");return this}},_createButtons:function(e){var f= +this,i=false;f.uiDialog.find(".ui-dialog-buttonpane").remove();typeof e==="object"&&e!==null&&a.each(e,function(){return!(i=true)});if(i){var b=a("
        ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),h=a("
        ").addClass("ui-dialog-buttonset").appendTo(b);a.each(e,function(k,l){l=a.isFunction(l)?{click:l,text:k}:l;var j=a("
        ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove()},value:function(d){if(d===g)return this._value();this._setOption("value",d);return this},_setOption:function(d,c){if(d==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}this._super("_setOption",d,c)},_value:function(){var d=this.options.value;if(typeof d!=="number")d=0;return Math.min(this.options.max,Math.max(this.min,d))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var d= +this.value(),c=this._percentage();if(this.oldValue!==d){this.oldValue=d;this._trigger("change")}this.valueDiv.toggle(d>this.min).toggleClass("ui-corner-right",d===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",d)}})})(jQuery); +(function(a){a.widget("ui.slider",a.ui.mouse,{version:"1.9pre",widgetEventPrefix:"slide",options:{animate:false,distance:0,max:100,min:0,orientation:"horizontal",range:false,step:1,value:0,values:null},_create:function(){var g=this,d=this.options,c=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),e=d.values&&d.values.length||1,f=[];this._mouseSliding=this._keySliding=false;this._animateOff=true;this._handleIndex=null;this._detectOrientation();this._mouseInit();this.element.addClass("ui-slider ui-slider-"+ +this.orientation+" ui-widget ui-widget-content ui-corner-all"+(d.disabled?" ui-slider-disabled ui-disabled":""));this.range=a([]);if(d.range){if(d.range===true){if(!d.values)d.values=[this._valueMin(),this._valueMin()];if(d.values.length&&d.values.length!==2)d.values=[d.values[0],d.values[0]]}this.range=a("
        ").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(d.range==="min"||d.range==="max"?" ui-slider-range-"+d.range:""))}for(var i=c.length;i"); +this.handles=c.add(a(f.join("")).appendTo(g.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){d.disabled||a(this).addClass("ui-state-hover")},function(){a(this).removeClass("ui-state-hover")}).focus(function(){if(d.disabled)a(this).blur();else{a(".ui-slider .ui-state-focus").removeClass("ui-state-focus");a(this).addClass("ui-state-focus")}}).blur(function(){a(this).removeClass("ui-state-focus")});this.handles.each(function(b){a(this).data("index.ui-slider-handle", +b)});this.handles.keydown(function(b){var h=true,k=a(this).data("index.ui-slider-handle"),l,j,m;if(!g.options.disabled){switch(b.keyCode){case a.ui.keyCode.HOME:case a.ui.keyCode.END:case a.ui.keyCode.PAGE_UP:case a.ui.keyCode.PAGE_DOWN:case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:h=false;if(!g._keySliding){g._keySliding=true;a(this).addClass("ui-state-active");l=g._start(b,k);if(l===false)return}}m=g.options.step;l=g.options.values&&g.options.values.length? +j=g.values(k):j=g.value();switch(b.keyCode){case a.ui.keyCode.HOME:j=g._valueMin();break;case a.ui.keyCode.END:j=g._valueMax();break;case a.ui.keyCode.PAGE_UP:j=g._trimAlignValue(l+(g._valueMax()-g._valueMin())/5);break;case a.ui.keyCode.PAGE_DOWN:j=g._trimAlignValue(l-(g._valueMax()-g._valueMin())/5);break;case a.ui.keyCode.UP:case a.ui.keyCode.RIGHT:if(l===g._valueMax())return;j=g._trimAlignValue(l+m);break;case a.ui.keyCode.DOWN:case a.ui.keyCode.LEFT:if(l===g._valueMin())return;j=g._trimAlignValue(l- +m)}g._slide(b,k,j);return h}}).keyup(function(b){var h=a(this).data("index.ui-slider-handle");if(g._keySliding){g._keySliding=false;g._stop(b,h);g._change(b,h);a(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); +return this},_mouseCapture:function(g){var d=this.options,c,e,f,i,b;if(d.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:g.pageX,y:g.pageY});e=this._valueMax()-this._valueMin()+1;i=this;this.handles.each(function(h){var k=Math.abs(c-i.values(h));if(e>k){e=k;f=a(this);b=h}});if(d.range===true&&this.values(1)===d.min){b+=1;f=a(this.handles[b])}if(this._start(g,b)===false)return false; +this._mouseSliding=true;i._handleIndex=b;f.addClass("ui-state-active").focus();d=f.offset();this._clickOffset=!a(g.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:g.pageX-d.left-f.width()/2,top:g.pageY-d.top-f.height()/2-(parseInt(f.css("borderTopWidth"),10)||0)-(parseInt(f.css("borderBottomWidth"),10)||0)+(parseInt(f.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(g,b,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(g){var d= +this._normValueFromMouse({x:g.pageX,y:g.pageY});this._slide(g,this._handleIndex,d);return false},_mouseStop:function(g){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(g,this._handleIndex);this._change(g,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(g){var d;if(this.orientation==="horizontal"){d= +this.elementSize.width;g=g.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{d=this.elementSize.height;g=g.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}d=g/d;if(d>1)d=1;if(d<0)d=0;if(this.orientation==="vertical")d=1-d;g=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+d*g)},_start:function(g,d){var c={handle:this.handles[d],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(d); +c.values=this.values()}return this._trigger("start",g,c)},_slide:function(g,d,c){var e;if(this.options.values&&this.options.values.length){e=this.values(d?0:1);if(this.options.values.length===2&&this.options.range===true&&(d===0&&c>e||d===1&&c1){this.options.values[g]=this._trimAlignValue(d);this._refreshValue();this._change(null,g)}else if(arguments.length)if(a.isArray(arguments[0])){c=this.options.values;e=arguments[0];for(f=0;f=this._valueMax())return this._valueMax();var d=this.options.step>0?this.options.step:1,c=(g-this._valueMin())%d;g-=c;if(Math.abs(c)*2>=d)g+=c>0?d:-d;return parseFloat(g.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var g= +this.options.range,d=this.options,c=this,e=!this._animateOff?d.animate:false,f,i={},b,h,k,l;if(this.options.values&&this.options.values.length)this.handles.each(function(j){f=(c.values(j)-c._valueMin())/(c._valueMax()-c._valueMin())*100;i[c.orientation==="horizontal"?"left":"bottom"]=f+"%";a(this).stop(1,1)[e?"animate":"css"](i,d.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(j===0)c.range.stop(1,1)[e?"animate":"css"]({left:f+"%"},d.animate);if(j===1)c.range[e?"animate":"css"]({width:f- +b+"%"},{queue:false,duration:d.animate})}else{if(j===0)c.range.stop(1,1)[e?"animate":"css"]({bottom:f+"%"},d.animate);if(j===1)c.range[e?"animate":"css"]({height:f-b+"%"},{queue:false,duration:d.animate})}b=f});else{h=this.value();k=this._valueMin();l=this._valueMax();f=l!==k?(h-k)/(l-k)*100:0;i[c.orientation==="horizontal"?"left":"bottom"]=f+"%";this.handle.stop(1,1)[e?"animate":"css"](i,d.animate);if(g==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[e?"animate":"css"]({width:f+"%"}, +d.animate);if(g==="max"&&this.orientation==="horizontal")this.range[e?"animate":"css"]({width:100-f+"%"},{queue:false,duration:d.animate});if(g==="min"&&this.orientation==="vertical")this.range.stop(1,1)[e?"animate":"css"]({height:f+"%"},d.animate);if(g==="max"&&this.orientation==="vertical")this.range[e?"animate":"css"]({height:100-f+"%"},{queue:false,duration:d.animate})}}})})(jQuery); +(function(a){function g(d){return function(){var c=this.element.val();d.apply(this,arguments);this._refresh();c!==this.element.val()&&this._trigger("change")}}a.widget("ui.spinner",{version:"1.9pre",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,incremental:true,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._value(this.element.val(),true);this._draw();this._bind(this._events);this._refresh()},_getCreateOptions:function(){var d= +{},c=this.element;a.each(["min","max","step"],function(e,f){var i=c.attr(f);if(i!==undefined&&i.length)d[f]=i});return d},_events:{keydown:function(d){this._start(d)&&this._keydown(d)&&d.preventDefault()},keyup:"_stop",focus:function(){this.uiSpinner.addClass("ui-state-active");this.previous=this.element.val()},blur:function(d){this._refresh();this.uiSpinner.removeClass("ui-state-active");this.previous!==this.element.val()&&this._trigger("change",d)},mousewheel:function(d,c){if(c){if(!this.spinning&& +!this._start(d))return false;this._spin((c>0?1:-1)*this.options.step,d);clearTimeout(this.mousewheelTimer);this.mousewheelTimer=setTimeout(function(){this.spinning&&this._stop(d)},100);d.preventDefault()}},"mousedown .ui-spinner-button":function(d){d.preventDefault();document.activeElement!==this.element[0]&&this.element.focus();if(this._start(d)!==false)this._repeat(null,a(d.currentTarget).hasClass("ui-spinner-up")?1:-1,d)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(d){if(a(d.currentTarget).hasClass("ui-state-active")){if(this._start(d)=== +false)return false;this._repeat(null,a(d.currentTarget).hasClass("ui-spinner-up")?1:-1,d)}},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var d=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this._hoverable(d);this.element.attr("role","spinbutton");this.buttons=d.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all");this.buttons.height()===d.height()&&d.height()> +0&&d.height(d.height());this.options.disabled&&this.disable()},_keydown:function(d){var c=this.options,e=a.ui.keyCode;switch(d.keyCode){case e.UP:this._repeat(null,1,d);return true;case e.DOWN:this._repeat(null,-1,d);return true;case e.PAGE_UP:this._repeat(null,c.page,d);return true;case e.PAGE_DOWN:this._repeat(null,-c.page,d);return true}return false},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""}, +_start:function(d){if(!this.spinning&&this._trigger("start",d)===false)return false;if(!this.counter)this.counter=1;return this.spinning=true},_repeat:function(d,c,e){d=d||500;clearTimeout(this.timer);this.timer=this._delay(function(){this._repeat(40,c,e)},d);this._spin(c*this.options.step,e)},_spin:function(d,c){var e=this.value()||0;if(!this.counter)this.counter=1;e=this._adjustValue(e+d*this._increment(this.counter));if(!this.spinning||this._trigger("spin",c,{value:e})!==false){this._value(e); +this.counter++}},_increment:function(d){var c=this.options.incremental;if(c)return a.isFunction(c)?c(d):Math.floor(d*d*d/5E4-d*d/500+17*d/200+1);return 1},_precision:function(){var d=this._precisionOf(this.options.step);if(this.options.min!==null)d=Math.max(d,this._precisionOf(this.options.min));return d},_precisionOf:function(d){d=d.toString();var c=d.indexOf(".");return c===-1?0:d.length-c-1},_adjustValue:function(d){var c,e=this.options;c=e.min!==null?e.min:0;d=Math.round((d-c)/e.step)*e.step; +d=parseFloat((c+d).toFixed(this._precision()));if(e.max!==null&&d>e.max)return e.max;if(e.min!==null&&d1&&b.href.replace(f,"")===i}}();a.widget("ui.tabs",{version:"1.9pre",options:{active:null,collapsible:false,event:"click",fx:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var f=this,i=f.options,b=i.active;f.running=false;f.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all");f._processTabs();if(b===null){location.hash&& +f.anchors.each(function(h,k){if(k.hash===location.hash){b=h;return false}});if(b===null)b=f.lis.filter(".ui-tabs-active").index();if(b===null||b===-1)b=f.lis.length?0:false}if(b!==false){b=this.lis.eq(b).index();if(b===-1)b=i.collapsible?false:0}i.active=b;if(!i.collapsible&&i.active===false&&this.anchors.length)i.active=0;if(a.isArray(i.disabled))i.disabled=a.unique(i.disabled.concat(a.map(this.lis.filter(".ui-state-disabled"),function(h){return f.lis.index(h)}))).sort();this._setupFx(i.fx);this._refresh(); +this.panels.hide();this.lis.removeClass("ui-tabs-active ui-state-active");if(i.active!==false&&this.anchors.length){this.active=this._findActive(i.active);f._getPanelForTab(this.active).show();this.lis.eq(i.active).addClass("ui-tabs-active ui-state-active");this.load(i.active)}else this.active=a()},_setOption:function(f,i){if(f=="active")this._activate(i);else if(f==="disabled")this._setupDisabled(i);else{this._super("_setOption",f,i);f==="collapsible"&&!i&&this.options.active===false&&this._activate(0); +f==="event"&&this._setupEvents(i);f==="fx"&&this._setupFx(i)}},_tabId:function(f){return a(f).attr("aria-controls")||"ui-tabs-"+ ++d},_sanitizeSelector:function(f){return f?f.replace(/[!"$%&'()*+,.\/:;<=>?@[\]^`{|}~]/g,"\\$&"):""},refresh:function(){var f=this.options,i=this.list.children(":has(a[href])");f.disabled=a.map(i.filter(".ui-state-disabled"),function(b){return i.index(b)});this._processTabs();this._refresh();this.panels.not(this._getPanelForTab(this.active)).hide();if(f.active===false|| +!this.anchors.length){f.active=false;this.active=a()}else if(this.active.length&&!a.contains(this.list[0],this.active[0])){f=f.active-1;this._activate(f>=0?f:0)}else f.active=this.anchors.index(this.active)},_refresh:function(){var f=this.options;this.element.toggleClass("ui-tabs-collapsible",f.collapsible);this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"); +this._setupDisabled(f.disabled);this._setupEvents(f.event);this.lis.unbind(".tabs");this._focusable(this.lis);this._hoverable(this.lis)},_processTabs:function(){var f=this;this.list=this.element.find("ol,ul").eq(0);this.lis=a(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return a("a",this)[0]});this.panels=a([]);this.anchors.each(function(i,b){var h,k;if(c(b)){h=b.hash;k=f.element.find(f._sanitizeSelector(h))}else{var l=f._tabId(b);h="#"+l;k=f.element.find(h);if(!k.length){k= +f._createPanel(l);k.insertAfter(f.panels[i-1]||f.list)}}if(k.length)f.panels=f.panels.add(k);a(b).attr("aria-controls",h.substring(1))})},_createPanel:function(f){return a("
        ").attr("id",f).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("destroy.tabs",true)},_setupDisabled:function(f){if(a.isArray(f))if(f.length){if(f.length===this.anchors.length)f=true}else f=false;for(var i=0,b;b=this.lis[i];i++)a(b).toggleClass("ui-state-disabled",f===true||a.inArray(i,f)!==-1);this.options.disabled= +f},_setupFx:function(f){if(f)if(a.isArray(f)){this.hideFx=f[0];this.showFx=f[1]}else this.hideFx=this.showFx=f},_resetStyle:function(f,i){!a.support.opacity&&i.opacity&&f[0].style.removeAttribute("filter")},_setupEvents:function(f){this.anchors.unbind(".tabs");f&&this.anchors.bind(f.split(" ").join(".tabs ")+".tabs",a.proxy(this,"_eventHandler"));this.anchors.bind("click.tabs",function(i){i.preventDefault()})},_eventHandler:function(f){var i=this.options,b=this.active,h=a(f.currentTarget),k=h[0]=== +b[0],l=k&&i.collapsible,j=l?a():this._getPanelForTab(h),m=!b.length?a():this._getPanelForTab(b),n=h.closest("li");b={oldTab:b,oldPanel:m,newTab:l?a():h,newPanel:j};f.preventDefault();if(n.hasClass("ui-state-disabled")||n.hasClass("ui-tabs-loading")||this.running||k&&!i.collapsible||this._trigger("beforeActivate",f,b)===false)h[0].blur();else{i.active=l?false:this.anchors.index(h);this.active=k?a():h;this.xhr&&this.xhr.abort();if(!m.length&&!j.length)throw"jQuery UI Tabs: Mismatching fragment identifier."; +if(j.length){this.load(this.anchors.index(h),f);h[0].blur()}this._toggle(f,b)}},_toggle:function(f,i){function b(){k.running=false;k._trigger("activate",f,i)}function h(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active");if(l.length&&k.showFx)l.animate(k.showFx,k.showFx.duration||"normal",function(){k._resetStyle(a(this),k.showFx);b()});else{l.show();b()}}var k=this,l=i.newPanel,j=i.oldPanel;k.running=true;if(j.length&&k.hideFx)j.animate(k.hideFx,k.hideFx.duration||"normal",function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"); +k._resetStyle(a(this),k.hideFx);h()});else{i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active");j.hide();h()}},_activate:function(f){f=this._findActive(f)[0];if(f!==this.active[0]){f=f||this.active[0];this._eventHandler({target:f,currentTarget:f,preventDefault:a.noop})}},_findActive:function(f){return typeof f==="number"?this.anchors.eq(f):typeof f==="string"?this.anchors.filter("[href$='"+f+"']"):a()},_getIndex:function(f){if(typeof f=="string")f=this.anchors.index(this.anchors.filter("[href$="+ +f+"]"));return f},_destroy:function(){this.xhr&&this.xhr.abort();this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.unbind(".tabs").removeData("href.tabs").removeData("load.tabs");this.lis.unbind(".tabs").add(this.panels).each(function(){a.data(this,"destroy.tabs")?a(this).remove():a(this).removeClass("ui-state-default ui-corner-top ui-tabs-active ui-state-active ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom")}); +return this},enable:function(f){var i=this.options.disabled;if(i!==false){if(f===g)i=false;else{f=this._getIndex(f);i=a.isArray(i)?a.map(i,function(b){return b!==f?b:null}):a.map(this.lis,function(b,h){return h!==f?h:null})}this._setupDisabled(i)}},disable:function(f){var i=this.options.disabled;if(i!==true){if(f===g)i=true;else{f=this._getIndex(f);if(a.inArray(f,i)!==-1)return;i=a.isArray(i)?a.merge([f],i).sort():[f]}this._setupDisabled(i)}},load:function(f,i){f=this._getIndex(f);var b=this,h=this.anchors.eq(f), +k=b._getPanelForTab(h),l={tab:h,panel:k};if(!c(h[0])){if(this.xhr=a.ajax({url:h.attr("href"),beforeSend:function(j,m){return b._trigger("beforeLoad",i,a.extend({jqXHR:j,ajaxSettings:m},l))}})){this.lis.eq(f).addClass("ui-tabs-loading");this.xhr.success(function(j){setTimeout(function(){k.html(j);b._trigger("load",i,l)},1)}).complete(function(j,m){setTimeout(function(){m==="abort"&&b.panels.stop(false,true);b.lis.eq(f).removeClass("ui-tabs-loading");j===b.xhr&&delete b.xhr})})}return this}},_getPanelForTab:function(f){return this.element.find(this._sanitizeSelector("#"+ +a(f).attr("aria-controls")))}});if(a.uiBackCompat!==false){a.ui.tabs.prototype._ui=function(f,i){return{tab:f,panel:i,index:this.anchors.index(f)}};(function(f,i){i.url=function(b,h){this.anchors.eq(b).attr("href",h)}})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){f.extend(i.options,{ajaxOptions:null,cache:false});var b=i._create,h=i._setOption,k=i._destroy,l=i.url||f.noop;f.extend(i,{_create:function(){b.call(this);var j=this;this.element.bind("tabsbeforeload.tabs",function(m,n){if(f.data(n.tab[0], +"cache.tabs"))m.preventDefault();else{f.extend(n.ajaxSettings,j.options.ajaxOptions,{error:function(o,p){try{j.options.ajaxOptions.error(o,p,n.tab.closest("li").index(),n.tab[0])}catch(q){}}});n.jqXHR.success(function(){j.options.cache&&f.data(n.tab[0],"cache.tabs",true)})}})},_setOption:function(j,m){j==="cache"&&m===false&&this.anchors.removeData("cache.tabs");h.apply(this,arguments)},_destroy:function(){this.anchors.removeData("cache.tabs");k.call(this)},url:function(j){this.anchors.eq(j).removeData("cache.tabs"); +l.apply(this,arguments)}})})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){i.abort=function(){this.xhr&&this.xhr.abort()}})(jQuery,jQuery.ui.tabs.prototype);a.widget("ui.tabs",a.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super("_create");this._bind({tabsbeforeload:function(f,i){if(this.options.spinner){var b=i.tab.find("span"),h=b.html();b.html(this.options.spinner);i.jqXHR.complete(function(){b.html(h)})}}})}});(function(f,i){f.extend(i.options,{enable:null,disable:null}); +var b=i.enable,h=i.disable;i.enable=function(k){var l=this.options,j;if(k&&l.disabled===true||f.isArray(l.disabled)&&f.inArray(k,l.disabled)!==-1)j=true;b.apply(this,arguments);j&&this._trigger("enable",null,this._ui(this.anchors[k],this.panels[k]))};i.disable=function(k){var l=this.options,j;if(k&&l.disabled===false||f.isArray(l.disabled)&&f.inArray(k,l.disabled)===-1)j=true;h.apply(this,arguments);j&&this._trigger("disable",null,this._ui(this.anchors[k],this.panels[k]))}})(jQuery,jQuery.ui.tabs.prototype); +(function(f,i){f.extend(i.options,{add:null,remove:null,tabTemplate:"
      • #{label}
      • "});i.add=function(b,h,k){if(k===g)k=this.anchors.length;var l=this.options;h=f(l.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,h));b=!b.indexOf("#")?b.replace("#",""):this._tabId(h.find("a")[0]);h.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);h.find("a").attr("aria-controls",b);var j=k>=this.lis.length,m=this.element.find("#"+b);if(!m.length){m= +this._createPanel(b);if(j)k>0?m.insertAfter(this.panels.eq(-1)):m.appendTo(this.element);else m.insertBefore(this.panels[k])}m.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide();j?h.appendTo(this.list):h.insertBefore(this.lis[k]);l.disabled=f.map(l.disabled,function(n){return n>=k?++n:n});this.refresh();this.lis.length===1&&l.active===false&&this.option("active",0);this._trigger("add",null,this._ui(this.anchors[k],this.panels[k]));return this};i.remove=function(b){b=this._getIndex(b); +var h=this.options,k=this.lis.eq(b).remove(),l=this._getPanelForTab(k.find("a[aria-controls]")).remove();if(k.hasClass("ui-tabs-active")&&this.anchors.length>2)this._activate(b+(b+1=b?--j:j});this.refresh();this._trigger("remove",null,this._ui(k.find("a")[0],l[0]));return this}})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){i.length=function(){return this.anchors.length}})(jQuery,jQuery.ui.tabs.prototype); +(function(f,i){f.extend(i.options,{idPrefix:"ui-tabs-"});i._tabId=function(b){return f(b).attr("aria-controls")||b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+ ++d}})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){f.extend(i.options,{panelTemplate:"
        "});i._createPanel=function(b){return f(this.options.panelTemplate).attr("id",b).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("destroy.tabs",true)}})(jQuery,jQuery.ui.tabs.prototype); +(function(f,i){var b=i._create,h=i._setOption,k=i._eventHandler;i._create=function(){var l=this.options;if(l.active===null&&l.selected!==g)l.active=l.selected===-1?false:l.selected;b.call(this);l.selected=l.active;if(l.selected===false)l.selected=-1};i._setOption=function(l,j){if(l!=="selected")return h.apply(this,arguments);var m=this.options;h.call(this,"active",j===-1?false:j);m.selected=m.active;if(m.selected===false)m.selected=-1};i._eventHandler=function(){k.apply(this,arguments);this.options.selected= +this.options.active;if(this.options.selected===false)this.options.selected=-1}})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){f.extend(i.options,{show:null,select:null});var b=i._create,h=i._trigger;i._create=function(){b.call(this);this.options.active!==false&&this._trigger("show",null,this._ui(this.active[0],this._getPanelForTab(this.active)[0]))};i._trigger=function(k,l,j){if(!h.apply(this,arguments))return false;if(k==="beforeActivate"&&j.newTab.length)h.call(this,"select",l,{tab:j.newTab[0], +panel:j.newPanel[0],index:j.newTab.closest("li").index()});else k==="activate"&&j.newTab.length&&h.call(this,"show",l,{tab:j.newTab[0],panel:j.newPanel[0],index:j.newTab.closest("li").index()})}})(jQuery,jQuery.ui.tabs.prototype);(function(f,i){i.select=function(b){b=this._getIndex(b);if(b===-1)if(this.options.collapsible&&this.options.selected!==-1)b=this.options.selected;else return;this.anchors.eq(b).trigger(this.options.event+".tabs")}})(jQuery,jQuery.ui.tabs.prototype);var e=0;a.widget("ui.tabs", +a.ui.tabs,{options:{cookie:null},_create:function(){var f=this.options,i;if(f.active==null&&f.cookie){i=parseInt(this._cookie(),10);if(i===-1)i=false;f.active=i}this._super("_create")},_cookie:function(f){var i=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++e)];if(arguments.length){i.push(f===false?-1:f);i.push(this.options.cookie)}return a.cookie.apply(null,i)},_refresh:function(){this._super("_refresh");this.options.cookie&&this._cookie(this.options.active,this.options.cookie)}, +_eventHandler:function(){this._superApply("_eventHandler",arguments);this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super("_destroy");this.options.cookie&&this._cookie(null,this.options.cookie)}});a.widget("ui.tabs",a.ui.tabs,{_trigger:function(f,i,b){b=a.extend({},b);if(f==="load"){b.panel=b.panel[0];b.tab=b.tab[0]}return this._super("_trigger",f,i,b)}})}})(jQuery); +(function(a){var g=0;a.widget("ui.tooltip",{version:"1.9pre",options:{content:function(){return a(this).attr("title")},hide:true,items:"[title]",position:{my:"left+15 center",at:"right center",collision:"flipfit flipfit"},show:true,tooltipClass:null,close:null,open:null},_create:function(){this._bind({mouseover:"open",focusin:"open"});this.tooltips={}},_setOption:function(d,c){if(d==="disabled"){this[c?"_disable":"_enable"]();this.options[d]=c}else this._super("_setOption",d,c)},_disable:function(){var d= +this;a.each(this.tooltips,function(c,e){var f=a.Event("blur");f.target=f.currentTarget=e[0];d.close(f,true)});this.element.find(this.options.items).andSelf().each(function(){var c=a(this);c.is("[title]")&&c.data("tooltip-title",c.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var d=a(this);d.data("tooltip-title")&&d.attr("title",d.data("tooltip-title"))})},open:function(d){var c,e=this,f=a(d?d.target:this.element).closest(this.options.items); +if(!(!f.length||f.attr("aria-describedby"))){f.data("tooltip-title")||f.data("tooltip-title",f.attr("title"));(c=this.options.content.call(f[0],function(i){setTimeout(function(){e._open(d,f,i)},1)}))&&e._open(d,f,c)}},_open:function(d,c,e){if(e){c.is("[title]")&&c.attr("title","");var f=this._find(c);if(!f.length){f=this._tooltip(c);c.attr("aria-describedby",f.attr("id"))}f.find(".ui-tooltip-content").html(e);f.stop(true).position(a.extend({of:c},this.options.position)).hide();this._show(f,this.options.show); +this._trigger("open",d,{tooltip:f});this._bind(c,{mouseleave:"close",blur:"close",keyup:function(i){if(i.keyCode==a.ui.keyCode.ESCAPE){i=a.Event(i);i.currentTarget=c[0];this.close(i,true)}}})}},close:function(d,c){var e=this,f=a(d?d.currentTarget:this.element),i=this._find(f);if(!(!c&&document.activeElement===f[0])){f.data("tooltip-title")&&f.attr("title",f.data("tooltip-title"));f.removeAttr("aria-describedby");i.stop(true);this._hide(i,this.options.hide,function(){a(this).remove();delete e.tooltips[this.id]}); +f.unbind("mouseleave.tooltip blur.tooltip keyup.tooltip");this._trigger("close",d,{tooltip:i})}},_tooltip:function(d){var c="ui-tooltip-"+g++,e=a("
        ").attr({id:c,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));a("
        ").addClass("ui-tooltip-content").appendTo(e);e.appendTo(document.body);a.fn.bgiframe&&e.bgiframe();this.tooltips[c]=d;return e},_find:function(d){return(d=d.attr("aria-describedby"))?a("#"+d):a()},_destroy:function(){a.each(this.tooltips, +function(d){a("#"+d).remove()})}})})(jQuery); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.js new file mode 100644 index 00000000..cd515f36 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.js @@ -0,0 +1,11767 @@ +/*! + * jQuery UI 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function( $, undefined ) { + +// prevent duplicate loading +// this is only a problem because we proxy existing functions +// and we don't want to double proxy them +$.ui = $.ui || {}; +if ( $.ui.version ) { + return; +} + +$.extend( $.ui, { + version: "1.8.16", + + keyCode: { + ALT: 18, + BACKSPACE: 8, + CAPS_LOCK: 20, + COMMA: 188, + COMMAND: 91, + COMMAND_LEFT: 91, // COMMAND + COMMAND_RIGHT: 93, + CONTROL: 17, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + INSERT: 45, + LEFT: 37, + MENU: 93, // COMMAND_RIGHT + NUMPAD_ADD: 107, + NUMPAD_DECIMAL: 110, + NUMPAD_DIVIDE: 111, + NUMPAD_ENTER: 108, + NUMPAD_MULTIPLY: 106, + NUMPAD_SUBTRACT: 109, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SHIFT: 16, + SPACE: 32, + TAB: 9, + UP: 38, + WINDOWS: 91 // COMMAND + } +}); + +// plugins +$.fn.extend({ + propAttr: $.fn.prop || $.fn.attr, + + _focus: $.fn.focus, + focus: function( delay, fn ) { + return typeof delay === "number" ? + this.each(function() { + var elem = this; + setTimeout(function() { + $( elem ).focus(); + if ( fn ) { + fn.call( elem ); + } + }, delay ); + }) : + this._focus.apply( this, arguments ); + }, + + scrollParent: function() { + var scrollParent; + if (($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) { + scrollParent = this.parents().filter(function() { + return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); + }).eq(0); + } else { + scrollParent = this.parents().filter(function() { + return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1)); + }).eq(0); + } + + return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent; + }, + + zIndex: function( zIndex ) { + if ( zIndex !== undefined ) { + return this.css( "zIndex", zIndex ); + } + + if ( this.length ) { + var elem = $( this[ 0 ] ), position, value; + while ( elem.length && elem[ 0 ] !== document ) { + // Ignore z-index if position is set to a value where z-index is ignored by the browser + // This makes behavior of this function consistent across browsers + // WebKit always returns auto if the element is positioned + position = elem.css( "position" ); + if ( position === "absolute" || position === "relative" || position === "fixed" ) { + // IE returns 0 when zIndex is not specified + // other browsers return a string + // we ignore the case of nested elements with an explicit value of 0 + //
        + value = parseInt( elem.css( "zIndex" ), 10 ); + if ( !isNaN( value ) && value !== 0 ) { + return value; + } + } + elem = elem.parent(); + } + } + + return 0; + }, + + disableSelection: function() { + return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) + + ".ui-disableSelection", function( event ) { + event.preventDefault(); + }); + }, + + enableSelection: function() { + return this.unbind( ".ui-disableSelection" ); + } +}); + +$.each( [ "Width", "Height" ], function( i, name ) { + var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], + type = name.toLowerCase(), + orig = { + innerWidth: $.fn.innerWidth, + innerHeight: $.fn.innerHeight, + outerWidth: $.fn.outerWidth, + outerHeight: $.fn.outerHeight + }; + + function reduce( elem, size, border, margin ) { + $.each( side, function() { + size -= parseFloat( $.curCSS( elem, "padding" + this, true) ) || 0; + if ( border ) { + size -= parseFloat( $.curCSS( elem, "border" + this + "Width", true) ) || 0; + } + if ( margin ) { + size -= parseFloat( $.curCSS( elem, "margin" + this, true) ) || 0; + } + }); + return size; + } + + $.fn[ "inner" + name ] = function( size ) { + if ( size === undefined ) { + return orig[ "inner" + name ].call( this ); + } + + return this.each(function() { + $( this ).css( type, reduce( this, size ) + "px" ); + }); + }; + + $.fn[ "outer" + name] = function( size, margin ) { + if ( typeof size !== "number" ) { + return orig[ "outer" + name ].call( this, size ); + } + + return this.each(function() { + $( this).css( type, reduce( this, size, true, margin ) + "px" ); + }); + }; +}); + +// selectors +function focusable( element, isTabIndexNotNaN ) { + var nodeName = element.nodeName.toLowerCase(); + if ( "area" === nodeName ) { + var map = element.parentNode, + mapName = map.name, + img; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap=#" + mapName + "]" )[0]; + return !!img && visible( img ); + } + return ( /input|select|textarea|button|object/.test( nodeName ) + ? !element.disabled + : "a" == nodeName + ? element.href || isTabIndexNotNaN + : isTabIndexNotNaN) + // the element and all of its ancestors must be visible + && visible( element ); +} + +function visible( element ) { + return !$( element ).parents().andSelf().filter(function() { + return $.curCSS( this, "visibility" ) === "hidden" || + $.expr.filters.hidden( this ); + }).length; +} + +$.extend( $.expr[ ":" ], { + data: function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, + + focusable: function( element ) { + return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); + }, + + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + isTabIndexNaN = isNaN( tabIndex ); + return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); + } +}); + +// support +$(function() { + var body = document.body, + div = body.appendChild( div = document.createElement( "div" ) ); + + $.extend( div.style, { + minHeight: "100px", + height: "auto", + padding: 0, + borderWidth: 0 + }); + + $.support.minHeight = div.offsetHeight === 100; + $.support.selectstart = "onselectstart" in div; + + // set display to none to avoid a layout bug in IE + // http://dev.jquery.com/ticket/4014 + body.removeChild( div ).style.display = "none"; +}); + + + + + +// deprecated +$.extend( $.ui, { + // $.ui.plugin is deprecated. Use the proxy pattern instead. + plugin: { + add: function( module, option, set ) { + var proto = $.ui[ module ].prototype; + for ( var i in set ) { + proto.plugins[ i ] = proto.plugins[ i ] || []; + proto.plugins[ i ].push( [ option, set[ i ] ] ); + } + }, + call: function( instance, name, args ) { + var set = instance.plugins[ name ]; + if ( !set || !instance.element[ 0 ].parentNode ) { + return; + } + + for ( var i = 0; i < set.length; i++ ) { + if ( instance.options[ set[ i ][ 0 ] ] ) { + set[ i ][ 1 ].apply( instance.element, args ); + } + } + } + }, + + // will be deprecated when we switch to jQuery 1.4 - use jQuery.contains() + contains: function( a, b ) { + return document.compareDocumentPosition ? + a.compareDocumentPosition( b ) & 16 : + a !== b && a.contains( b ); + }, + + // only used by resizable + hasScroll: function( el, a ) { + + //If overflow is hidden, the element might have extra content, but the user wants to hide it + if ( $( el ).css( "overflow" ) === "hidden") { + return false; + } + + var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop", + has = false; + + if ( el[ scroll ] > 0 ) { + return true; + } + + // TODO: determine which cases actually cause this to happen + // if the element doesn't have the scroll set, see if it's possible to + // set the scroll + el[ scroll ] = 1; + has = ( el[ scroll ] > 0 ); + el[ scroll ] = 0; + return has; + }, + + // these are odd functions, fix the API or move into individual plugins + isOverAxis: function( x, reference, size ) { + //Determines when x coordinate is over "b" element axis + return ( x > reference ) && ( x < ( reference + size ) ); + }, + isOver: function( y, x, top, left, height, width ) { + //Determines when x, y coordinates is over "b" element + return $.ui.isOverAxis( y, top, height ) && $.ui.isOverAxis( x, left, width ); + } +}); + +})( jQuery ); +/*! + * jQuery UI Widget 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Widget + */ +(function( $, undefined ) { + +// jQuery 1.4+ +if ( $.cleanData ) { + var _cleanData = $.cleanData; + $.cleanData = function( elems ) { + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { + try { + $( elem ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + } + _cleanData( elems ); + }; +} else { + var _remove = $.fn.remove; + $.fn.remove = function( selector, keepData ) { + return this.each(function() { + if ( !keepData ) { + if ( !selector || $.filter( selector, [ this ] ).length ) { + $( "*", this ).add( [ this ] ).each(function() { + try { + $( this ).triggerHandler( "remove" ); + // http://bugs.jquery.com/ticket/8235 + } catch( e ) {} + }); + } + } + return _remove.call( $(this), selector, keepData ); + }); + }; +} + +$.widget = function( name, base, prototype ) { + var namespace = name.split( "." )[ 0 ], + fullName; + name = name.split( "." )[ 1 ]; + fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + // create selector for plugin + $.expr[ ":" ][ fullName ] = function( elem ) { + return !!$.data( elem, name ); + }; + + $[ namespace ] = $[ namespace ] || {}; + $[ namespace ][ name ] = function( options, element ) { + // allow instantiation without initializing for simple inheritance + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + + var basePrototype = new base(); + // we need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from +// $.each( basePrototype, function( key, val ) { +// if ( $.isPlainObject(val) ) { +// basePrototype[ key ] = $.extend( {}, val ); +// } +// }); + basePrototype.options = $.extend( true, {}, basePrototype.options ); + $[ namespace ][ name ].prototype = $.extend( true, basePrototype, { + namespace: namespace, + widgetName: name, + widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, + widgetBaseClass: fullName + }, prototype ); + + $.widget.bridge( name, $[ namespace ][ name ] ); +}; + +$.widget.bridge = function( name, object ) { + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string", + args = Array.prototype.slice.call( arguments, 1 ), + returnValue = this; + + // allow multiple hashes to be passed on init + options = !isMethodCall && args.length ? + $.extend.apply( null, [ true, options ].concat(args) ) : + options; + + // prevent calls to internal methods + if ( isMethodCall && options.charAt( 0 ) === "_" ) { + return returnValue; + } + + if ( isMethodCall ) { + this.each(function() { + var instance = $.data( this, name ), + methodValue = instance && $.isFunction( instance[options] ) ? + instance[ options ].apply( instance, args ) : + instance; + // TODO: add this back in 1.9 and use $.error() (see #5972) +// if ( !instance ) { +// throw "cannot call methods on " + name + " prior to initialization; " + +// "attempted to call method '" + options + "'"; +// } +// if ( !$.isFunction( instance[options] ) ) { +// throw "no such method '" + options + "' for " + name + " widget instance"; +// } +// var methodValue = instance[ options ].apply( instance, args ); + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue; + return false; + } + }); + } else { + this.each(function() { + var instance = $.data( this, name ); + if ( instance ) { + instance.option( options || {} )._init(); + } else { + $.data( this, name, new object( options, this ) ); + } + }); + } + + return returnValue; + }; +}; + +$.Widget = function( options, element ) { + // allow instantiation without initializing for simple inheritance + if ( arguments.length ) { + this._createWidget( options, element ); + } +}; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + options: { + disabled: false + }, + _createWidget: function( options, element ) { + // $.widget.bridge stores the plugin instance, but we do it anyway + // so that it's stored even before the _create function runs + $.data( element, this.widgetName, this ); + this.element = $( element ); + this.options = $.extend( true, {}, + this.options, + this._getCreateOptions(), + options ); + + var self = this; + this.element.bind( "remove." + this.widgetName, function() { + self.destroy(); + }); + + this._create(); + this._trigger( "create" ); + this._init(); + }, + _getCreateOptions: function() { + return $.metadata && $.metadata.get( this.element[0] )[ this.widgetName ]; + }, + _create: function() {}, + _init: function() {}, + + destroy: function() { + this.element + .unbind( "." + this.widgetName ) + .removeData( this.widgetName ); + this.widget() + .unbind( "." + this.widgetName ) + .removeAttr( "aria-disabled" ) + .removeClass( + this.widgetBaseClass + "-disabled " + + "ui-state-disabled" ); + }, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + + if ( arguments.length === 0 ) { + // don't return a reference to the internal hash + return $.extend( {}, this.options ); + } + + if (typeof key === "string" ) { + if ( value === undefined ) { + return this.options[ key ]; + } + options = {}; + options[ key ] = value; + } + + this._setOptions( options ); + + return this; + }, + _setOptions: function( options ) { + var self = this; + $.each( options, function( key, value ) { + self._setOption( key, value ); + }); + + return this; + }, + _setOption: function( key, value ) { + this.options[ key ] = value; + + if ( key === "disabled" ) { + this.widget() + [ value ? "addClass" : "removeClass"]( + this.widgetBaseClass + "-disabled" + " " + + "ui-state-disabled" ) + .attr( "aria-disabled", value ); + } + + return this; + }, + + enable: function() { + return this._setOption( "disabled", false ); + }, + disable: function() { + return this._setOption( "disabled", true ); + }, + + _trigger: function( type, event, data ) { + var callback = this.options[ type ]; + + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + data = data || {}; + + // copy original event properties over to the new event + // this would happen if we could call $.event.fix instead of $.Event + // but we don't have a way to force an event to be fixed multiple times + if ( event.originalEvent ) { + for ( var i = $.event.props.length, prop; i; ) { + prop = $.event.props[ --i ]; + event[ prop ] = event.originalEvent[ prop ]; + } + } + + this.element.trigger( event, data ); + + return !( $.isFunction(callback) && + callback.call( this.element[0], event, data ) === false || + event.isDefaultPrevented() ); + } +}; + +})( jQuery ); +/*! + * jQuery UI Mouse 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +var mouseHandled = false; +$( document ).mouseup( function( e ) { + mouseHandled = false; +}); + +$.widget("ui.mouse", { + options: { + cancel: ':input,option', + distance: 1, + delay: 0 + }, + _mouseInit: function() { + var self = this; + + this.element + .bind('mousedown.'+this.widgetName, function(event) { + return self._mouseDown(event); + }) + .bind('click.'+this.widgetName, function(event) { + if (true === $.data(event.target, self.widgetName + '.preventClickEvent')) { + $.removeData(event.target, self.widgetName + '.preventClickEvent'); + event.stopImmediatePropagation(); + return false; + } + }); + + this.started = false; + }, + + // TODO: make sure destroying one instance of mouse doesn't mess with + // other instances of mouse + _mouseDestroy: function() { + this.element.unbind('.'+this.widgetName); + }, + + _mouseDown: function(event) { + // don't let more than one widget handle mouseStart + if( mouseHandled ) { return }; + + // we may have missed mouseup (out of window) + (this._mouseStarted && this._mouseUp(event)); + + this._mouseDownEvent = event; + + var self = this, + btnIsLeft = (event.which == 1), + // event.target.nodeName works around a bug in IE 8 with + // disabled inputs (#7620) + elIsCancel = (typeof this.options.cancel == "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); + if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { + return true; + } + + this.mouseDelayMet = !this.options.delay; + if (!this.mouseDelayMet) { + this._mouseDelayTimer = setTimeout(function() { + self.mouseDelayMet = true; + }, this.options.delay); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = (this._mouseStart(event) !== false); + if (!this._mouseStarted) { + event.preventDefault(); + return true; + } + } + + // Click event may never have fired (Gecko & Opera) + if (true === $.data(event.target, this.widgetName + '.preventClickEvent')) { + $.removeData(event.target, this.widgetName + '.preventClickEvent'); + } + + // these delegates are required to keep context + this._mouseMoveDelegate = function(event) { + return self._mouseMove(event); + }; + this._mouseUpDelegate = function(event) { + return self._mouseUp(event); + }; + $(document) + .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .bind('mouseup.'+this.widgetName, this._mouseUpDelegate); + + event.preventDefault(); + + mouseHandled = true; + return true; + }, + + _mouseMove: function(event) { + // IE mouseup check - mouseup happened when mouse was out of window + if ($.browser.msie && !(document.documentMode >= 9) && !event.button) { + return this._mouseUp(event); + } + + if (this._mouseStarted) { + this._mouseDrag(event); + return event.preventDefault(); + } + + if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { + this._mouseStarted = + (this._mouseStart(this._mouseDownEvent, event) !== false); + (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); + } + + return !this._mouseStarted; + }, + + _mouseUp: function(event) { + $(document) + .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate) + .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate); + + if (this._mouseStarted) { + this._mouseStarted = false; + + if (event.target == this._mouseDownEvent.target) { + $.data(event.target, this.widgetName + '.preventClickEvent', true); + } + + this._mouseStop(event); + } + + return false; + }, + + _mouseDistanceMet: function(event) { + return (Math.max( + Math.abs(this._mouseDownEvent.pageX - event.pageX), + Math.abs(this._mouseDownEvent.pageY - event.pageY) + ) >= this.options.distance + ); + }, + + _mouseDelayMet: function(event) { + return this.mouseDelayMet; + }, + + // These are placeholder methods, to be overriden by extending plugin + _mouseStart: function(event) {}, + _mouseDrag: function(event) {}, + _mouseStop: function(event) {}, + _mouseCapture: function(event) { return true; } +}); + +})(jQuery); +/* + * jQuery UI Draggable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget("ui.draggable", $.ui.mouse, { + widgetEventPrefix: "drag", + options: { + addClasses: true, + appendTo: "parent", + axis: false, + connectToSortable: false, + containment: false, + cursor: "auto", + cursorAt: false, + grid: false, + handle: false, + helper: "original", + iframeFix: false, + opacity: false, + refreshPositions: false, + revert: false, + revertDuration: 500, + scope: "default", + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + snap: false, + snapMode: "both", + snapTolerance: 20, + stack: false, + zIndex: false + }, + _create: function() { + + if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position"))) + this.element[0].style.position = 'relative'; + + (this.options.addClasses && this.element.addClass("ui-draggable")); + (this.options.disabled && this.element.addClass("ui-draggable-disabled")); + + this._mouseInit(); + + }, + + destroy: function() { + if(!this.element.data('draggable')) return; + this.element + .removeData("draggable") + .unbind(".draggable") + .removeClass("ui-draggable" + + " ui-draggable-dragging" + + " ui-draggable-disabled"); + this._mouseDestroy(); + + return this; + }, + + _mouseCapture: function(event) { + + var o = this.options; + + // among others, prevent a drag on a resizable-handle + if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle')) + return false; + + //Quit if we're not on a valid handle + this.handle = this._getHandle(event); + if (!this.handle) + return false; + + if ( o.iframeFix ) { + $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() { + $('
        ') + .css({ + width: this.offsetWidth+"px", height: this.offsetHeight+"px", + position: "absolute", opacity: "0.001", zIndex: 1000 + }) + .css($(this).offset()) + .appendTo("body"); + }); + } + + return true; + + }, + + _mouseStart: function(event) { + + var o = this.options; + + //Create and append the visible helper + this.helper = this._createHelper(event); + + //Cache the helper size + this._cacheHelperProportions(); + + //If ddmanager is used for droppables, set the global draggable + if($.ui.ddmanager) + $.ui.ddmanager.current = this; + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Store the helper's css position + this.cssPosition = this.helper.css("position"); + this.scrollParent = this.helper.scrollParent(); + + //The element's absolute position on the page minus margins + this.offset = this.positionAbs = this.element.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + //Generate the original position + this.originalPosition = this.position = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Set a containment if given in the options + if(o.containment) + this._setContainment(); + + //Trigger event + callbacks + if(this._trigger("start", event) === false) { + this._clear(); + return false; + } + + //Recache the helper size + this._cacheHelperProportions(); + + //Prepare the droppable offsets + if ($.ui.ddmanager && !o.dropBehaviour) + $.ui.ddmanager.prepareOffsets(this, event); + + this.helper.addClass("ui-draggable-dragging"); + this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position + + //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003) + if ( $.ui.ddmanager ) $.ui.ddmanager.dragStart(this, event); + + return true; + }, + + _mouseDrag: function(event, noPropagation) { + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + //Call plugins and callbacks and use the resulting position if something is returned + if (!noPropagation) { + var ui = this._uiHash(); + if(this._trigger('drag', event, ui) === false) { + this._mouseUp({}); + return false; + } + this.position = ui.position; + } + + if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; + if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; + if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); + + return false; + }, + + _mouseStop: function(event) { + + //If we are using droppables, inform the manager about the drop + var dropped = false; + if ($.ui.ddmanager && !this.options.dropBehaviour) + dropped = $.ui.ddmanager.drop(this, event); + + //if a drop comes from outside (a sortable) + if(this.dropped) { + dropped = this.dropped; + this.dropped = false; + } + + //if the original element is removed, don't bother to continue if helper is set to "original" + if((!this.element[0] || !this.element[0].parentNode) && this.options.helper == "original") + return false; + + if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) { + var self = this; + $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() { + if(self._trigger("stop", event) !== false) { + self._clear(); + } + }); + } else { + if(this._trigger("stop", event) !== false) { + this._clear(); + } + } + + return false; + }, + + _mouseUp: function(event) { + if (this.options.iframeFix === true) { + $("div.ui-draggable-iframeFix").each(function() { + this.parentNode.removeChild(this); + }); //Remove frame helpers + } + + //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003) + if( $.ui.ddmanager ) $.ui.ddmanager.dragStop(this, event); + + return $.ui.mouse.prototype._mouseUp.call(this, event); + }, + + cancel: function() { + + if(this.helper.is(".ui-draggable-dragging")) { + this._mouseUp({}); + } else { + this._clear(); + } + + return this; + + }, + + _getHandle: function(event) { + + var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false; + $(this.options.handle, this.element) + .find("*") + .andSelf() + .each(function() { + if(this == event.target) handle = true; + }); + + return handle; + + }, + + _createHelper: function(event) { + + var o = this.options; + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone().removeAttr('id') : this.element); + + if(!helper.parents('body').length) + helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo)); + + if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) + helper.css("position", "absolute"); + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj == 'string') { + obj = obj.split(' '); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ('left' in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ('right' in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ('top' in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ('bottom' in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information + || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix + po = { top: 0, left: 0 }; + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + }, + + _getRelativeOffset: function() { + + if(this.cssPosition == "relative") { + var p = this.element.position(); + return { + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.element.css("marginLeft"),10) || 0), + top: (parseInt(this.element.css("marginTop"),10) || 0), + right: (parseInt(this.element.css("marginRight"),10) || 0), + bottom: (parseInt(this.element.css("marginBottom"),10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var o = this.options; + if(o.containment == 'parent') o.containment = this.helper[0].parentNode; + if(o.containment == 'document' || o.containment == 'window') this.containment = [ + o.containment == 'document' ? 0 : $(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left, + o.containment == 'document' ? 0 : $(window).scrollTop() - this.offset.relative.top - this.offset.parent.top, + (o.containment == 'document' ? 0 : $(window).scrollLeft()) + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, + (o.containment == 'document' ? 0 : $(window).scrollTop()) + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + ]; + + if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) { + var c = $(o.containment); + var ce = c[0]; if(!ce) return; + var co = c.offset(); + var over = ($(ce).css("overflow") != 'hidden'); + + this.containment = [ + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0), + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0), + (over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left - this.margins.right, + (over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top - this.margins.bottom + ]; + this.relative_container = c; + + } else if(o.containment.constructor == Array) { + this.containment = o.containment; + } + + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) pos = this.position; + var mod = d == "absolute" ? 1 : -1; + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top // The absolute mouse position + + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) + - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left // The absolute mouse position + + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) + - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ) + }; + + }, + + _generatePosition: function(event) { + + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + var pageX = event.pageX; + var pageY = event.pageY; + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if(this.originalPosition) { //If we are not dragging yet, we won't check for options + var containment; + if(this.containment) { + if (this.relative_container){ + var co = this.relative_container.offset(); + containment = [ this.containment[0] + co.left, + this.containment[1] + co.top, + this.containment[2] + co.left, + this.containment[3] + co.top ]; + } + else { + containment = this.containment; + } + + if(event.pageX - this.offset.click.left < containment[0]) pageX = containment[0] + this.offset.click.left; + if(event.pageY - this.offset.click.top < containment[1]) pageY = containment[1] + this.offset.click.top; + if(event.pageX - this.offset.click.left > containment[2]) pageX = containment[2] + this.offset.click.left; + if(event.pageY - this.offset.click.top > containment[3]) pageY = containment[3] + this.offset.click.top; + } + + if(o.grid) { + //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950) + var top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY; + pageY = containment ? (!(top - this.offset.click.top < containment[1] || top - this.offset.click.top > containment[3]) ? top : (!(top - this.offset.click.top < containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + var left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX; + pageX = containment ? (!(left - this.offset.click.left < containment[0] || left - this.offset.click.left > containment[2]) ? left : (!(left - this.offset.click.left < containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + } + + return { + top: ( + pageY // The absolute mouse position + - this.offset.click.top // Click offset (relative to the element) + - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent + - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX // The absolute mouse position + - this.offset.click.left // Click offset (relative to the element) + - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent + - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _clear: function() { + this.helper.removeClass("ui-draggable-dragging"); + if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove(); + //if($.ui.ddmanager) $.ui.ddmanager.current = null; + this.helper = null; + this.cancelHelperRemoval = false; + }, + + // From now on bulk stuff - mainly helpers + + _trigger: function(type, event, ui) { + ui = ui || this._uiHash(); + $.ui.plugin.call(this, type, [event, ui]); + if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins + return $.Widget.prototype._trigger.call(this, type, event, ui); + }, + + plugins: {}, + + _uiHash: function(event) { + return { + helper: this.helper, + position: this.position, + originalPosition: this.originalPosition, + offset: this.positionAbs + }; + } + +}); + +$.extend($.ui.draggable, { + version: "1.8.16" +}); + +$.ui.plugin.add("draggable", "connectToSortable", { + start: function(event, ui) { + + var inst = $(this).data("draggable"), o = inst.options, + uiSortable = $.extend({}, ui, { item: inst.element }); + inst.sortables = []; + $(o.connectToSortable).each(function() { + var sortable = $.data(this, 'sortable'); + if (sortable && !sortable.options.disabled) { + inst.sortables.push({ + instance: sortable, + shouldRevert: sortable.options.revert + }); + sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page). + sortable._trigger("activate", event, uiSortable); + } + }); + + }, + stop: function(event, ui) { + + //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper + var inst = $(this).data("draggable"), + uiSortable = $.extend({}, ui, { item: inst.element }); + + $.each(inst.sortables, function() { + if(this.instance.isOver) { + + this.instance.isOver = 0; + + inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance + this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work) + + //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid' + if(this.shouldRevert) this.instance.options.revert = true; + + //Trigger the stop of the sortable + this.instance._mouseStop(event); + + this.instance.options.helper = this.instance.options._helper; + + //If the helper has been the original item, restore properties in the sortable + if(inst.options.helper == 'original') + this.instance.currentItem.css({ top: 'auto', left: 'auto' }); + + } else { + this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance + this.instance._trigger("deactivate", event, uiSortable); + } + + }); + + }, + drag: function(event, ui) { + + var inst = $(this).data("draggable"), self = this; + + var checkPos = function(o) { + var dyClick = this.offset.click.top, dxClick = this.offset.click.left; + var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left; + var itemHeight = o.height, itemWidth = o.width; + var itemTop = o.top, itemLeft = o.left; + + return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth); + }; + + $.each(inst.sortables, function(i) { + + //Copy over some variables to allow calling the sortable's native _intersectsWith + this.instance.positionAbs = inst.positionAbs; + this.instance.helperProportions = inst.helperProportions; + this.instance.offset.click = inst.offset.click; + + if(this.instance._intersectsWith(this.instance.containerCache)) { + + //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once + if(!this.instance.isOver) { + + this.instance.isOver = 1; + //Now we fake the start of dragging for the sortable instance, + //by cloning the list group item, appending it to the sortable and using it as inst.currentItem + //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one) + this.instance.currentItem = $(self).clone().removeAttr('id').appendTo(this.instance.element).data("sortable-item", true); + this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it + this.instance.options.helper = function() { return ui.helper[0]; }; + + event.target = this.instance.currentItem[0]; + this.instance._mouseCapture(event, true); + this.instance._mouseStart(event, true, true); + + //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes + this.instance.offset.click.top = inst.offset.click.top; + this.instance.offset.click.left = inst.offset.click.left; + this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left; + this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top; + + inst._trigger("toSortable", event); + inst.dropped = this.instance.element; //draggable revert needs that + //hack so receive/update callbacks work (mostly) + inst.currentItem = inst.element; + this.instance.fromOutside = inst; + + } + + //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable + if(this.instance.currentItem) this.instance._mouseDrag(event); + + } else { + + //If it doesn't intersect with the sortable, and it intersected before, + //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval + if(this.instance.isOver) { + + this.instance.isOver = 0; + this.instance.cancelHelperRemoval = true; + + //Prevent reverting on this forced stop + this.instance.options.revert = false; + + // The out event needs to be triggered independently + this.instance._trigger('out', event, this.instance._uiHash(this.instance)); + + this.instance._mouseStop(event, true); + this.instance.options.helper = this.instance.options._helper; + + //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size + this.instance.currentItem.remove(); + if(this.instance.placeholder) this.instance.placeholder.remove(); + + inst._trigger("fromSortable", event); + inst.dropped = false; //draggable revert needs that + } + + }; + + }); + + } +}); + +$.ui.plugin.add("draggable", "cursor", { + start: function(event, ui) { + var t = $('body'), o = $(this).data('draggable').options; + if (t.css("cursor")) o._cursor = t.css("cursor"); + t.css("cursor", o.cursor); + }, + stop: function(event, ui) { + var o = $(this).data('draggable').options; + if (o._cursor) $('body').css("cursor", o._cursor); + } +}); + +$.ui.plugin.add("draggable", "opacity", { + start: function(event, ui) { + var t = $(ui.helper), o = $(this).data('draggable').options; + if(t.css("opacity")) o._opacity = t.css("opacity"); + t.css('opacity', o.opacity); + }, + stop: function(event, ui) { + var o = $(this).data('draggable').options; + if(o._opacity) $(ui.helper).css('opacity', o._opacity); + } +}); + +$.ui.plugin.add("draggable", "scroll", { + start: function(event, ui) { + var i = $(this).data("draggable"); + if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset(); + }, + drag: function(event, ui) { + + var i = $(this).data("draggable"), o = i.options, scrolled = false; + + if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') { + + if(!o.axis || o.axis != 'x') { + if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed; + else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) + i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed; + } + + if(!o.axis || o.axis != 'y') { + if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed; + else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) + i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed; + } + + } else { + + if(!o.axis || o.axis != 'x') { + if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); + else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + } + + if(!o.axis || o.axis != 'y') { + if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); + else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + } + + } + + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) + $.ui.ddmanager.prepareOffsets(i, event); + + } +}); + +$.ui.plugin.add("draggable", "snap", { + start: function(event, ui) { + + var i = $(this).data("draggable"), o = i.options; + i.snapElements = []; + + $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() { + var $t = $(this); var $o = $t.offset(); + if(this != i.element[0]) i.snapElements.push({ + item: this, + width: $t.outerWidth(), height: $t.outerHeight(), + top: $o.top, left: $o.left + }); + }); + + }, + drag: function(event, ui) { + + var inst = $(this).data("draggable"), o = inst.options; + var d = o.snapTolerance; + + var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width, + y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height; + + for (var i = inst.snapElements.length - 1; i >= 0; i--){ + + var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width, + t = inst.snapElements[i].top, b = t + inst.snapElements[i].height; + + //Yes, I know, this is insane ;) + if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) { + if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + inst.snapElements[i].snapping = false; + continue; + } + + if(o.snapMode != 'inner') { + var ts = Math.abs(t - y2) <= d; + var bs = Math.abs(b - y1) <= d; + var ls = Math.abs(l - x2) <= d; + var rs = Math.abs(r - x1) <= d; + if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top; + if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left; + if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left; + } + + var first = (ts || bs || ls || rs); + + if(o.snapMode != 'outer') { + var ts = Math.abs(t - y1) <= d; + var bs = Math.abs(b - y2) <= d; + var ls = Math.abs(l - x1) <= d; + var rs = Math.abs(r - x2) <= d; + if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top; + if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top; + if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left; + if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left; + } + + if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) + (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item }))); + inst.snapElements[i].snapping = (ts || bs || ls || rs || first); + + }; + + } +}); + +$.ui.plugin.add("draggable", "stack", { + start: function(event, ui) { + + var o = $(this).data("draggable").options; + + var group = $.makeArray($(o.stack)).sort(function(a,b) { + return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0); + }); + if (!group.length) { return; } + + var min = parseInt(group[0].style.zIndex) || 0; + $(group).each(function(i) { + this.style.zIndex = min + i; + }); + + this[0].style.zIndex = min + group.length; + + } +}); + +$.ui.plugin.add("draggable", "zIndex", { + start: function(event, ui) { + var t = $(ui.helper), o = $(this).data("draggable").options; + if(t.css("zIndex")) o._zIndex = t.css("zIndex"); + t.css('zIndex', o.zIndex); + }, + stop: function(event, ui) { + var o = $(this).data("draggable").options; + if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex); + } +}); + +})(jQuery); +/* + * jQuery UI Droppable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Droppables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.mouse.js + * jquery.ui.draggable.js + */ +(function( $, undefined ) { + +$.widget("ui.droppable", { + widgetEventPrefix: "drop", + options: { + accept: '*', + activeClass: false, + addClasses: true, + greedy: false, + hoverClass: false, + scope: 'default', + tolerance: 'intersect' + }, + _create: function() { + + var o = this.options, accept = o.accept; + this.isover = 0; this.isout = 1; + + this.accept = $.isFunction(accept) ? accept : function(d) { + return d.is(accept); + }; + + //Store the droppable's proportions + this.proportions = { width: this.element[0].offsetWidth, height: this.element[0].offsetHeight }; + + // Add the reference and positions to the manager + $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || []; + $.ui.ddmanager.droppables[o.scope].push(this); + + (o.addClasses && this.element.addClass("ui-droppable")); + + }, + + destroy: function() { + var drop = $.ui.ddmanager.droppables[this.options.scope]; + for ( var i = 0; i < drop.length; i++ ) + if ( drop[i] == this ) + drop.splice(i, 1); + + this.element + .removeClass("ui-droppable ui-droppable-disabled") + .removeData("droppable") + .unbind(".droppable"); + + return this; + }, + + _setOption: function(key, value) { + + if(key == 'accept') { + this.accept = $.isFunction(value) ? value : function(d) { + return d.is(value); + }; + } + $.Widget.prototype._setOption.apply(this, arguments); + }, + + _activate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) this.element.addClass(this.options.activeClass); + (draggable && this._trigger('activate', event, this.ui(draggable))); + }, + + _deactivate: function(event) { + var draggable = $.ui.ddmanager.current; + if(this.options.activeClass) this.element.removeClass(this.options.activeClass); + (draggable && this._trigger('deactivate', event, this.ui(draggable))); + }, + + _over: function(event) { + + var draggable = $.ui.ddmanager.current; + if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element + + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.hoverClass) this.element.addClass(this.options.hoverClass); + this._trigger('over', event, this.ui(draggable)); + } + + }, + + _out: function(event) { + + var draggable = $.ui.ddmanager.current; + if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element + + if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); + this._trigger('out', event, this.ui(draggable)); + } + + }, + + _drop: function(event,custom) { + + var draggable = custom || $.ui.ddmanager.current; + if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element + + var childrenIntersection = false; + this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { + var inst = $.data(this, 'droppable'); + if( + inst.options.greedy + && !inst.options.disabled + && inst.options.scope == draggable.options.scope + && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) + && $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance) + ) { childrenIntersection = true; return false; } + }); + if(childrenIntersection) return false; + + if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + if(this.options.activeClass) this.element.removeClass(this.options.activeClass); + if(this.options.hoverClass) this.element.removeClass(this.options.hoverClass); + this._trigger('drop', event, this.ui(draggable)); + return this.element; + } + + return false; + + }, + + ui: function(c) { + return { + draggable: (c.currentItem || c.element), + helper: c.helper, + position: c.position, + offset: c.positionAbs + }; + } + +}); + +$.extend($.ui.droppable, { + version: "1.8.16" +}); + +$.ui.intersect = function(draggable, droppable, toleranceMode) { + + if (!droppable.offset) return false; + + var x1 = (draggable.positionAbs || draggable.position.absolute).left, x2 = x1 + draggable.helperProportions.width, + y1 = (draggable.positionAbs || draggable.position.absolute).top, y2 = y1 + draggable.helperProportions.height; + var l = droppable.offset.left, r = l + droppable.proportions.width, + t = droppable.offset.top, b = t + droppable.proportions.height; + + switch (toleranceMode) { + case 'fit': + return (l <= x1 && x2 <= r + && t <= y1 && y2 <= b); + break; + case 'intersect': + return (l < x1 + (draggable.helperProportions.width / 2) // Right Half + && x2 - (draggable.helperProportions.width / 2) < r // Left Half + && t < y1 + (draggable.helperProportions.height / 2) // Bottom Half + && y2 - (draggable.helperProportions.height / 2) < b ); // Top Half + break; + case 'pointer': + var draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left), + draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top), + isOver = $.ui.isOver(draggableTop, draggableLeft, t, l, droppable.proportions.height, droppable.proportions.width); + return isOver; + break; + case 'touch': + return ( + (y1 >= t && y1 <= b) || // Top edge touching + (y2 >= t && y2 <= b) || // Bottom edge touching + (y1 < t && y2 > b) // Surrounded vertically + ) && ( + (x1 >= l && x1 <= r) || // Left edge touching + (x2 >= l && x2 <= r) || // Right edge touching + (x1 < l && x2 > r) // Surrounded horizontally + ); + break; + default: + return false; + break; + } + +}; + +/* + This manager tracks offsets of draggables and droppables +*/ +$.ui.ddmanager = { + current: null, + droppables: { 'default': [] }, + prepareOffsets: function(t, event) { + + var m = $.ui.ddmanager.droppables[t.options.scope] || []; + var type = event ? event.type : null; // workaround for #2317 + var list = (t.currentItem || t.element).find(":data(droppable)").andSelf(); + + droppablesLoop: for (var i = 0; i < m.length; i++) { + + if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) continue; //No disabled and non-accepted + for (var j=0; j < list.length; j++) { if(list[j] == m[i].element[0]) { m[i].proportions.height = 0; continue droppablesLoop; } }; //Filter out elements in the current dragged item + m[i].visible = m[i].element.css("display") != "none"; if(!m[i].visible) continue; //If the element is not visible, continue + + if(type == "mousedown") m[i]._activate.call(m[i], event); //Activate the droppable if used directly from draggables + + m[i].offset = m[i].element.offset(); + m[i].proportions = { width: m[i].element[0].offsetWidth, height: m[i].element[0].offsetHeight }; + + } + + }, + drop: function(draggable, event) { + + var dropped = false; + $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + + if(!this.options) return; + if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) + dropped = dropped || this._drop.call(this, event); + + if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) { + this.isout = 1; this.isover = 0; + this._deactivate.call(this, event); + } + + }); + return dropped; + + }, + dragStart: function( draggable, event ) { + //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003) + draggable.element.parents( ":not(body,html)" ).bind( "scroll.droppable", function() { + if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); + }); + }, + drag: function(draggable, event) { + + //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse. + if(draggable.options.refreshPositions) $.ui.ddmanager.prepareOffsets(draggable, event); + + //Run through all droppables and check their positions based on specific tolerance options + $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() { + + if(this.options.disabled || this.greedyChild || !this.visible) return; + var intersects = $.ui.intersect(draggable, this, this.options.tolerance); + + var c = !intersects && this.isover == 1 ? 'isout' : (intersects && this.isover == 0 ? 'isover' : null); + if(!c) return; + + var parentInstance; + if (this.options.greedy) { + var parent = this.element.parents(':data(droppable):eq(0)'); + if (parent.length) { + parentInstance = $.data(parent[0], 'droppable'); + parentInstance.greedyChild = (c == 'isover' ? 1 : 0); + } + } + + // we just moved into a greedy child + if (parentInstance && c == 'isover') { + parentInstance['isover'] = 0; + parentInstance['isout'] = 1; + parentInstance._out.call(parentInstance, event); + } + + this[c] = 1; this[c == 'isout' ? 'isover' : 'isout'] = 0; + this[c == "isover" ? "_over" : "_out"].call(this, event); + + // we just moved out of a greedy child + if (parentInstance && c == 'isout') { + parentInstance['isout'] = 0; + parentInstance['isover'] = 1; + parentInstance._over.call(parentInstance, event); + } + }); + + }, + dragStop: function( draggable, event ) { + draggable.element.parents( ":not(body,html)" ).unbind( "scroll.droppable" ); + //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003) + if( !draggable.options.refreshPositions ) $.ui.ddmanager.prepareOffsets( draggable, event ); + } +}; + +})(jQuery); +/* + * jQuery UI Resizable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Resizables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget("ui.resizable", $.ui.mouse, { + widgetEventPrefix: "resize", + options: { + alsoResize: false, + animate: false, + animateDuration: "slow", + animateEasing: "swing", + aspectRatio: false, + autoHide: false, + containment: false, + ghost: false, + grid: false, + handles: "e,s,se", + helper: false, + maxHeight: null, + maxWidth: null, + minHeight: 10, + minWidth: 10, + zIndex: 1000 + }, + _create: function() { + + var self = this, o = this.options; + this.element.addClass("ui-resizable"); + + $.extend(this, { + _aspectRatio: !!(o.aspectRatio), + aspectRatio: o.aspectRatio, + originalElement: this.element, + _proportionallyResizeElements: [], + _helper: o.helper || o.ghost || o.animate ? o.helper || 'ui-resizable-helper' : null + }); + + //Wrap the element if it cannot hold child nodes + if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) { + + //Opera fix for relative positioning + if (/relative/.test(this.element.css('position')) && $.browser.opera) + this.element.css({ position: 'relative', top: 'auto', left: 'auto' }); + + //Create a wrapper element and set the wrapper to the new current internal element + this.element.wrap( + $('
        ').css({ + position: this.element.css('position'), + width: this.element.outerWidth(), + height: this.element.outerHeight(), + top: this.element.css('top'), + left: this.element.css('left') + }) + ); + + //Overwrite the original this.element + this.element = this.element.parent().data( + "resizable", this.element.data('resizable') + ); + + this.elementIsWrapper = true; + + //Move margins to the wrapper + this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") }); + this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0}); + + //Prevent Safari textarea resize + this.originalResizeStyle = this.originalElement.css('resize'); + this.originalElement.css('resize', 'none'); + + //Push the actual element to our proportionallyResize internal array + this._proportionallyResizeElements.push(this.originalElement.css({ position: 'static', zoom: 1, display: 'block' })); + + // avoid IE jump (hard set the margin) + this.originalElement.css({ margin: this.originalElement.css('margin') }); + + // fix handlers offset + this._proportionallyResize(); + + } + + this.handles = o.handles || (!$('.ui-resizable-handle', this.element).length ? "e,s,se" : { n: '.ui-resizable-n', e: '.ui-resizable-e', s: '.ui-resizable-s', w: '.ui-resizable-w', se: '.ui-resizable-se', sw: '.ui-resizable-sw', ne: '.ui-resizable-ne', nw: '.ui-resizable-nw' }); + if(this.handles.constructor == String) { + + if(this.handles == 'all') this.handles = 'n,e,s,w,se,sw,ne,nw'; + var n = this.handles.split(","); this.handles = {}; + + for(var i = 0; i < n.length; i++) { + + var handle = $.trim(n[i]), hname = 'ui-resizable-'+handle; + var axis = $('
        '); + + // increase zIndex of sw, se, ne, nw axis + //TODO : this modifies original option + if(/sw|se|ne|nw/.test(handle)) axis.css({ zIndex: ++o.zIndex }); + + //TODO : What's going on here? + if ('se' == handle) { + axis.addClass('ui-icon ui-icon-gripsmall-diagonal-se'); + }; + + //Insert into internal handles object and append to element + this.handles[handle] = '.ui-resizable-'+handle; + this.element.append(axis); + } + + } + + this._renderAxis = function(target) { + + target = target || this.element; + + for(var i in this.handles) { + + if(this.handles[i].constructor == String) + this.handles[i] = $(this.handles[i], this.element).show(); + + //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls) + if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) { + + var axis = $(this.handles[i], this.element), padWrapper = 0; + + //Checking the correct pad and border + padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth(); + + //The padding type i have to apply... + var padPos = [ 'padding', + /ne|nw|n/.test(i) ? 'Top' : + /se|sw|s/.test(i) ? 'Bottom' : + /^e$/.test(i) ? 'Right' : 'Left' ].join(""); + + target.css(padPos, padWrapper); + + this._proportionallyResize(); + + } + + //TODO: What's that good for? There's not anything to be executed left + if(!$(this.handles[i]).length) + continue; + + } + }; + + //TODO: make renderAxis a prototype function + this._renderAxis(this.element); + + this._handles = $('.ui-resizable-handle', this.element) + .disableSelection(); + + //Matching axis name + this._handles.mouseover(function() { + if (!self.resizing) { + if (this.className) + var axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i); + //Axis, default = se + self.axis = axis && axis[1] ? axis[1] : 'se'; + } + }); + + //If we want to auto hide the elements + if (o.autoHide) { + this._handles.hide(); + $(this.element) + .addClass("ui-resizable-autohide") + .hover(function() { + if (o.disabled) return; + $(this).removeClass("ui-resizable-autohide"); + self._handles.show(); + }, + function(){ + if (o.disabled) return; + if (!self.resizing) { + $(this).addClass("ui-resizable-autohide"); + self._handles.hide(); + } + }); + } + + //Initialize the mouse interaction + this._mouseInit(); + + }, + + destroy: function() { + + this._mouseDestroy(); + + var _destroy = function(exp) { + $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing") + .removeData("resizable").unbind(".resizable").find('.ui-resizable-handle').remove(); + }; + + //TODO: Unwrap at same DOM position + if (this.elementIsWrapper) { + _destroy(this.element); + var wrapper = this.element; + wrapper.after( + this.originalElement.css({ + position: wrapper.css('position'), + width: wrapper.outerWidth(), + height: wrapper.outerHeight(), + top: wrapper.css('top'), + left: wrapper.css('left') + }) + ).remove(); + } + + this.originalElement.css('resize', this.originalResizeStyle); + _destroy(this.originalElement); + + return this; + }, + + _mouseCapture: function(event) { + var handle = false; + for (var i in this.handles) { + if ($(this.handles[i])[0] == event.target) { + handle = true; + } + } + + return !this.options.disabled && handle; + }, + + _mouseStart: function(event) { + + var o = this.options, iniPos = this.element.position(), el = this.element; + + this.resizing = true; + this.documentScroll = { top: $(document).scrollTop(), left: $(document).scrollLeft() }; + + // bugfix for http://dev.jquery.com/ticket/1749 + if (el.is('.ui-draggable') || (/absolute/).test(el.css('position'))) { + el.css({ position: 'absolute', top: iniPos.top, left: iniPos.left }); + } + + //Opera fixing relative position + if ($.browser.opera && (/relative/).test(el.css('position'))) + el.css({ position: 'relative', top: 'auto', left: 'auto' }); + + this._renderProxy(); + + var curleft = num(this.helper.css('left')), curtop = num(this.helper.css('top')); + + if (o.containment) { + curleft += $(o.containment).scrollLeft() || 0; + curtop += $(o.containment).scrollTop() || 0; + } + + //Store needed variables + this.offset = this.helper.offset(); + this.position = { left: curleft, top: curtop }; + this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; + this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() }; + this.originalPosition = { left: curleft, top: curtop }; + this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() }; + this.originalMousePosition = { left: event.pageX, top: event.pageY }; + + //Aspect Ratio + this.aspectRatio = (typeof o.aspectRatio == 'number') ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1); + + var cursor = $('.ui-resizable-' + this.axis).css('cursor'); + $('body').css('cursor', cursor == 'auto' ? this.axis + '-resize' : cursor); + + el.addClass("ui-resizable-resizing"); + this._propagate("start", event); + return true; + }, + + _mouseDrag: function(event) { + + //Increase performance, avoid regex + var el = this.helper, o = this.options, props = {}, + self = this, smp = this.originalMousePosition, a = this.axis; + + var dx = (event.pageX-smp.left)||0, dy = (event.pageY-smp.top)||0; + var trigger = this._change[a]; + if (!trigger) return false; + + // Calculate the attrs that will be change + var data = trigger.apply(this, [event, dx, dy]), ie6 = $.browser.msie && $.browser.version < 7, csdif = this.sizeDiff; + + // Put this in the mouseDrag handler since the user can start pressing shift while resizing + this._updateVirtualBoundaries(event.shiftKey); + if (this._aspectRatio || event.shiftKey) + data = this._updateRatio(data, event); + + data = this._respectSize(data, event); + + // plugins callbacks need to be called first + this._propagate("resize", event); + + el.css({ + top: this.position.top + "px", left: this.position.left + "px", + width: this.size.width + "px", height: this.size.height + "px" + }); + + if (!this._helper && this._proportionallyResizeElements.length) + this._proportionallyResize(); + + this._updateCache(data); + + // calling the user callback at the end + this._trigger('resize', event, this.ui()); + + return false; + }, + + _mouseStop: function(event) { + + this.resizing = false; + var o = this.options, self = this; + + if(this._helper) { + var pr = this._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, + soffsetw = ista ? 0 : self.sizeDiff.width; + + var s = { width: (self.helper.width() - soffsetw), height: (self.helper.height() - soffseth) }, + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; + + if (!o.animate) + this.element.css($.extend(s, { top: top, left: left })); + + self.helper.height(self.size.height); + self.helper.width(self.size.width); + + if (this._helper && !o.animate) this._proportionallyResize(); + } + + $('body').css('cursor', 'auto'); + + this.element.removeClass("ui-resizable-resizing"); + + this._propagate("stop", event); + + if (this._helper) this.helper.remove(); + return false; + + }, + + _updateVirtualBoundaries: function(forceAspectRatio) { + var o = this.options, pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b; + + b = { + minWidth: isNumber(o.minWidth) ? o.minWidth : 0, + maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity, + minHeight: isNumber(o.minHeight) ? o.minHeight : 0, + maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity + }; + + if(this._aspectRatio || forceAspectRatio) { + // We want to create an enclosing box whose aspect ration is the requested one + // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension + pMinWidth = b.minHeight * this.aspectRatio; + pMinHeight = b.minWidth / this.aspectRatio; + pMaxWidth = b.maxHeight * this.aspectRatio; + pMaxHeight = b.maxWidth / this.aspectRatio; + + if(pMinWidth > b.minWidth) b.minWidth = pMinWidth; + if(pMinHeight > b.minHeight) b.minHeight = pMinHeight; + if(pMaxWidth < b.maxWidth) b.maxWidth = pMaxWidth; + if(pMaxHeight < b.maxHeight) b.maxHeight = pMaxHeight; + } + this._vBoundaries = b; + }, + + _updateCache: function(data) { + var o = this.options; + this.offset = this.helper.offset(); + if (isNumber(data.left)) this.position.left = data.left; + if (isNumber(data.top)) this.position.top = data.top; + if (isNumber(data.height)) this.size.height = data.height; + if (isNumber(data.width)) this.size.width = data.width; + }, + + _updateRatio: function(data, event) { + + var o = this.options, cpos = this.position, csize = this.size, a = this.axis; + + if (isNumber(data.height)) data.width = (data.height * this.aspectRatio); + else if (isNumber(data.width)) data.height = (data.width / this.aspectRatio); + + if (a == 'sw') { + data.left = cpos.left + (csize.width - data.width); + data.top = null; + } + if (a == 'nw') { + data.top = cpos.top + (csize.height - data.height); + data.left = cpos.left + (csize.width - data.width); + } + + return data; + }, + + _respectSize: function(data, event) { + + var el = this.helper, o = this._vBoundaries, pRatio = this._aspectRatio || event.shiftKey, a = this.axis, + ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height), + isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height); + + if (isminw) data.width = o.minWidth; + if (isminh) data.height = o.minHeight; + if (ismaxw) data.width = o.maxWidth; + if (ismaxh) data.height = o.maxHeight; + + var dw = this.originalPosition.left + this.originalSize.width, dh = this.position.top + this.size.height; + var cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a); + + if (isminw && cw) data.left = dw - o.minWidth; + if (ismaxw && cw) data.left = dw - o.maxWidth; + if (isminh && ch) data.top = dh - o.minHeight; + if (ismaxh && ch) data.top = dh - o.maxHeight; + + // fixing jump error on top/left - bug #2330 + var isNotwh = !data.width && !data.height; + if (isNotwh && !data.left && data.top) data.top = null; + else if (isNotwh && !data.top && data.left) data.left = null; + + return data; + }, + + _proportionallyResize: function() { + + var o = this.options; + if (!this._proportionallyResizeElements.length) return; + var element = this.helper || this.element; + + for (var i=0; i < this._proportionallyResizeElements.length; i++) { + + var prel = this._proportionallyResizeElements[i]; + + if (!this.borderDif) { + var b = [prel.css('borderTopWidth'), prel.css('borderRightWidth'), prel.css('borderBottomWidth'), prel.css('borderLeftWidth')], + p = [prel.css('paddingTop'), prel.css('paddingRight'), prel.css('paddingBottom'), prel.css('paddingLeft')]; + + this.borderDif = $.map(b, function(v, i) { + var border = parseInt(v,10)||0, padding = parseInt(p[i],10)||0; + return border + padding; + }); + } + + if ($.browser.msie && !(!($(element).is(':hidden') || $(element).parents(':hidden').length))) + continue; + + prel.css({ + height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0, + width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0 + }); + + }; + + }, + + _renderProxy: function() { + + var el = this.element, o = this.options; + this.elementOffset = el.offset(); + + if(this._helper) { + + this.helper = this.helper || $('
        '); + + // fix ie6 offset TODO: This seems broken + var ie6 = $.browser.msie && $.browser.version < 7, ie6offset = (ie6 ? 1 : 0), + pxyoffset = ( ie6 ? 2 : -1 ); + + this.helper.addClass(this._helper).css({ + width: this.element.outerWidth() + pxyoffset, + height: this.element.outerHeight() + pxyoffset, + position: 'absolute', + left: this.elementOffset.left - ie6offset +'px', + top: this.elementOffset.top - ie6offset +'px', + zIndex: ++o.zIndex //TODO: Don't modify option + }); + + this.helper + .appendTo("body") + .disableSelection(); + + } else { + this.helper = this.element; + } + + }, + + _change: { + e: function(event, dx, dy) { + return { width: this.originalSize.width + dx }; + }, + w: function(event, dx, dy) { + var o = this.options, cs = this.originalSize, sp = this.originalPosition; + return { left: sp.left + dx, width: cs.width - dx }; + }, + n: function(event, dx, dy) { + var o = this.options, cs = this.originalSize, sp = this.originalPosition; + return { top: sp.top + dy, height: cs.height - dy }; + }, + s: function(event, dx, dy) { + return { height: this.originalSize.height + dy }; + }, + se: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + }, + sw: function(event, dx, dy) { + return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + }, + ne: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy])); + }, + nw: function(event, dx, dy) { + return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy])); + } + }, + + _propagate: function(n, event) { + $.ui.plugin.call(this, n, [event, this.ui()]); + (n != "resize" && this._trigger(n, event, this.ui())); + }, + + plugins: {}, + + ui: function() { + return { + originalElement: this.originalElement, + element: this.element, + helper: this.helper, + position: this.position, + size: this.size, + originalSize: this.originalSize, + originalPosition: this.originalPosition + }; + } + +}); + +$.extend($.ui.resizable, { + version: "1.8.16" +}); + +/* + * Resizable Extensions + */ + +$.ui.plugin.add("resizable", "alsoResize", { + + start: function (event, ui) { + var self = $(this).data("resizable"), o = self.options; + + var _store = function (exp) { + $(exp).each(function() { + var el = $(this); + el.data("resizable-alsoresize", { + width: parseInt(el.width(), 10), height: parseInt(el.height(), 10), + left: parseInt(el.css('left'), 10), top: parseInt(el.css('top'), 10), + position: el.css('position') // to reset Opera on stop() + }); + }); + }; + + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.parentNode) { + if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); } + else { $.each(o.alsoResize, function (exp) { _store(exp); }); } + }else{ + _store(o.alsoResize); + } + }, + + resize: function (event, ui) { + var self = $(this).data("resizable"), o = self.options, os = self.originalSize, op = self.originalPosition; + + var delta = { + height: (self.size.height - os.height) || 0, width: (self.size.width - os.width) || 0, + top: (self.position.top - op.top) || 0, left: (self.position.left - op.left) || 0 + }, + + _alsoResize = function (exp, c) { + $(exp).each(function() { + var el = $(this), start = $(this).data("resizable-alsoresize"), style = {}, + css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ['width', 'height'] : ['width', 'height', 'top', 'left']; + + $.each(css, function (i, prop) { + var sum = (start[prop]||0) + (delta[prop]||0); + if (sum && sum >= 0) + style[prop] = sum || null; + }); + + // Opera fixing relative position + if ($.browser.opera && /relative/.test(el.css('position'))) { + self._revertToRelativePosition = true; + el.css({ position: 'absolute', top: 'auto', left: 'auto' }); + } + + el.css(style); + }); + }; + + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); }); + }else{ + _alsoResize(o.alsoResize); + } + }, + + stop: function (event, ui) { + var self = $(this).data("resizable"), o = self.options; + + var _reset = function (exp) { + $(exp).each(function() { + var el = $(this); + // reset position for Opera - no need to verify it was changed + el.css({ position: el.data("resizable-alsoresize").position }); + }); + }; + + if (self._revertToRelativePosition) { + self._revertToRelativePosition = false; + if (typeof(o.alsoResize) == 'object' && !o.alsoResize.nodeType) { + $.each(o.alsoResize, function (exp) { _reset(exp); }); + }else{ + _reset(o.alsoResize); + } + } + + $(this).removeData("resizable-alsoresize"); + } +}); + +$.ui.plugin.add("resizable", "animate", { + + stop: function(event, ui) { + var self = $(this).data("resizable"), o = self.options; + + var pr = self._proportionallyResizeElements, ista = pr.length && (/textarea/i).test(pr[0].nodeName), + soffseth = ista && $.ui.hasScroll(pr[0], 'left') /* TODO - jump height */ ? 0 : self.sizeDiff.height, + soffsetw = ista ? 0 : self.sizeDiff.width; + + var style = { width: (self.size.width - soffsetw), height: (self.size.height - soffseth) }, + left = (parseInt(self.element.css('left'), 10) + (self.position.left - self.originalPosition.left)) || null, + top = (parseInt(self.element.css('top'), 10) + (self.position.top - self.originalPosition.top)) || null; + + self.element.animate( + $.extend(style, top && left ? { top: top, left: left } : {}), { + duration: o.animateDuration, + easing: o.animateEasing, + step: function() { + + var data = { + width: parseInt(self.element.css('width'), 10), + height: parseInt(self.element.css('height'), 10), + top: parseInt(self.element.css('top'), 10), + left: parseInt(self.element.css('left'), 10) + }; + + if (pr && pr.length) $(pr[0]).css({ width: data.width, height: data.height }); + + // propagating resize, and updating values for each animation step + self._updateCache(data); + self._propagate("resize", event); + + } + } + ); + } + +}); + +$.ui.plugin.add("resizable", "containment", { + + start: function(event, ui) { + var self = $(this).data("resizable"), o = self.options, el = self.element; + var oc = o.containment, ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc; + if (!ce) return; + + self.containerElement = $(ce); + + if (/document/.test(oc) || oc == document) { + self.containerOffset = { left: 0, top: 0 }; + self.containerPosition = { left: 0, top: 0 }; + + self.parentData = { + element: $(document), left: 0, top: 0, + width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight + }; + } + + // i'm a node, so compute top, left, right, bottom + else { + var element = $(ce), p = []; + $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); }); + + self.containerOffset = element.offset(); + self.containerPosition = element.position(); + self.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) }; + + var co = self.containerOffset, ch = self.containerSize.height, cw = self.containerSize.width, + width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw ), height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch); + + self.parentData = { + element: ce, left: co.left, top: co.top, width: width, height: height + }; + } + }, + + resize: function(event, ui) { + var self = $(this).data("resizable"), o = self.options, + ps = self.containerSize, co = self.containerOffset, cs = self.size, cp = self.position, + pRatio = self._aspectRatio || event.shiftKey, cop = { top:0, left:0 }, ce = self.containerElement; + + if (ce[0] != document && (/static/).test(ce.css('position'))) cop = co; + + if (cp.left < (self._helper ? co.left : 0)) { + self.size.width = self.size.width + (self._helper ? (self.position.left - co.left) : (self.position.left - cop.left)); + if (pRatio) self.size.height = self.size.width / o.aspectRatio; + self.position.left = o.helper ? co.left : 0; + } + + if (cp.top < (self._helper ? co.top : 0)) { + self.size.height = self.size.height + (self._helper ? (self.position.top - co.top) : self.position.top); + if (pRatio) self.size.width = self.size.height * o.aspectRatio; + self.position.top = self._helper ? co.top : 0; + } + + self.offset.left = self.parentData.left+self.position.left; + self.offset.top = self.parentData.top+self.position.top; + + var woset = Math.abs( (self._helper ? self.offset.left - cop.left : (self.offset.left - cop.left)) + self.sizeDiff.width ), + hoset = Math.abs( (self._helper ? self.offset.top - cop.top : (self.offset.top - co.top)) + self.sizeDiff.height ); + + var isParent = self.containerElement.get(0) == self.element.parent().get(0), + isOffsetRelative = /relative|absolute/.test(self.containerElement.css('position')); + + if(isParent && isOffsetRelative) woset -= self.parentData.left; + + if (woset + self.size.width >= self.parentData.width) { + self.size.width = self.parentData.width - woset; + if (pRatio) self.size.height = self.size.width / self.aspectRatio; + } + + if (hoset + self.size.height >= self.parentData.height) { + self.size.height = self.parentData.height - hoset; + if (pRatio) self.size.width = self.size.height * self.aspectRatio; + } + }, + + stop: function(event, ui){ + var self = $(this).data("resizable"), o = self.options, cp = self.position, + co = self.containerOffset, cop = self.containerPosition, ce = self.containerElement; + + var helper = $(self.helper), ho = helper.offset(), w = helper.outerWidth() - self.sizeDiff.width, h = helper.outerHeight() - self.sizeDiff.height; + + if (self._helper && !o.animate && (/relative/).test(ce.css('position'))) + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + + if (self._helper && !o.animate && (/static/).test(ce.css('position'))) + $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h }); + + } +}); + +$.ui.plugin.add("resizable", "ghost", { + + start: function(event, ui) { + + var self = $(this).data("resizable"), o = self.options, cs = self.size; + + self.ghost = self.originalElement.clone(); + self.ghost + .css({ opacity: .25, display: 'block', position: 'relative', height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 }) + .addClass('ui-resizable-ghost') + .addClass(typeof o.ghost == 'string' ? o.ghost : ''); + + self.ghost.appendTo(self.helper); + + }, + + resize: function(event, ui){ + var self = $(this).data("resizable"), o = self.options; + if (self.ghost) self.ghost.css({ position: 'relative', height: self.size.height, width: self.size.width }); + }, + + stop: function(event, ui){ + var self = $(this).data("resizable"), o = self.options; + if (self.ghost && self.helper) self.helper.get(0).removeChild(self.ghost.get(0)); + } + +}); + +$.ui.plugin.add("resizable", "grid", { + + resize: function(event, ui) { + var self = $(this).data("resizable"), o = self.options, cs = self.size, os = self.originalSize, op = self.originalPosition, a = self.axis, ratio = o._aspectRatio || event.shiftKey; + o.grid = typeof o.grid == "number" ? [o.grid, o.grid] : o.grid; + var ox = Math.round((cs.width - os.width) / (o.grid[0]||1)) * (o.grid[0]||1), oy = Math.round((cs.height - os.height) / (o.grid[1]||1)) * (o.grid[1]||1); + + if (/^(se|s|e)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + } + else if (/^(ne)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.top = op.top - oy; + } + else if (/^(sw)$/.test(a)) { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.left = op.left - ox; + } + else { + self.size.width = os.width + ox; + self.size.height = os.height + oy; + self.position.top = op.top - oy; + self.position.left = op.left - ox; + } + } + +}); + +var num = function(v) { + return parseInt(v, 10) || 0; +}; + +var isNumber = function(value) { + return !isNaN(parseInt(value, 10)); +}; + +})(jQuery); +/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget("ui.selectable", $.ui.mouse, { + options: { + appendTo: 'body', + autoRefresh: true, + distance: 0, + filter: '*', + tolerance: 'touch' + }, + _create: function() { + var self = this; + + this.element.addClass("ui-selectable"); + + this.dragged = false; + + // cache selectee children based on filter + var selectees; + this.refresh = function() { + selectees = $(self.options.filter, self.element[0]); + selectees.each(function() { + var $this = $(this); + var pos = $this.offset(); + $.data(this, "selectable-item", { + element: this, + $element: $this, + left: pos.left, + top: pos.top, + right: pos.left + $this.outerWidth(), + bottom: pos.top + $this.outerHeight(), + startselected: false, + selected: $this.hasClass('ui-selected'), + selecting: $this.hasClass('ui-selecting'), + unselecting: $this.hasClass('ui-unselecting') + }); + }); + }; + this.refresh(); + + this.selectees = selectees.addClass("ui-selectee"); + + this._mouseInit(); + + this.helper = $("
        "); + }, + + destroy: function() { + this.selectees + .removeClass("ui-selectee") + .removeData("selectable-item"); + this.element + .removeClass("ui-selectable ui-selectable-disabled") + .removeData("selectable") + .unbind(".selectable"); + this._mouseDestroy(); + + return this; + }, + + _mouseStart: function(event) { + var self = this; + + this.opos = [event.pageX, event.pageY]; + + if (this.options.disabled) + return; + + var options = this.options; + + this.selectees = $(options.filter, this.element[0]); + + this._trigger("start", event); + + $(options.appendTo).append(this.helper); + // position helper (lasso) + this.helper.css({ + "left": event.clientX, + "top": event.clientY, + "width": 0, + "height": 0 + }); + + if (options.autoRefresh) { + this.refresh(); + } + + this.selectees.filter('.ui-selected').each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.startselected = true; + if (!event.metaKey) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + }); + + $(event.target).parents().andSelf().each(function() { + var selectee = $.data(this, "selectable-item"); + if (selectee) { + var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected'); + selectee.$element + .removeClass(doSelect ? "ui-unselecting" : "ui-selected") + .addClass(doSelect ? "ui-selecting" : "ui-unselecting"); + selectee.unselecting = !doSelect; + selectee.selecting = doSelect; + selectee.selected = doSelect; + // selectable (UN)SELECTING callback + if (doSelect) { + self._trigger("selecting", event, { + selecting: selectee.element + }); + } else { + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + return false; + } + }); + + }, + + _mouseDrag: function(event) { + var self = this; + this.dragged = true; + + if (this.options.disabled) + return; + + var options = this.options; + + var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY; + if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; } + if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; } + this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1}); + + this.selectees.each(function() { + var selectee = $.data(this, "selectable-item"); + //prevent helper from being selected if appendTo: selectable + if (!selectee || selectee.element == self.element[0]) + return; + var hit = false; + if (options.tolerance == 'touch') { + hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); + } else if (options.tolerance == 'fit') { + hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); + } + + if (hit) { + // SELECT + if (selectee.selected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + } + if (selectee.unselecting) { + selectee.$element.removeClass('ui-unselecting'); + selectee.unselecting = false; + } + if (!selectee.selecting) { + selectee.$element.addClass('ui-selecting'); + selectee.selecting = true; + // selectable SELECTING callback + self._trigger("selecting", event, { + selecting: selectee.element + }); + } + } else { + // UNSELECT + if (selectee.selecting) { + if (event.metaKey && selectee.startselected) { + selectee.$element.removeClass('ui-selecting'); + selectee.selecting = false; + selectee.$element.addClass('ui-selected'); + selectee.selected = true; + } else { + selectee.$element.removeClass('ui-selecting'); + selectee.selecting = false; + if (selectee.startselected) { + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + } + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + if (selectee.selected) { + if (!event.metaKey && !selectee.startselected) { + selectee.$element.removeClass('ui-selected'); + selectee.selected = false; + + selectee.$element.addClass('ui-unselecting'); + selectee.unselecting = true; + // selectable UNSELECTING callback + self._trigger("unselecting", event, { + unselecting: selectee.element + }); + } + } + } + }); + + return false; + }, + + _mouseStop: function(event) { + var self = this; + + this.dragged = false; + + var options = this.options; + + $('.ui-unselecting', this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass('ui-unselecting'); + selectee.unselecting = false; + selectee.startselected = false; + self._trigger("unselected", event, { + unselected: selectee.element + }); + }); + $('.ui-selecting', this.element[0]).each(function() { + var selectee = $.data(this, "selectable-item"); + selectee.$element.removeClass('ui-selecting').addClass('ui-selected'); + selectee.selecting = false; + selectee.selected = true; + selectee.startselected = true; + self._trigger("selected", event, { + selected: selectee.element + }); + }); + this._trigger("stop", event); + + this.helper.remove(); + + return false; + } + +}); + +$.extend($.ui.selectable, { + version: "1.8.16" +}); + +})(jQuery); +/* + * jQuery UI Sortable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Sortables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget("ui.sortable", $.ui.mouse, { + widgetEventPrefix: "sort", + options: { + appendTo: "parent", + axis: false, + connectWith: false, + containment: false, + cursor: 'auto', + cursorAt: false, + dropOnEmpty: true, + forcePlaceholderSize: false, + forceHelperSize: false, + grid: false, + handle: false, + helper: "original", + items: '> *', + opacity: false, + placeholder: false, + revert: false, + scroll: true, + scrollSensitivity: 20, + scrollSpeed: 20, + scope: "default", + tolerance: "intersect", + zIndex: 1000 + }, + _create: function() { + + var o = this.options; + this.containerCache = {}; + this.element.addClass("ui-sortable"); + + //Get the items + this.refresh(); + + //Let's determine if the items are being displayed horizontally + this.floating = this.items.length ? o.axis === 'x' || (/left|right/).test(this.items[0].item.css('float')) || (/inline|table-cell/).test(this.items[0].item.css('display')) : false; + + //Let's determine the parent's offset + this.offset = this.element.offset(); + + //Initialize mouse events for interaction + this._mouseInit(); + + }, + + destroy: function() { + this.element + .removeClass("ui-sortable ui-sortable-disabled") + .removeData("sortable") + .unbind(".sortable"); + this._mouseDestroy(); + + for ( var i = this.items.length - 1; i >= 0; i-- ) + this.items[i].item.removeData("sortable-item"); + + return this; + }, + + _setOption: function(key, value){ + if ( key === "disabled" ) { + this.options[ key ] = value; + + this.widget() + [ value ? "addClass" : "removeClass"]( "ui-sortable-disabled" ); + } else { + // Don't call widget base _setOption for disable as it adds ui-state-disabled class + $.Widget.prototype._setOption.apply(this, arguments); + } + }, + + _mouseCapture: function(event, overrideHandle) { + + if (this.reverting) { + return false; + } + + if(this.options.disabled || this.options.type == 'static') return false; + + //We have to refresh the items data once first + this._refreshItems(event); + + //Find out if the clicked node (or one of its parents) is a actual item in this.items + var currentItem = null, self = this, nodes = $(event.target).parents().each(function() { + if($.data(this, 'sortable-item') == self) { + currentItem = $(this); + return false; + } + }); + if($.data(event.target, 'sortable-item') == self) currentItem = $(event.target); + + if(!currentItem) return false; + if(this.options.handle && !overrideHandle) { + var validHandle = false; + + $(this.options.handle, currentItem).find("*").andSelf().each(function() { if(this == event.target) validHandle = true; }); + if(!validHandle) return false; + } + + this.currentItem = currentItem; + this._removeCurrentsFromItems(); + return true; + + }, + + _mouseStart: function(event, overrideHandle, noActivation) { + + var o = this.options, self = this; + this.currentContainer = this; + + //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture + this.refreshPositions(); + + //Create and append the visible helper + this.helper = this._createHelper(event); + + //Cache the helper size + this._cacheHelperProportions(); + + /* + * - Position generation - + * This block generates everything position related - it's the core of draggables. + */ + + //Cache the margins of the original element + this._cacheMargins(); + + //Get the next scrolling parent + this.scrollParent = this.helper.scrollParent(); + + //The element's absolute position on the page minus margins + this.offset = this.currentItem.offset(); + this.offset = { + top: this.offset.top - this.margins.top, + left: this.offset.left - this.margins.left + }; + + // Only after we got the offset, we can change the helper's position to absolute + // TODO: Still need to figure out a way to make relative sorting possible + this.helper.css("position", "absolute"); + this.cssPosition = this.helper.css("position"); + + $.extend(this.offset, { + click: { //Where the click happened, relative to the element + left: event.pageX - this.offset.left, + top: event.pageY - this.offset.top + }, + parent: this._getParentOffset(), + relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper + }); + + //Generate the original position + this.originalPosition = this._generatePosition(event); + this.originalPageX = event.pageX; + this.originalPageY = event.pageY; + + //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied + (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)); + + //Cache the former DOM position + this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] }; + + //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way + if(this.helper[0] != this.currentItem[0]) { + this.currentItem.hide(); + } + + //Create the placeholder + this._createPlaceholder(); + + //Set a containment if given in the options + if(o.containment) + this._setContainment(); + + if(o.cursor) { // cursor option + if ($('body').css("cursor")) this._storedCursor = $('body').css("cursor"); + $('body').css("cursor", o.cursor); + } + + if(o.opacity) { // opacity option + if (this.helper.css("opacity")) this._storedOpacity = this.helper.css("opacity"); + this.helper.css("opacity", o.opacity); + } + + if(o.zIndex) { // zIndex option + if (this.helper.css("zIndex")) this._storedZIndex = this.helper.css("zIndex"); + this.helper.css("zIndex", o.zIndex); + } + + //Prepare scrolling + if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') + this.overflowOffset = this.scrollParent.offset(); + + //Call callbacks + this._trigger("start", event, this._uiHash()); + + //Recache the helper size + if(!this._preserveHelperProportions) + this._cacheHelperProportions(); + + + //Post 'activate' events to possible containers + if(!noActivation) { + for (var i = this.containers.length - 1; i >= 0; i--) { this.containers[i]._trigger("activate", event, self._uiHash(this)); } + } + + //Prepare possible droppables + if($.ui.ddmanager) + $.ui.ddmanager.current = this; + + if ($.ui.ddmanager && !o.dropBehaviour) + $.ui.ddmanager.prepareOffsets(this, event); + + this.dragging = true; + + this.helper.addClass("ui-sortable-helper"); + this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position + return true; + + }, + + _mouseDrag: function(event) { + + //Compute the helpers position + this.position = this._generatePosition(event); + this.positionAbs = this._convertPositionTo("absolute"); + + if (!this.lastPositionAbs) { + this.lastPositionAbs = this.positionAbs; + } + + //Do scrolling + if(this.options.scroll) { + var o = this.options, scrolled = false; + if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') { + + if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed; + else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) + this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed; + + if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed; + else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) + this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed; + + } else { + + if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed); + else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) + scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed); + + if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed); + else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) + scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed); + + } + + if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) + $.ui.ddmanager.prepareOffsets(this, event); + } + + //Regenerate the absolute position used for position checks + this.positionAbs = this._convertPositionTo("absolute"); + + //Set the helper position + if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px'; + if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px'; + + //Rearrange + for (var i = this.items.length - 1; i >= 0; i--) { + + //Cache variables and intersection, continue if no intersection + var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item); + if (!intersection) continue; + + if(itemElement != this.currentItem[0] //cannot intersect with itself + && this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before + && !$.ui.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked + && (this.options.type == 'semi-dynamic' ? !$.ui.contains(this.element[0], itemElement) : true) + //&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container + ) { + + this.direction = intersection == 1 ? "down" : "up"; + + if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) { + this._rearrange(event, item); + } else { + break; + } + + this._trigger("change", event, this._uiHash()); + break; + } + } + + //Post events to containers + this._contactContainers(event); + + //Interconnect with droppables + if($.ui.ddmanager) $.ui.ddmanager.drag(this, event); + + //Call callbacks + this._trigger('sort', event, this._uiHash()); + + this.lastPositionAbs = this.positionAbs; + return false; + + }, + + _mouseStop: function(event, noPropagation) { + + if(!event) return; + + //If we are using droppables, inform the manager about the drop + if ($.ui.ddmanager && !this.options.dropBehaviour) + $.ui.ddmanager.drop(this, event); + + if(this.options.revert) { + var self = this; + var cur = self.placeholder.offset(); + + self.reverting = true; + + $(this.helper).animate({ + left: cur.left - this.offset.parent.left - self.margins.left + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollLeft), + top: cur.top - this.offset.parent.top - self.margins.top + (this.offsetParent[0] == document.body ? 0 : this.offsetParent[0].scrollTop) + }, parseInt(this.options.revert, 10) || 500, function() { + self._clear(event); + }); + } else { + this._clear(event, noPropagation); + } + + return false; + + }, + + cancel: function() { + + var self = this; + + if(this.dragging) { + + this._mouseUp({ target: null }); + + if(this.options.helper == "original") + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + else + this.currentItem.show(); + + //Post deactivating events to containers + for (var i = this.containers.length - 1; i >= 0; i--){ + this.containers[i]._trigger("deactivate", null, self._uiHash(this)); + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", null, self._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + if (this.placeholder) { + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + if(this.placeholder[0].parentNode) this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + if(this.options.helper != "original" && this.helper && this.helper[0].parentNode) this.helper.remove(); + + $.extend(this, { + helper: null, + dragging: false, + reverting: false, + _noFinalSort: null + }); + + if(this.domPosition.prev) { + $(this.domPosition.prev).after(this.currentItem); + } else { + $(this.domPosition.parent).prepend(this.currentItem); + } + } + + return this; + + }, + + serialize: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected); + var str = []; o = o || {}; + + $(items).each(function() { + var res = ($(o.item || this).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/)); + if(res) str.push((o.key || res[1]+'[]')+'='+(o.key && o.expression ? res[1] : res[2])); + }); + + if(!str.length && o.key) { + str.push(o.key + '='); + } + + return str.join('&'); + + }, + + toArray: function(o) { + + var items = this._getItemsAsjQuery(o && o.connected); + var ret = []; o = o || {}; + + items.each(function() { ret.push($(o.item || this).attr(o.attribute || 'id') || ''); }); + return ret; + + }, + + /* Be careful with the following core functions */ + _intersectsWith: function(item) { + + var x1 = this.positionAbs.left, + x2 = x1 + this.helperProportions.width, + y1 = this.positionAbs.top, + y2 = y1 + this.helperProportions.height; + + var l = item.left, + r = l + item.width, + t = item.top, + b = t + item.height; + + var dyClick = this.offset.click.top, + dxClick = this.offset.click.left; + + var isOverElement = (y1 + dyClick) > t && (y1 + dyClick) < b && (x1 + dxClick) > l && (x1 + dxClick) < r; + + if( this.options.tolerance == "pointer" + || this.options.forcePointerForContainers + || (this.options.tolerance != "pointer" && this.helperProportions[this.floating ? 'width' : 'height'] > item[this.floating ? 'width' : 'height']) + ) { + return isOverElement; + } else { + + return (l < x1 + (this.helperProportions.width / 2) // Right Half + && x2 - (this.helperProportions.width / 2) < r // Left Half + && t < y1 + (this.helperProportions.height / 2) // Bottom Half + && y2 - (this.helperProportions.height / 2) < b ); // Top Half + + } + }, + + _intersectsWithPointer: function(item) { + + var isOverElementHeight = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height), + isOverElementWidth = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width), + isOverElement = isOverElementHeight && isOverElementWidth, + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (!isOverElement) + return false; + + return this.floating ? + ( ((horizontalDirection && horizontalDirection == "right") || verticalDirection == "down") ? 2 : 1 ) + : ( verticalDirection && (verticalDirection == "down" ? 2 : 1) ); + + }, + + _intersectsWithSides: function(item) { + + var isOverBottomHalf = $.ui.isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height), + isOverRightHalf = $.ui.isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width), + verticalDirection = this._getDragVerticalDirection(), + horizontalDirection = this._getDragHorizontalDirection(); + + if (this.floating && horizontalDirection) { + return ((horizontalDirection == "right" && isOverRightHalf) || (horizontalDirection == "left" && !isOverRightHalf)); + } else { + return verticalDirection && ((verticalDirection == "down" && isOverBottomHalf) || (verticalDirection == "up" && !isOverBottomHalf)); + } + + }, + + _getDragVerticalDirection: function() { + var delta = this.positionAbs.top - this.lastPositionAbs.top; + return delta != 0 && (delta > 0 ? "down" : "up"); + }, + + _getDragHorizontalDirection: function() { + var delta = this.positionAbs.left - this.lastPositionAbs.left; + return delta != 0 && (delta > 0 ? "right" : "left"); + }, + + refresh: function(event) { + this._refreshItems(event); + this.refreshPositions(); + return this; + }, + + _connectWith: function() { + var options = this.options; + return options.connectWith.constructor == String + ? [options.connectWith] + : options.connectWith; + }, + + _getItemsAsjQuery: function(connected) { + + var self = this; + var items = []; + var queries = []; + var connectWith = this._connectWith(); + + if(connectWith && connected) { + for (var i = connectWith.length - 1; i >= 0; i--){ + var cur = $(connectWith[i]); + for (var j = cur.length - 1; j >= 0; j--){ + var inst = $.data(cur[j], 'sortable'); + if(inst && inst != this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), inst]); + } + }; + }; + } + + queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not('.ui-sortable-placeholder'), this]); + + for (var i = queries.length - 1; i >= 0; i--){ + queries[i][0].each(function() { + items.push(this); + }); + }; + + return $(items); + + }, + + _removeCurrentsFromItems: function() { + + var list = this.currentItem.find(":data(sortable-item)"); + + for (var i=0; i < this.items.length; i++) { + + for (var j=0; j < list.length; j++) { + if(list[j] == this.items[i].item[0]) + this.items.splice(i,1); + }; + + }; + + }, + + _refreshItems: function(event) { + + this.items = []; + this.containers = [this]; + var items = this.items; + var self = this; + var queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]]; + var connectWith = this._connectWith(); + + if(connectWith) { + for (var i = connectWith.length - 1; i >= 0; i--){ + var cur = $(connectWith[i]); + for (var j = cur.length - 1; j >= 0; j--){ + var inst = $.data(cur[j], 'sortable'); + if(inst && inst != this && !inst.options.disabled) { + queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]); + this.containers.push(inst); + } + }; + }; + } + + for (var i = queries.length - 1; i >= 0; i--) { + var targetData = queries[i][1]; + var _queries = queries[i][0]; + + for (var j=0, queriesLength = _queries.length; j < queriesLength; j++) { + var item = $(_queries[j]); + + item.data('sortable-item', targetData); // Data for target checking (mouse manager) + + items.push({ + item: item, + instance: targetData, + width: 0, height: 0, + left: 0, top: 0 + }); + }; + }; + + }, + + refreshPositions: function(fast) { + + //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change + if(this.offsetParent && this.helper) { + this.offset.parent = this._getParentOffset(); + } + + for (var i = this.items.length - 1; i >= 0; i--){ + var item = this.items[i]; + + //We ignore calculating positions of all connected containers when we're not over them + if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0]) + continue; + + var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item; + + if (!fast) { + item.width = t.outerWidth(); + item.height = t.outerHeight(); + } + + var p = t.offset(); + item.left = p.left; + item.top = p.top; + }; + + if(this.options.custom && this.options.custom.refreshContainers) { + this.options.custom.refreshContainers.call(this); + } else { + for (var i = this.containers.length - 1; i >= 0; i--){ + var p = this.containers[i].element.offset(); + this.containers[i].containerCache.left = p.left; + this.containers[i].containerCache.top = p.top; + this.containers[i].containerCache.width = this.containers[i].element.outerWidth(); + this.containers[i].containerCache.height = this.containers[i].element.outerHeight(); + }; + } + + return this; + }, + + _createPlaceholder: function(that) { + + var self = that || this, o = self.options; + + if(!o.placeholder || o.placeholder.constructor == String) { + var className = o.placeholder; + o.placeholder = { + element: function() { + + var el = $(document.createElement(self.currentItem[0].nodeName)) + .addClass(className || self.currentItem[0].className+" ui-sortable-placeholder") + .removeClass("ui-sortable-helper")[0]; + + if(!className) + el.style.visibility = "hidden"; + + return el; + }, + update: function(container, p) { + + // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that + // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified + if(className && !o.forcePlaceholderSize) return; + + //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item + if(!p.height()) { p.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css('paddingTop')||0, 10) - parseInt(self.currentItem.css('paddingBottom')||0, 10)); }; + if(!p.width()) { p.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css('paddingLeft')||0, 10) - parseInt(self.currentItem.css('paddingRight')||0, 10)); }; + } + }; + } + + //Create the placeholder + self.placeholder = $(o.placeholder.element.call(self.element, self.currentItem)); + + //Append it after the actual current item + self.currentItem.after(self.placeholder); + + //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317) + o.placeholder.update(self, self.placeholder); + + }, + + _contactContainers: function(event) { + + // get innermost container that intersects with item + var innermostContainer = null, innermostIndex = null; + + + for (var i = this.containers.length - 1; i >= 0; i--){ + + // never consider a container that's located within the item itself + if($.ui.contains(this.currentItem[0], this.containers[i].element[0])) + continue; + + if(this._intersectsWith(this.containers[i].containerCache)) { + + // if we've already found a container and it's more "inner" than this, then continue + if(innermostContainer && $.ui.contains(this.containers[i].element[0], innermostContainer.element[0])) + continue; + + innermostContainer = this.containers[i]; + innermostIndex = i; + + } else { + // container doesn't intersect. trigger "out" event if necessary + if(this.containers[i].containerCache.over) { + this.containers[i]._trigger("out", event, this._uiHash(this)); + this.containers[i].containerCache.over = 0; + } + } + + } + + // if no intersecting containers found, return + if(!innermostContainer) return; + + // move the item into the container if it's not there already + if(this.containers.length === 1) { + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } else if(this.currentContainer != this.containers[innermostIndex]) { + + //When entering a new container, we will find the item with the least distance and append our item near it + var dist = 10000; var itemWithLeastDistance = null; var base = this.positionAbs[this.containers[innermostIndex].floating ? 'left' : 'top']; + for (var j = this.items.length - 1; j >= 0; j--) { + if(!$.ui.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) continue; + var cur = this.items[j][this.containers[innermostIndex].floating ? 'left' : 'top']; + if(Math.abs(cur - base) < dist) { + dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j]; + } + } + + if(!itemWithLeastDistance && !this.options.dropOnEmpty) //Check if dropOnEmpty is enabled + return; + + this.currentContainer = this.containers[innermostIndex]; + itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true); + this._trigger("change", event, this._uiHash()); + this.containers[innermostIndex]._trigger("change", event, this._uiHash(this)); + + //Update the placeholder + this.options.placeholder.update(this.currentContainer, this.placeholder); + + this.containers[innermostIndex]._trigger("over", event, this._uiHash(this)); + this.containers[innermostIndex].containerCache.over = 1; + } + + + }, + + _createHelper: function(event) { + + var o = this.options; + var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper == 'clone' ? this.currentItem.clone() : this.currentItem); + + if(!helper.parents('body').length) //Add the helper to the DOM if that didn't happen already + $(o.appendTo != 'parent' ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]); + + if(helper[0] == this.currentItem[0]) + this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") }; + + if(helper[0].style.width == '' || o.forceHelperSize) helper.width(this.currentItem.width()); + if(helper[0].style.height == '' || o.forceHelperSize) helper.height(this.currentItem.height()); + + return helper; + + }, + + _adjustOffsetFromHelper: function(obj) { + if (typeof obj == 'string') { + obj = obj.split(' '); + } + if ($.isArray(obj)) { + obj = {left: +obj[0], top: +obj[1] || 0}; + } + if ('left' in obj) { + this.offset.click.left = obj.left + this.margins.left; + } + if ('right' in obj) { + this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left; + } + if ('top' in obj) { + this.offset.click.top = obj.top + this.margins.top; + } + if ('bottom' in obj) { + this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top; + } + }, + + _getParentOffset: function() { + + + //Get the offsetParent and cache its position + this.offsetParent = this.helper.offsetParent(); + var po = this.offsetParent.offset(); + + // This is a special case where we need to modify a offset calculated on start, since the following happened: + // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent + // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that + // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag + if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) { + po.left += this.scrollParent.scrollLeft(); + po.top += this.scrollParent.scrollTop(); + } + + if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information + || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix + po = { top: 0, left: 0 }; + + return { + top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0), + left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0) + }; + + }, + + _getRelativeOffset: function() { + + if(this.cssPosition == "relative") { + var p = this.currentItem.position(); + return { + top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(), + left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft() + }; + } else { + return { top: 0, left: 0 }; + } + + }, + + _cacheMargins: function() { + this.margins = { + left: (parseInt(this.currentItem.css("marginLeft"),10) || 0), + top: (parseInt(this.currentItem.css("marginTop"),10) || 0) + }; + }, + + _cacheHelperProportions: function() { + this.helperProportions = { + width: this.helper.outerWidth(), + height: this.helper.outerHeight() + }; + }, + + _setContainment: function() { + + var o = this.options; + if(o.containment == 'parent') o.containment = this.helper[0].parentNode; + if(o.containment == 'document' || o.containment == 'window') this.containment = [ + 0 - this.offset.relative.left - this.offset.parent.left, + 0 - this.offset.relative.top - this.offset.parent.top, + $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left, + ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top + ]; + + if(!(/^(document|window|parent)$/).test(o.containment)) { + var ce = $(o.containment)[0]; + var co = $(o.containment).offset(); + var over = ($(ce).css("overflow") != 'hidden'); + + this.containment = [ + co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left, + co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top, + co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left, + co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top + ]; + } + + }, + + _convertPositionTo: function(d, pos) { + + if(!pos) pos = this.position; + var mod = d == "absolute" ? 1 : -1; + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + return { + top: ( + pos.top // The absolute mouse position + + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent + + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border) + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod) + ), + left: ( + pos.left // The absolute mouse position + + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent + + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border) + - ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod) + ) + }; + + }, + + _generatePosition: function(event) { + + var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName); + + // This is another very weird special case that only happens for relative elements: + // 1. If the css position is relative + // 2. and the scroll parent is the document or similar to the offset parent + // we have to refresh the relative offset during the scroll so there are no jumps + if(this.cssPosition == 'relative' && !(this.scrollParent[0] != document && this.scrollParent[0] != this.offsetParent[0])) { + this.offset.relative = this._getRelativeOffset(); + } + + var pageX = event.pageX; + var pageY = event.pageY; + + /* + * - Position constraining - + * Constrain the position to a mix of grid, containment. + */ + + if(this.originalPosition) { //If we are not dragging yet, we won't check for options + + if(this.containment) { + if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left; + if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top; + if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left; + if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top; + } + + if(o.grid) { + var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1]; + pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top; + + var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0]; + pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left; + } + + } + + return { + top: ( + pageY // The absolute mouse position + - this.offset.click.top // Click offset (relative to the element) + - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent + - this.offset.parent.top // The offsetParent's offset without borders (offset + border) + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) )) + ), + left: ( + pageX // The absolute mouse position + - this.offset.click.left // Click offset (relative to the element) + - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent + - this.offset.parent.left // The offsetParent's offset without borders (offset + border) + + ($.browser.safari && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() )) + ) + }; + + }, + + _rearrange: function(event, i, a, hardRefresh) { + + a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction == 'down' ? i.item[0] : i.item[0].nextSibling)); + + //Various things done here to improve the performance: + // 1. we create a setTimeout, that calls refreshPositions + // 2. on the instance, we have a counter variable, that get's higher after every append + // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same + // 4. this lets only the last addition to the timeout stack through + this.counter = this.counter ? ++this.counter : 1; + var self = this, counter = this.counter; + + window.setTimeout(function() { + if(counter == self.counter) self.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove + },0); + + }, + + _clear: function(event, noPropagation) { + + this.reverting = false; + // We delay all events that have to be triggered to after the point where the placeholder has been removed and + // everything else normalized again + var delayedTriggers = [], self = this; + + // We first have to update the dom position of the actual currentItem + // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088) + if(!this._noFinalSort && this.currentItem.parent().length) this.placeholder.before(this.currentItem); + this._noFinalSort = null; + + if(this.helper[0] == this.currentItem[0]) { + for(var i in this._storedCSS) { + if(this._storedCSS[i] == 'auto' || this._storedCSS[i] == 'static') this._storedCSS[i] = ''; + } + this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"); + } else { + this.currentItem.show(); + } + + if(this.fromOutside && !noPropagation) delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); }); + if((this.fromOutside || this.domPosition.prev != this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent != this.currentItem.parent()[0]) && !noPropagation) delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed + if(!$.ui.contains(this.element[0], this.currentItem[0])) { //Node was moved out of the current element + if(!noPropagation) delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); }); + for (var i = this.containers.length - 1; i >= 0; i--){ + if($.ui.contains(this.containers[i].element[0], this.currentItem[0]) && !noPropagation) { + delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + } + }; + }; + + //Post events to containers + for (var i = this.containers.length - 1; i >= 0; i--){ + if(!noPropagation) delayedTriggers.push((function(c) { return function(event) { c._trigger("deactivate", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + if(this.containers[i].containerCache.over) { + delayedTriggers.push((function(c) { return function(event) { c._trigger("out", event, this._uiHash(this)); }; }).call(this, this.containers[i])); + this.containers[i].containerCache.over = 0; + } + } + + //Do what was originally in plugins + if(this._storedCursor) $('body').css("cursor", this._storedCursor); //Reset cursor + if(this._storedOpacity) this.helper.css("opacity", this._storedOpacity); //Reset opacity + if(this._storedZIndex) this.helper.css("zIndex", this._storedZIndex == 'auto' ? '' : this._storedZIndex); //Reset z-index + + this.dragging = false; + if(this.cancelHelperRemoval) { + if(!noPropagation) { + this._trigger("beforeStop", event, this._uiHash()); + for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + return false; + } + + if(!noPropagation) this._trigger("beforeStop", event, this._uiHash()); + + //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node! + this.placeholder[0].parentNode.removeChild(this.placeholder[0]); + + if(this.helper[0] != this.currentItem[0]) this.helper.remove(); this.helper = null; + + if(!noPropagation) { + for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events + this._trigger("stop", event, this._uiHash()); + } + + this.fromOutside = false; + return true; + + }, + + _trigger: function() { + if ($.Widget.prototype._trigger.apply(this, arguments) === false) { + this.cancel(); + } + }, + + _uiHash: function(inst) { + var self = inst || this; + return { + helper: self.helper, + placeholder: self.placeholder || $([]), + position: self.position, + originalPosition: self.originalPosition, + offset: self.positionAbs, + item: self.currentItem, + sender: inst ? inst.element : null + }; + } + +}); + +$.extend($.ui.sortable, { + version: "1.8.16" +}); + +})(jQuery); +/* + * jQuery UI Effects 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +;jQuery.effects || (function($, undefined) { + +$.effects = {}; + + + +/******************************************************************************/ +/****************************** COLOR ANIMATIONS ******************************/ +/******************************************************************************/ + +// override the animation for color styles +$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', + 'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], +function(i, attr) { + $.fx.step[attr] = function(fx) { + if (!fx.colorInit) { + fx.start = getColor(fx.elem, attr); + fx.end = getRGB(fx.end); + fx.colorInit = true; + } + + fx.elem.style[attr] = 'rgb(' + + Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' + + Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' + + Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')'; + }; +}); + +// Color Conversion functions from highlightFade +// By Blair Mitchelmore +// http://jquery.offput.ca/highlightFade/ + +// Parse strings looking for color tuples [255,255,255] +function getRGB(color) { + var result; + + // Check if we're already dealing with an array of colors + if ( color && color.constructor == Array && color.length == 3 ) + return color; + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) + return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) + return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) + return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) + return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) + return colors['transparent']; + + // Otherwise, we're most likely dealing with a named color + return colors[$.trim(color).toLowerCase()]; +} + +function getColor(elem, attr) { + var color; + + do { + color = $.curCSS(elem, attr); + + // Keep going until we find an element that has color, or we hit the body + if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) + break; + + attr = "backgroundColor"; + } while ( elem = elem.parentNode ); + + return getRGB(color); +}; + +// Some named colors to work with +// From Interface by Stefan Petre +// http://interface.eyecon.ro/ + +var colors = { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0], + transparent: [255,255,255] +}; + + + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ + +var classAnimationActions = ['add', 'remove', 'toggle'], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + +function getElementStyles() { + var style = document.defaultView + ? document.defaultView.getComputedStyle(this, null) + : this.currentStyle, + newStyle = {}, + key, + camelCase; + + // webkit enumerates style porperties + if (style && style.length && style[0] && style[style[0]]) { + var len = style.length; + while (len--) { + key = style[len]; + if (typeof style[key] == 'string') { + camelCase = key.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + newStyle[camelCase] = style[key]; + } + } + } else { + for (key in style) { + if (typeof style[key] === 'string') { + newStyle[key] = style[key]; + } + } + } + + return newStyle; +} + +function filterStyles(styles) { + var name, value; + for (name in styles) { + value = styles[name]; + if ( + // ignore null and undefined values + value == null || + // ignore functions (when does this occur?) + $.isFunction(value) || + // shorthand styles that need to be expanded + name in shorthandStyles || + // ignore scrollbars (break in IE) + (/scrollbar/).test(name) || + + // only colors or values that can be converted to numbers + (!(/color/i).test(name) && isNaN(parseFloat(value))) + ) { + delete styles[name]; + } + } + + return styles; +} + +function styleDifference(oldStyle, newStyle) { + var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459 + name; + + for (name in newStyle) { + if (oldStyle[name] != newStyle[name]) { + diff[name] = newStyle[name]; + } + } + + return diff; +} + +$.effects.animateClass = function(value, duration, easing, callback) { + if ($.isFunction(easing)) { + callback = easing; + easing = null; + } + + return this.queue(function() { + var that = $(this), + originalStyleAttr = that.attr('style') || ' ', + originalStyle = filterStyles(getElementStyles.call(this)), + newStyle, + className = that.attr('class'); + + $.each(classAnimationActions, function(i, action) { + if (value[action]) { + that[action + 'Class'](value[action]); + } + }); + newStyle = filterStyles(getElementStyles.call(this)); + that.attr('class', className); + + that.animate(styleDifference(originalStyle, newStyle), { + queue: false, + duration: duration, + easing: easing, + complete: function() { + $.each(classAnimationActions, function(i, action) { + if (value[action]) { that[action + 'Class'](value[action]); } + }); + // work around bug in IE by clearing the cssText before setting it + if (typeof that.attr('style') == 'object') { + that.attr('style').cssText = ''; + that.attr('style').cssText = originalStyleAttr; + } else { + that.attr('style', originalStyleAttr); + } + if (callback) { callback.apply(this, arguments); } + $.dequeue( this ); + } + }); + }); +}; + +$.fn.extend({ + _addClass: $.fn.addClass, + addClass: function(classNames, speed, easing, callback) { + return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); + }, + + _removeClass: $.fn.removeClass, + removeClass: function(classNames,speed,easing,callback) { + return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); + }, + + _toggleClass: $.fn.toggleClass, + toggleClass: function(classNames, force, speed, easing, callback) { + if ( typeof force == "boolean" || force === undefined ) { + if ( !speed ) { + // without speed parameter; + return this._toggleClass(classNames, force); + } else { + return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]); + } + } else { + // without switch parameter; + return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]); + } + }, + + switchClass: function(remove,add,speed,easing,callback) { + return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); + } +}); + + + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +$.extend($.effects, { + version: "1.8.16", + + // Saves a set of properties in a data storage + save: function(element, set) { + for(var i=0; i < set.length; i++) { + if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]); + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function(element, set) { + for(var i=0; i < set.length; i++) { + if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i])); + } + }, + + setMode: function(el, mode) { + if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle + return mode; + }, + + getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value + // this should be a little more flexible in the future to handle a string & hash + var y, x; + switch (origin[0]) { + case 'top': y = 0; break; + case 'middle': y = 0.5; break; + case 'bottom': y = 1; break; + default: y = origin[0] / original.height; + }; + switch (origin[1]) { + case 'left': x = 0; break; + case 'center': x = 0.5; break; + case 'right': x = 1; break; + default: x = origin[1] / original.width; + }; + return {x: x, y: y}; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function(element) { + + // if the element is already wrapped, return it + if (element.parent().is('.ui-effects-wrapper')) { + return element.parent(); + } + + // wrap the element + var props = { + width: element.outerWidth(true), + height: element.outerHeight(true), + 'float': element.css('float') + }, + wrapper = $('
        ') + .addClass('ui-effects-wrapper') + .css({ + fontSize: '100%', + background: 'transparent', + border: 'none', + margin: 0, + padding: 0 + }), + active = document.activeElement; + + element.wrap(wrapper); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element + + // transfer positioning properties to the wrapper + if (element.css('position') == 'static') { + wrapper.css({ position: 'relative' }); + element.css({ position: 'relative' }); + } else { + $.extend(props, { + position: element.css('position'), + zIndex: element.css('z-index') + }); + $.each(['top', 'left', 'bottom', 'right'], function(i, pos) { + props[pos] = element.css(pos); + if (isNaN(parseInt(props[pos], 10))) { + props[pos] = 'auto'; + } + }); + element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' }); + } + + return wrapper.css(props).show(); + }, + + removeWrapper: function(element) { + var parent, + active = document.activeElement; + + if (element.parent().is('.ui-effects-wrapper')) { + parent = element.parent().replaceWith(element); + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + return parent; + } + + return element; + }, + + setTransition: function(element, list, factor, value) { + value = value || {}; + $.each(list, function(i, x){ + unit = element.cssUnit(x); + if (unit[0] > 0) value[x] = unit[0] * factor + unit[1]; + }); + return value; + } +}); + + +function _normalizeArguments(effect, options, speed, callback) { + // shift params for method overloading + if (typeof effect == 'object') { + callback = options; + speed = null; + options = effect; + effect = options.effect; + } + if ($.isFunction(options)) { + callback = options; + speed = null; + options = {}; + } + if (typeof options == 'number' || $.fx.speeds[options]) { + callback = speed; + speed = options; + options = {}; + } + if ($.isFunction(speed)) { + callback = speed; + speed = null; + } + + options = options || {}; + + speed = speed || options.duration; + speed = $.fx.off ? 0 : typeof speed == 'number' + ? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default; + + callback = callback || options.complete; + + return [effect, options, speed, callback]; +} + +function standardSpeed( speed ) { + // valid standard speeds + if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { + return true; + } + + // invalid strings - treat as "normal" speed + if ( typeof speed === "string" && !$.effects[ speed ] ) { + return true; + } + + return false; +} + +$.fn.extend({ + effect: function(effect, options, speed, callback) { + var args = _normalizeArguments.apply(this, arguments), + // TODO: make effects take actual parameters instead of a hash + args2 = { + options: args[1], + duration: args[2], + callback: args[3] + }, + mode = args2.options.mode, + effectMethod = $.effects[effect]; + + if ( $.fx.off || !effectMethod ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args2.duration, args2.callback ); + } else { + return this.each(function() { + if ( args2.callback ) { + args2.callback.call( this ); + } + }); + } + } + + return effectMethod.call(this, args2); + }, + + _show: $.fn.show, + show: function(speed) { + if ( standardSpeed( speed ) ) { + return this._show.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'show'; + return this.effect.apply(this, args); + } + }, + + _hide: $.fn.hide, + hide: function(speed) { + if ( standardSpeed( speed ) ) { + return this._hide.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'hide'; + return this.effect.apply(this, args); + } + }, + + // jQuery core overloads toggle and creates _toggle + __toggle: $.fn.toggle, + toggle: function(speed) { + if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { + return this.__toggle.apply(this, arguments); + } else { + var args = _normalizeArguments.apply(this, arguments); + args[1].mode = 'toggle'; + return this.effect.apply(this, args); + } + }, + + // helper functions + cssUnit: function(key) { + var style = this.css(key), val = []; + $.each( ['em','px','%','pt'], function(i, unit){ + if(style.indexOf(unit) > 0) + val = [parseFloat(style), unit]; + }); + return val; + } +}); + + + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +// t: current time, b: begInnIng value, c: change In value, d: duration +$.easing.jswing = $.easing.swing; + +$.extend($.easing, +{ + def: 'easeOutQuad', + swing: function (x, t, b, c, d) { + //alert($.easing.default); + return $.easing[$.easing.def](x, t, b, c, d); + }, + easeInQuad: function (x, t, b, c, d) { + return c*(t/=d)*t + b; + }, + easeOutQuad: function (x, t, b, c, d) { + return -c *(t/=d)*(t-2) + b; + }, + easeInOutQuad: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t + b; + return -c/2 * ((--t)*(t-2) - 1) + b; + }, + easeInCubic: function (x, t, b, c, d) { + return c*(t/=d)*t*t + b; + }, + easeOutCubic: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t + 1) + b; + }, + easeInOutCubic: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t + b; + return c/2*((t-=2)*t*t + 2) + b; + }, + easeInQuart: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t + b; + }, + easeOutQuart: function (x, t, b, c, d) { + return -c * ((t=t/d-1)*t*t*t - 1) + b; + }, + easeInOutQuart: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t + b; + return -c/2 * ((t-=2)*t*t*t - 2) + b; + }, + easeInQuint: function (x, t, b, c, d) { + return c*(t/=d)*t*t*t*t + b; + }, + easeOutQuint: function (x, t, b, c, d) { + return c*((t=t/d-1)*t*t*t*t + 1) + b; + }, + easeInOutQuint: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b; + return c/2*((t-=2)*t*t*t*t + 2) + b; + }, + easeInSine: function (x, t, b, c, d) { + return -c * Math.cos(t/d * (Math.PI/2)) + c + b; + }, + easeOutSine: function (x, t, b, c, d) { + return c * Math.sin(t/d * (Math.PI/2)) + b; + }, + easeInOutSine: function (x, t, b, c, d) { + return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b; + }, + easeInExpo: function (x, t, b, c, d) { + return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b; + }, + easeOutExpo: function (x, t, b, c, d) { + return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b; + }, + easeInOutExpo: function (x, t, b, c, d) { + if (t==0) return b; + if (t==d) return b+c; + if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b; + return c/2 * (-Math.pow(2, -10 * --t) + 2) + b; + }, + easeInCirc: function (x, t, b, c, d) { + return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; + }, + easeOutCirc: function (x, t, b, c, d) { + return c * Math.sqrt(1 - (t=t/d-1)*t) + b; + }, + easeInOutCirc: function (x, t, b, c, d) { + if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; + return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; + }, + easeInElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + }, + easeOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; + }, + easeInOutElastic: function (x, t, b, c, d) { + var s=1.70158;var p=0;var a=c; + if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); + if (a < Math.abs(c)) { a=c; var s=p/4; } + else var s = p/(2*Math.PI) * Math.asin (c/a); + if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b; + return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b; + }, + easeInBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*(t/=d)*t*((s+1)*t - s) + b; + }, + easeOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b; + }, + easeInOutBack: function (x, t, b, c, d, s) { + if (s == undefined) s = 1.70158; + if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; + return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; + }, + easeInBounce: function (x, t, b, c, d) { + return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b; + }, + easeOutBounce: function (x, t, b, c, d) { + if ((t/=d) < (1/2.75)) { + return c*(7.5625*t*t) + b; + } else if (t < (2/2.75)) { + return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; + } else if (t < (2.5/2.75)) { + return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; + } else { + return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; + } + }, + easeInOutBounce: function (x, t, b, c, d) { + if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b; + return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b; + } +}); + +/* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +})(jQuery); +/* + * jQuery UI Effects Blind 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Blind + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.blind = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode + var direction = o.options.direction || 'vertical'; // Default direction + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper + var ref = (direction == 'vertical') ? 'height' : 'width'; + var distance = (direction == 'vertical') ? wrapper.height() : wrapper.width(); + if(mode == 'show') wrapper.css(ref, 0); // Shift + + // Animation + var animation = {}; + animation[ref] = mode == 'show' ? distance : 0; + + // Animate + wrapper.animate(animation, o.duration, o.options.easing, function() { + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(el[0], arguments); // Callback + el.dequeue(); + }); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Bounce 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Bounce + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.bounce = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode + var direction = o.options.direction || 'up'; // Default direction + var distance = o.options.distance || 20; // Default distance + var times = o.options.times || 5; // Default # of times + var speed = o.duration || 250; // Default speed per bounce + if (/show|hide/.test(mode)) props.push('opacity'); // Avoid touching opacity to prevent clearType and PNG issues in IE + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + $.effects.createWrapper(el); // Create Wrapper + var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; + var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; + var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 3 : el.outerWidth({margin:true}) / 3); + if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift + if (mode == 'hide') distance = distance / (times * 2); + if (mode != 'hide') times--; + + // Animate + if (mode == 'show') { // Show Bounce + var animation = {opacity: 1}; + animation[ref] = (motion == 'pos' ? '+=' : '-=') + distance; + el.animate(animation, speed / 2, o.options.easing); + distance = distance / 2; + times--; + }; + for (var i = 0; i < times; i++) { // Bounces + var animation1 = {}, animation2 = {}; + animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; + animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; + el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing); + distance = (mode == 'hide') ? distance * 2 : distance / 2; + }; + if (mode == 'hide') { // Last Bounce + var animation = {opacity: 0}; + animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; + el.animate(animation, speed / 2, o.options.easing, function(){ + el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + }); + } else { + var animation1 = {}, animation2 = {}; + animation1[ref] = (motion == 'pos' ? '-=' : '+=') + distance; + animation2[ref] = (motion == 'pos' ? '+=' : '-=') + distance; + el.animate(animation1, speed / 2, o.options.easing).animate(animation2, speed / 2, o.options.easing, function(){ + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + }); + }; + el.queue('fx', function() { el.dequeue(); }); + el.dequeue(); + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Clip 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Clip + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.clip = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right','height','width']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode + var direction = o.options.direction || 'vertical'; // Default direction + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper + var animate = el[0].tagName == 'IMG' ? wrapper : el; + var ref = { + size: (direction == 'vertical') ? 'height' : 'width', + position: (direction == 'vertical') ? 'top' : 'left' + }; + var distance = (direction == 'vertical') ? animate.height() : animate.width(); + if(mode == 'show') { animate.css(ref.size, 0); animate.css(ref.position, distance / 2); } // Shift + + // Animation + var animation = {}; + animation[ref.size] = mode == 'show' ? distance : 0; + animation[ref.position] = mode == 'show' ? 0 : distance / 2; + + // Animate + animate.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(el[0], arguments); // Callback + el.dequeue(); + }}); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Drop 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Drop + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.drop = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right','opacity']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode + var direction = o.options.direction || 'left'; // Default Direction + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + $.effects.createWrapper(el); // Create Wrapper + var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; + var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; + var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) / 2 : el.outerWidth({margin:true}) / 2); + if (mode == 'show') el.css('opacity', 0).css(ref, motion == 'pos' ? -distance : distance); // Shift + + // Animation + var animation = {opacity: mode == 'show' ? 1 : 0}; + animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; + + // Animate + el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + el.dequeue(); + }}); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Explode 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Explode + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.explode = function(o) { + + return this.queue(function() { + + var rows = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; + var cells = o.options.pieces ? Math.round(Math.sqrt(o.options.pieces)) : 3; + + o.options.mode = o.options.mode == 'toggle' ? ($(this).is(':visible') ? 'hide' : 'show') : o.options.mode; + var el = $(this).show().css('visibility', 'hidden'); + var offset = el.offset(); + + //Substract the margins - not fixing the problem yet. + offset.top -= parseInt(el.css("marginTop"),10) || 0; + offset.left -= parseInt(el.css("marginLeft"),10) || 0; + + var width = el.outerWidth(true); + var height = el.outerHeight(true); + + for(var i=0;i
        ') + .css({ + position: 'absolute', + visibility: 'visible', + left: -j*(width/cells), + top: -i*(height/rows) + }) + .parent() + .addClass('ui-effects-explode') + .css({ + position: 'absolute', + overflow: 'hidden', + width: width/cells, + height: height/rows, + left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? (j-Math.floor(cells/2))*(width/cells) : 0), + top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? (i-Math.floor(rows/2))*(height/rows) : 0), + opacity: o.options.mode == 'show' ? 0 : 1 + }).animate({ + left: offset.left + j*(width/cells) + (o.options.mode == 'show' ? 0 : (j-Math.floor(cells/2))*(width/cells)), + top: offset.top + i*(height/rows) + (o.options.mode == 'show' ? 0 : (i-Math.floor(rows/2))*(height/rows)), + opacity: o.options.mode == 'show' ? 1 : 0 + }, o.duration || 500); + } + } + + // Set a timeout, to call the callback approx. when the other animations have finished + setTimeout(function() { + + o.options.mode == 'show' ? el.css({ visibility: 'visible' }) : el.css({ visibility: 'visible' }).hide(); + if(o.callback) o.callback.apply(el[0]); // Callback + el.dequeue(); + + $('div.ui-effects-explode').remove(); + + }, o.duration || 500); + + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Fade 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.fade = function(o) { + return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'hide'); + + elem.animate({ opacity: mode }, { + queue: false, + duration: o.duration, + easing: o.options.easing, + complete: function() { + (o.callback && o.callback.apply(this, arguments)); + elem.dequeue(); + } + }); + }); +}; + +})(jQuery); +/* + * jQuery UI Effects Fold 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.fold = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'hide'); // Set Mode + var size = o.options.size || 15; // Default fold size + var horizFirst = !(!o.options.horizFirst); // Ensure a boolean value + var duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2; + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + var wrapper = $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper + var widthFirst = ((mode == 'show') != horizFirst); + var ref = widthFirst ? ['width', 'height'] : ['height', 'width']; + var distance = widthFirst ? [wrapper.width(), wrapper.height()] : [wrapper.height(), wrapper.width()]; + var percent = /([0-9]+)%/.exec(size); + if(percent) size = parseInt(percent[1],10) / 100 * distance[mode == 'hide' ? 0 : 1]; + if(mode == 'show') wrapper.css(horizFirst ? {height: 0, width: size} : {height: size, width: 0}); // Shift + + // Animation + var animation1 = {}, animation2 = {}; + animation1[ref[0]] = mode == 'show' ? distance[0] : size; + animation2[ref[1]] = mode == 'show' ? distance[1] : 0; + + // Animate + wrapper.animate(animation1, duration, o.options.easing) + .animate(animation2, duration, o.options.easing, function() { + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(el[0], arguments); // Callback + el.dequeue(); + }); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Highlight 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.highlight = function(o) { + return this.queue(function() { + var elem = $(this), + props = ['backgroundImage', 'backgroundColor', 'opacity'], + mode = $.effects.setMode(elem, o.options.mode || 'show'), + animation = { + backgroundColor: elem.css('backgroundColor') + }; + + if (mode == 'hide') { + animation.opacity = 0; + } + + $.effects.save(elem, props); + elem + .show() + .css({ + backgroundImage: 'none', + backgroundColor: o.options.color || '#ffff99' + }) + .animate(animation, { + queue: false, + duration: o.duration, + easing: o.options.easing, + complete: function() { + (mode == 'hide' && elem.hide()); + $.effects.restore(elem, props); + (mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter')); + (o.callback && o.callback.apply(this, arguments)); + elem.dequeue(); + } + }); + }); +}; + +})(jQuery); +/* + * jQuery UI Effects Pulsate 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.pulsate = function(o) { + return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'show'); + times = ((o.options.times || 5) * 2) - 1; + duration = o.duration ? o.duration / 2 : $.fx.speeds._default / 2, + isVisible = elem.is(':visible'), + animateTo = 0; + + if (!isVisible) { + elem.css('opacity', 0).show(); + animateTo = 1; + } + + if ((mode == 'hide' && isVisible) || (mode == 'show' && !isVisible)) { + times--; + } + + for (var i = 0; i < times; i++) { + elem.animate({ opacity: animateTo }, duration, o.options.easing); + animateTo = (animateTo + 1) % 2; + } + + elem.animate({ opacity: animateTo }, duration, o.options.easing, function() { + if (animateTo == 0) { + elem.hide(); + } + (o.callback && o.callback.apply(this, arguments)); + }); + + elem + .queue('fx', function() { elem.dequeue(); }) + .dequeue(); + }); +}; + +})(jQuery); +/* + * jQuery UI Effects Scale 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Scale + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.puff = function(o) { + return this.queue(function() { + var elem = $(this), + mode = $.effects.setMode(elem, o.options.mode || 'hide'), + percent = parseInt(o.options.percent, 10) || 150, + factor = percent / 100, + original = { height: elem.height(), width: elem.width() }; + + $.extend(o.options, { + fade: true, + mode: mode, + percent: mode == 'hide' ? percent : 100, + from: mode == 'hide' + ? original + : { + height: original.height * factor, + width: original.width * factor + } + }); + + elem.effect('scale', o.options, o.duration, o.callback); + elem.dequeue(); + }); +}; + +$.effects.scale = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this); + + // Set options + var options = $.extend(true, {}, o.options); + var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode + var percent = parseInt(o.options.percent,10) || (parseInt(o.options.percent,10) == 0 ? 0 : (mode == 'hide' ? 0 : 100)); // Set default scaling percent + var direction = o.options.direction || 'both'; // Set default axis + var origin = o.options.origin; // The origin of the scaling + if (mode != 'effect') { // Set default origin and restore for show/hide + options.origin = origin || ['middle','center']; + options.restore = true; + } + var original = {height: el.height(), width: el.width()}; // Save original + el.from = o.options.from || (mode == 'show' ? {height: 0, width: 0} : original); // Default from state + + // Adjust + var factor = { // Set scaling factor + y: direction != 'horizontal' ? (percent / 100) : 1, + x: direction != 'vertical' ? (percent / 100) : 1 + }; + el.to = {height: original.height * factor.y, width: original.width * factor.x}; // Set to state + + if (o.options.fade) { // Fade option to support puff + if (mode == 'show') {el.from.opacity = 0; el.to.opacity = 1;}; + if (mode == 'hide') {el.from.opacity = 1; el.to.opacity = 0;}; + }; + + // Animation + options.from = el.from; options.to = el.to; options.mode = mode; + + // Animate + el.effect('size', options, o.duration, o.callback); + el.dequeue(); + }); + +}; + +$.effects.size = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right','width','height','overflow','opacity']; + var props1 = ['position','top','bottom','left','right','overflow','opacity']; // Always restore + var props2 = ['width','height','overflow']; // Copy for children + var cProps = ['fontSize']; + var vProps = ['borderTopWidth', 'borderBottomWidth', 'paddingTop', 'paddingBottom']; + var hProps = ['borderLeftWidth', 'borderRightWidth', 'paddingLeft', 'paddingRight']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode + var restore = o.options.restore || false; // Default restore + var scale = o.options.scale || 'both'; // Default scale mode + var origin = o.options.origin; // The origin of the sizing + var original = {height: el.height(), width: el.width()}; // Save original + el.from = o.options.from || original; // Default from state + el.to = o.options.to || original; // Default to state + // Adjust + if (origin) { // Calculate baseline shifts + var baseline = $.effects.getBaseline(origin, original); + el.from.top = (original.height - el.from.height) * baseline.y; + el.from.left = (original.width - el.from.width) * baseline.x; + el.to.top = (original.height - el.to.height) * baseline.y; + el.to.left = (original.width - el.to.width) * baseline.x; + }; + var factor = { // Set scaling factor + from: {y: el.from.height / original.height, x: el.from.width / original.width}, + to: {y: el.to.height / original.height, x: el.to.width / original.width} + }; + if (scale == 'box' || scale == 'both') { // Scale the css box + if (factor.from.y != factor.to.y) { // Vertical props scaling + props = props.concat(vProps); + el.from = $.effects.setTransition(el, vProps, factor.from.y, el.from); + el.to = $.effects.setTransition(el, vProps, factor.to.y, el.to); + }; + if (factor.from.x != factor.to.x) { // Horizontal props scaling + props = props.concat(hProps); + el.from = $.effects.setTransition(el, hProps, factor.from.x, el.from); + el.to = $.effects.setTransition(el, hProps, factor.to.x, el.to); + }; + }; + if (scale == 'content' || scale == 'both') { // Scale the content + if (factor.from.y != factor.to.y) { // Vertical props scaling + props = props.concat(cProps); + el.from = $.effects.setTransition(el, cProps, factor.from.y, el.from); + el.to = $.effects.setTransition(el, cProps, factor.to.y, el.to); + }; + }; + $.effects.save(el, restore ? props : props1); el.show(); // Save & Show + $.effects.createWrapper(el); // Create Wrapper + el.css('overflow','hidden').css(el.from); // Shift + + // Animate + if (scale == 'content' || scale == 'both') { // Scale the children + vProps = vProps.concat(['marginTop','marginBottom']).concat(cProps); // Add margins/font-size + hProps = hProps.concat(['marginLeft','marginRight']); // Add margins + props2 = props.concat(vProps).concat(hProps); // Concat + el.find("*[width]").each(function(){ + child = $(this); + if (restore) $.effects.save(child, props2); + var c_original = {height: child.height(), width: child.width()}; // Save original + child.from = {height: c_original.height * factor.from.y, width: c_original.width * factor.from.x}; + child.to = {height: c_original.height * factor.to.y, width: c_original.width * factor.to.x}; + if (factor.from.y != factor.to.y) { // Vertical props scaling + child.from = $.effects.setTransition(child, vProps, factor.from.y, child.from); + child.to = $.effects.setTransition(child, vProps, factor.to.y, child.to); + }; + if (factor.from.x != factor.to.x) { // Horizontal props scaling + child.from = $.effects.setTransition(child, hProps, factor.from.x, child.from); + child.to = $.effects.setTransition(child, hProps, factor.to.x, child.to); + }; + child.css(child.from); // Shift children + child.animate(child.to, o.duration, o.options.easing, function(){ + if (restore) $.effects.restore(child, props2); // Restore children + }); // Animate children + }); + }; + + // Animate + el.animate(el.to, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { + if (el.to.opacity === 0) { + el.css('opacity', el.from.opacity); + } + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, restore ? props : props1); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + el.dequeue(); + }}); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Shake 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Shake + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.shake = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'effect'); // Set Mode + var direction = o.options.direction || 'left'; // Default direction + var distance = o.options.distance || 20; // Default distance + var times = o.options.times || 3; // Default # of times + var speed = o.duration || o.options.duration || 140; // Default speed per shake + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + $.effects.createWrapper(el); // Create Wrapper + var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; + var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; + + // Animation + var animation = {}, animation1 = {}, animation2 = {}; + animation[ref] = (motion == 'pos' ? '-=' : '+=') + distance; + animation1[ref] = (motion == 'pos' ? '+=' : '-=') + distance * 2; + animation2[ref] = (motion == 'pos' ? '-=' : '+=') + distance * 2; + + // Animate + el.animate(animation, speed, o.options.easing); + for (var i = 1; i < times; i++) { // Shakes + el.animate(animation1, speed, o.options.easing).animate(animation2, speed, o.options.easing); + }; + el.animate(animation1, speed, o.options.easing). + animate(animation, speed / 2, o.options.easing, function(){ // Last shake + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + }); + el.queue('fx', function() { el.dequeue(); }); + el.dequeue(); + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Slide 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Slide + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.slide = function(o) { + + return this.queue(function() { + + // Create element + var el = $(this), props = ['position','top','bottom','left','right']; + + // Set options + var mode = $.effects.setMode(el, o.options.mode || 'show'); // Set Mode + var direction = o.options.direction || 'left'; // Default Direction + + // Adjust + $.effects.save(el, props); el.show(); // Save & Show + $.effects.createWrapper(el).css({overflow:'hidden'}); // Create Wrapper + var ref = (direction == 'up' || direction == 'down') ? 'top' : 'left'; + var motion = (direction == 'up' || direction == 'left') ? 'pos' : 'neg'; + var distance = o.options.distance || (ref == 'top' ? el.outerHeight({margin:true}) : el.outerWidth({margin:true})); + if (mode == 'show') el.css(ref, motion == 'pos' ? (isNaN(distance) ? "-" + distance : -distance) : distance); // Shift + + // Animation + var animation = {}; + animation[ref] = (mode == 'show' ? (motion == 'pos' ? '+=' : '-=') : (motion == 'pos' ? '-=' : '+=')) + distance; + + // Animate + el.animate(animation, { queue: false, duration: o.duration, easing: o.options.easing, complete: function() { + if(mode == 'hide') el.hide(); // Hide + $.effects.restore(el, props); $.effects.removeWrapper(el); // Restore + if(o.callback) o.callback.apply(this, arguments); // Callback + el.dequeue(); + }}); + + }); + +}; + +})(jQuery); +/* + * jQuery UI Effects Transfer 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Transfer + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +$.effects.transfer = function(o) { + return this.queue(function() { + var elem = $(this), + target = $(o.options.to), + endPosition = target.offset(), + animation = { + top: endPosition.top, + left: endPosition.left, + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = elem.offset(), + transfer = $('
        ') + .appendTo(document.body) + .addClass(o.options.className) + .css({ + top: startPosition.top, + left: startPosition.left, + height: elem.innerHeight(), + width: elem.innerWidth(), + position: 'absolute' + }) + .animate(animation, o.duration, o.options.easing, function() { + transfer.remove(); + (o.callback && o.callback.apply(elem[0], arguments)); + elem.dequeue(); + }); + }); +}; + +})(jQuery); +/* + * jQuery UI Accordion 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Accordion + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget( "ui.accordion", { + options: { + active: 0, + animated: "slide", + autoHeight: true, + clearStyle: false, + collapsible: false, + event: "click", + fillSpace: false, + header: "> li > :first-child,> :not(li):even", + icons: { + header: "ui-icon-triangle-1-e", + headerSelected: "ui-icon-triangle-1-s" + }, + navigation: false, + navigationFilter: function() { + return this.href.toLowerCase() === location.href.toLowerCase(); + } + }, + + _create: function() { + var self = this, + options = self.options; + + self.running = 0; + + self.element + .addClass( "ui-accordion ui-widget ui-helper-reset" ) + // in lack of child-selectors in CSS + // we need to mark top-LIs in a UL-accordion for some IE-fix + .children( "li" ) + .addClass( "ui-accordion-li-fix" ); + + self.headers = self.element.find( options.header ) + .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" ) + .bind( "mouseenter.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).addClass( "ui-state-hover" ); + }) + .bind( "mouseleave.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( "ui-state-hover" ); + }) + .bind( "focus.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).addClass( "ui-state-focus" ); + }) + .bind( "blur.accordion", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( "ui-state-focus" ); + }); + + self.headers.next() + .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ); + + if ( options.navigation ) { + var current = self.element.find( "a" ).filter( options.navigationFilter ).eq( 0 ); + if ( current.length ) { + var header = current.closest( ".ui-accordion-header" ); + if ( header.length ) { + // anchor within header + self.active = header; + } else { + // anchor within content + self.active = current.closest( ".ui-accordion-content" ).prev(); + } + } + } + + self.active = self._findActive( self.active || options.active ) + .addClass( "ui-state-default ui-state-active" ) + .toggleClass( "ui-corner-all" ) + .toggleClass( "ui-corner-top" ); + self.active.next().addClass( "ui-accordion-content-active" ); + + self._createIcons(); + self.resize(); + + // ARIA + self.element.attr( "role", "tablist" ); + + self.headers + .attr( "role", "tab" ) + .bind( "keydown.accordion", function( event ) { + return self._keydown( event ); + }) + .next() + .attr( "role", "tabpanel" ); + + self.headers + .not( self.active || "" ) + .attr({ + "aria-expanded": "false", + "aria-selected": "false", + tabIndex: -1 + }) + .next() + .hide(); + + // make sure at least one header is in the tab order + if ( !self.active.length ) { + self.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + self.active + .attr({ + "aria-expanded": "true", + "aria-selected": "true", + tabIndex: 0 + }); + } + + // only need links in tab order for Safari + if ( !$.browser.safari ) { + self.headers.find( "a" ).attr( "tabIndex", -1 ); + } + + if ( options.event ) { + self.headers.bind( options.event.split(" ").join(".accordion ") + ".accordion", function(event) { + self._clickHandler.call( self, event, this ); + event.preventDefault(); + }); + } + }, + + _createIcons: function() { + var options = this.options; + if ( options.icons ) { + $( "" ) + .addClass( "ui-icon " + options.icons.header ) + .prependTo( this.headers ); + this.active.children( ".ui-icon" ) + .toggleClass(options.icons.header) + .toggleClass(options.icons.headerSelected); + this.element.addClass( "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this.headers.children( ".ui-icon" ).remove(); + this.element.removeClass( "ui-accordion-icons" ); + }, + + destroy: function() { + var options = this.options; + + this.element + .removeClass( "ui-accordion ui-widget ui-helper-reset" ) + .removeAttr( "role" ); + + this.headers + .unbind( ".accordion" ) + .removeClass( "ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) + .removeAttr( "role" ) + .removeAttr( "aria-expanded" ) + .removeAttr( "aria-selected" ) + .removeAttr( "tabIndex" ); + + this.headers.find( "a" ).removeAttr( "tabIndex" ); + this._destroyIcons(); + var contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role" ) + .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled" ); + if ( options.autoHeight || options.fillHeight ) { + contents.css( "height", "" ); + } + + return $.Widget.prototype.destroy.call( this ); + }, + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); + + if ( key == "active" ) { + this.activate( value ); + } + if ( key == "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } + // #5332 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + if ( key == "disabled" ) { + this.headers.add(this.headers.next()) + [ value ? "addClass" : "removeClass" ]( + "ui-accordion-disabled ui-state-disabled" ); + } + }, + + _keydown: function( event ) { + if ( this.options.disabled || event.altKey || event.ctrlKey ) { + return; + } + + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; + + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._clickHandler( { target: event.target }, event.target ); + event.preventDefault(); + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + toFocus.focus(); + return false; + } + + return true; + }, + + resize: function() { + var options = this.options, + maxHeight; + + if ( options.fillSpace ) { + if ( $.browser.msie ) { + var defOverflow = this.element.parent().css( "overflow" ); + this.element.parent().css( "overflow", "hidden"); + } + maxHeight = this.element.parent().height(); + if ($.browser.msie) { + this.element.parent().css( "overflow", defOverflow ); + } + + this.headers.each(function() { + maxHeight -= $( this ).outerHeight( true ); + }); + + this.headers.next() + .each(function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + }) + .css( "overflow", "auto" ); + } else if ( options.autoHeight ) { + maxHeight = 0; + this.headers.next() + .each(function() { + maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() ); + }) + .height( maxHeight ); + } + + return this; + }, + + activate: function( index ) { + // TODO this gets called on init, changing the option without an explicit call for that + this.options.active = index; + // call clickHandler with custom event + var active = this._findActive( index )[ 0 ]; + this._clickHandler( { target: active }, active ); + + return this; + }, + + _findActive: function( selector ) { + return selector + ? typeof selector === "number" + ? this.headers.filter( ":eq(" + selector + ")" ) + : this.headers.not( this.headers.not( selector ) ) + : selector === false + ? $( [] ) + : this.headers.filter( ":eq(0)" ); + }, + + // TODO isn't event.target enough? why the separate target argument? + _clickHandler: function( event, target ) { + var options = this.options; + if ( options.disabled ) { + return; + } + + // called only when using activate(false) to close all parts programmatically + if ( !event.target ) { + if ( !options.collapsible ) { + return; + } + this.active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( options.icons.headerSelected ) + .addClass( options.icons.header ); + this.active.next().addClass( "ui-accordion-content-active" ); + var toHide = this.active.next(), + data = { + options: options, + newHeader: $( [] ), + oldHeader: options.active, + newContent: $( [] ), + oldContent: toHide + }, + toShow = ( this.active = $( [] ) ); + this._toggle( toShow, toHide, data ); + return; + } + + // get the click target + var clicked = $( event.currentTarget || target ), + clickedIsActive = clicked[0] === this.active[0]; + + // TODO the option is changed, is that correct? + // TODO if it is correct, shouldn't that happen after determining that the click is valid? + options.active = options.collapsible && clickedIsActive ? + false : + this.headers.index( clicked ); + + // if animations are still active, or the active header is the target, ignore click + if ( this.running || ( !options.collapsible && clickedIsActive ) ) { + return; + } + + // find elements to show and hide + var active = this.active, + toShow = clicked.next(), + toHide = this.active.next(), + data = { + options: options, + newHeader: clickedIsActive && options.collapsible ? $([]) : clicked, + oldHeader: this.active, + newContent: clickedIsActive && options.collapsible ? $([]) : toShow, + oldContent: toHide + }, + down = this.headers.index( this.active[0] ) > this.headers.index( clicked[0] ); + + // when the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $([]) : clicked; + this._toggle( toShow, toHide, data, clickedIsActive, down ); + + // switch classes + active + .removeClass( "ui-state-active ui-corner-top" ) + .addClass( "ui-state-default ui-corner-all" ) + .children( ".ui-icon" ) + .removeClass( options.icons.headerSelected ) + .addClass( options.icons.header ); + if ( !clickedIsActive ) { + clicked + .removeClass( "ui-state-default ui-corner-all" ) + .addClass( "ui-state-active ui-corner-top" ) + .children( ".ui-icon" ) + .removeClass( options.icons.header ) + .addClass( options.icons.headerSelected ); + clicked + .next() + .addClass( "ui-accordion-content-active" ); + } + + return; + }, + + _toggle: function( toShow, toHide, data, clickedIsActive, down ) { + var self = this, + options = self.options; + + self.toShow = toShow; + self.toHide = toHide; + self.data = data; + + var complete = function() { + if ( !self ) { + return; + } + return self._completed.apply( self, arguments ); + }; + + // trigger changestart event + self._trigger( "changestart", null, self.data ); + + // count elements to animate + self.running = toHide.size() === 0 ? toShow.size() : toHide.size(); + + if ( options.animated ) { + var animOptions = {}; + + if ( options.collapsible && clickedIsActive ) { + animOptions = { + toShow: $( [] ), + toHide: toHide, + complete: complete, + down: down, + autoHeight: options.autoHeight || options.fillSpace + }; + } else { + animOptions = { + toShow: toShow, + toHide: toHide, + complete: complete, + down: down, + autoHeight: options.autoHeight || options.fillSpace + }; + } + + if ( !options.proxied ) { + options.proxied = options.animated; + } + + if ( !options.proxiedDuration ) { + options.proxiedDuration = options.duration; + } + + options.animated = $.isFunction( options.proxied ) ? + options.proxied( animOptions ) : + options.proxied; + + options.duration = $.isFunction( options.proxiedDuration ) ? + options.proxiedDuration( animOptions ) : + options.proxiedDuration; + + var animations = $.ui.accordion.animations, + duration = options.duration, + easing = options.animated; + + if ( easing && !animations[ easing ] && !$.easing[ easing ] ) { + easing = "slide"; + } + if ( !animations[ easing ] ) { + animations[ easing ] = function( options ) { + this.slide( options, { + easing: easing, + duration: duration || 700 + }); + }; + } + + animations[ easing ]( animOptions ); + } else { + if ( options.collapsible && clickedIsActive ) { + toShow.toggle(); + } else { + toHide.hide(); + toShow.show(); + } + + complete( true ); + } + + // TODO assert that the blur and focus triggers are really necessary, remove otherwise + toHide.prev() + .attr({ + "aria-expanded": "false", + "aria-selected": "false", + tabIndex: -1 + }) + .blur(); + toShow.prev() + .attr({ + "aria-expanded": "true", + "aria-selected": "true", + tabIndex: 0 + }) + .focus(); + }, + + _completed: function( cancel ) { + this.running = cancel ? 0 : --this.running; + if ( this.running ) { + return; + } + + if ( this.options.clearStyle ) { + this.toShow.add( this.toHide ).css({ + height: "", + overflow: "" + }); + } + + // other classes are removed before the animation; this one needs to stay until completed + this.toHide.removeClass( "ui-accordion-content-active" ); + // Work around for rendering bug in IE (#5421) + if ( this.toHide.length ) { + this.toHide.parent()[0].className = this.toHide.parent()[0].className; + } + + this._trigger( "change", null, this.data ); + } +}); + +$.extend( $.ui.accordion, { + version: "1.8.16", + animations: { + slide: function( options, additions ) { + options = $.extend({ + easing: "swing", + duration: 300 + }, options, additions ); + if ( !options.toHide.size() ) { + options.toShow.animate({ + height: "show", + paddingTop: "show", + paddingBottom: "show" + }, options ); + return; + } + if ( !options.toShow.size() ) { + options.toHide.animate({ + height: "hide", + paddingTop: "hide", + paddingBottom: "hide" + }, options ); + return; + } + var overflow = options.toShow.css( "overflow" ), + percentDone = 0, + showProps = {}, + hideProps = {}, + fxAttrs = [ "height", "paddingTop", "paddingBottom" ], + originalWidth; + // fix width before calculating height of hidden element + var s = options.toShow; + originalWidth = s[0].style.width; + s.width( parseInt( s.parent().width(), 10 ) + - parseInt( s.css( "paddingLeft" ), 10 ) + - parseInt( s.css( "paddingRight" ), 10 ) + - ( parseInt( s.css( "borderLeftWidth" ), 10 ) || 0 ) + - ( parseInt( s.css( "borderRightWidth" ), 10) || 0 ) ); + + $.each( fxAttrs, function( i, prop ) { + hideProps[ prop ] = "hide"; + + var parts = ( "" + $.css( options.toShow[0], prop ) ).match( /^([\d+-.]+)(.*)$/ ); + showProps[ prop ] = { + value: parts[ 1 ], + unit: parts[ 2 ] || "px" + }; + }); + options.toShow.css({ height: 0, overflow: "hidden" }).show(); + options.toHide + .filter( ":hidden" ) + .each( options.complete ) + .end() + .filter( ":visible" ) + .animate( hideProps, { + step: function( now, settings ) { + // only calculate the percent when animating height + // IE gets very inconsistent results when animating elements + // with small values, which is common for padding + if ( settings.prop == "height" ) { + percentDone = ( settings.end - settings.start === 0 ) ? 0 : + ( settings.now - settings.start ) / ( settings.end - settings.start ); + } + + options.toShow[ 0 ].style[ settings.prop ] = + ( percentDone * showProps[ settings.prop ].value ) + + showProps[ settings.prop ].unit; + }, + duration: options.duration, + easing: options.easing, + complete: function() { + if ( !options.autoHeight ) { + options.toShow.css( "height", "" ); + } + options.toShow.css({ + width: originalWidth, + overflow: overflow + }); + options.complete(); + } + }); + }, + bounceslide: function( options ) { + this.slide( options, { + easing: options.down ? "easeOutBounce" : "swing", + duration: options.down ? 1000 : 200 + }); + } + } +}); + +})( jQuery ); +/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function( $, undefined ) { + +// used to prevent race conditions with remote data sources +var requestIndex = 0; + +$.widget( "ui.autocomplete", { + options: { + appendTo: "body", + autoFocus: false, + delay: 300, + minLength: 1, + position: { + my: "left top", + at: "left bottom", + collision: "none" + }, + source: null + }, + + pending: 0, + + _create: function() { + var self = this, + doc = this.element[ 0 ].ownerDocument, + suppressKeyPress; + + this.element + .addClass( "ui-autocomplete-input" ) + .attr( "autocomplete", "off" ) + // TODO verify these actually work as intended + .attr({ + role: "textbox", + "aria-autocomplete": "list", + "aria-haspopup": "true" + }) + .bind( "keydown.autocomplete", function( event ) { + if ( self.options.disabled || self.element.propAttr( "readOnly" ) ) { + return; + } + + suppressKeyPress = false; + var keyCode = $.ui.keyCode; + switch( event.keyCode ) { + case keyCode.PAGE_UP: + self._move( "previousPage", event ); + break; + case keyCode.PAGE_DOWN: + self._move( "nextPage", event ); + break; + case keyCode.UP: + self._move( "previous", event ); + // prevent moving cursor to beginning of text field in some browsers + event.preventDefault(); + break; + case keyCode.DOWN: + self._move( "next", event ); + // prevent moving cursor to end of text field in some browsers + event.preventDefault(); + break; + case keyCode.ENTER: + case keyCode.NUMPAD_ENTER: + // when menu is open and has focus + if ( self.menu.active ) { + // #6055 - Opera still allows the keypress to occur + // which causes forms to submit + suppressKeyPress = true; + event.preventDefault(); + } + //passthrough - ENTER and TAB both select the current element + case keyCode.TAB: + if ( !self.menu.active ) { + return; + } + self.menu.select( event ); + break; + case keyCode.ESCAPE: + self.element.val( self.term ); + self.close( event ); + break; + default: + // keypress is triggered before the input value is changed + clearTimeout( self.searching ); + self.searching = setTimeout(function() { + // only search if the value has changed + if ( self.term != self.element.val() ) { + self.selectedItem = null; + self.search( null, event ); + } + }, self.options.delay ); + break; + } + }) + .bind( "keypress.autocomplete", function( event ) { + if ( suppressKeyPress ) { + suppressKeyPress = false; + event.preventDefault(); + } + }) + .bind( "focus.autocomplete", function() { + if ( self.options.disabled ) { + return; + } + + self.selectedItem = null; + self.previous = self.element.val(); + }) + .bind( "blur.autocomplete", function( event ) { + if ( self.options.disabled ) { + return; + } + + clearTimeout( self.searching ); + // clicks on the menu (or a button to trigger a search) will cause a blur event + self.closing = setTimeout(function() { + self.close( event ); + self._change( event ); + }, 150 ); + }); + this._initSource(); + this.response = function() { + return self._response.apply( self, arguments ); + }; + this.menu = $( "
          " ) + .addClass( "ui-autocomplete" ) + .appendTo( $( this.options.appendTo || "body", doc )[0] ) + // prevent the close-on-blur in case of a "slow" click on the menu (long mousedown) + .mousedown(function( event ) { + // clicking on the scrollbar causes focus to shift to the body + // but we can't detect a mouseup or a click immediately afterward + // so we have to track the next mousedown and close the menu if + // the user clicks somewhere outside of the autocomplete + var menuElement = self.menu.element[ 0 ]; + if ( !$( event.target ).closest( ".ui-menu-item" ).length ) { + setTimeout(function() { + $( document ).one( 'mousedown', function( event ) { + if ( event.target !== self.element[ 0 ] && + event.target !== menuElement && + !$.ui.contains( menuElement, event.target ) ) { + self.close(); + } + }); + }, 1 ); + } + + // use another timeout to make sure the blur-event-handler on the input was already triggered + setTimeout(function() { + clearTimeout( self.closing ); + }, 13); + }) + .menu({ + focus: function( event, ui ) { + var item = ui.item.data( "item.autocomplete" ); + if ( false !== self._trigger( "focus", event, { item: item } ) ) { + // use value to match what will end up in the input, if it was a key event + if ( /^key/.test(event.originalEvent.type) ) { + self.element.val( item.value ); + } + } + }, + selected: function( event, ui ) { + var item = ui.item.data( "item.autocomplete" ), + previous = self.previous; + + // only trigger when focus was lost (click on menu) + if ( self.element[0] !== doc.activeElement ) { + self.element.focus(); + self.previous = previous; + // #6109 - IE triggers two focus events and the second + // is asynchronous, so we need to reset the previous + // term synchronously and asynchronously :-( + setTimeout(function() { + self.previous = previous; + self.selectedItem = item; + }, 1); + } + + if ( false !== self._trigger( "select", event, { item: item } ) ) { + self.element.val( item.value ); + } + // reset the term after the select event + // this allows custom select handling to work properly + self.term = self.element.val(); + + self.close( event ); + self.selectedItem = item; + }, + blur: function( event, ui ) { + // don't set the value of the text field if it's already correct + // this prevents moving the cursor unnecessarily + if ( self.menu.element.is(":visible") && + ( self.element.val() !== self.term ) ) { + self.element.val( self.term ); + } + } + }) + .zIndex( this.element.zIndex() + 1 ) + // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 + .css({ top: 0, left: 0 }) + .hide() + .data( "menu" ); + if ( $.fn.bgiframe ) { + this.menu.element.bgiframe(); + } + }, + + destroy: function() { + this.element + .removeClass( "ui-autocomplete-input" ) + .removeAttr( "autocomplete" ) + .removeAttr( "role" ) + .removeAttr( "aria-autocomplete" ) + .removeAttr( "aria-haspopup" ); + this.menu.element.remove(); + $.Widget.prototype.destroy.call( this ); + }, + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); + if ( key === "source" ) { + this._initSource(); + } + if ( key === "appendTo" ) { + this.menu.element.appendTo( $( value || "body", this.element[0].ownerDocument )[0] ) + } + if ( key === "disabled" && value && this.xhr ) { + this.xhr.abort(); + } + }, + + _initSource: function() { + var self = this, + array, + url; + if ( $.isArray(this.options.source) ) { + array = this.options.source; + this.source = function( request, response ) { + response( $.ui.autocomplete.filter(array, request.term) ); + }; + } else if ( typeof this.options.source === "string" ) { + url = this.options.source; + this.source = function( request, response ) { + if ( self.xhr ) { + self.xhr.abort(); + } + self.xhr = $.ajax({ + url: url, + data: request, + dataType: "json", + autocompleteRequest: ++requestIndex, + success: function( data, status ) { + if ( this.autocompleteRequest === requestIndex ) { + response( data ); + } + }, + error: function() { + if ( this.autocompleteRequest === requestIndex ) { + response( [] ); + } + } + }); + }; + } else { + this.source = this.options.source; + } + }, + + search: function( value, event ) { + value = value != null ? value : this.element.val(); + + // always save the actual value, not the one passed as an argument + this.term = this.element.val(); + + if ( value.length < this.options.minLength ) { + return this.close( event ); + } + + clearTimeout( this.closing ); + if ( this._trigger( "search", event ) === false ) { + return; + } + + return this._search( value ); + }, + + _search: function( value ) { + this.pending++; + this.element.addClass( "ui-autocomplete-loading" ); + + this.source( { term: value }, this.response ); + }, + + _response: function( content ) { + if ( !this.options.disabled && content && content.length ) { + content = this._normalize( content ); + this._suggest( content ); + this._trigger( "open" ); + } else { + this.close(); + } + this.pending--; + if ( !this.pending ) { + this.element.removeClass( "ui-autocomplete-loading" ); + } + }, + + close: function( event ) { + clearTimeout( this.closing ); + if ( this.menu.element.is(":visible") ) { + this.menu.element.hide(); + this.menu.deactivate(); + this._trigger( "close", event ); + } + }, + + _change: function( event ) { + if ( this.previous !== this.element.val() ) { + this._trigger( "change", event, { item: this.selectedItem } ); + } + }, + + _normalize: function( items ) { + // assume all items have the right format when the first item is complete + if ( items.length && items[0].label && items[0].value ) { + return items; + } + return $.map( items, function(item) { + if ( typeof item === "string" ) { + return { + label: item, + value: item + }; + } + return $.extend({ + label: item.label || item.value, + value: item.value || item.label + }, item ); + }); + }, + + _suggest: function( items ) { + var ul = this.menu.element + .empty() + .zIndex( this.element.zIndex() + 1 ); + this._renderMenu( ul, items ); + // TODO refresh should check if the active item is still in the dom, removing the need for a manual deactivate + this.menu.deactivate(); + this.menu.refresh(); + + // size and position menu + ul.show(); + this._resizeMenu(); + ul.position( $.extend({ + of: this.element + }, this.options.position )); + + if ( this.options.autoFocus ) { + this.menu.next( new $.Event("mouseover") ); + } + }, + + _resizeMenu: function() { + var ul = this.menu.element; + ul.outerWidth( Math.max( + ul.width( "" ).outerWidth(), + this.element.outerWidth() + ) ); + }, + + _renderMenu: function( ul, items ) { + var self = this; + $.each( items, function( index, item ) { + self._renderItem( ul, item ); + }); + }, + + _renderItem: function( ul, item) { + return $( "
        • " ) + .data( "item.autocomplete", item ) + .append( $( "" ).text( item.label ) ) + .appendTo( ul ); + }, + + _move: function( direction, event ) { + if ( !this.menu.element.is(":visible") ) { + this.search( null, event ); + return; + } + if ( this.menu.first() && /^previous/.test(direction) || + this.menu.last() && /^next/.test(direction) ) { + this.element.val( this.term ); + this.menu.deactivate(); + return; + } + this.menu[ direction ]( event ); + }, + + widget: function() { + return this.menu.element; + } +}); + +$.extend( $.ui.autocomplete, { + escapeRegex: function( value ) { + return value.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }, + filter: function(array, term) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); + return $.grep( array, function(value) { + return matcher.test( value.label || value.value || value ); + }); + } +}); + +}( jQuery )); + +/* + * jQuery UI Menu (not officially released) + * + * This widget isn't yet finished and the API is subject to change. We plan to finish + * it for the next release. You're welcome to give it a try anyway and give us feedback, + * as long as you're okay with migrating your code later on. We can help with that, too. + * + * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Menu + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function($) { + +$.widget("ui.menu", { + _create: function() { + var self = this; + this.element + .addClass("ui-menu ui-widget ui-widget-content ui-corner-all") + .attr({ + role: "listbox", + "aria-activedescendant": "ui-active-menuitem" + }) + .click(function( event ) { + if ( !$( event.target ).closest( ".ui-menu-item a" ).length ) { + return; + } + // temporary + event.preventDefault(); + self.select( event ); + }); + this.refresh(); + }, + + refresh: function() { + var self = this; + + // don't refresh list items that are already adapted + var items = this.element.children("li:not(.ui-menu-item):has(a)") + .addClass("ui-menu-item") + .attr("role", "menuitem"); + + items.children("a") + .addClass("ui-corner-all") + .attr("tabindex", -1) + // mouseenter doesn't work with event delegation + .mouseenter(function( event ) { + self.activate( event, $(this).parent() ); + }) + .mouseleave(function() { + self.deactivate(); + }); + }, + + activate: function( event, item ) { + this.deactivate(); + if (this.hasScroll()) { + var offset = item.offset().top - this.element.offset().top, + scroll = this.element.scrollTop(), + elementHeight = this.element.height(); + if (offset < 0) { + this.element.scrollTop( scroll + offset); + } else if (offset >= elementHeight) { + this.element.scrollTop( scroll + offset - elementHeight + item.height()); + } + } + this.active = item.eq(0) + .children("a") + .addClass("ui-state-hover") + .attr("id", "ui-active-menuitem") + .end(); + this._trigger("focus", event, { item: item }); + }, + + deactivate: function() { + if (!this.active) { return; } + + this.active.children("a") + .removeClass("ui-state-hover") + .removeAttr("id"); + this._trigger("blur"); + this.active = null; + }, + + next: function(event) { + this.move("next", ".ui-menu-item:first", event); + }, + + previous: function(event) { + this.move("prev", ".ui-menu-item:last", event); + }, + + first: function() { + return this.active && !this.active.prevAll(".ui-menu-item").length; + }, + + last: function() { + return this.active && !this.active.nextAll(".ui-menu-item").length; + }, + + move: function(direction, edge, event) { + if (!this.active) { + this.activate(event, this.element.children(edge)); + return; + } + var next = this.active[direction + "All"](".ui-menu-item").eq(0); + if (next.length) { + this.activate(event, next); + } else { + this.activate(event, this.element.children(edge)); + } + }, + + // TODO merge with previousPage + nextPage: function(event) { + if (this.hasScroll()) { + // TODO merge with no-scroll-else + if (!this.active || this.last()) { + this.activate(event, this.element.children(".ui-menu-item:first")); + return; + } + var base = this.active.offset().top, + height = this.element.height(), + result = this.element.children(".ui-menu-item").filter(function() { + var close = $(this).offset().top - base - height + $(this).height(); + // TODO improve approximation + return close < 10 && close > -10; + }); + + // TODO try to catch this earlier when scrollTop indicates the last page anyway + if (!result.length) { + result = this.element.children(".ui-menu-item:last"); + } + this.activate(event, result); + } else { + this.activate(event, this.element.children(".ui-menu-item") + .filter(!this.active || this.last() ? ":first" : ":last")); + } + }, + + // TODO merge with nextPage + previousPage: function(event) { + if (this.hasScroll()) { + // TODO merge with no-scroll-else + if (!this.active || this.first()) { + this.activate(event, this.element.children(".ui-menu-item:last")); + return; + } + + var base = this.active.offset().top, + height = this.element.height(); + result = this.element.children(".ui-menu-item").filter(function() { + var close = $(this).offset().top - base + height - $(this).height(); + // TODO improve approximation + return close < 10 && close > -10; + }); + + // TODO try to catch this earlier when scrollTop indicates the last page anyway + if (!result.length) { + result = this.element.children(".ui-menu-item:first"); + } + this.activate(event, result); + } else { + this.activate(event, this.element.children(".ui-menu-item") + .filter(!this.active || this.first() ? ":last" : ":first")); + } + }, + + hasScroll: function() { + return this.element.height() < this.element[ $.fn.prop ? "prop" : "attr" ]("scrollHeight"); + }, + + select: function( event ) { + this._trigger("selected", event, { item: this.active }); + } +}); + +}(jQuery)); +/* + * jQuery UI Button 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Button + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +var lastActive, startXPos, startYPos, clickDragged, + baseClasses = "ui-button ui-widget ui-state-default ui-corner-all", + stateClasses = "ui-state-hover ui-state-active ", + typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only", + formResetHandler = function() { + var buttons = $( this ).find( ":ui-button" ); + setTimeout(function() { + buttons.button( "refresh" ); + }, 1 ); + }, + radioGroup = function( radio ) { + var name = radio.name, + form = radio.form, + radios = $( [] ); + if ( name ) { + if ( form ) { + radios = $( form ).find( "[name='" + name + "']" ); + } else { + radios = $( "[name='" + name + "']", radio.ownerDocument ) + .filter(function() { + return !this.form; + }); + } + } + return radios; + }; + +$.widget( "ui.button", { + options: { + disabled: null, + text: true, + label: null, + icons: { + primary: null, + secondary: null + } + }, + _create: function() { + this.element.closest( "form" ) + .unbind( "reset.button" ) + .bind( "reset.button", formResetHandler ); + + if ( typeof this.options.disabled !== "boolean" ) { + this.options.disabled = this.element.propAttr( "disabled" ); + } + + this._determineButtonType(); + this.hasTitle = !!this.buttonElement.attr( "title" ); + + var self = this, + options = this.options, + toggleButton = this.type === "checkbox" || this.type === "radio", + hoverClass = "ui-state-hover" + ( !toggleButton ? " ui-state-active" : "" ), + focusClass = "ui-state-focus"; + + if ( options.label === null ) { + options.label = this.buttonElement.html(); + } + + if ( this.element.is( ":disabled" ) ) { + options.disabled = true; + } + + this.buttonElement + .addClass( baseClasses ) + .attr( "role", "button" ) + .bind( "mouseenter.button", function() { + if ( options.disabled ) { + return; + } + $( this ).addClass( "ui-state-hover" ); + if ( this === lastActive ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "mouseleave.button", function() { + if ( options.disabled ) { + return; + } + $( this ).removeClass( hoverClass ); + }) + .bind( "click.button", function( event ) { + if ( options.disabled ) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + }); + + this.element + .bind( "focus.button", function() { + // no need to check disabled, focus won't be triggered anyway + self.buttonElement.addClass( focusClass ); + }) + .bind( "blur.button", function() { + self.buttonElement.removeClass( focusClass ); + }); + + if ( toggleButton ) { + this.element.bind( "change.button", function() { + if ( clickDragged ) { + return; + } + self.refresh(); + }); + // if mouse moves between mousedown and mouseup (drag) set clickDragged flag + // prevents issue where button state changes but checkbox/radio checked state + // does not in Firefox (see ticket #6970) + this.buttonElement + .bind( "mousedown.button", function( event ) { + if ( options.disabled ) { + return; + } + clickDragged = false; + startXPos = event.pageX; + startYPos = event.pageY; + }) + .bind( "mouseup.button", function( event ) { + if ( options.disabled ) { + return; + } + if ( startXPos !== event.pageX || startYPos !== event.pageY ) { + clickDragged = true; + } + }); + } + + if ( this.type === "checkbox" ) { + this.buttonElement.bind( "click.button", function() { + if ( options.disabled || clickDragged ) { + return false; + } + $( this ).toggleClass( "ui-state-active" ); + self.buttonElement.attr( "aria-pressed", self.element[0].checked ); + }); + } else if ( this.type === "radio" ) { + this.buttonElement.bind( "click.button", function() { + if ( options.disabled || clickDragged ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + self.buttonElement.attr( "aria-pressed", "true" ); + + var radio = self.element[ 0 ]; + radioGroup( radio ) + .not( radio ) + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + }); + } else { + this.buttonElement + .bind( "mousedown.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).addClass( "ui-state-active" ); + lastActive = this; + $( document ).one( "mouseup", function() { + lastActive = null; + }); + }) + .bind( "mouseup.button", function() { + if ( options.disabled ) { + return false; + } + $( this ).removeClass( "ui-state-active" ); + }) + .bind( "keydown.button", function(event) { + if ( options.disabled ) { + return false; + } + if ( event.keyCode == $.ui.keyCode.SPACE || event.keyCode == $.ui.keyCode.ENTER ) { + $( this ).addClass( "ui-state-active" ); + } + }) + .bind( "keyup.button", function() { + $( this ).removeClass( "ui-state-active" ); + }); + + if ( this.buttonElement.is("a") ) { + this.buttonElement.keyup(function(event) { + if ( event.keyCode === $.ui.keyCode.SPACE ) { + // TODO pass through original event correctly (just as 2nd argument doesn't work) + $( this ).click(); + } + }); + } + } + + // TODO: pull out $.Widget's handling for the disabled option into + // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can + // be overridden by individual plugins + this._setOption( "disabled", options.disabled ); + this._resetButton(); + }, + + _determineButtonType: function() { + + if ( this.element.is(":checkbox") ) { + this.type = "checkbox"; + } else if ( this.element.is(":radio") ) { + this.type = "radio"; + } else if ( this.element.is("input") ) { + this.type = "input"; + } else { + this.type = "button"; + } + + if ( this.type === "checkbox" || this.type === "radio" ) { + // we don't search against the document in case the element + // is disconnected from the DOM + var ancestor = this.element.parents().filter(":last"), + labelSelector = "label[for='" + this.element.attr("id") + "']"; + this.buttonElement = ancestor.find( labelSelector ); + if ( !this.buttonElement.length ) { + ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings(); + this.buttonElement = ancestor.filter( labelSelector ); + if ( !this.buttonElement.length ) { + this.buttonElement = ancestor.find( labelSelector ); + } + } + this.element.addClass( "ui-helper-hidden-accessible" ); + + var checked = this.element.is( ":checked" ); + if ( checked ) { + this.buttonElement.addClass( "ui-state-active" ); + } + this.buttonElement.attr( "aria-pressed", checked ); + } else { + this.buttonElement = this.element; + } + }, + + widget: function() { + return this.buttonElement; + }, + + destroy: function() { + this.element + .removeClass( "ui-helper-hidden-accessible" ); + this.buttonElement + .removeClass( baseClasses + " " + stateClasses + " " + typeClasses ) + .removeAttr( "role" ) + .removeAttr( "aria-pressed" ) + .html( this.buttonElement.find(".ui-button-text").html() ); + + if ( !this.hasTitle ) { + this.buttonElement.removeAttr( "title" ); + } + + $.Widget.prototype.destroy.call( this ); + }, + + _setOption: function( key, value ) { + $.Widget.prototype._setOption.apply( this, arguments ); + if ( key === "disabled" ) { + if ( value ) { + this.element.propAttr( "disabled", true ); + } else { + this.element.propAttr( "disabled", false ); + } + return; + } + this._resetButton(); + }, + + refresh: function() { + var isDisabled = this.element.is( ":disabled" ); + if ( isDisabled !== this.options.disabled ) { + this._setOption( "disabled", isDisabled ); + } + if ( this.type === "radio" ) { + radioGroup( this.element[0] ).each(function() { + if ( $( this ).is( ":checked" ) ) { + $( this ).button( "widget" ) + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + $( this ).button( "widget" ) + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + }); + } else if ( this.type === "checkbox" ) { + if ( this.element.is( ":checked" ) ) { + this.buttonElement + .addClass( "ui-state-active" ) + .attr( "aria-pressed", "true" ); + } else { + this.buttonElement + .removeClass( "ui-state-active" ) + .attr( "aria-pressed", "false" ); + } + } + }, + + _resetButton: function() { + if ( this.type === "input" ) { + if ( this.options.label ) { + this.element.val( this.options.label ); + } + return; + } + var buttonElement = this.buttonElement.removeClass( typeClasses ), + buttonText = $( "" ) + .addClass( "ui-button-text" ) + .html( this.options.label ) + .appendTo( buttonElement.empty() ) + .text(), + icons = this.options.icons, + multipleIcons = icons.primary && icons.secondary, + buttonClasses = []; + + if ( icons.primary || icons.secondary ) { + if ( this.options.text ) { + buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) ); + } + + if ( icons.primary ) { + buttonElement.prepend( "" ); + } + + if ( icons.secondary ) { + buttonElement.append( "" ); + } + + if ( !this.options.text ) { + buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" ); + + if ( !this.hasTitle ) { + buttonElement.attr( "title", buttonText ); + } + } + } else { + buttonClasses.push( "ui-button-text-only" ); + } + buttonElement.addClass( buttonClasses.join( " " ) ); + } +}); + +$.widget( "ui.buttonset", { + options: { + items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" + }, + + _create: function() { + this.element.addClass( "ui-buttonset" ); + }, + + _init: function() { + this.refresh(); + }, + + _setOption: function( key, value ) { + if ( key === "disabled" ) { + this.buttons.button( "option", key, value ); + } + + $.Widget.prototype._setOption.apply( this, arguments ); + }, + + refresh: function() { + var ltr = this.element.css( "direction" ) === "ltr"; + + this.buttons = this.element.find( this.options.items ) + .filter( ":ui-button" ) + .button( "refresh" ) + .end() + .not( ":ui-button" ) + .button() + .end() + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) + .filter( ":first" ) + .addClass( ltr ? "ui-corner-left" : "ui-corner-right" ) + .end() + .filter( ":last" ) + .addClass( ltr ? "ui-corner-right" : "ui-corner-left" ) + .end() + .end(); + }, + + destroy: function() { + this.element.removeClass( "ui-buttonset" ); + this.buttons + .map(function() { + return $( this ).button( "widget" )[ 0 ]; + }) + .removeClass( "ui-corner-left ui-corner-right" ) + .end() + .button( "destroy" ); + + $.Widget.prototype.destroy.call( this ); + } +}); + +}( jQuery ) ); +/* + * jQuery UI Datepicker 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Datepicker + * + * Depends: + * jquery.ui.core.js + */ +(function( $, undefined ) { + +$.extend($.ui, { datepicker: { version: "1.8.16" } }); + +var PROP_NAME = 'datepicker'; +var dpuuid = new Date().getTime(); +var instActive; + +/* Date picker manager. + Use the singleton instance of this class, $.datepicker, to interact with the date picker. + Settings for (groups of) date pickers are maintained in an instance object, + allowing multiple different settings on the same page. */ + +function Datepicker() { + this.debug = false; // Change this to true to start debugging + this._curInst = null; // The current instance in use + this._keyEvent = false; // If the last event was a key event + this._disabledInputs = []; // List of date picker inputs that have been disabled + this._datepickerShowing = false; // True if the popup picker is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this._mainDivId = 'ui-datepicker-div'; // The ID of the main datepicker division + this._inlineClass = 'ui-datepicker-inline'; // The name of the inline marker class + this._appendClass = 'ui-datepicker-append'; // The name of the append marker class + this._triggerClass = 'ui-datepicker-trigger'; // The name of the trigger marker class + this._dialogClass = 'ui-datepicker-dialog'; // The name of the dialog marker class + this._disableClass = 'ui-datepicker-disabled'; // The name of the disabled covering marker class + this._unselectableClass = 'ui-datepicker-unselectable'; // The name of the unselectable cell marker class + this._currentClass = 'ui-datepicker-current-day'; // The name of the current day marker class + this._dayOverClass = 'ui-datepicker-days-cell-over'; // The name of the day hover marker class + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + closeText: 'Done', // Display text for close link + prevText: 'Prev', // Display text for previous month link + nextText: 'Next', // Display text for next month link + currentText: 'Today', // Display text for current month link + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], // Names of months for drop-down and formatting + monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting + dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting + dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday + weekHeader: 'Wk', // Column header for week of the year + dateFormat: 'mm/dd/yy', // See format options on parseDate + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + isRTL: false, // True if right-to-left language, false if left-to-right + showMonthAfterYear: false, // True if the year select precedes month, false for month then year + yearSuffix: '' // Additional text to append to the year in the month headers + }; + this._defaults = { // Global defaults for all the date picker instances + showOn: 'focus', // 'focus' for popup on focus, + // 'button' for trigger button, or 'both' for either + showAnim: 'fadeIn', // Name of jQuery animation for popup + showOptions: {}, // Options for enhanced animations + defaultDate: null, // Used when field is blank: actual date, + // +/-number for offset from today, null for today + appendText: '', // Display text following the input box, e.g. showing the format + buttonText: '...', // Text for trigger button + buttonImage: '', // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links + gotoCurrent: false, // True if today link goes back to current selection instead + changeMonth: false, // True if month can be selected directly, false if only prev/next + changeYear: false, // True if year can be selected directly, false if only prev/next + yearRange: 'c-10:c+10', // Range of years to display in drop-down, + // either relative to today's year (-nn:+nn), relative to currently displayed year + // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n) + showOtherMonths: false, // True to show dates in other months, false to leave blank + selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable + showWeek: false, // True to show week of the year, false to not show it + calculateWeek: this.iso8601Week, // How to calculate the week of the year, + // takes a Date and returns the number of the week for it + shortYearCutoff: '+10', // Short year values < this are in the current century, + // > this are in the previous century, + // string value starting with '+' for current year + value + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + duration: 'fast', // Duration of display/closure + beforeShowDay: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or '', + // [2] = cell title (optional), e.g. $.datepicker.noWeekends + beforeShow: null, // Function that takes an input field and + // returns a set of custom settings for the date picker + onSelect: null, // Define a callback function when a date is selected + onChangeMonthYear: null, // Define a callback function when the month or year is changed + onClose: null, // Define a callback function when the datepicker is closed + numberOfMonths: 1, // Number of months to show at a time + showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0) + stepMonths: 1, // Number of months to step back/forward + stepBigMonths: 12, // Number of months to step back/forward for the big links + altField: '', // Selector for an alternate field to store selected dates into + altFormat: '', // The date format to use for the alternate field + constrainInput: true, // The input is constrained by the current date format + showButtonPanel: false, // True to show button panel, false to not show it + autoSize: false, // True to size the input for the date format, false to leave as is + disabled: false // The initial disabled state + }; + $.extend(this._defaults, this.regional['']); + this.dpDiv = bindHover($('
          ')); +} + +$.extend(Datepicker.prototype, { + /* Class name added to elements to indicate already configured with a date picker. */ + markerClassName: 'hasDatepicker', + + //Keep track of the maximum number of rows displayed (see #7043) + maxRows: 4, + + /* Debug logging (if enabled). */ + log: function () { + if (this.debug) + console.log.apply('', arguments); + }, + + // TODO rename to "widget" when switching to widget factory + _widgetDatepicker: function() { + return this.dpDiv; + }, + + /* Override the default settings for all instances of the date picker. + @param settings object - the new settings to use as defaults (anonymous object) + @return the manager object */ + setDefaults: function(settings) { + extendRemove(this._defaults, settings || {}); + return this; + }, + + /* Attach the date picker to a jQuery selection. + @param target element - the target input field or division or span + @param settings object - the new settings to use for this date picker instance (anonymous) */ + _attachDatepicker: function(target, settings) { + // check for settings on the control itself - in namespace 'date:' + var inlineSettings = null; + for (var attrName in this._defaults) { + var attrValue = target.getAttribute('date:' + attrName); + if (attrValue) { + inlineSettings = inlineSettings || {}; + try { + inlineSettings[attrName] = eval(attrValue); + } catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + var nodeName = target.nodeName.toLowerCase(); + var inline = (nodeName == 'div' || nodeName == 'span'); + if (!target.id) { + this.uuid += 1; + target.id = 'dp' + this.uuid; + } + var inst = this._newInst($(target), inline); + inst.settings = $.extend({}, settings || {}, inlineSettings || {}); + if (nodeName == 'input') { + this._connectDatepicker(target, inst); + } else if (inline) { + this._inlineDatepicker(target, inst); + } + }, + + /* Create a new instance object. */ + _newInst: function(target, inline) { + var id = target[0].id.replace(/([^A-Za-z0-9_-])/g, '\\\\$1'); // escape jQuery meta chars + return {id: id, input: target, // associated target + selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection + drawMonth: 0, drawYear: 0, // month being drawn + inline: inline, // is datepicker inline or not + dpDiv: (!inline ? this.dpDiv : // presentation div + bindHover($('
          ')))}; + }, + + /* Attach the date picker to an input field. */ + _connectDatepicker: function(target, inst) { + var input = $(target); + inst.append = $([]); + inst.trigger = $([]); + if (input.hasClass(this.markerClassName)) + return; + this._attachments(input, inst); + input.addClass(this.markerClassName).keydown(this._doKeyDown). + keypress(this._doKeyPress).keyup(this._doKeyUp). + bind("setData.datepicker", function(event, key, value) { + inst.settings[key] = value; + }).bind("getData.datepicker", function(event, key) { + return this._get(inst, key); + }); + this._autoSize(inst); + $.data(target, PROP_NAME, inst); + //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + }, + + /* Make attachments based on settings. */ + _attachments: function(input, inst) { + var appendText = this._get(inst, 'appendText'); + var isRTL = this._get(inst, 'isRTL'); + if (inst.append) + inst.append.remove(); + if (appendText) { + inst.append = $('' + appendText + ''); + input[isRTL ? 'before' : 'after'](inst.append); + } + input.unbind('focus', this._showDatepicker); + if (inst.trigger) + inst.trigger.remove(); + var showOn = this._get(inst, 'showOn'); + if (showOn == 'focus' || showOn == 'both') // pop-up date picker when in the marked field + input.focus(this._showDatepicker); + if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked + var buttonText = this._get(inst, 'buttonText'); + var buttonImage = this._get(inst, 'buttonImage'); + inst.trigger = $(this._get(inst, 'buttonImageOnly') ? + $('').addClass(this._triggerClass). + attr({ src: buttonImage, alt: buttonText, title: buttonText }) : + $('').addClass(this._triggerClass). + html(buttonImage == '' ? buttonText : $('').attr( + { src:buttonImage, alt:buttonText, title:buttonText }))); + input[isRTL ? 'before' : 'after'](inst.trigger); + inst.trigger.click(function() { + if ($.datepicker._datepickerShowing && $.datepicker._lastInput == input[0]) + $.datepicker._hideDatepicker(); + else + $.datepicker._showDatepicker(input[0]); + return false; + }); + } + }, + + /* Apply the maximum length for the date format. */ + _autoSize: function(inst) { + if (this._get(inst, 'autoSize') && !inst.inline) { + var date = new Date(2009, 12 - 1, 20); // Ensure double digits + var dateFormat = this._get(inst, 'dateFormat'); + if (dateFormat.match(/[DM]/)) { + var findMax = function(names) { + var max = 0; + var maxI = 0; + for (var i = 0; i < names.length; i++) { + if (names[i].length > max) { + max = names[i].length; + maxI = i; + } + } + return maxI; + }; + date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ? + 'monthNames' : 'monthNamesShort')))); + date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ? + 'dayNames' : 'dayNamesShort'))) + 20 - date.getDay()); + } + inst.input.attr('size', this._formatDate(inst, date).length); + } + }, + + /* Attach an inline date picker to a div. */ + _inlineDatepicker: function(target, inst) { + var divSpan = $(target); + if (divSpan.hasClass(this.markerClassName)) + return; + divSpan.addClass(this.markerClassName).append(inst.dpDiv). + bind("setData.datepicker", function(event, key, value){ + inst.settings[key] = value; + }).bind("getData.datepicker", function(event, key){ + return this._get(inst, key); + }); + $.data(target, PROP_NAME, inst); + this._setDate(inst, this._getDefaultDate(inst), true); + this._updateDatepicker(inst); + this._updateAlternate(inst); + //If disabled option is true, disable the datepicker before showing it (see ticket #5665) + if( inst.settings.disabled ) { + this._disableDatepicker( target ); + } + // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements + // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height + inst.dpDiv.css( "display", "block" ); + }, + + /* Pop-up the date picker in a "dialog" box. + @param input element - ignored + @param date string or Date - the initial date to display + @param onSelect function - the function to call when a date is selected + @param settings object - update the dialog date picker instance's settings (anonymous object) + @param pos int[2] - coordinates for the dialog's position within the screen or + event - with x/y coordinates or + leave empty for default (screen centre) + @return the manager object */ + _dialogDatepicker: function(input, date, onSelect, settings, pos) { + var inst = this._dialogInst; // internal instance + if (!inst) { + this.uuid += 1; + var id = 'dp' + this.uuid; + this._dialogInput = $(''); + this._dialogInput.keydown(this._doKeyDown); + $('body').append(this._dialogInput); + inst = this._dialogInst = this._newInst(this._dialogInput, false); + inst.settings = {}; + $.data(this._dialogInput[0], PROP_NAME, inst); + } + extendRemove(inst.settings, settings || {}); + date = (date && date.constructor == Date ? this._formatDate(inst, date) : date); + this._dialogInput.val(date); + + this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null); + if (!this._pos) { + var browserWidth = document.documentElement.clientWidth; + var browserHeight = document.documentElement.clientHeight; + var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; + var scrollY = document.documentElement.scrollTop || document.body.scrollTop; + this._pos = // should use actual width/height below + [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY]; + } + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css('left', (this._pos[0] + 20) + 'px').css('top', this._pos[1] + 'px'); + inst.settings.onSelect = onSelect; + this._inDialog = true; + this.dpDiv.addClass(this._dialogClass); + this._showDatepicker(this._dialogInput[0]); + if ($.blockUI) + $.blockUI(this.dpDiv); + $.data(this._dialogInput[0], PROP_NAME, inst); + return this; + }, + + /* Detach a datepicker from its control. + @param target element - the target input field or division or span */ + _destroyDatepicker: function(target) { + var $target = $(target); + var inst = $.data(target, PROP_NAME); + if (!$target.hasClass(this.markerClassName)) { + return; + } + var nodeName = target.nodeName.toLowerCase(); + $.removeData(target, PROP_NAME); + if (nodeName == 'input') { + inst.append.remove(); + inst.trigger.remove(); + $target.removeClass(this.markerClassName). + unbind('focus', this._showDatepicker). + unbind('keydown', this._doKeyDown). + unbind('keypress', this._doKeyPress). + unbind('keyup', this._doKeyUp); + } else if (nodeName == 'div' || nodeName == 'span') + $target.removeClass(this.markerClassName).empty(); + }, + + /* Enable the date picker to a jQuery selection. + @param target element - the target input field or division or span */ + _enableDatepicker: function(target) { + var $target = $(target); + var inst = $.data(target, PROP_NAME); + if (!$target.hasClass(this.markerClassName)) { + return; + } + var nodeName = target.nodeName.toLowerCase(); + if (nodeName == 'input') { + target.disabled = false; + inst.trigger.filter('button'). + each(function() { this.disabled = false; }).end(). + filter('img').css({opacity: '1.0', cursor: ''}); + } + else if (nodeName == 'div' || nodeName == 'span') { + var inline = $target.children('.' + this._inlineClass); + inline.children().removeClass('ui-state-disabled'); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + removeAttr("disabled"); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value == target ? null : value); }); // delete entry + }, + + /* Disable the date picker to a jQuery selection. + @param target element - the target input field or division or span */ + _disableDatepicker: function(target) { + var $target = $(target); + var inst = $.data(target, PROP_NAME); + if (!$target.hasClass(this.markerClassName)) { + return; + } + var nodeName = target.nodeName.toLowerCase(); + if (nodeName == 'input') { + target.disabled = true; + inst.trigger.filter('button'). + each(function() { this.disabled = true; }).end(). + filter('img').css({opacity: '0.5', cursor: 'default'}); + } + else if (nodeName == 'div' || nodeName == 'span') { + var inline = $target.children('.' + this._inlineClass); + inline.children().addClass('ui-state-disabled'); + inline.find("select.ui-datepicker-month, select.ui-datepicker-year"). + attr("disabled", "disabled"); + } + this._disabledInputs = $.map(this._disabledInputs, + function(value) { return (value == target ? null : value); }); // delete entry + this._disabledInputs[this._disabledInputs.length] = target; + }, + + /* Is the first field in a jQuery collection disabled as a datepicker? + @param target element - the target input field or division or span + @return boolean - true if disabled, false if enabled */ + _isDisabledDatepicker: function(target) { + if (!target) { + return false; + } + for (var i = 0; i < this._disabledInputs.length; i++) { + if (this._disabledInputs[i] == target) + return true; + } + return false; + }, + + /* Retrieve the instance data for the target control. + @param target element - the target input field or division or span + @return object - the associated instance data + @throws error if a jQuery problem getting data */ + _getInst: function(target) { + try { + return $.data(target, PROP_NAME); + } + catch (err) { + throw 'Missing instance data for this datepicker'; + } + }, + + /* Update or retrieve the settings for a date picker attached to an input field or division. + @param target element - the target input field or division or span + @param name object - the new settings to update or + string - the name of the setting to change or retrieve, + when retrieving also 'all' for all instance settings or + 'defaults' for all global defaults + @param value any - the new value for the setting + (omit if above is an object or to retrieve a value) */ + _optionDatepicker: function(target, name, value) { + var inst = this._getInst(target); + if (arguments.length == 2 && typeof name == 'string') { + return (name == 'defaults' ? $.extend({}, $.datepicker._defaults) : + (inst ? (name == 'all' ? $.extend({}, inst.settings) : + this._get(inst, name)) : null)); + } + var settings = name || {}; + if (typeof name == 'string') { + settings = {}; + settings[name] = value; + } + if (inst) { + if (this._curInst == inst) { + this._hideDatepicker(); + } + var date = this._getDateDatepicker(target, true); + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + extendRemove(inst.settings, settings); + // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided + if (minDate !== null && settings['dateFormat'] !== undefined && settings['minDate'] === undefined) + inst.settings.minDate = this._formatDate(inst, minDate); + if (maxDate !== null && settings['dateFormat'] !== undefined && settings['maxDate'] === undefined) + inst.settings.maxDate = this._formatDate(inst, maxDate); + this._attachments($(target), inst); + this._autoSize(inst); + this._setDate(inst, date); + this._updateAlternate(inst); + this._updateDatepicker(inst); + } + }, + + // change method deprecated + _changeDatepicker: function(target, name, value) { + this._optionDatepicker(target, name, value); + }, + + /* Redraw the date picker attached to an input field or division. + @param target element - the target input field or division or span */ + _refreshDatepicker: function(target) { + var inst = this._getInst(target); + if (inst) { + this._updateDatepicker(inst); + } + }, + + /* Set the dates for a jQuery selection. + @param target element - the target input field or division or span + @param date Date - the new date */ + _setDateDatepicker: function(target, date) { + var inst = this._getInst(target); + if (inst) { + this._setDate(inst, date); + this._updateDatepicker(inst); + this._updateAlternate(inst); + } + }, + + /* Get the date(s) for the first entry in a jQuery selection. + @param target element - the target input field or division or span + @param noDefault boolean - true if no default date is to be used + @return Date - the current date */ + _getDateDatepicker: function(target, noDefault) { + var inst = this._getInst(target); + if (inst && !inst.inline) + this._setDateFromField(inst, noDefault); + return (inst ? this._getDate(inst) : null); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(event) { + var inst = $.datepicker._getInst(event.target); + var handled = true; + var isRTL = inst.dpDiv.is('.ui-datepicker-rtl'); + inst._keyEvent = true; + if ($.datepicker._datepickerShowing) + switch (event.keyCode) { + case 9: $.datepicker._hideDatepicker(); + handled = false; + break; // hide on tab out + case 13: var sel = $('td.' + $.datepicker._dayOverClass + ':not(.' + + $.datepicker._currentClass + ')', inst.dpDiv); + if (sel[0]) + $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]); + var onSelect = $.datepicker._get(inst, 'onSelect'); + if (onSelect) { + var dateStr = $.datepicker._formatDate(inst); + + // trigger custom callback + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); + } + else + $.datepicker._hideDatepicker(); + return false; // don't submit the form + break; // select the value on enter + case 27: $.datepicker._hideDatepicker(); + break; // hide on escape + case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, 'stepBigMonths') : + -$.datepicker._get(inst, 'stepMonths')), 'M'); + break; // previous month/year on page up/+ ctrl + case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, 'stepBigMonths') : + +$.datepicker._get(inst, 'stepMonths')), 'M'); + break; // next month/year on page down/+ ctrl + case 35: if (event.ctrlKey || event.metaKey) $.datepicker._clearDate(event.target); + handled = event.ctrlKey || event.metaKey; + break; // clear on ctrl or command +end + case 36: if (event.ctrlKey || event.metaKey) $.datepicker._gotoToday(event.target); + handled = event.ctrlKey || event.metaKey; + break; // current on ctrl or command +home + case 37: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), 'D'); + handled = event.ctrlKey || event.metaKey; + // -1 day on ctrl or command +left + if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? + -$.datepicker._get(inst, 'stepBigMonths') : + -$.datepicker._get(inst, 'stepMonths')), 'M'); + // next month/year on alt +left on Mac + break; + case 38: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, -7, 'D'); + handled = event.ctrlKey || event.metaKey; + break; // -1 week on ctrl or command +up + case 39: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), 'D'); + handled = event.ctrlKey || event.metaKey; + // +1 day on ctrl or command +right + if (event.originalEvent.altKey) $.datepicker._adjustDate(event.target, (event.ctrlKey ? + +$.datepicker._get(inst, 'stepBigMonths') : + +$.datepicker._get(inst, 'stepMonths')), 'M'); + // next month/year on alt +right + break; + case 40: if (event.ctrlKey || event.metaKey) $.datepicker._adjustDate(event.target, +7, 'D'); + handled = event.ctrlKey || event.metaKey; + break; // +1 week on ctrl or command +down + default: handled = false; + } + else if (event.keyCode == 36 && event.ctrlKey) // display the date picker on ctrl+home + $.datepicker._showDatepicker(this); + else { + handled = false; + } + if (handled) { + event.preventDefault(); + event.stopPropagation(); + } + }, + + /* Filter entered characters - based on date format. */ + _doKeyPress: function(event) { + var inst = $.datepicker._getInst(event.target); + if ($.datepicker._get(inst, 'constrainInput')) { + var chars = $.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')); + var chr = String.fromCharCode(event.charCode == undefined ? event.keyCode : event.charCode); + return event.ctrlKey || event.metaKey || (chr < ' ' || !chars || chars.indexOf(chr) > -1); + } + }, + + /* Synchronise manual entry and field/alternate field. */ + _doKeyUp: function(event) { + var inst = $.datepicker._getInst(event.target); + if (inst.input.val() != inst.lastVal) { + try { + var date = $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), + (inst.input ? inst.input.val() : null), + $.datepicker._getFormatConfig(inst)); + if (date) { // only if valid + $.datepicker._setDateFromField(inst); + $.datepicker._updateAlternate(inst); + $.datepicker._updateDatepicker(inst); + } + } + catch (event) { + $.datepicker.log(event); + } + } + return true; + }, + + /* Pop-up the date picker for a given input field. + If false returned from beforeShow event handler do not show. + @param input element - the input field attached to the date picker or + event - if triggered by focus */ + _showDatepicker: function(input) { + input = input.target || input; + if (input.nodeName.toLowerCase() != 'input') // find from button/image trigger + input = $('input', input.parentNode)[0]; + if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput == input) // already here + return; + var inst = $.datepicker._getInst(input); + if ($.datepicker._curInst && $.datepicker._curInst != inst) { + if ( $.datepicker._datepickerShowing ) { + $.datepicker._triggerOnClose($.datepicker._curInst); + } + $.datepicker._curInst.dpDiv.stop(true, true); + } + var beforeShow = $.datepicker._get(inst, 'beforeShow'); + var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; + if(beforeShowSettings === false){ + //false + return; + } + extendRemove(inst.settings, beforeShowSettings); + inst.lastVal = null; + $.datepicker._lastInput = input; + $.datepicker._setDateFromField(inst); + if ($.datepicker._inDialog) // hide cursor + input.value = ''; + if (!$.datepicker._pos) { // position below input + $.datepicker._pos = $.datepicker._findPos(input); + $.datepicker._pos[1] += input.offsetHeight; // add the height + } + var isFixed = false; + $(input).parents().each(function() { + isFixed |= $(this).css('position') == 'fixed'; + return !isFixed; + }); + if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled + $.datepicker._pos[0] -= document.documentElement.scrollLeft; + $.datepicker._pos[1] -= document.documentElement.scrollTop; + } + var offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]}; + $.datepicker._pos = null; + //to avoid flashes on Firefox + inst.dpDiv.empty(); + // determine sizing offscreen + inst.dpDiv.css({position: 'absolute', display: 'block', top: '-1000px'}); + $.datepicker._updateDatepicker(inst); + // fix width for dynamic number of date pickers + // and adjust position before showing + offset = $.datepicker._checkOffset(inst, offset, isFixed); + inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ? + 'static' : (isFixed ? 'fixed' : 'absolute')), display: 'none', + left: offset.left + 'px', top: offset.top + 'px'}); + if (!inst.inline) { + var showAnim = $.datepicker._get(inst, 'showAnim'); + var duration = $.datepicker._get(inst, 'duration'); + var postProcess = function() { + var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only + if( !! cover.length ){ + var borders = $.datepicker._getBorders(inst.dpDiv); + cover.css({left: -borders[0], top: -borders[1], + width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}); + } + }; + inst.dpDiv.zIndex($(input).zIndex()+1); + $.datepicker._datepickerShowing = true; + if ($.effects && $.effects[showAnim]) + inst.dpDiv.show(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); + else + inst.dpDiv[showAnim || 'show']((showAnim ? duration : null), postProcess); + if (!showAnim || !duration) + postProcess(); + if (inst.input.is(':visible') && !inst.input.is(':disabled')) + inst.input.focus(); + $.datepicker._curInst = inst; + } + }, + + /* Generate the date picker content. */ + _updateDatepicker: function(inst) { + var self = this; + self.maxRows = 4; //Reset the max number of rows being displayed (see #7043) + var borders = $.datepicker._getBorders(inst.dpDiv); + instActive = inst; // for delegate hover events + inst.dpDiv.empty().append(this._generateHTML(inst)); + var cover = inst.dpDiv.find('iframe.ui-datepicker-cover'); // IE6- only + if( !!cover.length ){ //avoid call to outerXXXX() when not in IE6 + cover.css({left: -borders[0], top: -borders[1], width: inst.dpDiv.outerWidth(), height: inst.dpDiv.outerHeight()}) + } + inst.dpDiv.find('.' + this._dayOverClass + ' a').mouseover(); + var numMonths = this._getNumberOfMonths(inst); + var cols = numMonths[1]; + var width = 17; + inst.dpDiv.removeClass('ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4').width(''); + if (cols > 1) + inst.dpDiv.addClass('ui-datepicker-multi-' + cols).css('width', (width * cols) + 'em'); + inst.dpDiv[(numMonths[0] != 1 || numMonths[1] != 1 ? 'add' : 'remove') + + 'Class']('ui-datepicker-multi'); + inst.dpDiv[(this._get(inst, 'isRTL') ? 'add' : 'remove') + + 'Class']('ui-datepicker-rtl'); + if (inst == $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input && + // #6694 - don't focus the input if it's already focused + // this breaks the change event in IE + inst.input.is(':visible') && !inst.input.is(':disabled') && inst.input[0] != document.activeElement) + inst.input.focus(); + // deffered render of the years select (to avoid flashes on Firefox) + if( inst.yearshtml ){ + var origyearshtml = inst.yearshtml; + setTimeout(function(){ + //assure that inst.yearshtml didn't change. + if( origyearshtml === inst.yearshtml && inst.yearshtml ){ + inst.dpDiv.find('select.ui-datepicker-year:first').replaceWith(inst.yearshtml); + } + origyearshtml = inst.yearshtml = null; + }, 0); + } + }, + + /* Retrieve the size of left and top borders for an element. + @param elem (jQuery object) the element of interest + @return (number[2]) the left and top borders */ + _getBorders: function(elem) { + var convert = function(value) { + return {thin: 1, medium: 2, thick: 3}[value] || value; + }; + return [parseFloat(convert(elem.css('border-left-width'))), + parseFloat(convert(elem.css('border-top-width')))]; + }, + + /* Check positioning to remain on screen. */ + _checkOffset: function(inst, offset, isFixed) { + var dpWidth = inst.dpDiv.outerWidth(); + var dpHeight = inst.dpDiv.outerHeight(); + var inputWidth = inst.input ? inst.input.outerWidth() : 0; + var inputHeight = inst.input ? inst.input.outerHeight() : 0; + var viewWidth = document.documentElement.clientWidth + $(document).scrollLeft(); + var viewHeight = document.documentElement.clientHeight + $(document).scrollTop(); + + offset.left -= (this._get(inst, 'isRTL') ? (dpWidth - inputWidth) : 0); + offset.left -= (isFixed && offset.left == inst.input.offset().left) ? $(document).scrollLeft() : 0; + offset.top -= (isFixed && offset.top == (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0; + + // now check if datepicker is showing outside window viewport - move to a better place if so. + offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? + Math.abs(offset.left + dpWidth - viewWidth) : 0); + offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? + Math.abs(dpHeight + inputHeight) : 0); + + return offset; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + var inst = this._getInst(obj); + var isRTL = this._get(inst, 'isRTL'); + while (obj && (obj.type == 'hidden' || obj.nodeType != 1 || $.expr.filters.hidden(obj))) { + obj = obj[isRTL ? 'previousSibling' : 'nextSibling']; + } + var position = $(obj).offset(); + return [position.left, position.top]; + }, + + /* Trigger custom callback of onClose. */ + _triggerOnClose: function(inst) { + var onClose = this._get(inst, 'onClose'); + if (onClose) + onClose.apply((inst.input ? inst.input[0] : null), + [(inst.input ? inst.input.val() : ''), inst]); + }, + + /* Hide the date picker from view. + @param input element - the input field attached to the date picker */ + _hideDatepicker: function(input) { + var inst = this._curInst; + if (!inst || (input && inst != $.data(input, PROP_NAME))) + return; + if (this._datepickerShowing) { + var showAnim = this._get(inst, 'showAnim'); + var duration = this._get(inst, 'duration'); + var postProcess = function() { + $.datepicker._tidyDialog(inst); + this._curInst = null; + }; + if ($.effects && $.effects[showAnim]) + inst.dpDiv.hide(showAnim, $.datepicker._get(inst, 'showOptions'), duration, postProcess); + else + inst.dpDiv[(showAnim == 'slideDown' ? 'slideUp' : + (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); + if (!showAnim) + postProcess(); + $.datepicker._triggerOnClose(inst); + this._datepickerShowing = false; + this._lastInput = null; + if (this._inDialog) { + this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); + if ($.blockUI) { + $.unblockUI(); + $('body').append(this.dpDiv); + } + } + this._inDialog = false; + } + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst.dpDiv.removeClass(this._dialogClass).unbind('.ui-datepicker-calendar'); + }, + + /* Close date picker if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!$.datepicker._curInst) + return; + var $target = $(event.target); + if ($target[0].id != $.datepicker._mainDivId && + $target.parents('#' + $.datepicker._mainDivId).length == 0 && + !$target.hasClass($.datepicker.markerClassName) && + !$target.hasClass($.datepicker._triggerClass) && + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) + $.datepicker._hideDatepicker(); + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var target = $(id); + var inst = this._getInst(target[0]); + if (this._isDisabledDatepicker(target[0])) { + return; + } + this._adjustInstDate(inst, offset + + (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning + period); + this._updateDatepicker(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var target = $(id); + var inst = this._getInst(target[0]); + if (this._get(inst, 'gotoCurrent') && inst.currentDay) { + inst.selectedDay = inst.currentDay; + inst.drawMonth = inst.selectedMonth = inst.currentMonth; + inst.drawYear = inst.selectedYear = inst.currentYear; + } + else { + var date = new Date(); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + } + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var target = $(id); + var inst = this._getInst(target[0]); + inst['selected' + (period == 'M' ? 'Month' : 'Year')] = + inst['draw' + (period == 'M' ? 'Month' : 'Year')] = + parseInt(select.options[select.selectedIndex].value,10); + this._notifyChange(inst); + this._adjustDate(target); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, month, year, td) { + var target = $(id); + if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) { + return; + } + var inst = this._getInst(target[0]); + inst.selectedDay = inst.currentDay = $('a', td).html(); + inst.selectedMonth = inst.currentMonth = month; + inst.selectedYear = inst.currentYear = year; + this._selectDate(id, this._formatDate(inst, + inst.currentDay, inst.currentMonth, inst.currentYear)); + }, + + /* Erase the input field and hide the date picker. */ + _clearDate: function(id) { + var target = $(id); + var inst = this._getInst(target[0]); + this._selectDate(target, ''); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var target = $(id); + var inst = this._getInst(target[0]); + dateStr = (dateStr != null ? dateStr : this._formatDate(inst)); + if (inst.input) + inst.input.val(dateStr); + this._updateAlternate(inst); + var onSelect = this._get(inst, 'onSelect'); + if (onSelect) + onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback + else if (inst.input) + inst.input.trigger('change'); // fire the change event + if (inst.inline) + this._updateDatepicker(inst); + else { + this._hideDatepicker(); + this._lastInput = inst.input[0]; + if (typeof(inst.input[0]) != 'object') + inst.input.focus(); // restore focus + this._lastInput = null; + } + }, + + /* Update any alternate field to synchronise with the main field. */ + _updateAlternate: function(inst) { + var altField = this._get(inst, 'altField'); + if (altField) { // update alternate field too + var altFormat = this._get(inst, 'altFormat') || this._get(inst, 'dateFormat'); + var date = this._getDate(inst); + var dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst)); + $(altField).each(function() { $(this).val(dateStr); }); + } + }, + + /* Set as beforeShowDay function to prevent selection of weekends. + @param date Date - the date to customise + @return [boolean, string] - is this date selectable?, what is its CSS class? */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), '']; + }, + + /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition. + @param date Date - the date to get the week for + @return number - the number of the week within the year that contains this date */ + iso8601Week: function(date) { + var checkDate = new Date(date.getTime()); + // Find Thursday of this week starting on Monday + checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7)); + var time = checkDate.getTime(); + checkDate.setMonth(0); // Compare with Jan 1 + checkDate.setDate(1); + return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1; + }, + + /* Parse a string value into a date object. + See formatDate below for the possible formats. + + @param format string - the expected format of the date + @param value string - the date in the above format + @param settings Object - attributes include: + shortYearCutoff number - the cutoff year for determining the century (optional) + dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + dayNames string[7] - names of the days from Sunday (optional) + monthNamesShort string[12] - abbreviated names of the months (optional) + monthNames string[12] - names of the months (optional) + @return Date - the extracted date value or null if value is blank */ + parseDate: function (format, value, settings) { + if (format == null || value == null) + throw 'Invalid arguments'; + value = (typeof value == 'object' ? value.toString() : value + ''); + if (value == '') + return null; + var shortYearCutoff = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff; + shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; + var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; + var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; + var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; + var year = -1; + var month = -1; + var day = -1; + var doy = -1; + var literal = false; + // Check whether a format character is doubled + var lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); + if (matches) + iFormat++; + return matches; + }; + // Extract a number from the string value + var getNumber = function(match) { + var isDoubled = lookAhead(match); + var size = (match == '@' ? 14 : (match == '!' ? 20 : + (match == 'y' && isDoubled ? 4 : (match == 'o' ? 3 : 2)))); + var digits = new RegExp('^\\d{1,' + size + '}'); + var num = value.substring(iValue).match(digits); + if (!num) + throw 'Missing number at position ' + iValue; + iValue += num[0].length; + return parseInt(num[0], 10); + }; + // Extract a name from the string value and convert to an index + var getName = function(match, shortNames, longNames) { + var names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) { + return [ [k, v] ]; + }).sort(function (a, b) { + return -(a[1].length - b[1].length); + }); + var index = -1; + $.each(names, function (i, pair) { + var name = pair[1]; + if (value.substr(iValue, name.length).toLowerCase() == name.toLowerCase()) { + index = pair[0]; + iValue += name.length; + return false; + } + }); + if (index != -1) + return index + 1; + else + throw 'Unknown name at position ' + iValue; + }; + // Confirm that a literal character matches the string value + var checkLiteral = function() { + if (value.charAt(iValue) != format.charAt(iFormat)) + throw 'Unexpected literal at position ' + iValue; + iValue++; + }; + var iValue = 0; + for (var iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) + if (format.charAt(iFormat) == "'" && !lookAhead("'")) + literal = false; + else + checkLiteral(); + else + switch (format.charAt(iFormat)) { + case 'd': + day = getNumber('d'); + break; + case 'D': + getName('D', dayNamesShort, dayNames); + break; + case 'o': + doy = getNumber('o'); + break; + case 'm': + month = getNumber('m'); + break; + case 'M': + month = getName('M', monthNamesShort, monthNames); + break; + case 'y': + year = getNumber('y'); + break; + case '@': + var date = new Date(getNumber('@')); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case '!': + var date = new Date((getNumber('!') - this._ticksTo1970) / 10000); + year = date.getFullYear(); + month = date.getMonth() + 1; + day = date.getDate(); + break; + case "'": + if (lookAhead("'")) + checkLiteral(); + else + literal = true; + break; + default: + checkLiteral(); + } + } + if (iValue < value.length){ + throw "Extra/unparsed characters found in date: " + value.substring(iValue); + } + if (year == -1) + year = new Date().getFullYear(); + else if (year < 100) + year += new Date().getFullYear() - new Date().getFullYear() % 100 + + (year <= shortYearCutoff ? 0 : -100); + if (doy > -1) { + month = 1; + day = doy; + do { + var dim = this._getDaysInMonth(year, month - 1); + if (day <= dim) + break; + month++; + day -= dim; + } while (true); + } + var date = this._daylightSavingAdjust(new Date(year, month - 1, day)); + if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) + throw 'Invalid date'; // E.g. 31/02/00 + return date; + }, + + /* Standard date formats. */ + ATOM: 'yy-mm-dd', // RFC 3339 (ISO 8601) + COOKIE: 'D, dd M yy', + ISO_8601: 'yy-mm-dd', + RFC_822: 'D, d M y', + RFC_850: 'DD, dd-M-y', + RFC_1036: 'D, d M y', + RFC_1123: 'D, d M yy', + RFC_2822: 'D, d M yy', + RSS: 'D, d M y', // RFC 822 + TICKS: '!', + TIMESTAMP: '@', + W3C: 'yy-mm-dd', // ISO 8601 + + _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000), + + /* Format a date object into a string value. + The format can be combinations of the following: + d - day of month (no leading zero) + dd - day of month (two digit) + o - day of year (no leading zeros) + oo - day of year (three digit) + D - day name short + DD - day name long + m - month of year (no leading zero) + mm - month of year (two digit) + M - month name short + MM - month name long + y - year (two digit) + yy - year (four digit) + @ - Unix timestamp (ms since 01/01/1970) + ! - Windows ticks (100ns since 01/01/0001) + '...' - literal text + '' - single quote + + @param format string - the desired format of the date + @param date Date - the date value to format + @param settings Object - attributes include: + dayNamesShort string[7] - abbreviated names of the days from Sunday (optional) + dayNames string[7] - names of the days from Sunday (optional) + monthNamesShort string[12] - abbreviated names of the months (optional) + monthNames string[12] - names of the months (optional) + @return string - the date in the above format */ + formatDate: function (format, date, settings) { + if (!date) + return ''; + var dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort; + var dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames; + var monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort; + var monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames; + // Check whether a format character is doubled + var lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); + if (matches) + iFormat++; + return matches; + }; + // Format a number, with leading zero if necessary + var formatNumber = function(match, value, len) { + var num = '' + value; + if (lookAhead(match)) + while (num.length < len) + num = '0' + num; + return num; + }; + // Format a name, short or long as requested + var formatName = function(match, value, shortNames, longNames) { + return (lookAhead(match) ? longNames[value] : shortNames[value]); + }; + var output = ''; + var literal = false; + if (date) + for (var iFormat = 0; iFormat < format.length; iFormat++) { + if (literal) + if (format.charAt(iFormat) == "'" && !lookAhead("'")) + literal = false; + else + output += format.charAt(iFormat); + else + switch (format.charAt(iFormat)) { + case 'd': + output += formatNumber('d', date.getDate(), 2); + break; + case 'D': + output += formatName('D', date.getDay(), dayNamesShort, dayNames); + break; + case 'o': + output += formatNumber('o', + Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3); + break; + case 'm': + output += formatNumber('m', date.getMonth() + 1, 2); + break; + case 'M': + output += formatName('M', date.getMonth(), monthNamesShort, monthNames); + break; + case 'y': + output += (lookAhead('y') ? date.getFullYear() : + (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100); + break; + case '@': + output += date.getTime(); + break; + case '!': + output += date.getTime() * 10000 + this._ticksTo1970; + break; + case "'": + if (lookAhead("'")) + output += "'"; + else + literal = true; + break; + default: + output += format.charAt(iFormat); + } + } + return output; + }, + + /* Extract all possible characters from the date format. */ + _possibleChars: function (format) { + var chars = ''; + var literal = false; + // Check whether a format character is doubled + var lookAhead = function(match) { + var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match); + if (matches) + iFormat++; + return matches; + }; + for (var iFormat = 0; iFormat < format.length; iFormat++) + if (literal) + if (format.charAt(iFormat) == "'" && !lookAhead("'")) + literal = false; + else + chars += format.charAt(iFormat); + else + switch (format.charAt(iFormat)) { + case 'd': case 'm': case 'y': case '@': + chars += '0123456789'; + break; + case 'D': case 'M': + return null; // Accept anything + case "'": + if (lookAhead("'")) + chars += "'"; + else + literal = true; + break; + default: + chars += format.charAt(iFormat); + } + return chars; + }, + + /* Get a setting value, defaulting if necessary. */ + _get: function(inst, name) { + return inst.settings[name] !== undefined ? + inst.settings[name] : this._defaults[name]; + }, + + /* Parse existing date and initialise date picker. */ + _setDateFromField: function(inst, noDefault) { + if (inst.input.val() == inst.lastVal) { + return; + } + var dateFormat = this._get(inst, 'dateFormat'); + var dates = inst.lastVal = inst.input ? inst.input.val() : null; + var date, defaultDate; + date = defaultDate = this._getDefaultDate(inst); + var settings = this._getFormatConfig(inst); + try { + date = this.parseDate(dateFormat, dates, settings) || defaultDate; + } catch (event) { + this.log(event); + dates = (noDefault ? '' : dates); + } + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + inst.currentDay = (dates ? date.getDate() : 0); + inst.currentMonth = (dates ? date.getMonth() : 0); + inst.currentYear = (dates ? date.getFullYear() : 0); + this._adjustInstDate(inst); + }, + + /* Retrieve the default date shown on opening. */ + _getDefaultDate: function(inst) { + return this._restrictMinMax(inst, + this._determineDate(inst, this._get(inst, 'defaultDate'), new Date())); + }, + + /* A date may be specified as an exact value or a relative one. */ + _determineDate: function(inst, date, defaultDate) { + var offsetNumeric = function(offset) { + var date = new Date(); + date.setDate(date.getDate() + offset); + return date; + }; + var offsetString = function(offset) { + try { + return $.datepicker.parseDate($.datepicker._get(inst, 'dateFormat'), + offset, $.datepicker._getFormatConfig(inst)); + } + catch (e) { + // Ignore + } + var date = (offset.toLowerCase().match(/^c/) ? + $.datepicker._getDate(inst) : null) || new Date(); + var year = date.getFullYear(); + var month = date.getMonth(); + var day = date.getDate(); + var pattern = /([+-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g; + var matches = pattern.exec(offset); + while (matches) { + switch (matches[2] || 'd') { + case 'd' : case 'D' : + day += parseInt(matches[1],10); break; + case 'w' : case 'W' : + day += parseInt(matches[1],10) * 7; break; + case 'm' : case 'M' : + month += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + case 'y': case 'Y' : + year += parseInt(matches[1],10); + day = Math.min(day, $.datepicker._getDaysInMonth(year, month)); + break; + } + matches = pattern.exec(offset); + } + return new Date(year, month, day); + }; + var newDate = (date == null || date === '' ? defaultDate : (typeof date == 'string' ? offsetString(date) : + (typeof date == 'number' ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime())))); + newDate = (newDate && newDate.toString() == 'Invalid Date' ? defaultDate : newDate); + if (newDate) { + newDate.setHours(0); + newDate.setMinutes(0); + newDate.setSeconds(0); + newDate.setMilliseconds(0); + } + return this._daylightSavingAdjust(newDate); + }, + + /* Handle switch to/from daylight saving. + Hours may be non-zero on daylight saving cut-over: + > 12 when midnight changeover, but then cannot generate + midnight datetime, so jump to 1AM, otherwise reset. + @param date (Date) the date to check + @return (Date) the corrected date */ + _daylightSavingAdjust: function(date) { + if (!date) return null; + date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0); + return date; + }, + + /* Set the date(s) directly. */ + _setDate: function(inst, date, noChange) { + var clear = !date; + var origMonth = inst.selectedMonth; + var origYear = inst.selectedYear; + var newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date())); + inst.selectedDay = inst.currentDay = newDate.getDate(); + inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth(); + inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear(); + if ((origMonth != inst.selectedMonth || origYear != inst.selectedYear) && !noChange) + this._notifyChange(inst); + this._adjustInstDate(inst); + if (inst.input) { + inst.input.val(clear ? '' : this._formatDate(inst)); + } + }, + + /* Retrieve the date(s) directly. */ + _getDate: function(inst) { + var startDate = (!inst.currentYear || (inst.input && inst.input.val() == '') ? null : + this._daylightSavingAdjust(new Date( + inst.currentYear, inst.currentMonth, inst.currentDay))); + return startDate; + }, + + /* Generate the HTML for the current state of the date picker. */ + _generateHTML: function(inst) { + var today = new Date(); + today = this._daylightSavingAdjust( + new Date(today.getFullYear(), today.getMonth(), today.getDate())); // clear time + var isRTL = this._get(inst, 'isRTL'); + var showButtonPanel = this._get(inst, 'showButtonPanel'); + var hideIfNoPrevNext = this._get(inst, 'hideIfNoPrevNext'); + var navigationAsDateFormat = this._get(inst, 'navigationAsDateFormat'); + var numMonths = this._getNumberOfMonths(inst); + var showCurrentAtPos = this._get(inst, 'showCurrentAtPos'); + var stepMonths = this._get(inst, 'stepMonths'); + var isMultiMonth = (numMonths[0] != 1 || numMonths[1] != 1); + var currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) : + new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + var drawMonth = inst.drawMonth - showCurrentAtPos; + var drawYear = inst.drawYear; + if (drawMonth < 0) { + drawMonth += 12; + drawYear--; + } + if (maxDate) { + var maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(), + maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate())); + maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw); + while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) { + drawMonth--; + if (drawMonth < 0) { + drawMonth = 11; + drawYear--; + } + } + } + inst.drawMonth = drawMonth; + inst.drawYear = drawYear; + var prevText = this._get(inst, 'prevText'); + prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)), + this._getFormatConfig(inst))); + var prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ? + '' + prevText + '' : + (hideIfNoPrevNext ? '' : '' + prevText + '')); + var nextText = this._get(inst, 'nextText'); + nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText, + this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)), + this._getFormatConfig(inst))); + var next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ? + '' + nextText + '' : + (hideIfNoPrevNext ? '' : '' + nextText + '')); + var currentText = this._get(inst, 'currentText'); + var gotoDate = (this._get(inst, 'gotoCurrent') && inst.currentDay ? currentDate : today); + currentText = (!navigationAsDateFormat ? currentText : + this.formatDate(currentText, gotoDate, this._getFormatConfig(inst))); + var controls = (!inst.inline ? '' : ''); + var buttonPanel = (showButtonPanel) ? '
          ' + (isRTL ? controls : '') + + (this._isInRange(inst, gotoDate) ? '' : '') + (isRTL ? '' : controls) + '
          ' : ''; + var firstDay = parseInt(this._get(inst, 'firstDay'),10); + firstDay = (isNaN(firstDay) ? 0 : firstDay); + var showWeek = this._get(inst, 'showWeek'); + var dayNames = this._get(inst, 'dayNames'); + var dayNamesShort = this._get(inst, 'dayNamesShort'); + var dayNamesMin = this._get(inst, 'dayNamesMin'); + var monthNames = this._get(inst, 'monthNames'); + var monthNamesShort = this._get(inst, 'monthNamesShort'); + var beforeShowDay = this._get(inst, 'beforeShowDay'); + var showOtherMonths = this._get(inst, 'showOtherMonths'); + var selectOtherMonths = this._get(inst, 'selectOtherMonths'); + var calculateWeek = this._get(inst, 'calculateWeek') || this.iso8601Week; + var defaultDate = this._getDefaultDate(inst); + var html = ''; + for (var row = 0; row < numMonths[0]; row++) { + var group = ''; + this.maxRows = 4; + for (var col = 0; col < numMonths[1]; col++) { + var selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay)); + var cornerClass = ' ui-corner-all'; + var calender = ''; + if (isMultiMonth) { + calender += '
          '; + } + calender += '
          ' + + (/all|left/.test(cornerClass) && row == 0 ? (isRTL ? next : prev) : '') + + (/all|right/.test(cornerClass) && row == 0 ? (isRTL ? prev : next) : '') + + this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate, + row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers + '
          ' + + ''; + var thead = (showWeek ? '' : ''); + for (var dow = 0; dow < 7; dow++) { // days of the week + var day = (dow + firstDay) % 7; + thead += '= 5 ? ' class="ui-datepicker-week-end"' : '') + '>' + + '' + dayNamesMin[day] + ''; + } + calender += thead + ''; + var daysInMonth = this._getDaysInMonth(drawYear, drawMonth); + if (drawYear == inst.selectedYear && drawMonth == inst.selectedMonth) + inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); + var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; + var curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + var numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) + this.maxRows = numRows; + var printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); + for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows + calender += ''; + var tbody = (!showWeek ? '' : ''); + for (var dow = 0; dow < 7; dow++) { // create date picker days + var daySettings = (beforeShowDay ? + beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']); + var otherMonth = (printDate.getMonth() != drawMonth); + var unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + tbody += ''; // display selectable date + printDate.setDate(printDate.getDate() + 1); + printDate = this._daylightSavingAdjust(printDate); + } + calender += tbody + ''; + } + drawMonth++; + if (drawMonth > 11) { + drawMonth = 0; + drawYear++; + } + calender += '
          ' + this._get(inst, 'weekHeader') + '
          ' + + this._get(inst, 'calculateWeek')(printDate) + '' + // actions + (otherMonth && !showOtherMonths ? ' ' : // display for other months + (unselectable ? '' + printDate.getDate() + '' : '' + printDate.getDate() + '')) + '
          ' + (isMultiMonth ? '
          ' + + ((numMonths[0] > 0 && col == numMonths[1]-1) ? '
          ' : '') : ''); + group += calender; + } + html += group; + } + html += buttonPanel + ($.browser.msie && parseInt($.browser.version,10) < 7 && !inst.inline ? + '' : ''); + inst._keyEvent = false; + return html; + }, + + /* Generate the month and year header. */ + _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, + secondary, monthNames, monthNamesShort) { + var changeMonth = this._get(inst, 'changeMonth'); + var changeYear = this._get(inst, 'changeYear'); + var showMonthAfterYear = this._get(inst, 'showMonthAfterYear'); + var html = '
          '; + var monthHtml = ''; + // month selection + if (secondary || !changeMonth) + monthHtml += '' + monthNames[drawMonth] + ''; + else { + var inMinYear = (minDate && minDate.getFullYear() == drawYear); + var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear); + monthHtml += ''; + } + if (!showMonthAfterYear) + html += monthHtml + (secondary || !(changeMonth && changeYear) ? ' ' : ''); + // year selection + if ( !inst.yearshtml ) { + inst.yearshtml = ''; + if (secondary || !changeYear) + html += '' + drawYear + ''; + else { + // determine range of years to display + var years = this._get(inst, 'yearRange').split(':'); + var thisYear = new Date().getFullYear(); + var determineYear = function(value) { + var year = (value.match(/c[+-].*/) ? drawYear + parseInt(value.substring(1), 10) : + (value.match(/[+-].*/) ? thisYear + parseInt(value, 10) : + parseInt(value, 10))); + return (isNaN(year) ? thisYear : year); + }; + var year = determineYear(years[0]); + var endYear = Math.max(year, determineYear(years[1] || '')); + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + inst.yearshtml += ''; + + html += inst.yearshtml; + inst.yearshtml = null; + } + } + html += this._get(inst, 'yearSuffix'); + if (showMonthAfterYear) + html += (secondary || !(changeMonth && changeYear) ? ' ' : '') + monthHtml; + html += '
          '; // Close datepicker_header + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustInstDate: function(inst, offset, period) { + var year = inst.drawYear + (period == 'Y' ? offset : 0); + var month = inst.drawMonth + (period == 'M' ? offset : 0); + var day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + + (period == 'D' ? offset : 0); + var date = this._restrictMinMax(inst, + this._daylightSavingAdjust(new Date(year, month, day))); + inst.selectedDay = date.getDate(); + inst.drawMonth = inst.selectedMonth = date.getMonth(); + inst.drawYear = inst.selectedYear = date.getFullYear(); + if (period == 'M' || period == 'Y') + this._notifyChange(inst); + }, + + /* Ensure a date is within any min/max bounds. */ + _restrictMinMax: function(inst, date) { + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + var newDate = (minDate && date < minDate ? minDate : date); + newDate = (maxDate && newDate > maxDate ? maxDate : newDate); + return newDate; + }, + + /* Notify change of month/year. */ + _notifyChange: function(inst) { + var onChange = this._get(inst, 'onChangeMonthYear'); + if (onChange) + onChange.apply((inst.input ? inst.input[0] : null), + [inst.selectedYear, inst.selectedMonth + 1, inst]); + }, + + /* Determine the number of months to show. */ + _getNumberOfMonths: function(inst) { + var numMonths = this._get(inst, 'numberOfMonths'); + return (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths)); + }, + + /* Determine the current maximum date - ensure no time components are set. */ + _getMinMaxDate: function(inst, minMax) { + return this._determineDate(inst, this._get(inst, minMax + 'Date'), null); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(inst, offset, curYear, curMonth) { + var numMonths = this._getNumberOfMonths(inst); + var date = this._daylightSavingAdjust(new Date(curYear, + curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); + if (offset < 0) + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + return this._isInRange(inst, date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(inst, date) { + var minDate = this._getMinMaxDate(inst, 'min'); + var maxDate = this._getMinMaxDate(inst, 'max'); + return ((!minDate || date.getTime() >= minDate.getTime()) && + (!maxDate || date.getTime() <= maxDate.getTime())); + }, + + /* Provide the configuration settings for formatting/parsing. */ + _getFormatConfig: function(inst) { + var shortYearCutoff = this._get(inst, 'shortYearCutoff'); + shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff : + new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); + return {shortYearCutoff: shortYearCutoff, + dayNamesShort: this._get(inst, 'dayNamesShort'), dayNames: this._get(inst, 'dayNames'), + monthNamesShort: this._get(inst, 'monthNamesShort'), monthNames: this._get(inst, 'monthNames')}; + }, + + /* Format the given date for display. */ + _formatDate: function(inst, day, month, year) { + if (!day) { + inst.currentDay = inst.selectedDay; + inst.currentMonth = inst.selectedMonth; + inst.currentYear = inst.selectedYear; + } + var date = (day ? (typeof day == 'object' ? day : + this._daylightSavingAdjust(new Date(year, month, day))) : + this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); + return this.formatDate(this._get(inst, 'dateFormat'), date, this._getFormatConfig(inst)); + } +}); + +/* + * Bind hover events for datepicker elements. + * Done via delegate so the binding only occurs once in the lifetime of the parent div. + * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. + */ +function bindHover(dpDiv) { + var selector = 'button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a'; + return dpDiv.bind('mouseout', function(event) { + var elem = $( event.target ).closest( selector ); + if ( !elem.length ) { + return; + } + elem.removeClass( "ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover" ); + }) + .bind('mouseover', function(event) { + var elem = $( event.target ).closest( selector ); + if ($.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0]) || + !elem.length ) { + return; + } + elem.parents('.ui-datepicker-calendar').find('a').removeClass('ui-state-hover'); + elem.addClass('ui-state-hover'); + if (elem.hasClass('ui-datepicker-prev')) elem.addClass('ui-datepicker-prev-hover'); + if (elem.hasClass('ui-datepicker-next')) elem.addClass('ui-datepicker-next-hover'); + }); +} + +/* jQuery extend now ignores nulls! */ +function extendRemove(target, props) { + $.extend(target, props); + for (var name in props) + if (props[name] == null || props[name] == undefined) + target[name] = props[name]; + return target; +}; + +/* Determine whether an object is an array. */ +function isArray(a) { + return (a && (($.browser.safari && typeof a == 'object' && a.length) || + (a.constructor && a.constructor.toString().match(/\Array\(\)/)))); +}; + +/* Invoke the datepicker functionality. + @param options string - a command, optionally followed by additional parameters or + Object - settings for attaching new datepicker functionality + @return jQuery object */ +$.fn.datepicker = function(options){ + + /* Verify an empty collection wasn't passed - Fixes #6976 */ + if ( !this.length ) { + return this; + } + + /* Initialise the date picker. */ + if (!$.datepicker.initialized) { + $(document).mousedown($.datepicker._checkExternalClick). + find('body').append($.datepicker.dpDiv); + $.datepicker.initialized = true; + } + + var otherArgs = Array.prototype.slice.call(arguments, 1); + if (typeof options == 'string' && (options == 'isDisabled' || options == 'getDate' || options == 'widget')) + return $.datepicker['_' + options + 'Datepicker']. + apply($.datepicker, [this[0]].concat(otherArgs)); + if (options == 'option' && arguments.length == 2 && typeof arguments[1] == 'string') + return $.datepicker['_' + options + 'Datepicker']. + apply($.datepicker, [this[0]].concat(otherArgs)); + return this.each(function() { + typeof options == 'string' ? + $.datepicker['_' + options + 'Datepicker']. + apply($.datepicker, [this].concat(otherArgs)) : + $.datepicker._attachDatepicker(this, options); + }); +}; + +$.datepicker = new Datepicker(); // singleton instance +$.datepicker.initialized = false; +$.datepicker.uuid = new Date().getTime(); +$.datepicker.version = "1.8.16"; + +// Workaround for #4055 +// Add another global to avoid noConflict issues with inline event handlers +window['DP_jQuery_' + dpuuid] = $; + +})(jQuery); +/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function( $, undefined ) { + +var uiDialogClasses = + 'ui-dialog ' + + 'ui-widget ' + + 'ui-widget-content ' + + 'ui-corner-all ', + sizeRelatedOptions = { + buttons: true, + height: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + width: true + }, + resizableRelatedOptions = { + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true + }, + // support for jQuery 1.3.2 - handle common attrFn methods for dialog + attrFn = $.attrFn || { + val: true, + css: true, + html: true, + text: true, + data: true, + width: true, + height: true, + offset: true, + click: true + }; + +$.widget("ui.dialog", { + options: { + autoOpen: true, + buttons: {}, + closeOnEscape: true, + closeText: 'close', + dialogClass: '', + draggable: true, + hide: null, + height: 'auto', + maxHeight: false, + maxWidth: false, + minHeight: 150, + minWidth: 150, + modal: false, + position: { + my: 'center', + at: 'center', + collision: 'fit', + // ensure that the titlebar is never outside the document + using: function(pos) { + var topOffset = $(this).css(pos).offset().top; + if (topOffset < 0) { + $(this).css('top', pos.top - topOffset); + } + } + }, + resizable: true, + show: null, + stack: true, + title: '', + width: 300, + zIndex: 1000 + }, + + _create: function() { + this.originalTitle = this.element.attr('title'); + // #5742 - .attr() might return a DOMElement + if ( typeof this.originalTitle !== "string" ) { + this.originalTitle = ""; + } + + this.options.title = this.options.title || this.originalTitle; + var self = this, + options = self.options, + + title = options.title || ' ', + titleId = $.ui.dialog.getTitleId(self.element), + + uiDialog = (self.uiDialog = $('
          ')) + .appendTo(document.body) + .hide() + .addClass(uiDialogClasses + options.dialogClass) + .css({ + zIndex: options.zIndex + }) + // setting tabIndex makes the div focusable + // setting outline to 0 prevents a border on focus in Mozilla + .attr('tabIndex', -1).css('outline', 0).keydown(function(event) { + if (options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE) { + + self.close(event); + event.preventDefault(); + } + }) + .attr({ + role: 'dialog', + 'aria-labelledby': titleId + }) + .mousedown(function(event) { + self.moveToTop(false, event); + }), + + uiDialogContent = self.element + .show() + .removeAttr('title') + .addClass( + 'ui-dialog-content ' + + 'ui-widget-content') + .appendTo(uiDialog), + + uiDialogTitlebar = (self.uiDialogTitlebar = $('
          ')) + .addClass( + 'ui-dialog-titlebar ' + + 'ui-widget-header ' + + 'ui-corner-all ' + + 'ui-helper-clearfix' + ) + .prependTo(uiDialog), + + uiDialogTitlebarClose = $('') + .addClass( + 'ui-dialog-titlebar-close ' + + 'ui-corner-all' + ) + .attr('role', 'button') + .hover( + function() { + uiDialogTitlebarClose.addClass('ui-state-hover'); + }, + function() { + uiDialogTitlebarClose.removeClass('ui-state-hover'); + } + ) + .focus(function() { + uiDialogTitlebarClose.addClass('ui-state-focus'); + }) + .blur(function() { + uiDialogTitlebarClose.removeClass('ui-state-focus'); + }) + .click(function(event) { + self.close(event); + return false; + }) + .appendTo(uiDialogTitlebar), + + uiDialogTitlebarCloseText = (self.uiDialogTitlebarCloseText = $('')) + .addClass( + 'ui-icon ' + + 'ui-icon-closethick' + ) + .text(options.closeText) + .appendTo(uiDialogTitlebarClose), + + uiDialogTitle = $('') + .addClass('ui-dialog-title') + .attr('id', titleId) + .html(title) + .prependTo(uiDialogTitlebar); + + //handling of deprecated beforeclose (vs beforeClose) option + //Ticket #4669 http://dev.jqueryui.com/ticket/4669 + //TODO: remove in 1.9pre + if ($.isFunction(options.beforeclose) && !$.isFunction(options.beforeClose)) { + options.beforeClose = options.beforeclose; + } + + uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection(); + + if (options.draggable && $.fn.draggable) { + self._makeDraggable(); + } + if (options.resizable && $.fn.resizable) { + self._makeResizable(); + } + + self._createButtons(options.buttons); + self._isOpen = false; + + if ($.fn.bgiframe) { + uiDialog.bgiframe(); + } + }, + + _init: function() { + if ( this.options.autoOpen ) { + this.open(); + } + }, + + destroy: function() { + var self = this; + + if (self.overlay) { + self.overlay.destroy(); + } + self.uiDialog.hide(); + self.element + .unbind('.dialog') + .removeData('dialog') + .removeClass('ui-dialog-content ui-widget-content') + .hide().appendTo('body'); + self.uiDialog.remove(); + + if (self.originalTitle) { + self.element.attr('title', self.originalTitle); + } + + return self; + }, + + widget: function() { + return this.uiDialog; + }, + + close: function(event) { + var self = this, + maxZ, thisZ; + + if (false === self._trigger('beforeClose', event)) { + return; + } + + if (self.overlay) { + self.overlay.destroy(); + } + self.uiDialog.unbind('keypress.ui-dialog'); + + self._isOpen = false; + + if (self.options.hide) { + self.uiDialog.hide(self.options.hide, function() { + self._trigger('close', event); + }); + } else { + self.uiDialog.hide(); + self._trigger('close', event); + } + + $.ui.dialog.overlay.resize(); + + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) + if (self.options.modal) { + maxZ = 0; + $('.ui-dialog').each(function() { + if (this !== self.uiDialog[0]) { + thisZ = $(this).css('z-index'); + if(!isNaN(thisZ)) { + maxZ = Math.max(maxZ, thisZ); + } + } + }); + $.ui.dialog.maxZ = maxZ; + } + + return self; + }, + + isOpen: function() { + return this._isOpen; + }, + + // the force parameter allows us to move modal dialogs to their correct + // position on open + moveToTop: function(force, event) { + var self = this, + options = self.options, + saveScroll; + + if ((options.modal && !force) || + (!options.stack && !options.modal)) { + return self._trigger('focus', event); + } + + if (options.zIndex > $.ui.dialog.maxZ) { + $.ui.dialog.maxZ = options.zIndex; + } + if (self.overlay) { + $.ui.dialog.maxZ += 1; + self.overlay.$el.css('z-index', $.ui.dialog.overlay.maxZ = $.ui.dialog.maxZ); + } + + //Save and then restore scroll since Opera 9.5+ resets when parent z-Index is changed. + // http://ui.jquery.com/bugs/ticket/3193 + saveScroll = { scrollTop: self.element.scrollTop(), scrollLeft: self.element.scrollLeft() }; + $.ui.dialog.maxZ += 1; + self.uiDialog.css('z-index', $.ui.dialog.maxZ); + self.element.attr(saveScroll); + self._trigger('focus', event); + + return self; + }, + + open: function() { + if (this._isOpen) { return; } + + var self = this, + options = self.options, + uiDialog = self.uiDialog; + + self.overlay = options.modal ? new $.ui.dialog.overlay(self) : null; + self._size(); + self._position(options.position); + uiDialog.show(options.show); + self.moveToTop(true); + + // prevent tabbing out of modal dialogs + if (options.modal) { + uiDialog.bind('keypress.ui-dialog', function(event) { + if (event.keyCode !== $.ui.keyCode.TAB) { + return; + } + + var tabbables = $(':tabbable', this), + first = tabbables.filter(':first'), + last = tabbables.filter(':last'); + + if (event.target === last[0] && !event.shiftKey) { + first.focus(1); + return false; + } else if (event.target === first[0] && event.shiftKey) { + last.focus(1); + return false; + } + }); + } + + // set focus to the first tabbable element in the content area or the first button + // if there are no tabbable elements, set focus on the dialog itself + $(self.element.find(':tabbable').get().concat( + uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat( + uiDialog.get()))).eq(0).focus(); + + self._isOpen = true; + self._trigger('open'); + + return self; + }, + + _createButtons: function(buttons) { + var self = this, + hasButtons = false, + uiDialogButtonPane = $('
          ') + .addClass( + 'ui-dialog-buttonpane ' + + 'ui-widget-content ' + + 'ui-helper-clearfix' + ), + uiButtonSet = $( "
          " ) + .addClass( "ui-dialog-buttonset" ) + .appendTo( uiDialogButtonPane ); + + // if we already have a button pane, remove it + self.uiDialog.find('.ui-dialog-buttonpane').remove(); + + if (typeof buttons === 'object' && buttons !== null) { + $.each(buttons, function() { + return !(hasButtons = true); + }); + } + if (hasButtons) { + $.each(buttons, function(name, props) { + props = $.isFunction( props ) ? + { click: props, text: name } : + props; + var button = $('') + .click(function() { + props.click.apply(self.element[0], arguments); + }) + .appendTo(uiButtonSet); + // can't use .attr( props, true ) with jQuery 1.3.2. + $.each( props, function( key, value ) { + if ( key === "click" ) { + return; + } + if ( key in attrFn ) { + button[ key ]( value ); + } else { + button.attr( key, value ); + } + }); + if ($.fn.button) { + button.button(); + } + }); + uiDialogButtonPane.appendTo(self.uiDialog); + } + }, + + _makeDraggable: function() { + var self = this, + options = self.options, + doc = $(document), + heightBeforeDrag; + + function filteredUi(ui) { + return { + position: ui.position, + offset: ui.offset + }; + } + + self.uiDialog.draggable({ + cancel: '.ui-dialog-content, .ui-dialog-titlebar-close', + handle: '.ui-dialog-titlebar', + containment: 'document', + start: function(event, ui) { + heightBeforeDrag = options.height === "auto" ? "auto" : $(this).height(); + $(this).height($(this).height()).addClass("ui-dialog-dragging"); + self._trigger('dragStart', event, filteredUi(ui)); + }, + drag: function(event, ui) { + self._trigger('drag', event, filteredUi(ui)); + }, + stop: function(event, ui) { + options.position = [ui.position.left - doc.scrollLeft(), + ui.position.top - doc.scrollTop()]; + $(this).removeClass("ui-dialog-dragging").height(heightBeforeDrag); + self._trigger('dragStop', event, filteredUi(ui)); + $.ui.dialog.overlay.resize(); + } + }); + }, + + _makeResizable: function(handles) { + handles = (handles === undefined ? this.options.resizable : handles); + var self = this, + options = self.options, + // .ui-resizable has position: relative defined in the stylesheet + // but dialogs have to use absolute or fixed positioning + position = self.uiDialog.css('position'), + resizeHandles = (typeof handles === 'string' ? + handles : + 'n,e,s,w,se,sw,ne,nw' + ); + + function filteredUi(ui) { + return { + originalPosition: ui.originalPosition, + originalSize: ui.originalSize, + position: ui.position, + size: ui.size + }; + } + + self.uiDialog.resizable({ + cancel: '.ui-dialog-content', + containment: 'document', + alsoResize: self.element, + maxWidth: options.maxWidth, + maxHeight: options.maxHeight, + minWidth: options.minWidth, + minHeight: self._minHeight(), + handles: resizeHandles, + start: function(event, ui) { + $(this).addClass("ui-dialog-resizing"); + self._trigger('resizeStart', event, filteredUi(ui)); + }, + resize: function(event, ui) { + self._trigger('resize', event, filteredUi(ui)); + }, + stop: function(event, ui) { + $(this).removeClass("ui-dialog-resizing"); + options.height = $(this).height(); + options.width = $(this).width(); + self._trigger('resizeStop', event, filteredUi(ui)); + $.ui.dialog.overlay.resize(); + } + }) + .css('position', position) + .find('.ui-resizable-se').addClass('ui-icon ui-icon-grip-diagonal-se'); + }, + + _minHeight: function() { + var options = this.options; + + if (options.height === 'auto') { + return options.minHeight; + } else { + return Math.min(options.minHeight, options.height); + } + }, + + _position: function(position) { + var myAt = [], + offset = [0, 0], + isVisible; + + if (position) { + // deep extending converts arrays to objects in jQuery <= 1.3.2 :-( + // if (typeof position == 'string' || $.isArray(position)) { + // myAt = $.isArray(position) ? position : position.split(' '); + + if (typeof position === 'string' || (typeof position === 'object' && '0' in position)) { + myAt = position.split ? position.split(' ') : [position[0], position[1]]; + if (myAt.length === 1) { + myAt[1] = myAt[0]; + } + + $.each(['left', 'top'], function(i, offsetPosition) { + if (+myAt[i] === myAt[i]) { + offset[i] = myAt[i]; + myAt[i] = offsetPosition; + } + }); + + position = { + my: myAt.join(" "), + at: myAt.join(" "), + offset: offset.join(" ") + }; + } + + position = $.extend({}, $.ui.dialog.prototype.options.position, position); + } else { + position = $.ui.dialog.prototype.options.position; + } + + // need to show the dialog to get the actual offset in the position plugin + isVisible = this.uiDialog.is(':visible'); + if (!isVisible) { + this.uiDialog.show(); + } + this.uiDialog + // workaround for jQuery bug #5781 http://dev.jquery.com/ticket/5781 + .css({ top: 0, left: 0 }) + .position($.extend({ of: window }, position)); + if (!isVisible) { + this.uiDialog.hide(); + } + }, + + _setOptions: function( options ) { + var self = this, + resizableOptions = {}, + resize = false; + + $.each( options, function( key, value ) { + self._setOption( key, value ); + + if ( key in sizeRelatedOptions ) { + resize = true; + } + if ( key in resizableRelatedOptions ) { + resizableOptions[ key ] = value; + } + }); + + if ( resize ) { + this._size(); + } + if ( this.uiDialog.is( ":data(resizable)" ) ) { + this.uiDialog.resizable( "option", resizableOptions ); + } + }, + + _setOption: function(key, value){ + var self = this, + uiDialog = self.uiDialog; + + switch (key) { + //handling of deprecated beforeclose (vs beforeClose) option + //Ticket #4669 http://dev.jqueryui.com/ticket/4669 + //TODO: remove in 1.9pre + case "beforeclose": + key = "beforeClose"; + break; + case "buttons": + self._createButtons(value); + break; + case "closeText": + // ensure that we always pass a string + self.uiDialogTitlebarCloseText.text("" + value); + break; + case "dialogClass": + uiDialog + .removeClass(self.options.dialogClass) + .addClass(uiDialogClasses + value); + break; + case "disabled": + if (value) { + uiDialog.addClass('ui-dialog-disabled'); + } else { + uiDialog.removeClass('ui-dialog-disabled'); + } + break; + case "draggable": + var isDraggable = uiDialog.is( ":data(draggable)" ); + if ( isDraggable && !value ) { + uiDialog.draggable( "destroy" ); + } + + if ( !isDraggable && value ) { + self._makeDraggable(); + } + break; + case "position": + self._position(value); + break; + case "resizable": + // currently resizable, becoming non-resizable + var isResizable = uiDialog.is( ":data(resizable)" ); + if (isResizable && !value) { + uiDialog.resizable('destroy'); + } + + // currently resizable, changing handles + if (isResizable && typeof value === 'string') { + uiDialog.resizable('option', 'handles', value); + } + + // currently non-resizable, becoming resizable + if (!isResizable && value !== false) { + self._makeResizable(value); + } + break; + case "title": + // convert whatever was passed in o a string, for html() to not throw up + $(".ui-dialog-title", self.uiDialogTitlebar).html("" + (value || ' ')); + break; + } + + $.Widget.prototype._setOption.apply(self, arguments); + }, + + _size: function() { + /* If the user has resized the dialog, the .ui-dialog and .ui-dialog-content + * divs will both have width and height set, so we need to reset them + */ + var options = this.options, + nonContentHeight, + minContentHeight, + isVisible = this.uiDialog.is( ":visible" ); + + // reset content sizing + this.element.show().css({ + width: 'auto', + minHeight: 0, + height: 0 + }); + + if (options.minWidth > options.width) { + options.width = options.minWidth; + } + + // reset wrapper sizing + // determine the height of all the non-content elements + nonContentHeight = this.uiDialog.css({ + height: 'auto', + width: options.width + }) + .height(); + minContentHeight = Math.max( 0, options.minHeight - nonContentHeight ); + + if ( options.height === "auto" ) { + // only needed for IE6 support + if ( $.support.minHeight ) { + this.element.css({ + minHeight: minContentHeight, + height: "auto" + }); + } else { + this.uiDialog.show(); + var autoHeight = this.element.css( "height", "auto" ).height(); + if ( !isVisible ) { + this.uiDialog.hide(); + } + this.element.height( Math.max( autoHeight, minContentHeight ) ); + } + } else { + this.element.height( Math.max( options.height - nonContentHeight, 0 ) ); + } + + if (this.uiDialog.is(':data(resizable)')) { + this.uiDialog.resizable('option', 'minHeight', this._minHeight()); + } + } +}); + +$.extend($.ui.dialog, { + version: "1.8.16", + + uuid: 0, + maxZ: 0, + + getTitleId: function($el) { + var id = $el.attr('id'); + if (!id) { + this.uuid += 1; + id = this.uuid; + } + return 'ui-dialog-title-' + id; + }, + + overlay: function(dialog) { + this.$el = $.ui.dialog.overlay.create(dialog); + } +}); + +$.extend($.ui.dialog.overlay, { + instances: [], + // reuse old instances due to IE memory leak with alpha transparency (see #5185) + oldInstances: [], + maxZ: 0, + events: $.map('focus,mousedown,mouseup,keydown,keypress,click'.split(','), + function(event) { return event + '.dialog-overlay'; }).join(' '), + create: function(dialog) { + if (this.instances.length === 0) { + // prevent use of anchors and inputs + // we use a setTimeout in case the overlay is created from an + // event that we're going to be cancelling (see #2804) + setTimeout(function() { + // handle $(el).dialog().dialog('close') (see #4065) + if ($.ui.dialog.overlay.instances.length) { + $(document).bind($.ui.dialog.overlay.events, function(event) { + // stop events if the z-index of the target is < the z-index of the overlay + // we cannot return true when we don't want to cancel the event (#3523) + if ($(event.target).zIndex() < $.ui.dialog.overlay.maxZ) { + return false; + } + }); + } + }, 1); + + // allow closing by pressing the escape key + $(document).bind('keydown.dialog-overlay', function(event) { + if (dialog.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode && + event.keyCode === $.ui.keyCode.ESCAPE) { + + dialog.close(event); + event.preventDefault(); + } + }); + + // handle window resize + $(window).bind('resize.dialog-overlay', $.ui.dialog.overlay.resize); + } + + var $el = (this.oldInstances.pop() || $('
          ').addClass('ui-widget-overlay')) + .appendTo(document.body) + .css({ + width: this.width(), + height: this.height() + }); + + if ($.fn.bgiframe) { + $el.bgiframe(); + } + + this.instances.push($el); + return $el; + }, + + destroy: function($el) { + var indexOf = $.inArray($el, this.instances); + if (indexOf != -1){ + this.oldInstances.push(this.instances.splice(indexOf, 1)[0]); + } + + if (this.instances.length === 0) { + $([document, window]).unbind('.dialog-overlay'); + } + + $el.remove(); + + // adjust the maxZ to allow other modal dialogs to continue to work (see #4309) + var maxZ = 0; + $.each(this.instances, function() { + maxZ = Math.max(maxZ, this.css('z-index')); + }); + this.maxZ = maxZ; + }, + + height: function() { + var scrollHeight, + offsetHeight; + // handle IE 6 + if ($.browser.msie && $.browser.version < 7) { + scrollHeight = Math.max( + document.documentElement.scrollHeight, + document.body.scrollHeight + ); + offsetHeight = Math.max( + document.documentElement.offsetHeight, + document.body.offsetHeight + ); + + if (scrollHeight < offsetHeight) { + return $(window).height() + 'px'; + } else { + return scrollHeight + 'px'; + } + // handle "good" browsers + } else { + return $(document).height() + 'px'; + } + }, + + width: function() { + var scrollWidth, + offsetWidth; + // handle IE + if ( $.browser.msie ) { + scrollWidth = Math.max( + document.documentElement.scrollWidth, + document.body.scrollWidth + ); + offsetWidth = Math.max( + document.documentElement.offsetWidth, + document.body.offsetWidth + ); + + if (scrollWidth < offsetWidth) { + return $(window).width() + 'px'; + } else { + return scrollWidth + 'px'; + } + // handle "good" browsers + } else { + return $(document).width() + 'px'; + } + }, + + resize: function() { + /* If the dialog is draggable and the user drags it past the + * right edge of the window, the document becomes wider so we + * need to stretch the overlay. If the user then drags the + * dialog back to the left, the document will become narrower, + * so we need to shrink the overlay to the appropriate size. + * This is handled by shrinking the overlay before setting it + * to the full document size. + */ + var $overlays = $([]); + $.each($.ui.dialog.overlay.instances, function() { + $overlays = $overlays.add(this); + }); + + $overlays.css({ + width: 0, + height: 0 + }).css({ + width: $.ui.dialog.overlay.width(), + height: $.ui.dialog.overlay.height() + }); + } +}); + +$.extend($.ui.dialog.overlay.prototype, { + destroy: function() { + $.ui.dialog.overlay.destroy(this.$el); + } +}); + +}(jQuery)); +/* + * jQuery UI Position 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */ +(function( $, undefined ) { + +$.ui = $.ui || {}; + +var horizontalPositions = /left|center|right/, + verticalPositions = /top|center|bottom/, + center = "center", + _position = $.fn.position, + _offset = $.fn.offset; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var target = $( options.of ), + targetElem = target[0], + collision = ( options.collision || "flip" ).split( " " ), + offset = options.offset ? options.offset.split( " " ) : [ 0, 0 ], + targetWidth, + targetHeight, + basePosition; + + if ( targetElem.nodeType === 9 ) { + targetWidth = target.width(); + targetHeight = target.height(); + basePosition = { top: 0, left: 0 }; + // TODO: use $.isWindow() in 1.9 + } else if ( targetElem.setTimeout ) { + targetWidth = target.width(); + targetHeight = target.height(); + basePosition = { top: target.scrollTop(), left: target.scrollLeft() }; + } else if ( targetElem.preventDefault ) { + // force left top to allow flipping + options.at = "left top"; + targetWidth = targetHeight = 0; + basePosition = { top: options.of.pageY, left: options.of.pageX }; + } else { + targetWidth = target.outerWidth(); + targetHeight = target.outerHeight(); + basePosition = target.offset(); + } + + // force my and at to have valid horizontal and veritcal positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[this] || "" ).split( " " ); + if ( pos.length === 1) { + pos = horizontalPositions.test( pos[0] ) ? + pos.concat( [center] ) : + verticalPositions.test( pos[0] ) ? + [ center ].concat( pos ) : + [ center, center ]; + } + pos[ 0 ] = horizontalPositions.test( pos[0] ) ? pos[ 0 ] : center; + pos[ 1 ] = verticalPositions.test( pos[1] ) ? pos[ 1 ] : center; + options[ this ] = pos; + }); + + // normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + // normalize offset option + offset[ 0 ] = parseInt( offset[0], 10 ) || 0; + if ( offset.length === 1 ) { + offset[ 1 ] = offset[ 0 ]; + } + offset[ 1 ] = parseInt( offset[1], 10 ) || 0; + + if ( options.at[0] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[0] === center ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[1] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[1] === center ) { + basePosition.top += targetHeight / 2; + } + + basePosition.left += offset[ 0 ]; + basePosition.top += offset[ 1 ]; + + return this.each(function() { + var elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseInt( $.curCSS( this, "marginLeft", true ) ) || 0, + marginTop = parseInt( $.curCSS( this, "marginTop", true ) ) || 0, + collisionWidth = elemWidth + marginLeft + + ( parseInt( $.curCSS( this, "marginRight", true ) ) || 0 ), + collisionHeight = elemHeight + marginTop + + ( parseInt( $.curCSS( this, "marginBottom", true ) ) || 0 ), + position = $.extend( {}, basePosition ), + collisionPosition; + + if ( options.my[0] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[0] === center ) { + position.left -= elemWidth / 2; + } + + if ( options.my[1] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[1] === center ) { + position.top -= elemHeight / 2; + } + + // prevent fractions (see #5280) + position.left = Math.round( position.left ); + position.top = Math.round( position.top ); + + collisionPosition = { + left: position.left - marginLeft, + top: position.top - marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[i] ] ) { + $.ui.position[ collision[i] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: offset, + my: options.my, + at: options.at + }); + } + }); + + if ( $.fn.bgiframe ) { + elem.bgiframe(); + } + elem.offset( $.extend( position, { using: options.using } ) ); + }); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var win = $( window ), + over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(); + position.left = over > 0 ? position.left - over : Math.max( position.left - data.collisionPosition.left, position.left ); + }, + top: function( position, data ) { + var win = $( window ), + over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(); + position.top = over > 0 ? position.top - over : Math.max( position.top - data.collisionPosition.top, position.top ); + } + }, + + flip: { + left: function( position, data ) { + if ( data.at[0] === center ) { + return; + } + var win = $( window ), + over = data.collisionPosition.left + data.collisionWidth - win.width() - win.scrollLeft(), + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + -data.targetWidth, + offset = -2 * data.offset[ 0 ]; + position.left += data.collisionPosition.left < 0 ? + myOffset + atOffset + offset : + over > 0 ? + myOffset + atOffset + offset : + 0; + }, + top: function( position, data ) { + if ( data.at[1] === center ) { + return; + } + var win = $( window ), + over = data.collisionPosition.top + data.collisionHeight - win.height() - win.scrollTop(), + myOffset = data.my[ 1 ] === "top" ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + -data.targetHeight, + offset = -2 * data.offset[ 1 ]; + position.top += data.collisionPosition.top < 0 ? + myOffset + atOffset + offset : + over > 0 ? + myOffset + atOffset + offset : + 0; + } + } +}; + +// offset setter from jQuery 1.4 +if ( !$.offset.setOffset ) { + $.offset.setOffset = function( elem, options ) { + // set position first, in-case top/left are set even on static elem + if ( /static/.test( $.curCSS( elem, "position" ) ) ) { + elem.style.position = "relative"; + } + var curElem = $( elem ), + curOffset = curElem.offset(), + curTop = parseInt( $.curCSS( elem, "top", true ), 10 ) || 0, + curLeft = parseInt( $.curCSS( elem, "left", true ), 10) || 0, + props = { + top: (options.top - curOffset.top) + curTop, + left: (options.left - curOffset.left) + curLeft + }; + + if ( 'using' in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + }; + + $.fn.offset = function( options ) { + var elem = this[ 0 ]; + if ( !elem || !elem.ownerDocument ) { return null; } + if ( options ) { + return this.each(function() { + $.offset.setOffset( this, options ); + }); + } + return _offset.call( this ); + }; +} + +}( jQuery )); +/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +$.widget( "ui.progressbar", { + options: { + value: 0, + max: 100 + }, + + min: 0, + + _create: function() { + this.element + .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .attr({ + role: "progressbar", + "aria-valuemin": this.min, + "aria-valuemax": this.options.max, + "aria-valuenow": this._value() + }); + + this.valueDiv = $( "
          " ) + .appendTo( this.element ); + + this.oldValue = this._value(); + this._refreshValue(); + }, + + destroy: function() { + this.element + .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" ) + .removeAttr( "role" ) + .removeAttr( "aria-valuemin" ) + .removeAttr( "aria-valuemax" ) + .removeAttr( "aria-valuenow" ); + + this.valueDiv.remove(); + + $.Widget.prototype.destroy.apply( this, arguments ); + }, + + value: function( newValue ) { + if ( newValue === undefined ) { + return this._value(); + } + + this._setOption( "value", newValue ); + return this; + }, + + _setOption: function( key, value ) { + if ( key === "value" ) { + this.options.value = value; + this._refreshValue(); + if ( this._value() === this.options.max ) { + this._trigger( "complete" ); + } + } + + $.Widget.prototype._setOption.apply( this, arguments ); + }, + + _value: function() { + var val = this.options.value; + // normalize invalid value + if ( typeof val !== "number" ) { + val = 0; + } + return Math.min( this.options.max, Math.max( this.min, val ) ); + }, + + _percentage: function() { + return 100 * this._value() / this.options.max; + }, + + _refreshValue: function() { + var value = this.value(); + var percentage = this._percentage(); + + if ( this.oldValue !== value ) { + this.oldValue = value; + this._trigger( "change" ); + } + + this.valueDiv + .toggle( value > this.min ) + .toggleClass( "ui-corner-right", value === this.options.max ) + .width( percentage.toFixed(0) + "%" ); + this.element.attr( "aria-valuenow", value ); + } +}); + +$.extend( $.ui.progressbar, { + version: "1.8.16" +}); + +})( jQuery ); +/* + * jQuery UI Slider 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Slider + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +// number of pages in a slider +// (how many times can you page up/down to go through the whole range) +var numPages = 5; + +$.widget( "ui.slider", $.ui.mouse, { + + widgetEventPrefix: "slide", + + options: { + animate: false, + distance: 0, + max: 100, + min: 0, + orientation: "horizontal", + range: false, + step: 1, + value: 0, + values: null + }, + + _create: function() { + var self = this, + o = this.options, + existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ), + handle = "", + handleCount = ( o.values && o.values.length ) || 1, + handles = []; + + this._keySliding = false; + this._mouseSliding = false; + this._animateOff = true; + this._handleIndex = null; + this._detectOrientation(); + this._mouseInit(); + + this.element + .addClass( "ui-slider" + + " ui-slider-" + this.orientation + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" + + ( o.disabled ? " ui-slider-disabled ui-disabled" : "" ) ); + + this.range = $([]); + + if ( o.range ) { + if ( o.range === true ) { + if ( !o.values ) { + o.values = [ this._valueMin(), this._valueMin() ]; + } + if ( o.values.length && o.values.length !== 2 ) { + o.values = [ o.values[0], o.values[0] ]; + } + } + + this.range = $( "
          " ) + .appendTo( this.element ) + .addClass( "ui-slider-range" + + // note: this isn't the most fittingly semantic framework class for this element, + // but worked best visually with a variety of themes + " ui-widget-header" + + ( ( o.range === "min" || o.range === "max" ) ? " ui-slider-range-" + o.range : "" ) ); + } + + for ( var i = existingHandles.length; i < handleCount; i += 1 ) { + handles.push( handle ); + } + + this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( self.element ) ); + + this.handle = this.handles.eq( 0 ); + + this.handles.add( this.range ).filter( "a" ) + .click(function( event ) { + event.preventDefault(); + }) + .hover(function() { + if ( !o.disabled ) { + $( this ).addClass( "ui-state-hover" ); + } + }, function() { + $( this ).removeClass( "ui-state-hover" ); + }) + .focus(function() { + if ( !o.disabled ) { + $( ".ui-slider .ui-state-focus" ).removeClass( "ui-state-focus" ); + $( this ).addClass( "ui-state-focus" ); + } else { + $( this ).blur(); + } + }) + .blur(function() { + $( this ).removeClass( "ui-state-focus" ); + }); + + this.handles.each(function( i ) { + $( this ).data( "index.ui-slider-handle", i ); + }); + + this.handles + .keydown(function( event ) { + var ret = true, + index = $( this ).data( "index.ui-slider-handle" ), + allowed, + curVal, + newVal, + step; + + if ( self.options.disabled ) { + return; + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + case $.ui.keyCode.END: + case $.ui.keyCode.PAGE_UP: + case $.ui.keyCode.PAGE_DOWN: + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + ret = false; + if ( !self._keySliding ) { + self._keySliding = true; + $( this ).addClass( "ui-state-active" ); + allowed = self._start( event, index ); + if ( allowed === false ) { + return; + } + } + break; + } + + step = self.options.step; + if ( self.options.values && self.options.values.length ) { + curVal = newVal = self.values( index ); + } else { + curVal = newVal = self.value(); + } + + switch ( event.keyCode ) { + case $.ui.keyCode.HOME: + newVal = self._valueMin(); + break; + case $.ui.keyCode.END: + newVal = self._valueMax(); + break; + case $.ui.keyCode.PAGE_UP: + newVal = self._trimAlignValue( curVal + ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.PAGE_DOWN: + newVal = self._trimAlignValue( curVal - ( (self._valueMax() - self._valueMin()) / numPages ) ); + break; + case $.ui.keyCode.UP: + case $.ui.keyCode.RIGHT: + if ( curVal === self._valueMax() ) { + return; + } + newVal = self._trimAlignValue( curVal + step ); + break; + case $.ui.keyCode.DOWN: + case $.ui.keyCode.LEFT: + if ( curVal === self._valueMin() ) { + return; + } + newVal = self._trimAlignValue( curVal - step ); + break; + } + + self._slide( event, index, newVal ); + + return ret; + + }) + .keyup(function( event ) { + var index = $( this ).data( "index.ui-slider-handle" ); + + if ( self._keySliding ) { + self._keySliding = false; + self._stop( event, index ); + self._change( event, index ); + $( this ).removeClass( "ui-state-active" ); + } + + }); + + this._refreshValue(); + + this._animateOff = false; + }, + + destroy: function() { + this.handles.remove(); + this.range.remove(); + + this.element + .removeClass( "ui-slider" + + " ui-slider-horizontal" + + " ui-slider-vertical" + + " ui-slider-disabled" + + " ui-widget" + + " ui-widget-content" + + " ui-corner-all" ) + .removeData( "slider" ) + .unbind( ".slider" ); + + this._mouseDestroy(); + + return this; + }, + + _mouseCapture: function( event ) { + var o = this.options, + position, + normValue, + distance, + closestHandle, + self, + index, + allowed, + offset, + mouseOverHandle; + + if ( o.disabled ) { + return false; + } + + this.elementSize = { + width: this.element.outerWidth(), + height: this.element.outerHeight() + }; + this.elementOffset = this.element.offset(); + + position = { x: event.pageX, y: event.pageY }; + normValue = this._normValueFromMouse( position ); + distance = this._valueMax() - this._valueMin() + 1; + self = this; + this.handles.each(function( i ) { + var thisDistance = Math.abs( normValue - self.values(i) ); + if ( distance > thisDistance ) { + distance = thisDistance; + closestHandle = $( this ); + index = i; + } + }); + + // workaround for bug #3736 (if both handles of a range are at 0, + // the first is always used as the one with least distance, + // and moving it is obviously prevented by preventing negative ranges) + if( o.range === true && this.values(1) === o.min ) { + index += 1; + closestHandle = $( this.handles[index] ); + } + + allowed = this._start( event, index ); + if ( allowed === false ) { + return false; + } + this._mouseSliding = true; + + self._handleIndex = index; + + closestHandle + .addClass( "ui-state-active" ) + .focus(); + + offset = closestHandle.offset(); + mouseOverHandle = !$( event.target ).parents().andSelf().is( ".ui-slider-handle" ); + this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : { + left: event.pageX - offset.left - ( closestHandle.width() / 2 ), + top: event.pageY - offset.top - + ( closestHandle.height() / 2 ) - + ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) - + ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) + + ( parseInt( closestHandle.css("marginTop"), 10 ) || 0) + }; + + if ( !this.handles.hasClass( "ui-state-hover" ) ) { + this._slide( event, index, normValue ); + } + this._animateOff = true; + return true; + }, + + _mouseStart: function( event ) { + return true; + }, + + _mouseDrag: function( event ) { + var position = { x: event.pageX, y: event.pageY }, + normValue = this._normValueFromMouse( position ); + + this._slide( event, this._handleIndex, normValue ); + + return false; + }, + + _mouseStop: function( event ) { + this.handles.removeClass( "ui-state-active" ); + this._mouseSliding = false; + + this._stop( event, this._handleIndex ); + this._change( event, this._handleIndex ); + + this._handleIndex = null; + this._clickOffset = null; + this._animateOff = false; + + return false; + }, + + _detectOrientation: function() { + this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal"; + }, + + _normValueFromMouse: function( position ) { + var pixelTotal, + pixelMouse, + percentMouse, + valueTotal, + valueMouse; + + if ( this.orientation === "horizontal" ) { + pixelTotal = this.elementSize.width; + pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 ); + } else { + pixelTotal = this.elementSize.height; + pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 ); + } + + percentMouse = ( pixelMouse / pixelTotal ); + if ( percentMouse > 1 ) { + percentMouse = 1; + } + if ( percentMouse < 0 ) { + percentMouse = 0; + } + if ( this.orientation === "vertical" ) { + percentMouse = 1 - percentMouse; + } + + valueTotal = this._valueMax() - this._valueMin(); + valueMouse = this._valueMin() + percentMouse * valueTotal; + + return this._trimAlignValue( valueMouse ); + }, + + _start: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + return this._trigger( "start", event, uiHash ); + }, + + _slide: function( event, index, newVal ) { + var otherVal, + newValues, + allowed; + + if ( this.options.values && this.options.values.length ) { + otherVal = this.values( index ? 0 : 1 ); + + if ( ( this.options.values.length === 2 && this.options.range === true ) && + ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) ) + ) { + newVal = otherVal; + } + + if ( newVal !== this.values( index ) ) { + newValues = this.values(); + newValues[ index ] = newVal; + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal, + values: newValues + } ); + otherVal = this.values( index ? 0 : 1 ); + if ( allowed !== false ) { + this.values( index, newVal, true ); + } + } + } else { + if ( newVal !== this.value() ) { + // A slide can be canceled by returning false from the slide callback + allowed = this._trigger( "slide", event, { + handle: this.handles[ index ], + value: newVal + } ); + if ( allowed !== false ) { + this.value( newVal ); + } + } + } + }, + + _stop: function( event, index ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "stop", event, uiHash ); + }, + + _change: function( event, index ) { + if ( !this._keySliding && !this._mouseSliding ) { + var uiHash = { + handle: this.handles[ index ], + value: this.value() + }; + if ( this.options.values && this.options.values.length ) { + uiHash.value = this.values( index ); + uiHash.values = this.values(); + } + + this._trigger( "change", event, uiHash ); + } + }, + + value: function( newValue ) { + if ( arguments.length ) { + this.options.value = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, 0 ); + return; + } + + return this._value(); + }, + + values: function( index, newValue ) { + var vals, + newValues, + i; + + if ( arguments.length > 1 ) { + this.options.values[ index ] = this._trimAlignValue( newValue ); + this._refreshValue(); + this._change( null, index ); + return; + } + + if ( arguments.length ) { + if ( $.isArray( arguments[ 0 ] ) ) { + vals = this.options.values; + newValues = arguments[ 0 ]; + for ( i = 0; i < vals.length; i += 1 ) { + vals[ i ] = this._trimAlignValue( newValues[ i ] ); + this._change( null, i ); + } + this._refreshValue(); + } else { + if ( this.options.values && this.options.values.length ) { + return this._values( index ); + } else { + return this.value(); + } + } + } else { + return this._values(); + } + }, + + _setOption: function( key, value ) { + var i, + valsLength = 0; + + if ( $.isArray( this.options.values ) ) { + valsLength = this.options.values.length; + } + + $.Widget.prototype._setOption.apply( this, arguments ); + + switch ( key ) { + case "disabled": + if ( value ) { + this.handles.filter( ".ui-state-focus" ).blur(); + this.handles.removeClass( "ui-state-hover" ); + this.handles.propAttr( "disabled", true ); + this.element.addClass( "ui-disabled" ); + } else { + this.handles.propAttr( "disabled", false ); + this.element.removeClass( "ui-disabled" ); + } + break; + case "orientation": + this._detectOrientation(); + this.element + .removeClass( "ui-slider-horizontal ui-slider-vertical" ) + .addClass( "ui-slider-" + this.orientation ); + this._refreshValue(); + break; + case "value": + this._animateOff = true; + this._refreshValue(); + this._change( null, 0 ); + this._animateOff = false; + break; + case "values": + this._animateOff = true; + this._refreshValue(); + for ( i = 0; i < valsLength; i += 1 ) { + this._change( null, i ); + } + this._animateOff = false; + break; + } + }, + + //internal value getter + // _value() returns value trimmed by min and max, aligned by step + _value: function() { + var val = this.options.value; + val = this._trimAlignValue( val ); + + return val; + }, + + //internal values getter + // _values() returns array of values trimmed by min and max, aligned by step + // _values( index ) returns single value trimmed by min and max, aligned by step + _values: function( index ) { + var val, + vals, + i; + + if ( arguments.length ) { + val = this.options.values[ index ]; + val = this._trimAlignValue( val ); + + return val; + } else { + // .slice() creates a copy of the array + // this copy gets trimmed by min and max and then returned + vals = this.options.values.slice(); + for ( i = 0; i < vals.length; i+= 1) { + vals[ i ] = this._trimAlignValue( vals[ i ] ); + } + + return vals; + } + }, + + // returns the step-aligned value that val is closest to, between (inclusive) min and max + _trimAlignValue: function( val ) { + if ( val <= this._valueMin() ) { + return this._valueMin(); + } + if ( val >= this._valueMax() ) { + return this._valueMax(); + } + var step = ( this.options.step > 0 ) ? this.options.step : 1, + valModStep = (val - this._valueMin()) % step, + alignValue = val - valModStep; + + if ( Math.abs(valModStep) * 2 >= step ) { + alignValue += ( valModStep > 0 ) ? step : ( -step ); + } + + // Since JavaScript has problems with large floats, round + // the final value to 5 digits after the decimal point (see #4124) + return parseFloat( alignValue.toFixed(5) ); + }, + + _valueMin: function() { + return this.options.min; + }, + + _valueMax: function() { + return this.options.max; + }, + + _refreshValue: function() { + var oRange = this.options.range, + o = this.options, + self = this, + animate = ( !this._animateOff ) ? o.animate : false, + valPercent, + _set = {}, + lastValPercent, + value, + valueMin, + valueMax; + + if ( this.options.values && this.options.values.length ) { + this.handles.each(function( i, j ) { + valPercent = ( self.values(i) - self._valueMin() ) / ( self._valueMax() - self._valueMin() ) * 100; + _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + if ( self.options.range === true ) { + if ( self.orientation === "horizontal" ) { + if ( i === 0 ) { + self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); + } + if ( i === 1 ) { + self.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } else { + if ( i === 0 ) { + self.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); + } + if ( i === 1 ) { + self.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + } + lastValPercent = valPercent; + }); + } else { + value = this.value(); + valueMin = this._valueMin(); + valueMax = this._valueMax(); + valPercent = ( valueMax !== valueMin ) ? + ( value - valueMin ) / ( valueMax - valueMin ) * 100 : + 0; + _set[ self.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; + this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); + + if ( oRange === "min" && this.orientation === "horizontal" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "horizontal" ) { + this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + if ( oRange === "min" && this.orientation === "vertical" ) { + this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate ); + } + if ( oRange === "max" && this.orientation === "vertical" ) { + this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } ); + } + } + } + +}); + +$.extend( $.ui.slider, { + version: "1.8.16" +}); + +}(jQuery)); +/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function( $, undefined ) { + +var tabId = 0, + listId = 0; + +function getNextTabId() { + return ++tabId; +} + +function getNextListId() { + return ++listId; +} + +$.widget( "ui.tabs", { + options: { + add: null, + ajaxOptions: null, + cache: false, + cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true } + collapsible: false, + disable: null, + disabled: [], + enable: null, + event: "click", + fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } + idPrefix: "ui-tabs-", + load: null, + panelTemplate: "
          ", + remove: null, + select: null, + show: null, + spinner: "Loading…", + tabTemplate: "
        • #{label}
        • " + }, + + _create: function() { + this._tabify( true ); + }, + + _setOption: function( key, value ) { + if ( key == "selected" ) { + if (this.options.collapsible && value == this.options.selected ) { + return; + } + this.select( value ); + } else { + this.options[ key ] = value; + this._tabify(); + } + }, + + _tabId: function( a ) { + return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) || + this.options.idPrefix + getNextTabId(); + }, + + _sanitizeSelector: function( hash ) { + // we need this because an id may contain a ":" + return hash.replace( /:/g, "\\:" ); + }, + + _cookie: function() { + var cookie = this.cookie || + ( this.cookie = this.options.cookie.name || "ui-tabs-" + getNextListId() ); + return $.cookie.apply( null, [ cookie ].concat( $.makeArray( arguments ) ) ); + }, + + _ui: function( tab, panel ) { + return { + tab: tab, + panel: panel, + index: this.anchors.index( tab ) + }; + }, + + _cleanup: function() { + // restore all former loading tabs labels + this.lis.filter( ".ui-state-processing" ) + .removeClass( "ui-state-processing" ) + .find( "span:data(label.tabs)" ) + .each(function() { + var el = $( this ); + el.html( el.data( "label.tabs" ) ).removeData( "label.tabs" ); + }); + }, + + _tabify: function( init ) { + var self = this, + o = this.options, + fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash + + this.list = this.element.find( "ol,ul" ).eq( 0 ); + this.lis = $( " > li:has(a[href])", this.list ); + this.anchors = this.lis.map(function() { + return $( "a", this )[ 0 ]; + }); + this.panels = $( [] ); + + this.anchors.each(function( i, a ) { + var href = $( a ).attr( "href" ); + // For dynamically created HTML that contains a hash as href IE < 8 expands + // such href to the full page url with hash and then misinterprets tab as ajax. + // Same consideration applies for an added tab with a fragment identifier + // since a[href=#fragment-identifier] does unexpectedly not match. + // Thus normalize href attribute... + var hrefBase = href.split( "#" )[ 0 ], + baseEl; + if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || + ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { + href = a.hash; + a.href = href; + } + + // inline tab + if ( fragmentId.test( href ) ) { + self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) ); + // remote tab + // prevent loading the page itself if href is just "#" + } else if ( href && href !== "#" ) { + // required for restore on destroy + $.data( a, "href.tabs", href ); + + // TODO until #3808 is fixed strip fragment identifier from url + // (IE fails to load from such url) + $.data( a, "load.tabs", href.replace( /#.*$/, "" ) ); + + var id = self._tabId( a ); + a.href = "#" + id; + var $panel = self.element.find( "#" + id ); + if ( !$panel.length ) { + $panel = $( o.panelTemplate ) + .attr( "id", id ) + .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ) + .insertAfter( self.panels[ i - 1 ] || self.list ); + $panel.data( "destroy.tabs", true ); + } + self.panels = self.panels.add( $panel ); + // invalid tab href + } else { + o.disabled.push( i ); + } + }); + + // initialization from scratch + if ( init ) { + // attach necessary classes for styling + this.element.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" ); + this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); + this.lis.addClass( "ui-state-default ui-corner-top" ); + this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); + + // Selected tab + // use "selected" option or try to retrieve: + // 1. from fragment identifier in url + // 2. from cookie + // 3. from selected class attribute on
        • + if ( o.selected === undefined ) { + if ( location.hash ) { + this.anchors.each(function( i, a ) { + if ( a.hash == location.hash ) { + o.selected = i; + return false; + } + }); + } + if ( typeof o.selected !== "number" && o.cookie ) { + o.selected = parseInt( self._cookie(), 10 ); + } + if ( typeof o.selected !== "number" && this.lis.filter( ".ui-tabs-selected" ).length ) { + o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); + } + o.selected = o.selected || ( this.lis.length ? 0 : -1 ); + } else if ( o.selected === null ) { // usage of null is deprecated, TODO remove in next release + o.selected = -1; + } + + // sanity check - default to first tab... + o.selected = ( ( o.selected >= 0 && this.anchors[ o.selected ] ) || o.selected < 0 ) + ? o.selected + : 0; + + // Take disabling tabs via class attribute from HTML + // into account and update option properly. + // A selected tab cannot become disabled. + o.disabled = $.unique( o.disabled.concat( + $.map( this.lis.filter( ".ui-state-disabled" ), function( n, i ) { + return self.lis.index( n ); + }) + ) ).sort(); + + if ( $.inArray( o.selected, o.disabled ) != -1 ) { + o.disabled.splice( $.inArray( o.selected, o.disabled ), 1 ); + } + + // highlight selected tab + this.panels.addClass( "ui-tabs-hide" ); + this.lis.removeClass( "ui-tabs-selected ui-state-active" ); + // check for length avoids error when initializing empty list + if ( o.selected >= 0 && this.anchors.length ) { + self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) ).removeClass( "ui-tabs-hide" ); + this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" ); + + // seems to be expected behavior that the show callback is fired + self.element.queue( "tabs", function() { + self._trigger( "show", null, + self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) ); + }); + + this.load( o.selected ); + } + + // clean up to avoid memory leaks in certain versions of IE 6 + // TODO: namespace this event + $( window ).bind( "unload", function() { + self.lis.add( self.anchors ).unbind( ".tabs" ); + self.lis = self.anchors = self.panels = null; + }); + // update selected after add/remove + } else { + o.selected = this.lis.index( this.lis.filter( ".ui-tabs-selected" ) ); + } + + // update collapsible + // TODO: use .toggleClass() + this.element[ o.collapsible ? "addClass" : "removeClass" ]( "ui-tabs-collapsible" ); + + // set or update cookie after init and add/remove respectively + if ( o.cookie ) { + this._cookie( o.selected, o.cookie ); + } + + // disable tabs + for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { + $( li )[ $.inArray( i, o.disabled ) != -1 && + // TODO: use .toggleClass() + !$( li ).hasClass( "ui-tabs-selected" ) ? "addClass" : "removeClass" ]( "ui-state-disabled" ); + } + + // reset cache if switching from cached to not cached + if ( o.cache === false ) { + this.anchors.removeData( "cache.tabs" ); + } + + // remove all handlers before, tabify may run on existing tabs after add or option change + this.lis.add( this.anchors ).unbind( ".tabs" ); + + if ( o.event !== "mouseover" ) { + var addState = function( state, el ) { + if ( el.is( ":not(.ui-state-disabled)" ) ) { + el.addClass( "ui-state-" + state ); + } + }; + var removeState = function( state, el ) { + el.removeClass( "ui-state-" + state ); + }; + this.lis.bind( "mouseover.tabs" , function() { + addState( "hover", $( this ) ); + }); + this.lis.bind( "mouseout.tabs", function() { + removeState( "hover", $( this ) ); + }); + this.anchors.bind( "focus.tabs", function() { + addState( "focus", $( this ).closest( "li" ) ); + }); + this.anchors.bind( "blur.tabs", function() { + removeState( "focus", $( this ).closest( "li" ) ); + }); + } + + // set up animations + var hideFx, showFx; + if ( o.fx ) { + if ( $.isArray( o.fx ) ) { + hideFx = o.fx[ 0 ]; + showFx = o.fx[ 1 ]; + } else { + hideFx = showFx = o.fx; + } + } + + // Reset certain styles left over from animation + // and prevent IE's ClearType bug... + function resetStyle( $el, fx ) { + $el.css( "display", "" ); + if ( !$.support.opacity && fx.opacity ) { + $el[ 0 ].style.removeAttribute( "filter" ); + } + } + + // Show a tab... + var showTab = showFx + ? function( clicked, $show ) { + $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); + $show.hide().removeClass( "ui-tabs-hide" ) // avoid flicker that way + .animate( showFx, showFx.duration || "normal", function() { + resetStyle( $show, showFx ); + self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); + }); + } + : function( clicked, $show ) { + $( clicked ).closest( "li" ).addClass( "ui-tabs-selected ui-state-active" ); + $show.removeClass( "ui-tabs-hide" ); + self._trigger( "show", null, self._ui( clicked, $show[ 0 ] ) ); + }; + + // Hide a tab, $show is optional... + var hideTab = hideFx + ? function( clicked, $hide ) { + $hide.animate( hideFx, hideFx.duration || "normal", function() { + self.lis.removeClass( "ui-tabs-selected ui-state-active" ); + $hide.addClass( "ui-tabs-hide" ); + resetStyle( $hide, hideFx ); + self.element.dequeue( "tabs" ); + }); + } + : function( clicked, $hide, $show ) { + self.lis.removeClass( "ui-tabs-selected ui-state-active" ); + $hide.addClass( "ui-tabs-hide" ); + self.element.dequeue( "tabs" ); + }; + + // attach tab event handler, unbind to avoid duplicates from former tabifying... + this.anchors.bind( o.event + ".tabs", function() { + var el = this, + $li = $(el).closest( "li" ), + $hide = self.panels.filter( ":not(.ui-tabs-hide)" ), + $show = self.element.find( self._sanitizeSelector( el.hash ) ); + + // If tab is already selected and not collapsible or tab disabled or + // or is already loading or click callback returns false stop here. + // Check if click handler returns false last so that it is not executed + // for a disabled or loading tab! + if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible) || + $li.hasClass( "ui-state-disabled" ) || + $li.hasClass( "ui-state-processing" ) || + self.panels.filter( ":animated" ).length || + self._trigger( "select", null, self._ui( this, $show[ 0 ] ) ) === false ) { + this.blur(); + return false; + } + + o.selected = self.anchors.index( this ); + + self.abort(); + + // if tab may be closed + if ( o.collapsible ) { + if ( $li.hasClass( "ui-tabs-selected" ) ) { + o.selected = -1; + + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); + } + + self.element.queue( "tabs", function() { + hideTab( el, $hide ); + }).dequeue( "tabs" ); + + this.blur(); + return false; + } else if ( !$hide.length ) { + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); + } + + self.element.queue( "tabs", function() { + showTab( el, $show ); + }); + + // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171 + self.load( self.anchors.index( this ) ); + + this.blur(); + return false; + } + } + + if ( o.cookie ) { + self._cookie( o.selected, o.cookie ); + } + + // show new tab + if ( $show.length ) { + if ( $hide.length ) { + self.element.queue( "tabs", function() { + hideTab( el, $hide ); + }); + } + self.element.queue( "tabs", function() { + showTab( el, $show ); + }); + + self.load( self.anchors.index( this ) ); + } else { + throw "jQuery UI Tabs: Mismatching fragment identifier."; + } + + // Prevent IE from keeping other link focussed when using the back button + // and remove dotted border from clicked link. This is controlled via CSS + // in modern browsers; blur() removes focus from address bar in Firefox + // which can become a usability and annoying problem with tabs('rotate'). + if ( $.browser.msie ) { + this.blur(); + } + }); + + // disable click in any case + this.anchors.bind( "click.tabs", function(){ + return false; + }); + }, + + _getIndex: function( index ) { + // meta-function to give users option to provide a href string instead of a numerical index. + // also sanitizes numerical indexes to valid values. + if ( typeof index == "string" ) { + index = this.anchors.index( this.anchors.filter( "[href$=" + index + "]" ) ); + } + + return index; + }, + + destroy: function() { + var o = this.options; + + this.abort(); + + this.element + .unbind( ".tabs" ) + .removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" ) + .removeData( "tabs" ); + + this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); + + this.anchors.each(function() { + var href = $.data( this, "href.tabs" ); + if ( href ) { + this.href = href; + } + var $this = $( this ).unbind( ".tabs" ); + $.each( [ "href", "load", "cache" ], function( i, prefix ) { + $this.removeData( prefix + ".tabs" ); + }); + }); + + this.lis.unbind( ".tabs" ).add( this.panels ).each(function() { + if ( $.data( this, "destroy.tabs" ) ) { + $( this ).remove(); + } else { + $( this ).removeClass([ + "ui-state-default", + "ui-corner-top", + "ui-tabs-selected", + "ui-state-active", + "ui-state-hover", + "ui-state-focus", + "ui-state-disabled", + "ui-tabs-panel", + "ui-widget-content", + "ui-corner-bottom", + "ui-tabs-hide" + ].join( " " ) ); + } + }); + + if ( o.cookie ) { + this._cookie( null, o.cookie ); + } + + return this; + }, + + add: function( url, label, index ) { + if ( index === undefined ) { + index = this.anchors.length; + } + + var self = this, + o = this.options, + $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), + id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); + + $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); + + // try to find an existing element before creating a new one + var $panel = self.element.find( "#" + id ); + if ( !$panel.length ) { + $panel = $( o.panelTemplate ) + .attr( "id", id ) + .data( "destroy.tabs", true ); + } + $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide" ); + + if ( index >= this.lis.length ) { + $li.appendTo( this.list ); + $panel.appendTo( this.list[ 0 ].parentNode ); + } else { + $li.insertBefore( this.lis[ index ] ); + $panel.insertBefore( this.panels[ index ] ); + } + + o.disabled = $.map( o.disabled, function( n, i ) { + return n >= index ? ++n : n; + }); + + this._tabify(); + + if ( this.anchors.length == 1 ) { + o.selected = 0; + $li.addClass( "ui-tabs-selected ui-state-active" ); + $panel.removeClass( "ui-tabs-hide" ); + this.element.queue( "tabs", function() { + self._trigger( "show", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); + }); + + this.load( 0 ); + } + + this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); + return this; + }, + + remove: function( index ) { + index = this._getIndex( index ); + var o = this.options, + $li = this.lis.eq( index ).remove(), + $panel = this.panels.eq( index ).remove(); + + // If selected tab was removed focus tab to the right or + // in case the last tab was removed the tab to the left. + if ( $li.hasClass( "ui-tabs-selected" ) && this.anchors.length > 1) { + this.select( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); + } + + o.disabled = $.map( + $.grep( o.disabled, function(n, i) { + return n != index; + }), + function( n, i ) { + return n >= index ? --n : n; + }); + + this._tabify(); + + this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); + return this; + }, + + enable: function( index ) { + index = this._getIndex( index ); + var o = this.options; + if ( $.inArray( index, o.disabled ) == -1 ) { + return; + } + + this.lis.eq( index ).removeClass( "ui-state-disabled" ); + o.disabled = $.grep( o.disabled, function( n, i ) { + return n != index; + }); + + this._trigger( "enable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); + return this; + }, + + disable: function( index ) { + index = this._getIndex( index ); + var self = this, o = this.options; + // cannot disable already selected tab + if ( index != o.selected ) { + this.lis.eq( index ).addClass( "ui-state-disabled" ); + + o.disabled.push( index ); + o.disabled.sort(); + + this._trigger( "disable", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); + } + + return this; + }, + + select: function( index ) { + index = this._getIndex( index ); + if ( index == -1 ) { + if ( this.options.collapsible && this.options.selected != -1 ) { + index = this.options.selected; + } else { + return this; + } + } + this.anchors.eq( index ).trigger( this.options.event + ".tabs" ); + return this; + }, + + load: function( index ) { + index = this._getIndex( index ); + var self = this, + o = this.options, + a = this.anchors.eq( index )[ 0 ], + url = $.data( a, "load.tabs" ); + + this.abort(); + + // not remote or from cache + if ( !url || this.element.queue( "tabs" ).length !== 0 && $.data( a, "cache.tabs" ) ) { + this.element.dequeue( "tabs" ); + return; + } + + // load remote from here on + this.lis.eq( index ).addClass( "ui-state-processing" ); + + if ( o.spinner ) { + var span = $( "span", a ); + span.data( "label.tabs", span.html() ).html( o.spinner ); + } + + this.xhr = $.ajax( $.extend( {}, o.ajaxOptions, { + url: url, + success: function( r, s ) { + self.element.find( self._sanitizeSelector( a.hash ) ).html( r ); + + // take care of tab labels + self._cleanup(); + + if ( o.cache ) { + $.data( a, "cache.tabs", true ); + } + + self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); + try { + o.ajaxOptions.success( r, s ); + } + catch ( e ) {} + }, + error: function( xhr, s, e ) { + // take care of tab labels + self._cleanup(); + + self._trigger( "load", null, self._ui( self.anchors[ index ], self.panels[ index ] ) ); + try { + // Passing index avoid a race condition when this method is + // called after the user has selected another tab. + // Pass the anchor that initiated this request allows + // loadError to manipulate the tab content panel via $(a.hash) + o.ajaxOptions.error( xhr, s, index, a ); + } + catch ( e ) {} + } + } ) ); + + // last, so that load event is fired before show... + self.element.dequeue( "tabs" ); + + return this; + }, + + abort: function() { + // stop possibly running animations + this.element.queue( [] ); + this.panels.stop( false, true ); + + // "tabs" queue must not contain more than two elements, + // which are the callbacks for the latest clicked tab... + this.element.queue( "tabs", this.element.queue( "tabs" ).splice( -2, 2 ) ); + + // terminate pending requests from other tabs + if ( this.xhr ) { + this.xhr.abort(); + delete this.xhr; + } + + // take care of tab labels + this._cleanup(); + return this; + }, + + url: function( index, url ) { + this.anchors.eq( index ).removeData( "cache.tabs" ).data( "load.tabs", url ); + return this; + }, + + length: function() { + return this.anchors.length; + } +}); + +$.extend( $.ui.tabs, { + version: "1.8.16" +}); + +/* + * Tabs Extensions + */ + +/* + * Rotate + */ +$.extend( $.ui.tabs.prototype, { + rotation: null, + rotate: function( ms, continuing ) { + var self = this, + o = this.options; + + var rotate = self._rotate || ( self._rotate = function( e ) { + clearTimeout( self.rotation ); + self.rotation = setTimeout(function() { + var t = o.selected; + self.select( ++t < self.anchors.length ? t : 0 ); + }, ms ); + + if ( e ) { + e.stopPropagation(); + } + }); + + var stop = self._unrotate || ( self._unrotate = !continuing + ? function(e) { + if (e.clientX) { // in case of a true click + self.rotate(null); + } + } + : function( e ) { + t = o.selected; + rotate(); + }); + + // start rotation + if ( ms ) { + this.element.bind( "tabsshow", rotate ); + this.anchors.bind( o.event + ".tabs", stop ); + rotate(); + // stop rotation + } else { + clearTimeout( self.rotation ); + this.element.unbind( "tabsshow", rotate ); + this.anchors.unbind( o.event + ".tabs", stop ); + delete this._rotate; + delete this._unrotate; + } + + return this; + } +}); + +})( jQuery ); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.min.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.min.js new file mode 100644 index 00000000..14c9064f --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery-ui.min.js @@ -0,0 +1,791 @@ +/*! + * jQuery UI 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI + */ +(function(c,j){function k(a,b){var d=a.nodeName.toLowerCase();if("area"===d){b=a.parentNode;d=b.name;if(!a.href||!d||b.nodeName.toLowerCase()!=="map")return false;a=c("img[usemap=#"+d+"]")[0];return!!a&&l(a)}return(/input|select|textarea|button|object/.test(d)?!a.disabled:"a"==d?a.href||b:b)&&l(a)}function l(a){return!c(a).parents().andSelf().filter(function(){return c.curCSS(this,"visibility")==="hidden"||c.expr.filters.hidden(this)}).length}c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.16", +keyCode:{ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91}});c.fn.extend({propAttr:c.fn.prop||c.fn.attr,_focus:c.fn.focus,focus:function(a,b){return typeof a==="number"?this.each(function(){var d= +this;setTimeout(function(){c(d).focus();b&&b.call(d)},a)}):this._focus.apply(this,arguments)},scrollParent:function(){var a;a=c.browser.msie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(c.curCSS(this,"position",1))&&/(auto|scroll)/.test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(c.curCSS(this, +"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0);return/fixed/.test(this.css("position"))||!a.length?c(document):a},zIndex:function(a){if(a!==j)return this.css("zIndex",a);if(this.length){a=c(this[0]);for(var b;a.length&&a[0]!==document;){b=a.css("position");if(b==="absolute"||b==="relative"||b==="fixed"){b=parseInt(a.css("zIndex"),10);if(!isNaN(b)&&b!==0)return b}a=a.parent()}}return 0},disableSelection:function(){return this.bind((c.support.selectstart?"selectstart": +"mousedown")+".ui-disableSelection",function(a){a.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}});c.each(["Width","Height"],function(a,b){function d(f,g,m,n){c.each(e,function(){g-=parseFloat(c.curCSS(f,"padding"+this,true))||0;if(m)g-=parseFloat(c.curCSS(f,"border"+this+"Width",true))||0;if(n)g-=parseFloat(c.curCSS(f,"margin"+this,true))||0});return g}var e=b==="Width"?["Left","Right"]:["Top","Bottom"],h=b.toLowerCase(),i={innerWidth:c.fn.innerWidth,innerHeight:c.fn.innerHeight, +outerWidth:c.fn.outerWidth,outerHeight:c.fn.outerHeight};c.fn["inner"+b]=function(f){if(f===j)return i["inner"+b].call(this);return this.each(function(){c(this).css(h,d(this,f)+"px")})};c.fn["outer"+b]=function(f,g){if(typeof f!=="number")return i["outer"+b].call(this,f);return this.each(function(){c(this).css(h,d(this,f,true,g)+"px")})}});c.extend(c.expr[":"],{data:function(a,b,d){return!!c.data(a,d[3])},focusable:function(a){return k(a,!isNaN(c.attr(a,"tabindex")))},tabbable:function(a){var b=c.attr(a, +"tabindex"),d=isNaN(b);return(d||b>=0)&&k(a,!d)}});c(function(){var a=document.body,b=a.appendChild(b=document.createElement("div"));c.extend(b.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0});c.support.minHeight=b.offsetHeight===100;c.support.selectstart="onselectstart"in b;a.removeChild(b).style.display="none"});c.extend(c.ui,{plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&& +a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=9)&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){b(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted= +false;a.target==this._mouseDownEvent.target&&b.data(a.target,this.widgetName+".preventClickEvent",true);this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX-a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +;/* + * jQuery UI Position 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Position + */ +(function(c){c.ui=c.ui||{};var n=/left|center|right/,o=/top|center|bottom/,t=c.fn.position,u=c.fn.offset;c.fn.position=function(b){if(!b||!b.of)return t.apply(this,arguments);b=c.extend({},b);var a=c(b.of),d=a[0],g=(b.collision||"flip").split(" "),e=b.offset?b.offset.split(" "):[0,0],h,k,j;if(d.nodeType===9){h=a.width();k=a.height();j={top:0,left:0}}else if(d.setTimeout){h=a.width();k=a.height();j={top:a.scrollTop(),left:a.scrollLeft()}}else if(d.preventDefault){b.at="left top";h=k=0;j={top:b.of.pageY, +left:b.of.pageX}}else{h=a.outerWidth();k=a.outerHeight();j=a.offset()}c.each(["my","at"],function(){var f=(b[this]||"").split(" ");if(f.length===1)f=n.test(f[0])?f.concat(["center"]):o.test(f[0])?["center"].concat(f):["center","center"];f[0]=n.test(f[0])?f[0]:"center";f[1]=o.test(f[1])?f[1]:"center";b[this]=f});if(g.length===1)g[1]=g[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(b.at[0]==="right")j.left+=h;else if(b.at[0]==="center")j.left+=h/2;if(b.at[1]==="bottom")j.top+= +k;else if(b.at[1]==="center")j.top+=k/2;j.left+=e[0];j.top+=e[1];return this.each(function(){var f=c(this),l=f.outerWidth(),m=f.outerHeight(),p=parseInt(c.curCSS(this,"marginLeft",true))||0,q=parseInt(c.curCSS(this,"marginTop",true))||0,v=l+p+(parseInt(c.curCSS(this,"marginRight",true))||0),w=m+q+(parseInt(c.curCSS(this,"marginBottom",true))||0),i=c.extend({},j),r;if(b.my[0]==="right")i.left-=l;else if(b.my[0]==="center")i.left-=l/2;if(b.my[1]==="bottom")i.top-=m;else if(b.my[1]==="center")i.top-= +m/2;i.left=Math.round(i.left);i.top=Math.round(i.top);r={left:i.left-p,top:i.top-q};c.each(["left","top"],function(s,x){c.ui.position[g[s]]&&c.ui.position[g[s]][x](i,{targetWidth:h,targetHeight:k,elemWidth:l,elemHeight:m,collisionPosition:r,collisionWidth:v,collisionHeight:w,offset:e,my:b.my,at:b.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(i,{using:b.using}))})};c.ui.position={fit:{left:function(b,a){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();b.left= +d>0?b.left-d:Math.max(b.left-a.collisionPosition.left,b.left)},top:function(b,a){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();b.top=d>0?b.top-d:Math.max(b.top-a.collisionPosition.top,b.top)}},flip:{left:function(b,a){if(a.at[0]!=="center"){var d=c(window);d=a.collisionPosition.left+a.collisionWidth-d.width()-d.scrollLeft();var g=a.my[0]==="left"?-a.elemWidth:a.my[0]==="right"?a.elemWidth:0,e=a.at[0]==="left"?a.targetWidth:-a.targetWidth,h=-2*a.offset[0];b.left+= +a.collisionPosition.left<0?g+e+h:d>0?g+e+h:0}},top:function(b,a){if(a.at[1]!=="center"){var d=c(window);d=a.collisionPosition.top+a.collisionHeight-d.height()-d.scrollTop();var g=a.my[1]==="top"?-a.elemHeight:a.my[1]==="bottom"?a.elemHeight:0,e=a.at[1]==="top"?a.targetHeight:-a.targetHeight,h=-2*a.offset[1];b.top+=a.collisionPosition.top<0?g+e+h:d>0?g+e+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(b,a){if(/static/.test(c.curCSS(b,"position")))b.style.position="relative";var d=c(b), +g=d.offset(),e=parseInt(c.curCSS(b,"top",true),10)||0,h=parseInt(c.curCSS(b,"left",true),10)||0;g={top:a.top-g.top+e,left:a.left-g.left+h};"using"in a?a.using.call(b,g):d.css(g)};c.fn.offset=function(b){var a=this[0];if(!a||!a.ownerDocument)return null;if(b)return this.each(function(){c.offset.setOffset(this,b)});return u.call(this)}}})(jQuery); +;/* + * jQuery UI Draggable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(d){d.widget("ui.draggable",d.ui.mouse,{widgetEventPrefix:"drag",options:{addClasses:true,appendTo:"parent",axis:false,connectToSortable:false,containment:false,cursor:"auto",cursorAt:false,grid:false,handle:false,helper:"original",iframeFix:false,opacity:false,refreshPositions:false,revert:false,revertDuration:500,scope:"default",scroll:true,scrollSensitivity:20,scrollSpeed:20,snap:false,snapMode:"both",snapTolerance:20,stack:false,zIndex:false},_create:function(){if(this.options.helper== +"original"&&!/^(?:r|a|f)/.test(this.element.css("position")))this.element[0].style.position="relative";this.options.addClasses&&this.element.addClass("ui-draggable");this.options.disabled&&this.element.addClass("ui-draggable-disabled");this._mouseInit()},destroy:function(){if(this.element.data("draggable")){this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy();return this}},_mouseCapture:function(a){var b= +this.options;if(this.helper||b.disabled||d(a.target).is(".ui-resizable-handle"))return false;this.handle=this._getHandle(a);if(!this.handle)return false;if(b.iframeFix)d(b.iframeFix===true?"iframe":b.iframeFix).each(function(){d('
          ').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(d(this).offset()).appendTo("body")});return true},_mouseStart:function(a){var b=this.options; +this.helper=this._createHelper(a);this._cacheHelperProportions();if(d.ui.ddmanager)d.ui.ddmanager.current=this;this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}); +this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);b.containment&&this._setContainment();if(this._trigger("start",a)===false){this._clear();return false}this._cacheHelperProportions();d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,true);d.ui.ddmanager&&d.ui.ddmanager.dragStart(this,a);return true}, +_mouseDrag:function(a,b){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!b){b=this._uiHash();if(this._trigger("drag",a,b)===false){this._mouseUp({});return false}this.position=b.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);return false},_mouseStop:function(a){var b= +false;if(d.ui.ddmanager&&!this.options.dropBehaviour)b=d.ui.ddmanager.drop(this,a);if(this.dropped){b=this.dropped;this.dropped=false}if((!this.element[0]||!this.element[0].parentNode)&&this.options.helper=="original")return false;if(this.options.revert=="invalid"&&!b||this.options.revert=="valid"&&b||this.options.revert===true||d.isFunction(this.options.revert)&&this.options.revert.call(this.element,b)){var c=this;d(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration, +10),function(){c._trigger("stop",a)!==false&&c._clear()})}else this._trigger("stop",a)!==false&&this._clear();return false},_mouseUp:function(a){this.options.iframeFix===true&&d("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});d.ui.ddmanager&&d.ui.ddmanager.dragStop(this,a);return d.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var b=!this.options.handle|| +!d(this.options.handle,this.element).length?true:false;d(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==a.target)b=true});return b},_createHelper:function(a){var b=this.options;a=d.isFunction(b.helper)?d(b.helper.apply(this.element[0],[a])):b.helper=="clone"?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo(b.appendTo=="parent"?this.element[0].parentNode:b.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&& +a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){if(typeof a=="string")a=a.split(" ");if(d.isArray(a))a={left:+a[0],top:+a[1]||0};if("left"in a)this.offset.click.left=a.left+this.margins.left;if("right"in a)this.offset.click.left=this.helperProportions.width-a.right+this.margins.left;if("top"in a)this.offset.click.top=a.top+this.margins.top;if("bottom"in a)this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top},_getParentOffset:function(){this.offsetParent= +this.helper.offsetParent();var a=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0])){a.left+=this.scrollParent.scrollLeft();a.top+=this.scrollParent.scrollTop()}if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&d.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"), +10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var a=this.element.position();return{top:a.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:a.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"), +10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;if(a.containment=="parent")a.containment=this.helper[0].parentNode;if(a.containment=="document"||a.containment=="window")this.containment=[a.containment=="document"?0:d(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,a.containment=="document"?0:d(window).scrollTop()-this.offset.relative.top-this.offset.parent.top, +(a.containment=="document"?0:d(window).scrollLeft())+d(a.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a.containment=="document"?0:d(window).scrollTop())+(d(a.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){a=d(a.containment);var b=a[0];if(b){a.offset();var c=d(b).css("overflow")!= +"hidden";this.containment=[(parseInt(d(b).css("borderLeftWidth"),10)||0)+(parseInt(d(b).css("paddingLeft"),10)||0),(parseInt(d(b).css("borderTopWidth"),10)||0)+(parseInt(d(b).css("paddingTop"),10)||0),(c?Math.max(b.scrollWidth,b.offsetWidth):b.offsetWidth)-(parseInt(d(b).css("borderLeftWidth"),10)||0)-(parseInt(d(b).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(c?Math.max(b.scrollHeight,b.offsetHeight):b.offsetHeight)-(parseInt(d(b).css("borderTopWidth"), +10)||0)-(parseInt(d(b).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom];this.relative_container=a}}else if(a.containment.constructor==Array)this.containment=a.containment},_convertPositionTo:function(a,b){if(!b)b=this.position;a=a=="absolute"?1:-1;var c=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName);return{top:b.top+ +this.offset.relative.top*a+this.offset.parent.top*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():f?0:c.scrollTop())*a),left:b.left+this.offset.relative.left*a+this.offset.parent.left*a-(d.browser.safari&&d.browser.version<526&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():f?0:c.scrollLeft())*a)}},_generatePosition:function(a){var b=this.options,c=this.cssPosition=="absolute"&& +!(this.scrollParent[0]!=document&&d.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,f=/(html|body)/i.test(c[0].tagName),e=a.pageX,h=a.pageY;if(this.originalPosition){var g;if(this.containment){if(this.relative_container){g=this.relative_container.offset();g=[this.containment[0]+g.left,this.containment[1]+g.top,this.containment[2]+g.left,this.containment[3]+g.top]}else g=this.containment;if(a.pageX-this.offset.click.leftg[2])e=g[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>g[3])h=g[3]+this.offset.click.top}if(b.grid){h=b.grid[1]?this.originalPageY+Math.round((h-this.originalPageY)/b.grid[1])*b.grid[1]:this.originalPageY;h=g?!(h-this.offset.click.topg[3])?h:!(h-this.offset.click.topg[2])?e:!(e-this.offset.click.left=0;i--){var j=c.snapElements[i].left,l=j+c.snapElements[i].width,k=c.snapElements[i].top,m=k+c.snapElements[i].height;if(j-e=j&&f<=l||h>=j&&h<=l||fl)&&(e>= +i&&e<=k||g>=i&&g<=k||ek);default:return false}};d.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,b){var c=d.ui.ddmanager.droppables[a.options.scope]||[],e=b?b.type:null,g=(a.currentItem||a.element).find(":data(droppable)").andSelf(),f=0;a:for(;f
        • ').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!e(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var d=0;d
          ');/sw|se|ne|nw/.test(f)&&g.css({zIndex:++a.zIndex});"se"==f&&g.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(g)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== +String)this.handles[i]=e(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=e(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}e(this.handles[i])}};this._renderAxis(this.element);this._handles=e(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();e(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){e(this).removeClass("ui-resizable-autohide");b._handles.show()}},function(){if(!a.disabled)if(!b.resizing){e(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy(); +var b=function(c){e(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a= +false;for(var c in this.handles)if(e(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()};if(d.is(".ui-draggable")||/absolute/.test(d.css("position")))d.css({position:"absolute",top:c.top,left:c.left});e.browser.opera&&/relative/.test(d.css("position"))&&d.css({position:"relative",top:"auto",left:"auto"}); +this._renderProxy();c=m(this.helper.css("left"));var f=m(this.helper.css("top"));if(a.containment){c+=e(a.containment).scrollLeft()||0;f+=e(a.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:c,top:f};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:c,top:f};this.sizeDiff= +{width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio:this.originalSize.width/this.originalSize.height||1;a=e(".ui-resizable-"+this.axis).css("cursor");e("body").css("cursor",a=="auto"?this.axis+"-resize":a);d.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,d=this._change[this.axis]; +if(!d)return false;c=d.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize",b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false}, +_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var d=this._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName);d=f&&e.ui.hasScroll(d[0],"left")?0:c.sizeDiff.height;f=f?0:c.sizeDiff.width;f={width:c.helper.width()-f,height:c.helper.height()-d};d=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var g=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(e.extend(f, +{top:g,left:d}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}e("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",b);this._helper&&this.helper.remove();return false},_updateVirtualBoundaries:function(b){var a=this.options,c,d,f;a={minWidth:k(a.minWidth)?a.minWidth:0,maxWidth:k(a.maxWidth)?a.maxWidth:Infinity,minHeight:k(a.minHeight)?a.minHeight:0,maxHeight:k(a.maxHeight)?a.maxHeight: +Infinity};if(this._aspectRatio||b){b=a.minHeight*this.aspectRatio;d=a.minWidth/this.aspectRatio;c=a.maxHeight*this.aspectRatio;f=a.maxWidth/this.aspectRatio;if(b>a.minWidth)a.minWidth=b;if(d>a.minHeight)a.minHeight=d;if(cb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(g)b.width=a.minWidth;if(h)b.height=a.minHeight;if(d)b.width=a.maxWidth;if(f)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height,l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(g&&l)b.left=i-a.minWidth;if(d&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(f&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left= +null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a
          ');var a=e.browser.msie&&e.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+ +a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+ +c}},se:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){e.ui.plugin.call(this,b,[a,this.ui()]); +b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});e.extend(e.ui.resizable,{version:"1.8.16"});e.ui.plugin.add("resizable","alsoResize",{start:function(){var b=e(this).data("resizable").options,a=function(c){e(c).each(function(){var d=e(this);d.data("resizable-alsoresize",{width:parseInt(d.width(), +10),height:parseInt(d.height(),10),left:parseInt(d.css("left"),10),top:parseInt(d.css("top"),10),position:d.css("position")})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else e.each(b.alsoResize,function(c){a(c)});else a(b.alsoResize)},resize:function(b,a){var c=e(this).data("resizable");b=c.options;var d=c.originalSize,f=c.originalPosition,g={height:c.size.height-d.height||0,width:c.size.width-d.width||0,top:c.position.top- +f.top||0,left:c.position.left-f.left||0},h=function(i,j){e(i).each(function(){var l=e(this),q=e(this).data("resizable-alsoresize"),p={},r=j&&j.length?j:l.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(r,function(n,o){if((n=(q[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(e.browser.opera&&/relative/.test(l.css("position"))){c._revertToRelativePosition=true;l.css({position:"absolute",top:"auto",left:"auto"})}l.css(p)})};typeof b.alsoResize=="object"&&!b.alsoResize.nodeType? +e.each(b.alsoResize,function(i,j){h(i,j)}):h(b.alsoResize)},stop:function(){var b=e(this).data("resizable"),a=b.options,c=function(d){e(d).each(function(){var f=e(this);f.css({position:f.data("resizable-alsoresize").position})})};if(b._revertToRelativePosition){b._revertToRelativePosition=false;typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?e.each(a.alsoResize,function(d){c(d)}):c(a.alsoResize)}e(this).removeData("resizable-alsoresize")}});e.ui.plugin.add("resizable","animate",{stop:function(b){var a= +e(this).data("resizable"),c=a.options,d=a._proportionallyResizeElements,f=d.length&&/textarea/i.test(d[0].nodeName),g=f&&e.ui.hasScroll(d[0],"left")?0:a.sizeDiff.height;f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-g};g=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(e.extend(f,h&&g?{top:h,left:g}:{}),{duration:c.animateDuration,easing:c.animateEasing, +step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};d&&d.length&&e(d[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});e.ui.plugin.add("resizable","containment",{start:function(){var b=e(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof e?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= +e(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight}}else{var d=e(a),f=[];e(["Top","Right","Left","Bottom"]).each(function(i,j){f[i]=m(d.css("padding"+j))});b.containerOffset=d.offset();b.containerPosition=d.position();b.containerSize={height:d.innerHeight()-f[3],width:d.innerWidth()-f[1]};c=b.containerOffset; +var g=b.containerSize.height,h=b.containerSize.width;h=e.ui.hasScroll(a,"left")?a.scrollWidth:h;g=e.ui.hasScroll(a)?a.scrollHeight:g;b.parentData={element:a,left:c.left,top:c.top,width:h,height:g}}}},resize:function(b){var a=e(this).data("resizable"),c=a.options,d=a.containerOffset,f=a.position;b=a._aspectRatio||b.shiftKey;var g={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))g=d;if(f.left<(a._helper?d.left:0)){a.size.width+=a._helper?a.position.left-d.left: +a.position.left-g.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?d.left:0}if(f.top<(a._helper?d.top:0)){a.size.height+=a._helper?a.position.top-d.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?d.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-g.left:a.offset.left-g.left)+a.sizeDiff.width);d=Math.abs((a._helper?a.offset.top-g.top:a.offset.top- +d.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);g=/relative|absolute/.test(a.containerElement.css("position"));if(f&&g)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(d+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-d;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=e(this).data("resizable"),a=b.options,c=b.containerOffset,d=b.containerPosition, +f=b.containerElement,g=e(b.helper),h=g.offset(),i=g.outerWidth()-b.sizeDiff.width;g=g.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g});b._helper&&!a.animate&&/static/.test(f.css("position"))&&e(this).css({left:h.left-d.left-c.left,width:i,height:g})}});e.ui.plugin.add("resizable","ghost",{start:function(){var b=e(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, +display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=e(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=e(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});e.ui.plugin.add("resizable","grid",{resize:function(){var b= +e(this).data("resizable"),a=b.options,c=b.size,d=b.originalSize,f=b.originalPosition,g=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-d.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-d.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a}else if(/^(ne)$/.test(g)){b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}else{if(/^(sw)$/.test(g)){b.size.width=d.width+h;b.size.height= +d.height+a}else{b.size.width=d.width+h;b.size.height=d.height+a;b.position.top=f.top-a}b.position.left=f.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); +;/* + * jQuery UI Selectable 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), +selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
          ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting");b.unselecting=true;f._trigger("unselecting", +c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f=this;this.dragged=true;if(!this.options.disabled){var d= +this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var a=this.options;this.containerCache={};this.element.addClass("ui-sortable"); +this.refresh();this.floating=this.items.length?a.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):false;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var a=this.items.length-1;a>=0;a--)this.items[a].item.removeData("sortable-item");return this},_setOption:function(a,b){if(a=== +"disabled"){this.options[a]=b;this.widget()[b?"addClass":"removeClass"]("ui-sortable-disabled")}else d.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,b){if(this.reverting)return false;if(this.options.disabled||this.options.type=="static")return false;this._refreshItems(a);var c=null,e=this;d(a.target).parents().each(function(){if(d.data(this,"sortable-item")==e){c=d(this);return false}});if(d.data(a.target,"sortable-item")==e)c=d(a.target);if(!c)return false;if(this.options.handle&& +!b){var f=false;d(this.options.handle,c).find("*").andSelf().each(function(){if(this==a.target)f=true});if(!f)return false}this.currentItem=c;this._removeCurrentsFromItems();return true},_mouseStart:function(a,b,c){b=this.options;var e=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top, +left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");d.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;b.cursorAt&&this._adjustOffsetFromHelper(b.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]}; +this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder();b.containment&&this._setContainment();if(b.cursor){if(d("body").css("cursor"))this._storedCursor=d("body").css("cursor");d("body").css("cursor",b.cursor)}if(b.opacity){if(this.helper.css("opacity"))this._storedOpacity=this.helper.css("opacity");this.helper.css("opacity",b.opacity)}if(b.zIndex){if(this.helper.css("zIndex"))this._storedZIndex=this.helper.css("zIndex");this.helper.css("zIndex",b.zIndex)}if(this.scrollParent[0]!= +document&&this.scrollParent[0].tagName!="HTML")this.overflowOffset=this.scrollParent.offset();this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!c)for(c=this.containers.length-1;c>=0;c--)this.containers[c]._trigger("activate",a,e._uiHash(this));if(d.ui.ddmanager)d.ui.ddmanager.current=this;d.ui.ddmanager&&!b.dropBehaviour&&d.ui.ddmanager.prepareOffsets(this,a);this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a); +return true},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs)this.lastPositionAbs=this.positionAbs;if(this.options.scroll){var b=this.options,c=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageY=0;b--){c=this.items[b];var e=c.item[0],f=this._intersectsWithPointer(c);if(f)if(e!=this.currentItem[0]&&this.placeholder[f==1?"next":"prev"]()[0]!=e&&!d.ui.contains(this.placeholder[0],e)&&(this.options.type=="semi-dynamic"?!d.ui.contains(this.element[0], +e):true)){this.direction=f==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(c))this._rearrange(a,c);else break;this._trigger("change",a,this._uiHash());break}}this._contactContainers(a);d.ui.ddmanager&&d.ui.ddmanager.drag(this,a);this._trigger("sort",a,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(a,b){if(a){d.ui.ddmanager&&!this.options.dropBehaviour&&d.ui.ddmanager.drop(this,a);if(this.options.revert){var c=this;b=c.placeholder.offset(); +c.reverting=true;d(this.helper).animate({left:b.left-this.offset.parent.left-c.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:b.top-this.offset.parent.top-c.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){c._clear(a)})}else this._clear(a,b);return false}},cancel:function(){var a=this;if(this.dragging){this._mouseUp({target:null});this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"): +this.currentItem.show();for(var b=this.containers.length-1;b>=0;b--){this.containers[b]._trigger("deactivate",null,a._uiHash(this));if(this.containers[b].containerCache.over){this.containers[b]._trigger("out",null,a._uiHash(this));this.containers[b].containerCache.over=0}}}if(this.placeholder){this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]);this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove();d.extend(this,{helper:null, +dragging:false,reverting:false,_noFinalSort:null});this.domPosition.prev?d(this.domPosition.prev).after(this.currentItem):d(this.domPosition.parent).prepend(this.currentItem)}return this},serialize:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};d(b).each(function(){var e=(d(a.item||this).attr(a.attribute||"id")||"").match(a.expression||/(.+)[-=_](.+)/);if(e)c.push((a.key||e[1]+"[]")+"="+(a.key&&a.expression?e[1]:e[2]))});!c.length&&a.key&&c.push(a.key+"=");return c.join("&")}, +toArray:function(a){var b=this._getItemsAsjQuery(a&&a.connected),c=[];a=a||{};b.each(function(){c.push(d(a.item||this).attr(a.attribute||"id")||"")});return c},_intersectsWith:function(a){var b=this.positionAbs.left,c=b+this.helperProportions.width,e=this.positionAbs.top,f=e+this.helperProportions.height,g=a.left,h=g+a.width,i=a.top,k=i+a.height,j=this.offset.click.top,l=this.offset.click.left;j=e+j>i&&e+jg&&b+la[this.floating?"width":"height"]?j:g0?"down":"up")},_getDragHorizontalDirection:function(){var a=this.positionAbs.left-this.lastPositionAbs.left;return a!=0&&(a>0?"right":"left")},refresh:function(a){this._refreshItems(a);this.refreshPositions();return this},_connectWith:function(){var a=this.options;return a.connectWith.constructor==String?[a.connectWith]:a.connectWith},_getItemsAsjQuery:function(a){var b=[],c=[],e=this._connectWith(); +if(e&&a)for(a=e.length-1;a>=0;a--)for(var f=d(e[a]),g=f.length-1;g>=0;g--){var h=d.data(f[g],"sortable");if(h&&h!=this&&!h.options.disabled)c.push([d.isFunction(h.options.items)?h.options.items.call(h.element):d(h.options.items,h.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),h])}c.push([d.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):d(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), +this]);for(a=c.length-1;a>=0;a--)c[a][0].each(function(){b.push(this)});return d(b)},_removeCurrentsFromItems:function(){for(var a=this.currentItem.find(":data(sortable-item)"),b=0;b=0;f--)for(var g=d(e[f]),h=g.length-1;h>=0;h--){var i=d.data(g[h],"sortable");if(i&&i!=this&&!i.options.disabled){c.push([d.isFunction(i.options.items)?i.options.items.call(i.element[0],a,{item:this.currentItem}):d(i.options.items,i.element),i]);this.containers.push(i)}}for(f=c.length-1;f>=0;f--){a=c[f][1];e=c[f][0];h=0;for(g=e.length;h=0;b--){var c=this.items[b];if(!(c.instance!=this.currentContainer&&this.currentContainer&&c.item[0]!=this.currentItem[0])){var e=this.options.toleranceElement?d(this.options.toleranceElement,c.item):c.item;if(!a){c.width=e.outerWidth();c.height=e.outerHeight()}e=e.offset();c.left=e.left;c.top=e.top}}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(b= +this.containers.length-1;b>=0;b--){e=this.containers[b].element.offset();this.containers[b].containerCache.left=e.left;this.containers[b].containerCache.top=e.top;this.containers[b].containerCache.width=this.containers[b].element.outerWidth();this.containers[b].containerCache.height=this.containers[b].element.outerHeight()}return this},_createPlaceholder:function(a){var b=a||this,c=b.options;if(!c.placeholder||c.placeholder.constructor==String){var e=c.placeholder;c.placeholder={element:function(){var f= +d(document.createElement(b.currentItem[0].nodeName)).addClass(e||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!e)f.style.visibility="hidden";return f},update:function(f,g){if(!(e&&!c.forcePlaceholderSize)){g.height()||g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10));g.width()||g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")|| +0,10))}}}}b.placeholder=d(c.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);c.placeholder.update(b,b.placeholder)},_contactContainers:function(a){for(var b=null,c=null,e=this.containers.length-1;e>=0;e--)if(!d.ui.contains(this.currentItem[0],this.containers[e].element[0]))if(this._intersectsWith(this.containers[e].containerCache)){if(!(b&&d.ui.contains(this.containers[e].element[0],b.element[0]))){b=this.containers[e];c=e}}else if(this.containers[e].containerCache.over){this.containers[e]._trigger("out", +a,this._uiHash(this));this.containers[e].containerCache.over=0}if(b)if(this.containers.length===1){this.containers[c]._trigger("over",a,this._uiHash(this));this.containers[c].containerCache.over=1}else if(this.currentContainer!=this.containers[c]){b=1E4;e=null;for(var f=this.positionAbs[this.containers[c].floating?"left":"top"],g=this.items.length-1;g>=0;g--)if(d.ui.contains(this.containers[c].element[0],this.items[g].item[0])){var h=this.items[g][this.containers[c].floating?"left":"top"];if(Math.abs(h- +f)this.containment[2])f=this.containment[2]+this.offset.click.left;if(a.pageY-this.offset.click.top>this.containment[3])g=this.containment[3]+this.offset.click.top}if(b.grid){g=this.originalPageY+Math.round((g- +this.originalPageY)/b.grid[1])*b.grid[1];g=this.containment?!(g-this.offset.click.topthis.containment[3])?g:!(g-this.offset.click.topthis.containment[2])?f:!(f-this.offset.click.left=0;e--)if(d.ui.contains(this.containers[e].element[0],this.currentItem[0])&&!b){c.push(function(f){return function(g){f._trigger("receive",g,this._uiHash(this))}}.call(this,this.containers[e]));c.push(function(f){return function(g){f._trigger("update",g,this._uiHash(this))}}.call(this,this.containers[e]))}}for(e=this.containers.length-1;e>=0;e--){b||c.push(function(f){return function(g){f._trigger("deactivate",g,this._uiHash(this))}}.call(this, +this.containers[e]));if(this.containers[e].containerCache.over){c.push(function(f){return function(g){f._trigger("out",g,this._uiHash(this))}}.call(this,this.containers[e]));this.containers[e].containerCache.over=0}}this._storedCursor&&d("body").css("cursor",this._storedCursor);this._storedOpacity&&this.helper.css("opacity",this._storedOpacity);if(this._storedZIndex)this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex);this.dragging=false;if(this.cancelHelperRemoval){if(!b){this._trigger("beforeStop", +a,this._uiHash());for(e=0;e li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:false,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,b=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix"); +a.headers=a.element.find(b.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){b.disabled||c(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){b.disabled||c(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){b.disabled||c(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){b.disabled||c(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(b.navigation){var d=a.element.find("a").filter(b.navigationFilter).eq(0);if(d.length){var h=d.closest(".ui-accordion-header");a.active=h.length?h:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||b.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", +function(f){return a._keydown(f)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);c.browser.safari||a.headers.find("a").attr("tabIndex",-1);b.event&&a.headers.bind(b.event.split(" ").join(".accordion ")+".accordion",function(f){a._clickHandler.call(a,f,this);f.preventDefault()})},_createIcons:function(){var a= +this.options;if(a.icons){c("").addClass("ui-icon "+a.icons.header).prependTo(this.headers);this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected);this.element.addClass("ui-accordion-icons")}},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); +this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var b=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");if(a.autoHeight||a.fillHeight)b.css("height","");return c.Widget.prototype.destroy.call(this)},_setOption:function(a,b){c.Widget.prototype._setOption.apply(this,arguments);a=="active"&&this.activate(b);if(a=="icons"){this._destroyIcons(); +b&&this._createIcons()}if(a=="disabled")this.headers.add(this.headers.next())[b?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!(this.options.disabled||a.altKey||a.ctrlKey)){var b=c.ui.keyCode,d=this.headers.length,h=this.headers.index(a.target),f=false;switch(a.keyCode){case b.RIGHT:case b.DOWN:f=this.headers[(h+1)%d];break;case b.LEFT:case b.UP:f=this.headers[(h-1+d)%d];break;case b.SPACE:case b.ENTER:this._clickHandler({target:a.target},a.target); +a.preventDefault()}if(f){c(a.target).attr("tabIndex",-1);c(f).attr("tabIndex",0);f.focus();return false}return true}},resize:function(){var a=this.options,b;if(a.fillSpace){if(c.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}b=this.element.parent().height();c.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){b-=c(this).outerHeight(true)});this.headers.next().each(function(){c(this).height(Math.max(0,b-c(this).innerHeight()+ +c(this).height()))}).css("overflow","auto")}else if(a.autoHeight){b=0;this.headers.next().each(function(){b=Math.max(b,c(this).height("").height())}).height(b)}return this},activate:function(a){this.options.active=a;a=this._findActive(a)[0];this._clickHandler({target:a},a);return this},_findActive:function(a){return a?typeof a==="number"?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):a===false?c([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,b){var d=this.options; +if(!d.disabled)if(a.target){a=c(a.currentTarget||b);b=a[0]===this.active[0];d.active=d.collapsible&&b?false:this.headers.index(a);if(!(this.running||!d.collapsible&&b)){var h=this.active;j=a.next();g=this.active.next();e={options:d,newHeader:b&&d.collapsible?c([]):a,oldHeader:this.active,newContent:b&&d.collapsible?c([]):j,oldContent:g};var f=this.headers.index(this.active[0])>this.headers.index(a[0]);this.active=b?c([]):a;this._toggle(j,g,e,b,f);h.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +if(!b){a.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected);a.next().addClass("ui-accordion-content-active")}}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var g=this.active.next(), +e={options:d,newHeader:c([]),oldHeader:d.active,newContent:c([]),oldContent:g},j=this.active=c([]);this._toggle(j,g,e)}},_toggle:function(a,b,d,h,f){var g=this,e=g.options;g.toShow=a;g.toHide=b;g.data=d;var j=function(){if(g)return g._completed.apply(g,arguments)};g._trigger("changestart",null,g.data);g.running=b.size()===0?a.size():b.size();if(e.animated){d={};d=e.collapsible&&h?{toShow:c([]),toHide:b,complete:j,down:f,autoHeight:e.autoHeight||e.fillSpace}:{toShow:a,toHide:b,complete:j,down:f,autoHeight:e.autoHeight|| +e.fillSpace};if(!e.proxied)e.proxied=e.animated;if(!e.proxiedDuration)e.proxiedDuration=e.duration;e.animated=c.isFunction(e.proxied)?e.proxied(d):e.proxied;e.duration=c.isFunction(e.proxiedDuration)?e.proxiedDuration(d):e.proxiedDuration;h=c.ui.accordion.animations;var i=e.duration,k=e.animated;if(k&&!h[k]&&!c.easing[k])k="slide";h[k]||(h[k]=function(l){this.slide(l,{easing:k,duration:i||700})});h[k](d)}else{if(e.collapsible&&h)a.toggle();else{b.hide();a.show()}j(true)}b.prev().attr({"aria-expanded":"false", +"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(a){this.running=a?0:--this.running;if(!this.running){this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""});this.toHide.removeClass("ui-accordion-content-active");if(this.toHide.length)this.toHide.parent()[0].className=this.toHide.parent()[0].className;this._trigger("change",null,this.data)}}});c.extend(c.ui.accordion,{version:"1.8.16", +animations:{slide:function(a,b){a=c.extend({easing:"swing",duration:300},a,b);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),h=0,f={},g={},e;b=a.toShow;e=b[0].style.width;b.width(parseInt(b.parent().width(),10)-parseInt(b.css("paddingLeft"),10)-parseInt(b.css("paddingRight"),10)-(parseInt(b.css("borderLeftWidth"),10)||0)-(parseInt(b.css("borderRightWidth"),10)||0));c.each(["height","paddingTop","paddingBottom"],function(j,i){g[i]="hide";j=(""+c.css(a.toShow[0],i)).match(/^([\d+-.]+)(.*)$/); +f[i]={value:j[1],unit:j[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(g,{step:function(j,i){if(i.prop=="height")h=i.end-i.start===0?0:(i.now-i.start)/(i.end-i.start);a.toShow[0].style[i.prop]=h*f[i.prop].value+f[i.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:e,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", +paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(a){this.slide(a,{easing:a.down?"easeOutBounce":"swing",duration:a.down?1E3:200})}}})})(jQuery); +;/* + * jQuery UI Autocomplete 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Autocomplete + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.position.js + */ +(function(d){var e=0;d.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:false,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var a=this,b=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(c){if(!(a.options.disabled||a.element.propAttr("readOnly"))){g= +false;var f=d.ui.keyCode;switch(c.keyCode){case f.PAGE_UP:a._move("previousPage",c);break;case f.PAGE_DOWN:a._move("nextPage",c);break;case f.UP:a._move("previous",c);c.preventDefault();break;case f.DOWN:a._move("next",c);c.preventDefault();break;case f.ENTER:case f.NUMPAD_ENTER:if(a.menu.active){g=true;c.preventDefault()}case f.TAB:if(!a.menu.active)return;a.menu.select(c);break;case f.ESCAPE:a.element.val(a.term);a.close(c);break;default:clearTimeout(a.searching);a.searching=setTimeout(function(){if(a.term!= +a.element.val()){a.selectedItem=null;a.search(null,c)}},a.options.delay);break}}}).bind("keypress.autocomplete",function(c){if(g){g=false;c.preventDefault()}}).bind("focus.autocomplete",function(){if(!a.options.disabled){a.selectedItem=null;a.previous=a.element.val()}}).bind("blur.autocomplete",function(c){if(!a.options.disabled){clearTimeout(a.searching);a.closing=setTimeout(function(){a.close(c);a._change(c)},150)}});this._initSource();this.response=function(){return a._response.apply(a,arguments)}; +this.menu=d("
            ").addClass("ui-autocomplete").appendTo(d(this.options.appendTo||"body",b)[0]).mousedown(function(c){var f=a.menu.element[0];d(c.target).closest(".ui-menu-item").length||setTimeout(function(){d(document).one("mousedown",function(h){h.target!==a.element[0]&&h.target!==f&&!d.ui.contains(f,h.target)&&a.close()})},1);setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(c,f){f=f.item.data("item.autocomplete");false!==a._trigger("focus",c,{item:f})&&/^key/.test(c.originalEvent.type)&& +a.element.val(f.value)},selected:function(c,f){var h=f.item.data("item.autocomplete"),i=a.previous;if(a.element[0]!==b.activeElement){a.element.focus();a.previous=i;setTimeout(function(){a.previous=i;a.selectedItem=h},1)}false!==a._trigger("select",c,{item:h})&&a.element.val(h.value);a.term=a.element.val();a.close(c);a.selectedItem=h},blur:function(){a.menu.element.is(":visible")&&a.element.val()!==a.term&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu"); +d.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();d.Widget.prototype.destroy.call(this)},_setOption:function(a,b){d.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource();if(a==="appendTo")this.menu.element.appendTo(d(b||"body",this.element[0].ownerDocument)[0]);a==="disabled"&& +b&&this.xhr&&this.xhr.abort()},_initSource:function(){var a=this,b,g;if(d.isArray(this.options.source)){b=this.options.source;this.source=function(c,f){f(d.ui.autocomplete.filter(b,c.term))}}else if(typeof this.options.source==="string"){g=this.options.source;this.source=function(c,f){a.xhr&&a.xhr.abort();a.xhr=d.ajax({url:g,data:c,dataType:"json",autocompleteRequest:++e,success:function(h){this.autocompleteRequest===e&&f(h)},error:function(){this.autocompleteRequest===e&&f([])}})}}else this.source= +this.options.source},search:function(a,b){a=a!=null?a:this.element.val();this.term=this.element.val();if(a.length").data("item.autocomplete",b).append(d("").text(b.label)).appendTo(a)},_move:function(a,b){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](b);else this.search(null,b)},widget:function(){return this.menu.element}});d.extend(d.ui.autocomplete,{escapeRegex:function(a){return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, +"\\$&")},filter:function(a,b){var g=new RegExp(d.ui.autocomplete.escapeRegex(b),"i");return d.grep(a,function(c){return g.test(c.label||c.value||c)})}})})(jQuery); +(function(d){d.widget("ui.menu",{_create:function(){var e=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(a){if(d(a.target).closest(".ui-menu-item a").length){a.preventDefault();e.select(a)}});this.refresh()},refresh:function(){var e=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(a){e.activate(a,d(this).parent())}).mouseleave(function(){e.deactivate()})},activate:function(e,a){this.deactivate();if(this.hasScroll()){var b=a.offset().top-this.element.offset().top,g=this.element.scrollTop(),c=this.element.height();if(b<0)this.element.scrollTop(g+b);else b>=c&&this.element.scrollTop(g+b-c+a.height())}this.active=a.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",e,{item:a})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); +this._trigger("blur");this.active=null}},next:function(e){this.move("next",".ui-menu-item:first",e)},previous:function(e){this.move("prev",".ui-menu-item:last",e)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(e,a,b){if(this.active){e=this.active[e+"All"](".ui-menu-item").eq(0);e.length?this.activate(b,e):this.activate(b,this.element.children(a))}else this.activate(b, +this.element.children(a))},nextPage:function(e){if(this.hasScroll())if(!this.active||this.last())this.activate(e,this.element.children(".ui-menu-item:first"));else{var a=this.active.offset().top,b=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var c=d(this).offset().top-a-b+d(this).height();return c<10&&c>-10});g.length||(g=this.element.children(".ui-menu-item:last"));this.activate(e,g)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.last()?":first":":last"))},previousPage:function(e){if(this.hasScroll())if(!this.active||this.first())this.activate(e,this.element.children(".ui-menu-item:last"));else{var a=this.active.offset().top,b=this.element.height();result=this.element.children(".ui-menu-item").filter(function(){var g=d(this).offset().top-a+b-d(this).height();return g<10&&g>-10});result.length||(result=this.element.children(".ui-menu-item:first"));this.activate(e,result)}else this.activate(e,this.element.children(".ui-menu-item").filter(!this.active|| +this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),e=this.options.icons,f=e.primary&&e.secondary,d=[];if(e.primary||e.secondary){if(this.options.text)d.push("ui-button-text-icon"+(f?"s":e.primary?"-primary":"-secondary"));e.primary&&a.prepend("");e.secondary&&a.append("");if(!this.options.text){d.push(f?"ui-button-icons-only": +"ui-button-icon-only");this.hasTitle||a.attr("title",c)}}else d.push("ui-button-text-only");a.addClass(d.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){a==="disabled"&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a=this.element.css("direction")=== +"ltr";this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); +b.Widget.prototype.destroy.call(this)}})})(jQuery); +;/* + * jQuery UI Dialog 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function(c,l){var m={buttons:true,height:true,maxHeight:true,maxWidth:true,minHeight:true,minWidth:true,width:true},n={maxHeight:true,maxWidth:true,minHeight:true,minWidth:true},o=c.attrFn||{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true,click:true};c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false, +position:{my:"center",at:"center",collision:"fit",using:function(a){var b=c(this).css(a).offset().top;b<0&&c(this).css("top",a.top-b)}},resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");if(typeof this.originalTitle!=="string")this.originalTitle="";this.options.title=this.options.title||this.originalTitle;var a=this,b=a.options,d=b.title||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
            ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&!i.isDefaultPrevented()&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
            ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), +h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d,e;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== +b.uiDialog[0]){e=c(this).css("z-index");isNaN(e)||(d=Math.max(d,e))}});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.scrollTop(),scrollLeft:d.element.scrollLeft()};c.ui.dialog.maxZ+=1; +d.uiDialog.css("z-index",c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== +f[0]&&e.shiftKey){g.focus(1);return false}}});c(a.element.find(":tabbable").get().concat(d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();a._isOpen=true;a._trigger("open");return a}},_createButtons:function(a){var b=this,d=false,e=c("
            ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),g=c("
            ").addClass("ui-dialog-buttonset").appendTo(e);b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a, +function(){return!(d=true)});if(d){c.each(a,function(f,h){h=c.isFunction(h)?{click:h,text:f}:h;var i=c('').click(function(){h.click.apply(b.element[0],arguments)}).appendTo(g);c.each(h,function(j,k){if(j!=="click")j in o?i[j](k):i.attr(j,k)});c.fn.button&&i.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", +handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging");b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition, +originalSize:f.originalSize,position:f.position,size:f.size}}a=a===l?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position");a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize", +f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop",f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0],e;if(a){if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "): +[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(g,f){if(+b[g]===b[g]){d[g]=b[g];b[g]=f}});a={my:b.join(" "),at:b.join(" "),offset:d.join(" ")}}a=c.extend({},c.ui.dialog.prototype.options.position,a)}else a=c.ui.dialog.prototype.options.position;(e=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(c.extend({of:window},a));e||this.uiDialog.hide()},_setOptions:function(a){var b=this,d={},e=false;c.each(a,function(g,f){b._setOption(g,f); +if(g in m)e=true;if(g in n)d[g]=f});e&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",d)},_setOption:function(a,b){var d=this,e=d.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"): +e.removeClass("ui-dialog-disabled");break;case "draggable":var g=e.is(":data(draggable)");g&&!b&&e.draggable("destroy");!g&&b&&d._makeDraggable();break;case "position":d._position(b);break;case "resizable":(g=e.is(":data(resizable)"))&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title",d.uiDialogTitlebar).html(""+(b||" "));break}c.Widget.prototype._setOption.apply(d,arguments)},_size:function(){var a= +this.options,b,d,e=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});if(a.minWidth>a.width)a.width=a.minWidth;b=this.uiDialog.css({height:"auto",width:a.width}).height();d=Math.max(0,a.minHeight-b);if(a.height==="auto")if(c.support.minHeight)this.element.css({minHeight:d,height:"auto"});else{this.uiDialog.show();a=this.element.css("height","auto").height();e||this.uiDialog.hide();this.element.height(Math.max(a,d))}else this.element.height(Math.max(a.height- +b,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.16",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "), +create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&&c(document).bind(c.ui.dialog.overlay.events,function(d){if(c(d.target).zIndex()
            ").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&&b.bgiframe();this.instances.push(b);return b},destroy:function(a){var b=c.inArray(a,this.instances);b!=-1&&this.oldInstances.push(this.instances.splice(b,1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var d=0;c.each(this.instances,function(){d=Math.max(d,this.css("z-index"))});this.maxZ=d},height:function(){var a,b;if(c.browser.msie&& +c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight);return a").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(b.range==="min"||b.range==="max"?" ui-slider-range-"+b.range:""))}for(var j=c.length;j"); +this.handles=c.add(d(e.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(g){g.preventDefault()}).hover(function(){b.disabled||d(this).addClass("ui-state-hover")},function(){d(this).removeClass("ui-state-hover")}).focus(function(){if(b.disabled)d(this).blur();else{d(".ui-slider .ui-state-focus").removeClass("ui-state-focus");d(this).addClass("ui-state-focus")}}).blur(function(){d(this).removeClass("ui-state-focus")});this.handles.each(function(g){d(this).data("index.ui-slider-handle", +g)});this.handles.keydown(function(g){var k=true,l=d(this).data("index.ui-slider-handle"),i,h,m;if(!a.options.disabled){switch(g.keyCode){case d.ui.keyCode.HOME:case d.ui.keyCode.END:case d.ui.keyCode.PAGE_UP:case d.ui.keyCode.PAGE_DOWN:case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:k=false;if(!a._keySliding){a._keySliding=true;d(this).addClass("ui-state-active");i=a._start(g,l);if(i===false)return}break}m=a.options.step;i=a.options.values&&a.options.values.length? +(h=a.values(l)):(h=a.value());switch(g.keyCode){case d.ui.keyCode.HOME:h=a._valueMin();break;case d.ui.keyCode.END:h=a._valueMax();break;case d.ui.keyCode.PAGE_UP:h=a._trimAlignValue(i+(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(i-(a._valueMax()-a._valueMin())/5);break;case d.ui.keyCode.UP:case d.ui.keyCode.RIGHT:if(i===a._valueMax())return;h=a._trimAlignValue(i+m);break;case d.ui.keyCode.DOWN:case d.ui.keyCode.LEFT:if(i===a._valueMin())return;h=a._trimAlignValue(i- +m);break}a._slide(g,l,h);return k}}).keyup(function(g){var k=d(this).data("index.ui-slider-handle");if(a._keySliding){a._keySliding=false;a._stop(g,k);a._change(g,k);d(this).removeClass("ui-state-active")}});this._refreshValue();this._animateOff=false},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy(); +return this},_mouseCapture:function(a){var b=this.options,c,f,e,j,g;if(b.disabled)return false;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();c=this._normValueFromMouse({x:a.pageX,y:a.pageY});f=this._valueMax()-this._valueMin()+1;j=this;this.handles.each(function(k){var l=Math.abs(c-j.values(k));if(f>l){f=l;e=d(this);g=k}});if(b.range===true&&this.values(1)===b.min){g+=1;e=d(this.handles[g])}if(this._start(a,g)===false)return false; +this._mouseSliding=true;j._handleIndex=g;e.addClass("ui-state-active").focus();b=e.offset();this._clickOffset=!d(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-b.left-e.width()/2,top:a.pageY-b.top-e.height()/2-(parseInt(e.css("borderTopWidth"),10)||0)-(parseInt(e.css("borderBottomWidth"),10)||0)+(parseInt(e.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,g,c);return this._animateOff=true},_mouseStart:function(){return true},_mouseDrag:function(a){var b= +this._normValueFromMouse({x:a.pageX,y:a.pageY});this._slide(a,this._handleIndex,b);return false},_mouseStop:function(a){this.handles.removeClass("ui-state-active");this._mouseSliding=false;this._stop(a,this._handleIndex);this._change(a,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=false},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(a){var b;if(this.orientation==="horizontal"){b= +this.elementSize.width;a=a.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)}else{b=this.elementSize.height;a=a.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)}b=a/b;if(b>1)b=1;if(b<0)b=0;if(this.orientation==="vertical")b=1-b;a=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+b*a)},_start:function(a,b){var c={handle:this.handles[b],value:this.value()};if(this.options.values&&this.options.values.length){c.value=this.values(b); +c.values=this.values()}return this._trigger("start",a,c)},_slide:function(a,b,c){var f;if(this.options.values&&this.options.values.length){f=this.values(b?0:1);if(this.options.values.length===2&&this.options.range===true&&(b===0&&c>f||b===1&&c1){this.options.values[a]=this._trimAlignValue(b);this._refreshValue();this._change(null,a)}else if(arguments.length)if(d.isArray(arguments[0])){c=this.options.values;f=arguments[0];for(e=0;e=this._valueMax())return this._valueMax();var b=this.options.step>0?this.options.step:1,c=(a-this._valueMin())%b;a=a-c;if(Math.abs(c)*2>=b)a+=c>0?b:-b;return parseFloat(a.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var a= +this.options.range,b=this.options,c=this,f=!this._animateOff?b.animate:false,e,j={},g,k,l,i;if(this.options.values&&this.options.values.length)this.handles.each(function(h){e=(c.values(h)-c._valueMin())/(c._valueMax()-c._valueMin())*100;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";d(this).stop(1,1)[f?"animate":"css"](j,b.animate);if(c.options.range===true)if(c.orientation==="horizontal"){if(h===0)c.range.stop(1,1)[f?"animate":"css"]({left:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({width:e- +g+"%"},{queue:false,duration:b.animate})}else{if(h===0)c.range.stop(1,1)[f?"animate":"css"]({bottom:e+"%"},b.animate);if(h===1)c.range[f?"animate":"css"]({height:e-g+"%"},{queue:false,duration:b.animate})}g=e});else{k=this.value();l=this._valueMin();i=this._valueMax();e=i!==l?(k-l)/(i-l)*100:0;j[c.orientation==="horizontal"?"left":"bottom"]=e+"%";this.handle.stop(1,1)[f?"animate":"css"](j,b.animate);if(a==="min"&&this.orientation==="horizontal")this.range.stop(1,1)[f?"animate":"css"]({width:e+"%"}, +b.animate);if(a==="max"&&this.orientation==="horizontal")this.range[f?"animate":"css"]({width:100-e+"%"},{queue:false,duration:b.animate});if(a==="min"&&this.orientation==="vertical")this.range.stop(1,1)[f?"animate":"css"]({height:e+"%"},b.animate);if(a==="max"&&this.orientation==="vertical")this.range[f?"animate":"css"]({height:100-e+"%"},{queue:false,duration:b.animate})}}});d.extend(d.ui.slider,{version:"1.8.16"})})(jQuery); +;/* + * jQuery UI Tabs 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(d,p){function u(){return++v}function w(){return++x}var v=0,x=0;d.widget("ui.tabs",{options:{add:null,ajaxOptions:null,cache:false,cookie:null,collapsible:false,disable:null,disabled:[],enable:null,event:"click",fx:null,idPrefix:"ui-tabs-",load:null,panelTemplate:"
            ",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
          • #{label}
          • "},_create:function(){this._tabify(true)},_setOption:function(b,e){if(b=="selected")this.options.collapsible&& +e==this.options.selected||this.select(e);else{this.options[b]=e;this._tabify()}},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+u()},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var b=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+w());return d.cookie.apply(null,[b].concat(d.makeArray(arguments)))},_ui:function(b,e){return{tab:b,panel:e,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var b= +d(this);b.html(b.data("label.tabs")).removeData("label.tabs")})},_tabify:function(b){function e(g,f){g.css("display","");!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}var a=this,c=this.options,h=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=d(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);this.anchors.each(function(g,f){var i=d(f).attr("href"),l=i.split("#")[0],q;if(l&&(l===location.toString().split("#")[0]|| +(q=d("base")[0])&&l===q.href)){i=f.hash;f.href=i}if(h.test(i))a.panels=a.panels.add(a.element.find(a._sanitizeSelector(i)));else if(i&&i!=="#"){d.data(f,"href.tabs",i);d.data(f,"load.tabs",i.replace(/#.*$/,""));i=a._tabId(f);f.href="#"+i;f=a.element.find("#"+i);if(!f.length){f=d(c.panelTemplate).attr("id",i).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else c.disabled.push(g)});if(b){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(c.selected===p){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){c.selected=g;return false}});if(typeof c.selected!=="number"&&c.cookie)c.selected=parseInt(a._cookie(),10);if(typeof c.selected!=="number"&&this.lis.filter(".ui-tabs-selected").length)c.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"));c.selected=c.selected||(this.lis.length?0:-1)}else if(c.selected===null)c.selected=-1;c.selected=c.selected>=0&&this.anchors[c.selected]||c.selected<0?c.selected:0;c.disabled=d.unique(c.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(c.selected,c.disabled)!=-1&&c.disabled.splice(d.inArray(c.selected,c.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); +if(c.selected>=0&&this.anchors.length){a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash)).removeClass("ui-tabs-hide");this.lis.eq(c.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[c.selected],a.element.find(a._sanitizeSelector(a.anchors[c.selected].hash))[0]))});this.load(c.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else c.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); +this.element[c.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");c.cookie&&this._cookie(c.selected,c.cookie);b=0;for(var j;j=this.lis[b];b++)d(j)[d.inArray(b,c.disabled)!=-1&&!d(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");c.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(c.event!=="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+ +g)};this.lis.bind("mouseover.tabs",function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(c.fx)if(d.isArray(c.fx)){m=c.fx[0];o=c.fx[1]}else m=o=c.fx;var r=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal", +function(){e(f,o);a._trigger("show",null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},s=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")}; +this.anchors.bind(c.event+".tabs",function(){var g=this,f=d(g).closest("li"),i=a.panels.filter(":not(.ui-tabs-hide)"),l=a.element.find(a._sanitizeSelector(g.hash));if(f.hasClass("ui-tabs-selected")&&!c.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a.panels.filter(":animated").length||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}c.selected=a.anchors.index(this);a.abort();if(c.collapsible)if(f.hasClass("ui-tabs-selected")){c.selected= +-1;c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){s(g,i)}).dequeue("tabs");this.blur();return false}else if(!i.length){c.cookie&&a._cookie(c.selected,c.cookie);a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this));this.blur();return false}c.cookie&&a._cookie(c.selected,c.cookie);if(l.length){i.length&&a.element.queue("tabs",function(){s(g,i)});a.element.queue("tabs",function(){r(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; +d.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){if(typeof b=="string")b=this.anchors.index(this.anchors.filter("[href$="+b+"]"));return b},destroy:function(){var b=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e= +d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(c,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this,"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});b.cookie&&this._cookie(null,b.cookie);return this},add:function(b, +e,a){if(a===p)a=this.anchors.length;var c=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,b).replace(/#\{label\}/g,e));b=!b.indexOf("#")?b.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs",true);var j=c.element.find("#"+b);j.length||(j=d(h.panelTemplate).attr("id",b).data("destroy.tabs",true));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);j.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]); +j.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");j.removeClass("ui-tabs-hide");this.element.queue("tabs",function(){c._trigger("show",null,c._ui(c.anchors[0],c.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(b){b=this._getIndex(b);var e=this.options,a=this.lis.eq(b).remove(),c=this.panels.eq(b).remove(); +if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(b+(b+1=b?--h:h});this._tabify();this._trigger("remove",null,this._ui(a.find("a")[0],c[0]));return this},enable:function(b){b=this._getIndex(b);var e=this.options;if(d.inArray(b,e.disabled)!=-1){this.lis.eq(b).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=b});this._trigger("enable",null, +this._ui(this.anchors[b],this.panels[b]));return this}},disable:function(b){b=this._getIndex(b);var e=this.options;if(b!=e.selected){this.lis.eq(b).addClass("ui-state-disabled");e.disabled.push(b);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b]))}return this},select:function(b){b=this._getIndex(b);if(b==-1)if(this.options.collapsible&&this.options.selected!=-1)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+".tabs");return this}, +load:function(b){b=this._getIndex(b);var e=this,a=this.options,c=this.anchors.eq(b)[0],h=d.data(c,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(c,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(b).addClass("ui-state-processing");if(a.spinner){var j=d("span",c);j.data("label.tabs",j.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){e.element.find(e._sanitizeSelector(c.hash)).html(k);e._cleanup();a.cache&&d.data(c, +"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[b],e.panels[b]));try{a.ajaxOptions.error(k,n,b,c)}catch(m){}}}));e.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this}, +url:function(b,e){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.16"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(b,e){var a=this,c=this.options,h=a._rotate||(a._rotate=function(j){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=c.selected;a.select(++k'))}function N(a){return a.bind("mouseout", +function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");b.length&&b.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(b){b=d(b.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!(d.datepicker._isDisabledDatepicker(J.inline?a.parent()[0]:J.input[0])||!b.length)){b.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); +b.addClass("ui-state-hover");b.hasClass("ui-datepicker-prev")&&b.addClass("ui-datepicker-prev-hover");b.hasClass("ui-datepicker-next")&&b.addClass("ui-datepicker-next-hover")}})}function H(a,b){d.extend(a,b);for(var c in b)if(b[c]==null||b[c]==C)a[c]=b[c];return a}d.extend(d.ui,{datepicker:{version:"1.8.16"}});var B=(new Date).getTime(),J;d.extend(M.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv}, +setDefaults:function(a){H(this._defaults,a||{});return this},_attachDatepicker:function(a,b){var c=null;for(var e in this._defaults){var f=a.getAttribute("date:"+e);if(f){c=c||{};try{c[e]=eval(f)}catch(h){c[e]=f}}}e=a.nodeName.toLowerCase();f=e=="div"||e=="span";if(!a.id){this.uuid+=1;a.id="dp"+this.uuid}var i=this._newInst(d(a),f);i.settings=d.extend({},b||{},c||{});if(e=="input")this._connectDatepicker(a,i);else f&&this._inlineDatepicker(a,i)},_newInst:function(a,b){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g, +"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:b,dpDiv:!b?this.dpDiv:N(d('
            '))}},_connectDatepicker:function(a,b){var c=d(a);b.append=d([]);b.trigger=d([]);if(!c.hasClass(this.markerClassName)){this._attachments(c,b);c.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker", +function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});this._autoSize(b);d.data(a,"datepicker",b);b.settings.disabled&&this._disableDatepicker(a)}},_attachments:function(a,b){var c=this._get(b,"appendText"),e=this._get(b,"isRTL");b.append&&b.append.remove();if(c){b.append=d(''+c+"");a[e?"before":"after"](b.append)}a.unbind("focus",this._showDatepicker);b.trigger&&b.trigger.remove();c=this._get(b,"showOn");if(c== +"focus"||c=="both")a.focus(this._showDatepicker);if(c=="button"||c=="both"){c=this._get(b,"buttonText");var f=this._get(b,"buttonImage");b.trigger=d(this._get(b,"buttonImageOnly")?d("").addClass(this._triggerClass).attr({src:f,alt:c,title:c}):d('').addClass(this._triggerClass).html(f==""?c:d("").attr({src:f,alt:c,title:c})));a[e?"before":"after"](b.trigger);b.trigger.click(function(){d.datepicker._datepickerShowing&&d.datepicker._lastInput==a[0]?d.datepicker._hideDatepicker(): +d.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(a){if(this._get(a,"autoSize")&&!a.inline){var b=new Date(2009,11,20),c=this._get(a,"dateFormat");if(c.match(/[DM]/)){var e=function(f){for(var h=0,i=0,g=0;gh){h=f[g].length;i=g}return i};b.setMonth(e(this._get(a,c.match(/MM/)?"monthNames":"monthNamesShort")));b.setDate(e(this._get(a,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-b.getDay())}a.input.attr("size",this._formatDate(a,b).length)}},_inlineDatepicker:function(a, +b){var c=d(a);if(!c.hasClass(this.markerClassName)){c.addClass(this.markerClassName).append(b.dpDiv).bind("setData.datepicker",function(e,f,h){b.settings[f]=h}).bind("getData.datepicker",function(e,f){return this._get(b,f)});d.data(a,"datepicker",b);this._setDate(b,this._getDefaultDate(b),true);this._updateDatepicker(b);this._updateAlternate(b);b.settings.disabled&&this._disableDatepicker(a);b.dpDiv.css("display","block")}},_dialogDatepicker:function(a,b,c,e,f){a=this._dialogInst;if(!a){this.uuid+= +1;this._dialogInput=d('');this._dialogInput.keydown(this._doKeyDown);d("body").append(this._dialogInput);a=this._dialogInst=this._newInst(this._dialogInput,false);a.settings={};d.data(this._dialogInput[0],"datepicker",a)}H(a.settings,e||{});b=b&&b.constructor==Date?this._formatDate(a,b):b;this._dialogInput.val(b);this._pos=f?f.length?f:[f.pageX,f.pageY]:null;if(!this._pos)this._pos=[document.documentElement.clientWidth/ +2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)];this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px");a.settings.onSelect=c;this._inDialog=true;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);d.blockUI&&d.blockUI(this.dpDiv);d.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var b= +d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();d.removeData(a,"datepicker");if(e=="input"){c.append.remove();c.trigger.remove();b.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown",this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)}else if(e=="div"||e=="span")b.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var b=d(a),c=d.data(a,"datepicker");if(b.hasClass(this.markerClassName)){var e= +a.nodeName.toLowerCase();if(e=="input"){a.disabled=false;c.trigger.filter("button").each(function(){this.disabled=false}).end().filter("img").css({opacity:"1.0",cursor:""})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().removeClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f==a?null:f})}},_disableDatepicker:function(a){var b=d(a),c=d.data(a, +"datepicker");if(b.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if(e=="input"){a.disabled=true;c.trigger.filter("button").each(function(){this.disabled=true}).end().filter("img").css({opacity:"0.5",cursor:"default"})}else if(e=="div"||e=="span"){b=b.children("."+this._inlineClass);b.children().addClass("ui-state-disabled");b.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled")}this._disabledInputs=d.map(this._disabledInputs,function(f){return f== +a?null:f});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(a){if(!a)return false;for(var b=0;b-1}},_doKeyUp:function(a){a=d.datepicker._getInst(a.target);if(a.input.val()!=a.lastVal)try{if(d.datepicker.parseDate(d.datepicker._get(a,"dateFormat"),a.input?a.input.val():null,d.datepicker._getFormatConfig(a))){d.datepicker._setDateFromField(a);d.datepicker._updateAlternate(a);d.datepicker._updateDatepicker(a)}}catch(b){d.datepicker.log(b)}return true},_showDatepicker:function(a){a=a.target||a;if(a.nodeName.toLowerCase()!="input")a=d("input", +a.parentNode)[0];if(!(d.datepicker._isDisabledDatepicker(a)||d.datepicker._lastInput==a)){var b=d.datepicker._getInst(a);if(d.datepicker._curInst&&d.datepicker._curInst!=b){d.datepicker._datepickerShowing&&d.datepicker._triggerOnClose(d.datepicker._curInst);d.datepicker._curInst.dpDiv.stop(true,true)}var c=d.datepicker._get(b,"beforeShow");c=c?c.apply(a,[a,b]):{};if(c!==false){H(b.settings,c);b.lastVal=null;d.datepicker._lastInput=a;d.datepicker._setDateFromField(b);if(d.datepicker._inDialog)a.value= +"";if(!d.datepicker._pos){d.datepicker._pos=d.datepicker._findPos(a);d.datepicker._pos[1]+=a.offsetHeight}var e=false;d(a).parents().each(function(){e|=d(this).css("position")=="fixed";return!e});if(e&&d.browser.opera){d.datepicker._pos[0]-=document.documentElement.scrollLeft;d.datepicker._pos[1]-=document.documentElement.scrollTop}c={left:d.datepicker._pos[0],top:d.datepicker._pos[1]};d.datepicker._pos=null;b.dpDiv.empty();b.dpDiv.css({position:"absolute",display:"block",top:"-1000px"});d.datepicker._updateDatepicker(b); +c=d.datepicker._checkOffset(b,c,e);b.dpDiv.css({position:d.datepicker._inDialog&&d.blockUI?"static":e?"fixed":"absolute",display:"none",left:c.left+"px",top:c.top+"px"});if(!b.inline){c=d.datepicker._get(b,"showAnim");var f=d.datepicker._get(b,"duration"),h=function(){var i=b.dpDiv.find("iframe.ui-datepicker-cover");if(i.length){var g=d.datepicker._getBorders(b.dpDiv);i.css({left:-g[0],top:-g[1],width:b.dpDiv.outerWidth(),height:b.dpDiv.outerHeight()})}};b.dpDiv.zIndex(d(a).zIndex()+1);d.datepicker._datepickerShowing= +true;d.effects&&d.effects[c]?b.dpDiv.show(c,d.datepicker._get(b,"showOptions"),f,h):b.dpDiv[c||"show"](c?f:null,h);if(!c||!f)h();b.input.is(":visible")&&!b.input.is(":disabled")&&b.input.focus();d.datepicker._curInst=b}}}},_updateDatepicker:function(a){this.maxRows=4;var b=d.datepicker._getBorders(a.dpDiv);J=a;a.dpDiv.empty().append(this._generateHTML(a));var c=a.dpDiv.find("iframe.ui-datepicker-cover");c.length&&c.css({left:-b[0],top:-b[1],width:a.dpDiv.outerWidth(),height:a.dpDiv.outerHeight()}); +a.dpDiv.find("."+this._dayOverClass+" a").mouseover();b=this._getNumberOfMonths(a);c=b[1];a.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");c>1&&a.dpDiv.addClass("ui-datepicker-multi-"+c).css("width",17*c+"em");a.dpDiv[(b[0]!=1||b[1]!=1?"add":"remove")+"Class"]("ui-datepicker-multi");a.dpDiv[(this._get(a,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl");a==d.datepicker._curInst&&d.datepicker._datepickerShowing&&a.input&&a.input.is(":visible")&& +!a.input.is(":disabled")&&a.input[0]!=document.activeElement&&a.input.focus();if(a.yearshtml){var e=a.yearshtml;setTimeout(function(){e===a.yearshtml&&a.yearshtml&&a.dpDiv.find("select.ui-datepicker-year:first").replaceWith(a.yearshtml);e=a.yearshtml=null},0)}},_getBorders:function(a){var b=function(c){return{thin:1,medium:2,thick:3}[c]||c};return[parseFloat(b(a.css("border-left-width"))),parseFloat(b(a.css("border-top-width")))]},_checkOffset:function(a,b,c){var e=a.dpDiv.outerWidth(),f=a.dpDiv.outerHeight(), +h=a.input?a.input.outerWidth():0,i=a.input?a.input.outerHeight():0,g=document.documentElement.clientWidth+d(document).scrollLeft(),j=document.documentElement.clientHeight+d(document).scrollTop();b.left-=this._get(a,"isRTL")?e-h:0;b.left-=c&&b.left==a.input.offset().left?d(document).scrollLeft():0;b.top-=c&&b.top==a.input.offset().top+i?d(document).scrollTop():0;b.left-=Math.min(b.left,b.left+e>g&&g>e?Math.abs(b.left+e-g):0);b.top-=Math.min(b.top,b.top+f>j&&j>f?Math.abs(f+i):0);return b},_findPos:function(a){for(var b= +this._get(this._getInst(a),"isRTL");a&&(a.type=="hidden"||a.nodeType!=1||d.expr.filters.hidden(a));)a=a[b?"previousSibling":"nextSibling"];a=d(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");if(b)b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var b=this._curInst;if(!(!b||a&&b!=d.data(a,"datepicker")))if(this._datepickerShowing){a=this._get(b,"showAnim");var c=this._get(b,"duration"),e=function(){d.datepicker._tidyDialog(b); +this._curInst=null};d.effects&&d.effects[a]?b.dpDiv.hide(a,d.datepicker._get(b,"showOptions"),c,e):b.dpDiv[a=="slideDown"?"slideUp":a=="fadeIn"?"fadeOut":"hide"](a?c:null,e);a||e();d.datepicker._triggerOnClose(b);this._datepickerShowing=false;this._lastInput=null;if(this._inDialog){this._dialogInput.css({position:"absolute",left:"0",top:"-100px"});if(d.blockUI){d.unblockUI();d("body").append(this.dpDiv)}}this._inDialog=false}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, +_checkExternalClick:function(a){if(d.datepicker._curInst){a=d(a.target);a[0].id!=d.datepicker._mainDivId&&a.parents("#"+d.datepicker._mainDivId).length==0&&!a.hasClass(d.datepicker.markerClassName)&&!a.hasClass(d.datepicker._triggerClass)&&d.datepicker._datepickerShowing&&!(d.datepicker._inDialog&&d.blockUI)&&d.datepicker._hideDatepicker()}},_adjustDate:function(a,b,c){a=d(a);var e=this._getInst(a[0]);if(!this._isDisabledDatepicker(a[0])){this._adjustInstDate(e,b+(c=="M"?this._get(e,"showCurrentAtPos"): +0),c);this._updateDatepicker(e)}},_gotoToday:function(a){a=d(a);var b=this._getInst(a[0]);if(this._get(b,"gotoCurrent")&&b.currentDay){b.selectedDay=b.currentDay;b.drawMonth=b.selectedMonth=b.currentMonth;b.drawYear=b.selectedYear=b.currentYear}else{var c=new Date;b.selectedDay=c.getDate();b.drawMonth=b.selectedMonth=c.getMonth();b.drawYear=b.selectedYear=c.getFullYear()}this._notifyChange(b);this._adjustDate(a)},_selectMonthYear:function(a,b,c){a=d(a);var e=this._getInst(a[0]);e["selected"+(c=="M"? +"Month":"Year")]=e["draw"+(c=="M"?"Month":"Year")]=parseInt(b.options[b.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_selectDay:function(a,b,c,e){var f=d(a);if(!(d(e).hasClass(this._unselectableClass)||this._isDisabledDatepicker(f[0]))){f=this._getInst(f[0]);f.selectedDay=f.currentDay=d("a",e).html();f.selectedMonth=f.currentMonth=b;f.selectedYear=f.currentYear=c;this._selectDate(a,this._formatDate(f,f.currentDay,f.currentMonth,f.currentYear))}},_clearDate:function(a){a=d(a); +this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,b){a=this._getInst(d(a)[0]);b=b!=null?b:this._formatDate(a);a.input&&a.input.val(b);this._updateAlternate(a);var c=this._get(a,"onSelect");if(c)c.apply(a.input?a.input[0]:null,[b,a]);else a.input&&a.input.trigger("change");if(a.inline)this._updateDatepicker(a);else{this._hideDatepicker();this._lastInput=a.input[0];typeof a.input[0]!="object"&&a.input.focus();this._lastInput=null}},_updateAlternate:function(a){var b=this._get(a,"altField"); +if(b){var c=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),f=this.formatDate(c,e,this._getFormatConfig(a));d(b).each(function(){d(this).val(f)})}},noWeekends:function(a){a=a.getDay();return[a>0&&a<6,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b=a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,b,c){if(a==null||b==null)throw"Invalid arguments";b=typeof b=="object"? +b.toString():b+"";if(b=="")return null;var e=(c?c.shortYearCutoff:null)||this._defaults.shortYearCutoff;e=typeof e!="string"?e:(new Date).getFullYear()%100+parseInt(e,10);for(var f=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,h=(c?c.dayNames:null)||this._defaults.dayNames,i=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort,g=(c?c.monthNames:null)||this._defaults.monthNames,j=c=-1,l=-1,u=-1,k=false,o=function(p){(p=A+1-1){j=1;l=u;do{e=this._getDaysInMonth(c,j-1);if(l<=e)break;j++;l-=e}while(1)}v=this._daylightSavingAdjust(new Date(c,j-1,l));if(v.getFullYear()!=c||v.getMonth()+1!=j||v.getDate()!=l)throw"Invalid date";return v},ATOM:"yy-mm-dd", +COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925))*24*60*60*1E7,formatDate:function(a,b,c){if(!b)return"";var e=(c?c.dayNamesShort:null)||this._defaults.dayNamesShort,f=(c?c.dayNames:null)||this._defaults.dayNames,h=(c?c.monthNamesShort:null)||this._defaults.monthNamesShort;c=(c?c.monthNames: +null)||this._defaults.monthNames;var i=function(o){(o=k+1 +12?a.getHours()+2:0);return a},_setDate:function(a,b,c){var e=!b,f=a.selectedMonth,h=a.selectedYear;b=this._restrictMinMax(a,this._determineDate(a,b,new Date));a.selectedDay=a.currentDay=b.getDate();a.drawMonth=a.selectedMonth=a.currentMonth=b.getMonth();a.drawYear=a.selectedYear=a.currentYear=b.getFullYear();if((f!=a.selectedMonth||h!=a.selectedYear)&&!c)this._notifyChange(a);this._adjustInstDate(a);if(a.input)a.input.val(e?"":this._formatDate(a))},_getDate:function(a){return!a.currentYear||a.input&& +a.input.val()==""?null:this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay))},_generateHTML:function(a){var b=new Date;b=this._daylightSavingAdjust(new Date(b.getFullYear(),b.getMonth(),b.getDate()));var c=this._get(a,"isRTL"),e=this._get(a,"showButtonPanel"),f=this._get(a,"hideIfNoPrevNext"),h=this._get(a,"navigationAsDateFormat"),i=this._getNumberOfMonths(a),g=this._get(a,"showCurrentAtPos"),j=this._get(a,"stepMonths"),l=i[0]!=1||i[1]!=1,u=this._daylightSavingAdjust(!a.currentDay? +new Date(9999,9,9):new Date(a.currentYear,a.currentMonth,a.currentDay)),k=this._getMinMaxDate(a,"min"),o=this._getMinMaxDate(a,"max");g=a.drawMonth-g;var m=a.drawYear;if(g<0){g+=12;m--}if(o){var n=this._daylightSavingAdjust(new Date(o.getFullYear(),o.getMonth()-i[0]*i[1]+1,o.getDate()));for(n=k&&nn;){g--;if(g<0){g=11;m--}}}a.drawMonth=g;a.drawYear=m;n=this._get(a,"prevText");n=!h?n:this.formatDate(n,this._daylightSavingAdjust(new Date(m,g-j,1)),this._getFormatConfig(a)); +n=this._canAdjustMonth(a,-1,m,g)?''+n+"":f?"":''+n+"";var s=this._get(a,"nextText");s=!h?s:this.formatDate(s,this._daylightSavingAdjust(new Date(m, +g+j,1)),this._getFormatConfig(a));f=this._canAdjustMonth(a,+1,m,g)?''+s+"":f?"":''+s+"";j=this._get(a,"currentText");s=this._get(a,"gotoCurrent")&& +a.currentDay?u:b;j=!h?j:this.formatDate(j,s,this._getFormatConfig(a));h=!a.inline?'":"";e=e?'
            '+(c?h:"")+(this._isInRange(a,s)?'":"")+(c?"":h)+"
            ":"";h=parseInt(this._get(a,"firstDay"),10);h=isNaN(h)?0:h;j=this._get(a,"showWeek");s=this._get(a,"dayNames");this._get(a,"dayNamesShort");var q=this._get(a,"dayNamesMin"),A=this._get(a,"monthNames"),v=this._get(a,"monthNamesShort"),p=this._get(a,"beforeShowDay"),D=this._get(a,"showOtherMonths"),K=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var E=this._getDefaultDate(a),w="",x=0;x1)switch(G){case 0:y+=" ui-datepicker-group-first";t=" ui-corner-"+(c?"right":"left");break;case i[1]-1:y+=" ui-datepicker-group-last";t=" ui-corner-"+(c?"left":"right");break;default:y+=" ui-datepicker-group-middle";t="";break}y+='">'}y+='
            '+(/all|left/.test(t)&& +x==0?c?f:n:"")+(/all|right/.test(t)&&x==0?c?n:f:"")+this._generateMonthYearHeader(a,g,m,k,o,x>0||G>0,A,v)+'
            ';var z=j?'":"";for(t=0;t<7;t++){var r=(t+h)%7;z+="=5?' class="ui-datepicker-week-end"':"")+'>'+q[r]+""}y+=z+"";z=this._getDaysInMonth(m,g);if(m==a.selectedYear&&g==a.selectedMonth)a.selectedDay=Math.min(a.selectedDay, +z);t=(this._getFirstDayOfMonth(m,g)-h+7)%7;z=Math.ceil((t+z)/7);this.maxRows=z=l?this.maxRows>z?this.maxRows:z:z;r=this._daylightSavingAdjust(new Date(m,g,1-t));for(var Q=0;Q";var R=!j?"":'";for(t=0;t<7;t++){var I=p?p.apply(a.input?a.input[0]:null,[r]):[true,""],F=r.getMonth()!=g,L=F&&!K||!I[0]||k&&ro;R+='";r.setDate(r.getDate()+1);r=this._daylightSavingAdjust(r)}y+=R+""}g++;if(g>11){g=0;m++}y+="
            '+this._get(a,"weekHeader")+"
            '+this._get(a,"calculateWeek")(r)+""+(F&&!D?" ":L?''+ +r.getDate()+"":''+r.getDate()+"")+"
            "+(l?""+(i[0]>0&&G==i[1]-1?'
            ':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': +"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
            ',o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b, +e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
            ";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+ +(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input? +a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c, +e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a, +"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this; +if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a== +"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.16";window["DP_jQuery_"+B]=d})(jQuery); +;/* + * jQuery UI Progressbar 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Progressbar + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + */ +(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
            ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.16"})})(jQuery); +;/* + * jQuery UI Effects 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, +a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= +a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", +"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, +0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, +211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, +d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})}; +f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, +[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), +d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement; +if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)}); +return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this, +arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/ +2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b, +d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c, +a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b, +d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ +e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +;/* + * jQuery UI Effects Fade 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fade + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Fold 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Fold + * + * Depends: + * jquery.effects.core.js + */ +(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], +10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); +;/* + * jQuery UI Effects Highlight 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Highlight + * + * Depends: + * jquery.effects.core.js + */ +(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); +;/* + * jQuery UI Effects Pulsate 1.8.16 + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Pulsate + * + * Depends: + * jquery.effects.core.js + */ +(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); +b.dequeue()})})}})(jQuery); +; \ No newline at end of file diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.js new file mode 100644 index 00000000..d75b4f3c --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.js @@ -0,0 +1,80 @@ +/* + * jQuery UI Effects Blind 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Blind + * + * Depends: + * jquery.effects.core.js + */ +(function( $, undefined ) { + +var rvertical = /up|down|vertical/, + rpositivemotion = /up|left|vertical|horizontal/; + +$.effects.effect.blind = function( o, done ) { + // Create element + var el = $( this ), + props = [ "position", "top", "bottom", "left", "right", "height", "width" ], + mode = $.effects.setMode( el, o.mode || "hide" ), + direction = o.direction || "up", + vertical = rvertical.test( direction ), + ref = vertical ? "height" : "width", + ref2 = vertical ? "top" : "left", + motion = rpositivemotion.test( direction ), + animation = {}, + show = mode === "show", + wrapper, distance, top; + + // if already wrapped, the wrapper's properties are my property. #6245 + if ( el.parent().is( ".ui-effects-wrapper" ) ) { + $.effects.save( el.parent(), props ); + } else { + $.effects.save( el, props ); + } + el.show(); + top = parseInt(el.css('top'), 10); + wrapper = $.effects.createWrapper( el ).css({ + overflow: "hidden" + }); + + distance = vertical ? wrapper[ ref ]() + top : wrapper[ ref ](); + + animation[ ref ] = show ? distance : 0; + if ( !motion ) { + el + .css( vertical ? "bottom" : "right", 0 ) + .css( vertical ? "top" : "left", "" ) + .css({ position: "absolute" }); + animation[ ref2 ] = show ? 0 : distance; + } + + // start at 0 if we are showing + if ( show ) { + wrapper.css( ref, 0 ); + if ( ! motion ) { + wrapper.css( ref2, distance ); + } + } + + // Animate + wrapper.animate( animation, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + if ( mode === "hide" ) { + el.hide(); + } + $.effects.restore( el, props ); + $.effects.removeWrapper( el ); + done(); + } + }); + +}; + +})(jQuery); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.min.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.min.js new file mode 100644 index 00000000..101c15d4 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.blind.min.js @@ -0,0 +1,14 @@ +/* + * jQuery UI Effects Blind 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/Blind + * + * Depends: + * jquery.effects.core.js + */ +(function(b){var n=/up|down|vertical/,o=/up|left|vertical|horizontal/;b.effects.effect.blind=function(g,p){var a=b(this),i=["position","top","bottom","left","right","height","width"],l=b.effects.setMode(a,g.mode||"hide"),e=g.direction||"up",f=n.test(e),h=f?"height":"width",m=f?"top":"left";e=o.test(e);var j={},k=l==="show",c,d;a.parent().is(".ui-effects-wrapper")?b.effects.save(a.parent(),i):b.effects.save(a,i);a.show();d=parseInt(a.css("top"),10);c=b.effects.createWrapper(a).css({overflow:"hidden"}); +d=f?c[h]()+d:c[h]();j[h]=k?d:0;if(!e){a.css(f?"bottom":"right",0).css(f?"top":"left","").css({position:"absolute"});j[m]=k?0:d}if(k){c.css(h,0);e||c.css(m,d)}c.animate(j,{duration:g.duration,easing:g.easing,queue:false,complete:function(){l==="hide"&&a.hide();b.effects.restore(a,i);b.effects.removeWrapper(a);p()}})}})(jQuery); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.js new file mode 100644 index 00000000..ab9349a8 --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.js @@ -0,0 +1,890 @@ +/* + * jQuery UI Effects 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +;jQuery.effects || (function($, undefined) { + +var backCompat = $.uiBackCompat !== false; + +$.effects = { + effect: {} +}; + +/******************************************************************************/ +/****************************** COLOR ANIMATIONS ******************************/ +/******************************************************************************/ + +// override the animation for color styles +$.each(["backgroundColor", "borderBottomColor", "borderLeftColor", + "borderRightColor", "borderTopColor", "borderColor", "color", "outlineColor"], +function(i, attr) { + $.fx.step[attr] = function(fx) { + if (!fx.colorInit) { + fx.start = getColor(fx.elem, attr); + fx.end = getRGB(fx.end); + fx.colorInit = true; + } + + fx.elem.style[attr] = "rgb(" + + Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + "," + + Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + "," + + Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ")"; + }; +}); + +// Color Conversion functions from highlightFade +// By Blair Mitchelmore +// http://jquery.offput.ca/highlightFade/ + +// Parse strings looking for color tuples [255,255,255] +function getRGB(color) { + var result; + + // Check if we're already dealing with an array of colors + if ( color && color.constructor === Array && color.length === 3 ) + return color; + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) + return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) + return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) + return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) + return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; + + // Look for rgba(0, 0, 0, 0) == transparent in Safari 3 + if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) + return colors["transparent"]; + + // Otherwise, we're most likely dealing with a named color + return colors[$.trim(color).toLowerCase()]; +} + +function getColor(elem, attr) { + var color; + + do { + color = $.curCSS(elem, attr); + + // Keep going until we find an element that has color, or we hit the body + if ( color != "" && color !== "transparent" || $.nodeName(elem, "body") ) + break; + + attr = "backgroundColor"; + } while ( elem = elem.parentNode ); + + return getRGB(color); +}; + +// Some named colors to work with +// From Interface by Stefan Petre +// http://interface.eyecon.ro/ + +var colors = { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0], + transparent: [255,255,255] +}; + + + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ + +var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }, + // prefix used for storing data on .data() + dataSpace = "ec.storage."; + +$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; +}); + +function getElementStyles() { + var style = this.ownerDocument.defaultView + ? this.ownerDocument.defaultView.getComputedStyle( this, null ) + : this.currentStyle, + newStyle = {}, + key, + camelCase, + len; + + // webkit enumerates style porperties + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + newStyle[ $.camelCase( key ) ] = style[ key ]; + } + } + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + newStyle[ key ] = style[ key ]; + } + } + } + + return newStyle; +} + + +function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; + + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] != value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } + + return diff; +} + +$.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + finalClass, + allAnimations = o.children ? animated.find( "*" ).andSelf() : animated; + + // map the animated objects to store the original styles. + allAnimations = allAnimations.map(function() { + var el = $( this ); + return { + el: el, + originalStyleAttr: el.attr( "style" ) || " ", + start: getElementStyles.call( this ) + }; + }); + + // apply class change + $.each( classAnimationActions, function(i, action) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + }); + finalClass = animated.attr( "class" ); + + // map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map(function() { + this.end = getElementStyles.call( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + }); + + // apply original class + animated.attr( "class", baseClass ); + + // map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map(function() { + var styleInfo = this, + dfd = $.Deferred(); + + this.el.animate( this.diff, { + duration: o.duration, + easing: o.easing, + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + }); + return dfd.promise(); + }); + + // once all animations have completed: + $.when.apply( $, allAnimations.get() ).done(function() { + + // set the final class + animated.attr( "class", finalClass ); + + // for each animated element + $.each( arguments, function() { + if ( typeof this.el.attr( "style" ) === "object" ) { + this.el.attr( "style" ).cssText = ""; + this.el.attr( "style" ).cssText = this.originalStyleAttr; + } else { + this.el.attr( "style", this.originalStyleAttr ); + } + }); + + // this is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + }); + }); +}; + +$.fn.extend({ + _addClass: $.fn.addClass, + addClass: function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.apply( this, [{ add: classNames }, speed, easing, callback ]) : + this._addClass(classNames); + }, + + _removeClass: $.fn.removeClass, + removeClass: function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.apply( this, [{ remove: classNames }, speed, easing, callback ]) : + this._removeClass(classNames); + }, + + _toggleClass: $.fn.toggleClass, + toggleClass: function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { + // without speed parameter; + return this._toggleClass( classNames, force ); + } else { + return $.effects.animateClass.apply( this, [( force ? { add:classNames } : { remove:classNames }), speed, easing, callback ]); + } + } else { + // without force parameter; + return $.effects.animateClass.apply( this, [{ toggle: classNames }, force, speed, easing ]); + } + }, + + switchClass: function( remove, add, speed, easing, callback) { + return $.effects.animateClass.apply( this, [{ + add: add, + remove: remove + }, speed, easing, callback ]); + } +}); + + + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +$.extend( $.effects, { + version: "1.9pre", + + // Saves a set of properties in a data storage + save: function( element, set ) { + for( var i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + for( var i=0; i < set.length; i++ ) { + if ( set[ i ] !== null ) { + element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); + } + } + }, + + setMode: function( el, mode ) { + if (mode === "toggle") { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + // this should be a little more flexible in the future to handle a string & hash + getBaseline: function( origin, original ) { + var y, x; + switch ( origin[ 0 ] ) { + case "top": y = 0; break; + case "middle": y = 0.5; break; + case "bottom": y = 1; break; + default: y = origin[ 0 ] / original.height; + }; + switch ( origin[ 1 ] ) { + case "left": x = 0; break; + case "center": x = 0.5; break; + case "right": x = 1; break; + default: x = origin[ 1 ] / original.width; + }; + return { + x: x, + y: y + }; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { + + // if the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" )) { + return element.parent(); + } + + // wrap the element + var props = { + width: element.outerWidth(true), + height: element.outerHeight(true), + "float": element.css( "float" ) + }, + wrapper = $( "
            " ) + .addClass( "ui-effects-wrapper" ) + .css({ + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + }), + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + + wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element + + // transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css({ position: "relative" }); + element.css({ position: "relative" }); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + }); + $.each([ "top", "left", "bottom", "right" ], function(i, pos) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; + } + }); + element.css({ + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + }); + } + element.css(size); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).focus(); + } + } + + + return element; + }, + + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function(i, x){ + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + }); + return value; + } +}); + +// return an effect options object for the given parameters: +function _normalizeArguments( effect, options, speed, callback ) { + + // short path for passing an effect options object: + if ( $.isPlainObject( effect ) ) { + return effect; + } + + // convert to an object + effect = { effect: effect }; + + // catch (effect) + if ( options === undefined ) { + options = {}; + } + + // catch (effect, callback) + if ( $.isFunction( options ) ) { + callback = options; + speed = null; + options = {}; + } + + // catch (effect, speed, ?) + if ( $.type( options ) === "number" || $.fx.speeds[ options ]) { + callback = speed; + speed = options; + options = {}; + } + + // catch (effect, options, callback) + if ( $.isFunction( speed ) ) { + callback = speed; + speed = null; + } + + // add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : typeof speed === "number" + ? speed : speed in $.fx.speeds ? $.fx.speeds[ speed ] : $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; +} + +function standardSpeed( speed ) { + // valid standard speeds + if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) { + return true; + } + + // invalid strings - treat as "normal" speed + if ( typeof speed === "string" && !$.effects.effect[ speed ] ) { + // TODO: remove in 2.0 (#7115) + if ( backCompat && $.effects[ speed ] ) { + return false; + } + return true; + } + + return false; +} + +$.fn.extend({ + effect: function( effect, options, speed, callback ) { + var args = _normalizeArguments.apply( this, arguments ), + mode = args.mode, + queue = args.queue, + effectMethod = $.effects.effect[ args.effect ], + + // DEPRECATED: remove in 2.0 (#7115) + oldEffectMethod = !effectMethod && backCompat && $.effects[ args.effect ]; + + if ( $.fx.off || !( effectMethod || oldEffectMethod ) ) { + // delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, args.complete ); + } else { + return this.each( function() { + if ( args.complete ) { + args.complete.call( this ); + } + }); + } + } + + function run( next ) { + var elem = $( this ), + complete = args.complete, + mode = args.mode; + + function done() { + if ( $.isFunction( complete ) ) { + complete.call( elem[0] ); + } + if ( $.isFunction( next ) ) { + next(); + } + } + + // if the element is hiddden and mode is hide, + // or element is visible and mode is show + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + done(); + } else { + effectMethod.call( elem[0], args, done ); + } + } + + // TODO: remove this check in 2.0, effectMethod will always be true + if ( effectMethod ) { + return queue === false ? this.each( run ) : this.queue( queue || "fx", run ); + } else { + // DEPRECATED: remove in 2.0 (#7115) + return oldEffectMethod.call(this, { + options: args, + duration: args.duration, + callback: args.complete, + mode: args.mode + }); + } + }, + + _show: $.fn.show, + show: function( speed ) { + if ( standardSpeed( speed ) ) { + return this._show.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }, + + _hide: $.fn.hide, + hide: function( speed ) { + if ( standardSpeed( speed ) ) { + return this._hide.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }, + + // jQuery core overloads toggle and creates _toggle + __toggle: $.fn.toggle, + toggle: function( speed ) { + if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) { + return this.__toggle.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }, + + // helper functions + cssUnit: function(key) { + var style = this.css( key ), + val = []; + + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { + if ( style.indexOf( unit ) > 0 ) + val = [ parseFloat( style ), unit ]; + }); + return val; + } +}); + + + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + +/* + * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/ + * + * Uses the built in easing capabilities added In jQuery 1.1 + * to offer multiple easing options + * + * TERMS OF USE - jQuery Easing + * + * Open source under the BSD License. + * + * Copyright 2008 George McGinley Smith + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * +*/ + +// t: current time, b: begInnIng value, c: change In value, d: duration +$.easing.jswing = $.easing.swing; + +$.extend( $.easing, { + def: "easeOutQuad", + swing: function ( x, t, b, c, d ) { + return $.easing[ $.easing.def ]( x, t, b, c, d ); + }, + easeInQuad: function ( x, t, b, c, d ) { + return c * ( t /= d ) * t + b; + }, + easeOutQuad: function ( x, t, b, c, d ) { + return -c * ( t /= d ) * ( t - 2 ) + b; + }, + easeInOutQuad: function ( x, t, b, c, d ) { + if ( ( t /= d / 2 ) < 1 ) return c / 2 * t * t + b; + return -c / 2 * ( ( --t ) * ( t-2 ) - 1) + b; + }, + easeInCubic: function ( x, t, b, c, d ) { + return c * ( t /= d ) * t * t + b; + }, + easeOutCubic: function ( x, t, b, c, d ) { + return c * ( ( t = t / d - 1 ) * t * t + 1 ) + b; + }, + easeInOutCubic: function ( x, t, b, c, d ) { + if ( ( t /= d / 2 ) < 1 ) return c / 2 * t * t * t + b; + return c / 2 * ( ( t -= 2 ) * t * t + 2) + b; + }, + easeInQuart: function ( x, t, b, c, d ) { + return c * ( t /= d ) * t * t * t + b; + }, + easeOutQuart: function ( x, t, b, c, d ) { + return -c * ( ( t = t / d - 1 ) * t * t * t - 1) + b; + }, + easeInOutQuart: function ( x, t, b, c, d ) { + if ( (t /= d / 2 ) < 1 ) return c / 2 * t * t * t * t + b; + return -c / 2 * ( ( t -= 2 ) * t * t * t - 2) + b; + }, + easeInQuint: function ( x, t, b, c, d ) { + return c * ( t /= d ) * t * t * t * t + b; + }, + easeOutQuint: function ( x, t, b, c, d ) { + return c * ( ( t = t / d - 1 ) * t * t * t * t + 1) + b; + }, + easeInOutQuint: function ( x, t, b, c, d ) { + if ( ( t /= d / 2 ) < 1 ) return c / 2 * t * t * t * t * t + b; + return c / 2 * ( ( t -= 2 ) * t * t * t * t + 2) + b; + }, + easeInSine: function ( x, t, b, c, d ) { + return -c * Math.cos( t / d * ( Math.PI / 2 ) ) + c + b; + }, + easeOutSine: function ( x, t, b, c, d ) { + return c * Math.sin( t / d * ( Math.PI /2 ) ) + b; + }, + easeInOutSine: function ( x, t, b, c, d ) { + return -c / 2 * ( Math.cos( Math.PI * t / d ) - 1 ) + b; + }, + easeInExpo: function ( x, t, b, c, d ) { + return ( t==0 ) ? b : c * Math.pow( 2, 10 * ( t / d - 1) ) + b; + }, + easeOutExpo: function ( x, t, b, c, d ) { + return ( t==d ) ? b + c : c * ( -Math.pow( 2, -10 * t / d) + 1) + b; + }, + easeInOutExpo: function ( x, t, b, c, d ) { + if ( t==0 ) return b; + if ( t==d ) return b + c; + if ( ( t /= d / 2) < 1) return c / 2 * Math.pow( 2, 10 * (t - 1) ) + b; + return c / 2 * ( -Math.pow( 2, -10 * --t ) + 2 ) + b; + }, + easeInCirc: function ( x, t, b, c, d ) { + return -c * ( Math.sqrt( 1 - ( t /= d ) * t ) - 1 ) + b; + }, + easeOutCirc: function ( x, t, b, c, d ) { + return c * Math.sqrt( 1 - ( t = t / d - 1 ) * t ) + b; + }, + easeInOutCirc: function ( x, t, b, c, d ) { + if ( ( t /= d / 2) < 1 ) return -c / 2 * ( Math.sqrt( 1 - t * t ) - 1 ) + b; + return c / 2 * ( Math.sqrt( 1 - ( t -= 2 ) * t ) + 1 ) + b; + }, + easeInElastic: function ( x, t, b, c, d ) { + var s = 1.70158, + p = d * 0.3, + a = c; + if ( t == 0 ) return b; + if ( ( t /= d ) == 1 ) return b+c; + if ( a < Math.abs( c ) ) { + a = c; + s = p / 4; + } else { + s = p / ( 2 * Math.PI ) * Math.asin( c / a ); + } + return - ( a * Math.pow( 2, 10 * ( t -= 1 ) ) * Math.sin( ( t * d - s) * ( 2 * Math.PI ) / p ) ) + b; + }, + easeOutElastic: function ( x, t, b, c, d ) { + var s = 1.70158, + p = d * 0.3, + a = c; + if ( t == 0 ) return b; + if ( ( t /= d ) == 1 ) return b+c; + if ( a < Math.abs( c ) ) { + a = c; + s = p / 4; + } else { + s = p / ( 2 * Math.PI ) * Math.asin( c / a ); + } + return a * Math.pow( 2, -10 * t ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) + c + b; + }, + easeInOutElastic: function ( x, t, b, c, d ) { + var s = 1.70158, + p = d * ( 0.3 * 1.5 ), + a = c; + if ( t == 0 ) return b; + if ( ( t /= d / 2 ) == 2 ) return b+c; + if ( a < Math.abs( c ) ) { + a = c; + s = p / 4; + } else { + s = p / ( 2 * Math.PI ) * Math.asin( c / a ); + } + if ( t < 1 ) return -.5 * ( a * Math.pow( 2, 10 * ( t -= 1 ) ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) ) + b; + return a * Math.pow( 2, -10 * ( t -= 1 ) ) * Math.sin( ( t * d - s ) * ( 2 * Math.PI ) / p ) *.5 + c + b; + }, + easeInBack: function ( x, t, b, c, d, s ) { + if ( s == undefined ) s = 1.70158; + return c * ( t /= d ) * t * ( ( s+1 ) * t - s ) + b; + }, + easeOutBack: function ( x, t, b, c, d, s ) { + if ( s == undefined ) s = 1.70158; + return c * ( ( t = t / d - 1 ) * t * ( ( s + 1 ) * t + s) + 1) + b; + }, + easeInOutBack: function ( x, t, b, c, d, s ) { + if ( s == undefined ) s = 1.70158; + if ( ( t /= d / 2 ) < 1 ) return c / 2 * ( t * t * ( ( ( s *= 1.525 ) + 1 ) * t - s ) ) + b; + return c / 2 * ( ( t -= 2 ) * t * ( ( ( s *= 1.525 ) + 1 ) * t + s) + 2) + b; + }, + easeInBounce: function ( x, t, b, c, d ) { + return c - $.easing.easeOutBounce( x, d - t, 0, c, d ) + b; + }, + easeOutBounce: function ( x, t, b, c, d ) { + if ( ( t /= d ) < ( 1 / 2.75 ) ) { + return c * ( 7.5625 * t * t ) + b; + } else if ( t < ( 2 / 2.75 ) ) { + return c * ( 7.5625 * ( t -= ( 1.5 / 2.75 ) ) * t + .75 ) + b; + } else if ( t < ( 2.5 / 2.75 ) ) { + return c * ( 7.5625 * ( t -= ( 2.25/ 2.75 ) ) * t + .9375 ) + b; + } else { + return c * ( 7.5625 * ( t -= ( 2.625 / 2.75 ) ) * t + .984375 ) + b; + } + }, + easeInOutBounce: function ( x, t, b, c, d ) { + if ( t < d / 2 ) return $.easing.easeInBounce( x, t * 2, 0, c, d ) * .5 + b; + return $.easing.easeOutBounce( x, t * 2 - d, 0, c, d ) * .5 + c * .5 + b; + } +}); + +/* + * + * TERMS OF USE - EASING EQUATIONS + * + * Open source under the BSD License. + * + * Copyright 2001 Robert Penner + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * Neither the name of the author nor the names of contributors may be used to endorse + * or promote products derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +})(jQuery); diff --git a/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.min.js b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.min.js new file mode 100644 index 00000000..9e92123a --- /dev/null +++ b/wqflask/wqflask/static/packages/jqplot/examples/jquery-ui/js/jquery.effects.core.min.js @@ -0,0 +1,32 @@ +/* + * jQuery UI Effects 1.9pre + * + * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||function(f,m){function r(c){var a;if(c&&c.constructor===Array&&c.length===3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], +16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return s.transparent;return s[f.trim(c).toLowerCase()]}function t(){var c=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(d=c.length;d--;){b=c[d];if(typeof c[b]==="string")a[f.camelCase(b)]=c[b]}else for(b in c)if(typeof c[b]=== +"string")a[b]=c[b];return a}function o(c,a,b,d){if(f.isPlainObject(c))return c;c={effect:c};if(a===m)a={};if(f.isFunction(a)){d=a;b=null;a={}}if(f.type(a)==="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a&&f.extend(c,a);b=b||a.duration;c.duration=f.fx.off?0:typeof b==="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;c.complete=d||a.complete;return c}function q(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects.effect[c]){if(u&& +f.effects[c])return false;return true}return false}var u=f.uiBackCompat!==false;f.effects={effect:{}};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){var d;d=b.elem;var e=a,g;do{g=f.curCSS(d,e);if(g!=""&&g!=="transparent"||f.nodeName(d,"body"))break;e="backgroundColor"}while(d=d.parentNode);d=r(g);b.start=d;b.end=r(b.end);b.colorInit=true}b.elem.style[a]= +"rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var s={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139, +0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192, +203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},w=["add","remove","toggle"],x={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(c,a){f.fx.step[a]=function(b){if(b.end!=="none"&&!b.setAttr||b.pos===1&&!b.setAttr){jQuery.style(b.elem,a,b.end);b.setAttr= +true}}});f.effects.animateClass=function(c,a,b,d){var e=f.speed(a,b,d);return this.queue(function(){var g=f(this),h=g.attr("class")||"",n,j=e.children?g.find("*").andSelf():g;j=j.map(function(){var k=f(this);return{el:k,originalStyleAttr:k.attr("style")||" ",start:t.call(this)}});f.each(w,function(k,i){if(c[i])g[i+"Class"](c[i])});n=g.attr("class");j=j.map(function(){this.end=t.call(this.el[0]);var k=this.start,i=this.end,v={},l,p;for(l in i){p=i[l];if(k[l]!=p)if(!x[l])if(f.fx.step[l]||!isNaN(parseFloat(p)))v[l]= +p}this.diff=v;return this});g.attr("class",h);j=j.map(function(){var k=this,i=f.Deferred();this.el.animate(this.diff,{duration:e.duration,easing:e.easing,queue:false,complete:function(){i.resolve(k)}});return i.promise()});f.when.apply(f,j.get()).done(function(){g.attr("class",n);f.each(arguments,function(){if(typeof this.el.attr("style")==="object"){this.el.attr("style").cssText="";this.el.attr("style").cssText=this.originalStyleAttr}else this.el.attr("style",this.originalStyleAttr)});e.complete.call(g[0])})})}; +f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a==="boolean"||a===m?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, +[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.9pre",save:function(c,a){for(var b=0;b").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), +d={width:c.width(),height:c.height()},e=document.activeElement;c.wrap(b);if(c[0]===e||f.contains(c[0],e))f(e).focus();b=c.parent();if(c.css("position")==="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(g,h){a[h]=c.css(h);if(isNaN(parseInt(a[h],10)))a[h]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}c.css(d);return b.css(a).show()}, +removeWrapper:function(c){var a=document.activeElement;if(c.parent().is(".ui-effects-wrapper")){c.parent().replaceWith(c);if(c[0]===a||f.contains(c[0],a))f(a).focus()}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){var h=c.cssUnit(g);if(h[0]>0)d[g]=h[0]*b+h[1]});return d}});f.fn.extend({effect:function(){function c(h){function n(){f.isFunction(k)&&k.call(j[0]);f.isFunction(h)&&h()}var j=f(this),k=a.complete,i=a.mode;(j.is(":hidden")?i==="hide":i==="show")?n():e.call(j[0], +a,n)}var a=o.apply(this,arguments),b=a.mode,d=a.queue,e=f.effects.effect[a.effect],g=!e&&u&&f.effects[a.effect];if(f.fx.off||!(e||g))return b?this[b](a.duration,a.complete):this.each(function(){a.complete&&a.complete.call(this)});return e?d===false?this.each(c):this.queue(d||"fx",c):g.call(this,{options:a,duration:a.duration,callback:a.complete,mode:a.mode})},_show:f.fn.show,show:function(c){if(q(c))return this._show.apply(this,arguments);else{var a=o.apply(this,arguments);a.mode="show";return this.effect.call(this, +a)}},_hide:f.fn.hide,hide:function(c){if(q(c))return this._hide.apply(this,arguments);else{var a=o.apply(this,arguments);a.mode="hide";return this.effect.call(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(q(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=o.apply(this,arguments);a.mode="toggle";return this.effect.call(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a), +e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a, +b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2* +((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+ +b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=e*0.3,h=d;if(a==0)return b;if((a/=e)==1)return b+d;if(h + + +// Create a jquery plugin that prints the given element. +jQuery.fn.print = function(){ + // NOTE: We are trimming the jQuery collection down to the + // first element in the collection. + if (this.size() > 1){ + this.eq( 0 ).print(); + return; + } else if (!this.size()){ + return; + } + + var chart = $(this).closest('div.quintile-outer-container').find('div.jqplot-target'); + var imgelem = chart.jqplotToImageElem(); + console.log(imgelem); + + // ASSERT: At this point, we know that the current jQuery + // collection (as defined by THIS), contains only one + // printable element. + + // Create a random name for the print frame. + var strFrameName = ("printer-" + (new Date()).getTime()); + + // Create an iFrame with the new name. + var jFrame = $( "