5 new commits in galaxy-central:
https://bitbucket.org/galaxy/galaxy-central/commits/e51282a5b1bf/ Changeset: e51282a5b1bf User: dannon Date: 2014-02-22 15:25:20 Summary: Cloudlaunch cleanup/pep8 Affected #: 1 file
diff -r fac578cca75887d811e67993a655fed20c0d8713 -r e51282a5b1bff80518db274800c2be7de2968785 lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py --- a/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py +++ b/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py @@ -11,13 +11,14 @@ import os import tempfile import time -import pkg_resources + from galaxy import eggs -pkg_resources.require('boto') -import boto from galaxy import web from galaxy.web.base.controller import BaseUIController from galaxy.util.json import to_json_string + +eggs.require('boto') +import boto from boto.ec2.regioninfo import RegionInfo from boto.exception import EC2ResponseError, S3ResponseError from boto.s3.connection import OrdinaryCallingFormat, S3Connection @@ -29,20 +30,24 @@
class CloudController(BaseUIController): + """Galaxy Cloud Functions"""
def __init__(self, app): BaseUIController.__init__(self, app)
@web.expose - def index(self, trans, share_string=None, ami=None, bucket_default = None): + def index(self, trans, share_string=None, ami=None, bucket_default=None): + """ + Serves the default page requesting AWS keys + """ return trans.fill_template("cloud/index.mako", - default_keypair = DEFAULT_KEYPAIR, - share_string=share_string, - ami=ami, - bucket_default=bucket_default) + default_keypair=DEFAULT_KEYPAIR, + share_string=share_string, + ami=ami, + bucket_default=bucket_default)
@web.expose - def get_account_info(self, trans, key_id, secret, **kwargs): + def get_account_info(self, trans, key_id, secret): """ Get EC2 Account Info """ @@ -54,7 +59,7 @@ except EC2ResponseError, e: log.error("Problem starting an instance: %s\n%s" % (e, e.body)) trans.response.status = 400 - return e.error_message or "Instance failure, but no specific error was detected. Please check your AWS Console." + return e.error_message or "Error retrieving account information. Please verify your credentials are correct, and contact galaxy support to report this issue." account_info['keypairs'] = [akp.name for akp in kps] #Existing Clusters s3_conn = S3Connection(key_id, secret, calling_format=OrdinaryCallingFormat()) @@ -79,7 +84,7 @@ for line in pd_contents.split('\n'): if 'vol_id' in line: vol_id = line.split(':')[1].strip() - v = ec2_conn.get_all_volumes(volume_ids = [vol_id]) + v = ec2_conn.get_all_volumes(volume_ids=[vol_id]) if v: zone = v[0].zone else: @@ -91,7 +96,7 @@ if key.name.endswith('.clusterName'): clusters.append({'name': key.name.split('.clusterName')[0], 'persistent_data': pd_contents, - 'zone':zone}) + 'zone': zone}) account_info['clusters'] = clusters account_info['zones'] = [z.name for z in ec2_conn.get_all_zones()] return to_json_string(account_info) @@ -111,29 +116,25 @@ return ec2_error else: user_provided_data = {'cluster_name': cluster_name, - 'access_key': key_id, - 'secret_key': secret, - 'instance_type': instance_type} + 'access_key': key_id, + 'secret_key': secret, + 'instance_type': instance_type} if password: user_provided_data['password'] = password if share_string: user_provided_data['share_string'] = share_string if bucket_default: - user_provided_data['bucket_default'] = bucket_default - + user_provided_data['bucket_default'] = bucket_default if not ami: ami = trans.app.config.cloudlaunch_default_ami - rs = run_instance(ec2_conn=ec2_conn, - image_id = ami, - user_provided_data=user_provided_data, - key_name=kp_name, - security_groups=[sg_name], - placement=zone - ) + image_id=ami, + user_provided_data=user_provided_data, + key_name=kp_name, + security_groups=[sg_name], + placement=zone) if rs: instance = rs.instances[0] - ct = 0 while not instance.public_dns_name: try: instance.update() @@ -141,7 +142,6 @@ #This can happen when update is invoked before the instance is fully registered. #Prevent failure, wait it out. pass - ct += 1 time.sleep(1) if kp_material: #We have created a keypair. Save to tempfile for one time retrieval. @@ -152,14 +152,12 @@ kp_material_tag = fname[fname.rfind(PKEY_PREFIX) + len(PKEY_PREFIX):] else: kp_material_tag = None - return to_json_string({ - 'cluster_name': cluster_name, - 'instance_id': rs.instances[0].id, - 'image_id': rs.instances[0].image_id, - 'public_dns_name': rs.instances[0].public_dns_name, - 'kp_name': kp_name, - 'kp_material_tag':kp_material_tag - }) + return to_json_string({'cluster_name': cluster_name, + 'instance_id': rs.instances[0].id, + 'image_id': rs.instances[0].image_id, + 'public_dns_name': rs.instances[0].public_dns_name, + 'kp_name': kp_name, + 'kp_material_tag': kp_material_tag}) else: trans.response.status = 400 return "Instance failure, but no specific error was detected. Please check your AWS Console." @@ -173,16 +171,17 @@ kp_material = f.read() f.close() trans.response.headers['Content-Length'] = int( os.stat( expected_path ).st_size ) - trans.response.set_content_type( "application/octet-stream" ) #force octet-stream so Safari doesn't append mime extensions to filename + trans.response.set_content_type( "application/octet-stream" ) # force octet-stream so Safari doesn't append mime extensions to filename trans.response.headers["Content-Disposition"] = 'attachment; filename="%s.pem"' % DEFAULT_KEYPAIR os.remove(expected_path) return kp_material trans.response.status = 400 return "Invalid identifier"
-# ## Cloud interaction methods + def connect_ec2(a_key, s_key): - """ Create and return an EC2 connection object. + """ + Create and return an EC2 connection object. """ # Use variables for forward looking flexibility # AWS connection values @@ -193,14 +192,15 @@ ec2_conn_path = '/' r = RegionInfo(name=region_name, endpoint=region_endpoint) ec2_conn = boto.connect_ec2(aws_access_key_id=a_key, - aws_secret_access_key=s_key, - api_version='2011-11-01', # needed for availability zone support - is_secure=is_secure, - region=r, - port=ec2_port, - path=ec2_conn_path) + aws_secret_access_key=s_key, + api_version='2011-11-01', # needed for availability zone support + is_secure=is_secure, + region=r, + port=ec2_port, + path=ec2_conn_path) return ec2_conn
+ def create_cm_security_group(ec2_conn, sg_name='CloudMan'): """ Create a security group with all authorizations required to run CloudMan. If the group already exists, check its rules and add the missing ones. @@ -220,11 +220,11 @@ cmsg = ec2_conn.create_security_group(sg_name, 'A security group for CloudMan') # Add appropriate authorization rules # If these rules already exist, nothing will be changed in the SG - ports = (('80', '80'), # Web UI - ('20', '21'), # FTP - ('22', '22'), # ssh - ('30000', '30100'), # FTP transfer - ('42284', '42284')) # CloudMan UI + ports = (('80', '80'), # Web UI + ('20', '21'), # FTP + ('22', '22'), # ssh + ('30000', '30100'), # FTP transfer + ('42284', '42284')) # CloudMan UI for port in ports: try: if not rule_exists(cmsg.rules, from_port=port[0], to_port=port[1]): @@ -234,7 +234,7 @@ except EC2ResponseError, e: log.error("A problem with security group authorizations: %s" % e) # Add rule that allows communication between instances in the same SG - g_rule_exists = False # Flag to indicate if group rule already exists + g_rule_exists = False # Flag to indicate if group rule already exists for rule in cmsg.rules: for grant in rule.grants: if grant.name == cmsg.name: @@ -250,6 +250,7 @@ log.info("Done configuring '%s' security group" % cmsg.name) return cmsg.name
+ def rule_exists(rules, from_port, to_port, ip_protocol='tcp', cidr_ip='0.0.0.0/0'): """ A convenience method to check if an authorization rule in a security group exists. @@ -260,6 +261,7 @@ return True return False
+ def create_key_pair(ec2_conn, key_name=DEFAULT_KEYPAIR): """ Create a key pair with the provided name. Return the name of the key or None if there was an error creating the key. @@ -279,6 +281,7 @@ return None, None return kp.name, kp.material
+ def run_instance(ec2_conn, user_provided_data, image_id=None, kernel_id=None, ramdisk_id=None, key_name=DEFAULT_KEYPAIR, placement=None, security_groups=['CloudMan']): @@ -310,6 +313,7 @@ log.warning("Problem starting an instance?") return rs
+ def _find_placement(ec2_conn, instance_type): """Find a region zone that supports our requested instance type.
@@ -328,4 +332,3 @@ return cur_loc log.error("Did not find availabilty zone in {0} for {1}".format(base, instance_type)) return None -
https://bitbucket.org/galaxy/galaxy-central/commits/e45c2616e207/ Changeset: e45c2616e207 User: dannon Date: 2014-04-03 21:23:52 Summary: Incremental work / shifting changes to bioblend but committed here for posterity. Affected #: 1 file
diff -r e51282a5b1bff80518db274800c2be7de2968785 -r e45c2616e207e25e4978d14343bd5bff495a16b0 lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py --- a/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py +++ b/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py @@ -3,10 +3,8 @@
Adapted from Brad Chapman and Enis Afgan's BioCloudCentral BioCloudCentral Source: https://github.com/chapmanb/biocloudcentral - """
-import datetime import logging import os import tempfile @@ -19,14 +17,19 @@
eggs.require('boto') import boto +import boto.vpc from boto.ec2.regioninfo import RegionInfo from boto.exception import EC2ResponseError, S3ResponseError from boto.s3.connection import OrdinaryCallingFormat, S3Connection
log = logging.getLogger(__name__)
+logging.getLogger('boto').setLevel(logging.INFO) + + PKEY_PREFIX = 'gxy_pkey' DEFAULT_KEYPAIR = 'cloudman_keypair' +CLOUDMAN_TAG_KEY = 'galaxy:cloudman'
class CloudController(BaseUIController): @@ -51,7 +54,6 @@ """ Get EC2 Account Info """ - #Keypairs account_info = {} try: ec2_conn = connect_ec2(key_id, secret) @@ -79,19 +81,7 @@ # This will also allow for much more sophisticated rendering of existing clusters # Currently, this zone detection is a hack. pd_contents = pd.get_contents_as_string() - zone = '' - try: - for line in pd_contents.split('\n'): - if 'vol_id' in line: - vol_id = line.split(':')[1].strip() - v = ec2_conn.get_all_volumes(volume_ids=[vol_id]) - if v: - zone = v[0].zone - else: - zone = '' - except: - #If anything goes wrong with zone detection, use the default selection. - zone = '' + zone = get_zone_from_pd(pd_contents, ec2_conn) for key in bucket.list(): if key.name.endswith('.clusterName'): clusters.append({'name': key.name.split('.clusterName')[0], @@ -107,60 +97,51 @@ try: # Create security group & key pair used when starting an instance ec2_conn = connect_ec2(key_id, secret) - sg_name = create_cm_security_group(ec2_conn) + sg = get_or_create_cm_security_group(ec2_conn) kp_name, kp_material = create_key_pair(ec2_conn, key_name=keypair) except EC2ResponseError, err: ec2_error = err.error_message if ec2_error: trans.response.status = 400 return ec2_error + #Get an elastic ip, add to UserData. + user_provided_data = _format_user_data(cluster_name, key_id, secret, password, share_string, bucket_default) + if not ami: + ami = trans.app.config.cloudlaunch_default_ami + rs = _run_instance(ec2_conn=ec2_conn, + image_id=ami, + user_provided_data=user_provided_data, + key_name=kp_name, + security_group_ids=[sg.id], + placement=zone, + instance_type=instance_type, + subnet_id=get_or_create_cm_subnet(key_id, secret, zone).id) + if not rs: + trans.response.status = 400 + return "Instance failure, but no specific error was detected. Please check your AWS Console." + instance = rs.instances[0] + while not instance.public_dns_name: + try: + instance.update() + except EC2ResponseError: + # This can happen when update is invoked before the instance is fully registered. + pass + time.sleep(1) + if kp_material: + #We have created a keypair. Save to tempfile for one time retrieval. + (fd, fname) = tempfile.mkstemp(prefix=PKEY_PREFIX, dir=trans.app.config.new_file_path) + f = os.fdopen(fd, 'wt') + f.write(kp_material) + f.close() + kp_material_tag = fname[fname.rfind(PKEY_PREFIX) + len(PKEY_PREFIX):] else: - user_provided_data = {'cluster_name': cluster_name, - 'access_key': key_id, - 'secret_key': secret, - 'instance_type': instance_type} - if password: - user_provided_data['password'] = password - if share_string: - user_provided_data['share_string'] = share_string - if bucket_default: - user_provided_data['bucket_default'] = bucket_default - if not ami: - ami = trans.app.config.cloudlaunch_default_ami - rs = run_instance(ec2_conn=ec2_conn, - image_id=ami, - user_provided_data=user_provided_data, - key_name=kp_name, - security_groups=[sg_name], - placement=zone) - if rs: - instance = rs.instances[0] - while not instance.public_dns_name: - try: - instance.update() - except EC2ResponseError: - #This can happen when update is invoked before the instance is fully registered. - #Prevent failure, wait it out. - pass - time.sleep(1) - if kp_material: - #We have created a keypair. Save to tempfile for one time retrieval. - (fd, fname) = tempfile.mkstemp(prefix=PKEY_PREFIX, dir=trans.app.config.new_file_path) - f = os.fdopen(fd, 'wt') - f.write(kp_material) - f.close() - kp_material_tag = fname[fname.rfind(PKEY_PREFIX) + len(PKEY_PREFIX):] - else: - kp_material_tag = None - return to_json_string({'cluster_name': cluster_name, - 'instance_id': rs.instances[0].id, - 'image_id': rs.instances[0].image_id, - 'public_dns_name': rs.instances[0].public_dns_name, - 'kp_name': kp_name, - 'kp_material_tag': kp_material_tag}) - else: - trans.response.status = 400 - return "Instance failure, but no specific error was detected. Please check your AWS Console." + kp_material_tag = None + return to_json_string({'cluster_name': cluster_name, + 'instance_id': rs.instances[0].id, + 'image_id': rs.instances[0].image_id, + 'public_dns_name': rs.instances[0].public_dns_name, + 'kp_name': kp_name, + 'kp_material_tag': kp_material_tag})
@web.expose def get_pkey(self, trans, kp_material_tag=None): @@ -179,6 +160,21 @@ return "Invalid identifier"
+def get_zone_from_pd(pd_contents, ec2_conn): + try: + for line in pd_contents.split('\n'): + if 'vol_id' in line: + vol_id = line.split(':')[1].strip() + v = ec2_conn.get_all_volumes(volume_ids=[vol_id]) + if v: + return v[0].zone + except: + # Things can go wrong with Zone detection outside of our control. Use + # the default zone if this happens. + pass + return '' + + def connect_ec2(a_key, s_key): """ Create and return an EC2 connection object. @@ -193,7 +189,6 @@ r = RegionInfo(name=region_name, endpoint=region_endpoint) ec2_conn = boto.connect_ec2(aws_access_key_id=a_key, aws_secret_access_key=s_key, - api_version='2011-11-01', # needed for availability zone support is_secure=is_secure, region=r, port=ec2_port, @@ -201,23 +196,22 @@ return ec2_conn
-def create_cm_security_group(ec2_conn, sg_name='CloudMan'): - """ Create a security group with all authorizations required to run CloudMan. - If the group already exists, check its rules and add the missing ones. - Return the name of the created security group. +def get_or_create_cm_security_group(ec2_conn, sg_name='CloudManVPC'): """ - cmsg = None - # Check if this security group already exists - sgs = ec2_conn.get_all_security_groups() - for sg in sgs: - if sg.name == sg_name: - cmsg = sg - log.debug("Security group '%s' already exists; will add authorizations next." % sg_name) - break - # If it does not exist, create security group - if cmsg is None: + Create a security group with all authorizations required to run CloudMan. + If the group already exists, check its rules and add the missing ones. + Return the name of the created security group. + """ + cm_sg = None + # Check if this security group already exists. We can't use the built-in + # filtering here, because VPC security groups can't be filtered by name. + sg = ec2_conn.get_all_security_groups(filters={'group_name': sg_name}) + if sg: + cm_sg = sg[0] + else: + # If it does not exist, create security group log.debug("Creating Security Group %s" % sg_name) - cmsg = ec2_conn.create_security_group(sg_name, 'A security group for CloudMan') + cm_sg = ec2_conn.create_security_group(sg_name, 'A security group for CloudMan', vpc_id=get_or_create_cm_vpc(ec2_conn.access_key, ec2_conn.secret_key).id) # Add appropriate authorization rules # If these rules already exist, nothing will be changed in the SG ports = (('80', '80'), # Web UI @@ -226,29 +220,68 @@ ('30000', '30100'), # FTP transfer ('42284', '42284')) # CloudMan UI for port in ports: - try: - if not rule_exists(cmsg.rules, from_port=port[0], to_port=port[1]): - cmsg.authorize(ip_protocol='tcp', from_port=port[0], to_port=port[1], cidr_ip='0.0.0.0/0') - else: - log.debug("Rule (%s:%s) already exists in the SG" % (port[0], port[1])) - except EC2ResponseError, e: - log.error("A problem with security group authorizations: %s" % e) + if not rule_exists(cm_sg.rules, from_port=port[0], to_port=port[1]): + cm_sg.authorize(ip_protocol='tcp', from_port=port[0], to_port=port[1], cidr_ip='0.0.0.0/0') + else: + log.debug("Rule (%s:%s) already exists in the SG" % (port[0], port[1])) # Add rule that allows communication between instances in the same SG g_rule_exists = False # Flag to indicate if group rule already exists - for rule in cmsg.rules: - for grant in rule.grants: - if grant.name == cmsg.name: + for rule in cm_sg.rules: + for grant in rule.grants:#[g for g in rule.grants if g.name == cm_sg.name]: + print grant.name + if grant.name == cm_sg.name: g_rule_exists = True log.debug("Group rule already exists in the SG") if g_rule_exists: break - if g_rule_exists is False: - try: - cmsg.authorize(src_group=cmsg) - except EC2ResponseError, e: - log.error("A problem w/ security group authorization: %s" % e) - log.info("Done configuring '%s' security group" % cmsg.name) - return cmsg.name + #if g_rule_exists is False: + # cm_sg.authorize(src_group=cm_sg) + log.info("Done configuring '%s' security group" % cm_sg.name) + return cm_sg + + + +def get_or_create_cm_vpc(a_key, s_key): + vpc_conn = boto.vpc.VPCConnection(a_key, s_key) + vpcs = vpc_conn.get_all_vpcs() + cloudman_vpc = None + for vpc in vpcs: + if CLOUDMAN_TAG_KEY in vpc.tags: + cloudman_vpc = vpc + if not cloudman_vpc: + #create a new one. + cloudman_vpc = vpc_conn.create_vpc('10.0.0.0/16') + cloudman_vpc.add_tag(CLOUDMAN_TAG_KEY, '') + return cloudman_vpc + + +def get_or_create_cm_subnet(a_key, s_key, availability_zone): + log.debug("GETTING SUBNET in %s" % availability_zone) + vpc_conn = boto.vpc.VPCConnection(a_key, s_key) + subnets = vpc_conn.get_all_subnets() + cloudman_subnet = None + for subnet in subnets: + log.debug("SN: %s, SNAZ:AZ: %s:%s:%s" % (subnet, subnet.availability_zone, availability_zone, subnet.availability_zone == availability_zone)) + if (not availability_zone or subnet.availability_zone == availability_zone) and CLOUDMAN_TAG_KEY in subnet.tags: + cloudman_subnet = subnet + if not cloudman_subnet: + #create a new one. + cloudman_subnet = vpc_conn.create_subnet(get_or_create_cm_vpc(a_key, s_key).id, '10.0.0.0/24', availability_zone) + cloudman_subnet.add_tag(CLOUDMAN_TAG_KEY, '') + return cloudman_subnet + + +def _format_user_data(cluster_name, key_id, secret, password, share_string, bucket_default): + user_provided_data = {'cluster_name': cluster_name, + 'access_key': key_id, + 'secret_key': secret} + if password: + user_provided_data['password'] = password + if share_string: + user_provided_data['share_string'] = share_string + if bucket_default: + user_provided_data['bucket_default'] = bucket_default + return "\n".join(['%s: %s' % (key, value) for key, value in user_provided_data.iteritems() if key != 'kp_material'])
def rule_exists(rules, from_port, to_port, ip_protocol='tcp', cidr_ip='0.0.0.0/0'): @@ -282,24 +315,22 @@ return kp.name, kp.material
-def run_instance(ec2_conn, user_provided_data, image_id=None, - kernel_id=None, ramdisk_id=None, key_name=DEFAULT_KEYPAIR, - placement=None, security_groups=['CloudMan']): - """ Start an instance. If instance start was OK, return the ResultSet object - else return None. +def _run_instance(ec2_conn, user_provided_data, instance_type, image_id=None, + kernel_id=None, ramdisk_id=None, key_name=DEFAULT_KEYPAIR, + placement=None, security_group_ids=None, subnet_id=None): + """ + Start an instance. If instance start was OK, return the ResultSet object + else return None. """ rs = None - instance_type = user_provided_data['instance_type'] - # Remove 'instance_type' key from the dict before creating user data - del user_provided_data['instance_type'] - ud = "\n".join(['%s: %s' % (key, value) for key, value in user_provided_data.iteritems() if key != 'kp_material']) try: rs = ec2_conn.run_instances(image_id=image_id, instance_type=instance_type, key_name=key_name, - security_groups=security_groups, - user_data=ud, + security_group_ids=security_group_ids, + user_data=user_provided_data, kernel_id=kernel_id, + subnet_id=subnet_id, ramdisk_id=ramdisk_id, placement=placement) except EC2ResponseError, e: @@ -312,23 +343,3 @@ else: log.warning("Problem starting an instance?") return rs - - -def _find_placement(ec2_conn, instance_type): - """Find a region zone that supports our requested instance type. - - We need to check spot prices in the potential availability zones - for support before deciding on a region: - - http://blog.piefox.com/2011/07/ec2-availability-zones-and-instance.html - """ - base = ec2_conn.region.name - yesterday = datetime.datetime.now() - datetime.timedelta(1) - for loc_choice in ["b", "a", "c", "d"]: - cur_loc = "{base}{ext}".format(base=base, ext=loc_choice) - if len(ec2_conn.get_spot_price_history(instance_type=instance_type, - end_time=yesterday.isoformat(), - availability_zone=cur_loc)) > 0: - return cur_loc - log.error("Did not find availabilty zone in {0} for {1}".format(base, instance_type)) - return None
https://bitbucket.org/galaxy/galaxy-central/commits/347a9169e3ec/ Changeset: 347a9169e3ec User: dannon Date: 2014-04-03 21:24:32 Summary: Merge back with -central. Affected #: 558 files
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 .hgignore --- a/.hgignore +++ b/.hgignore @@ -77,6 +77,7 @@ tool-data/shared/ucsc/builds.txt tool-data/shared/ensembl/builds.txt tool-data/shared/ucsc/publicbuilds.txt +tool-data/shared/ucsc/ucsc_build_sites.txt tool-data/*.loc tool-data/genome/*
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 README.txt --- a/README.txt +++ b/README.txt @@ -26,6 +26,6 @@ on adding tools can be found on the Galaxy website (linked above).
Not all dependencies are included for the tools provided in the sample -tool_conf.xml. A full list of external dependencies is available at: +tool_conf.xml. A full list of external dependencies is available at:
-http://wiki.g2.bx.psu.edu/Admin/Tools/Tool%20Dependencies +https://wiki.galaxyproject.org/Admin/Tools/ToolDependencies
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/Gruntfile.js --- /dev/null +++ b/config/plugins/visualizations/charts/Gruntfile.js @@ -0,0 +1,24 @@ +// NOTE: use 'sudo npm install .', then 'grunt' to use this file +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + requirejs: { + compile: { + options: { + baseUrl : "../../../../static/scripts/", + paths : { + "plugin": "../../config/plugins/visualizations/charts/static" + }, + shim : { + "libs/underscore": { exports: "_" }, + "libs/backbone/backbone": { exports: "Backbone" } + }, + name : "plugin/app", + out : "static/build-app.js", + } + } + } + }); + grunt.loadNpmTasks('grunt-contrib-requirejs'); + grunt.registerTask( 'default', [ 'requirejs' ]); +};
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/package.json --- /dev/null +++ b/config/plugins/visualizations/charts/package.json @@ -0,0 +1,18 @@ +{ + "name": "galaxy-charts", + "version": "0.0.0", + "description": "Charts visualization plugin for the Galaxy informatics framework", + "main": " ", + "keywords": [ + "galaxy", + "visualization", + "d3" + ], + "author": "Aysam Guerler", + "license": "BSD", + "devDependencies": { + "grunt": "~0.4.1", + "grunt-cli": "~0.1.9", + "grunt-contrib-requirejs": "~0.4.3" + } +}
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/app.js --- a/config/plugins/visualizations/charts/static/app.js +++ b/config/plugins/visualizations/charts/static/app.js @@ -1,10 +1,12 @@ // dependencies -define(['mvc/ui/ui-portlet', 'plugin/library/ui', 'utils/utils', - 'plugin/views/charts', 'plugin/views/viewport', 'plugin/views/chart', 'plugin/views/group', - 'plugin/models/config', 'plugin/models/datasets', 'plugin/models/chart', 'plugin/models/charts', 'plugin/models/group', 'plugin/models/types'], - function( Portlet, Ui, Utils, - ChartsView, ViewportView, ChartView, GroupView, - Config, Datasets, Chart, Charts, Group, Types +define(['mvc/ui/ui-modal', 'mvc/ui/ui-portlet', 'plugin/library/ui', 'utils/utils', + 'plugin/library/jobs', 'plugin/library/datasets', 'plugin/library/storage', + 'plugin/views/viewer', 'plugin/views/editor', + 'plugin/models/config', 'plugin/models/chart', + 'plugin/charts/types'], + function( Modal, Portlet, Ui, Utils, Jobs, Datasets, Storage, + ViewerView, EditorView, + Config, Chart, Types ) {
// widget @@ -13,66 +15,75 @@ // initialize initialize: function(options) { + // deactivate all debugs outputs + //window.console.debug = function() {}; + // link options this.options = options;
- // link galaxy - this.modal = parent.Galaxy.modal; + // link galaxy modal or create one + if (Galaxy && Galaxy.modal) { + this.modal = Galaxy.modal; + } else { + this.modal = new Modal.View(); + }
- // create configuration model + // + // models + // this.config = new Config(); - - // create chart models this.types = new Types(); this.chart = new Chart(); - this.charts = new Charts(); - this.group = new Group();
- // create dataset handler + // + // libraries + // + this.jobs = new Jobs(this); this.datasets = new Datasets(this); + this.storage = new Storage(this);
- // create views - this.charts_view = new ChartsView(this); - this.group_view = new GroupView(this); - this.chart_view = new ChartView(this); - this.viewport_view = new ViewportView(this); - - // append view port to charts viewer - this.charts_view.append(this.viewport_view.$el); - - // create portlet - if (!this.options.config.widget) { - this.portlet = new Portlet.View({icon : 'fa-bar-chart-o', title : 'Charts'}); - } else { - this.portlet = $('<div></div>'); - } + // + // views + // + this.viewer_view = new ViewerView(this); + this.editor_view = new EditorView(this);
// append views - this.portlet.append(this.charts_view.$el); - this.portlet.append(this.group_view.$el); - this.portlet.append(this.chart_view.$el); - - // set element - if (!this.options.config.widget) { - this.setElement(this.portlet.$el); + this.$el.append(this.viewer_view.$el); + this.$el.append(this.editor_view.$el); + + // pick start screen + if (!this.storage.load()) { + // show editor + this.go('editor'); } else { - this.setElement(this.portlet); + // show viewport + this.go('viewer'); + + // draw chart + var self = this; + this.chart.deferred.execute(function() { + self.chart.trigger('redraw'); + }); } - - // hide views - this.group_view.$el.hide(); - this.charts_view.$el.hide(); - - // events - var self = this; - this.config.on('change:current_view', function() { - self._showCurrent(); - }); },
- // current view - _showCurrent: function() { + // loads a view and makes sure that all others are hidden + go: function(view_id) { + // hide all tooltips + $('.tooltip').hide();
+ // pick view + switch (view_id) { + case 'editor' : + this.editor_view.show(); + this.viewer_view.hide(); + break; + case 'viewer' : + this.editor_view.hide(); + this.viewer_view.show(); + break; + } },
// execute command
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/build-app.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/build-app.js @@ -0,0 +1,6 @@ +// Underscore.js 1.4.4 +// http://underscorejs.org +// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. +// Underscore may be freely distributed under the MIT license. + +(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\":"\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n!=""){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()}),t.set("dataset_id_job","")}},submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"chartskit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:a,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Job has been queued..."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._loop(n.id,function(e){switch(e.state){case"ok":return t.state("wait","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),s&&s(),!0;case"running":return t.state("wait","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the Charts-Kit. Please make sure it is installed. "+n),s&&s()})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh")},ready:function(){return this.counter==0?!0:!1}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._create_svg();var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=e.find("#icon");t.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info"));var n=r.chart.get("state");switch(n){case"ok":e.hide();break;case"failed":t.addClass("fa fa-warning");break;default:t.addClass("fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_create_svg:function(){this.svg&&this.svg.remove(),this.$el.append($(this._template_svg())),this.svg_el=this.$el.find("svg"),this.svg=d3.select(this.svg_el[0])},_draw:function(e){var t=this;this._create_svg(),e.state("wait","Please wait...");var n=e.deferred.register(),r=e.get("type"),i=this.app.types.get(r);if(!i.execute||i.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/"+r],function(r){var s=new r(t.app,{svg:t.svg});i.execute?e.get("dataset_id_job")==""?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){s.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):s.draw(n,e,t._defaultRequestDictionary(e)):s.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={groups:[]};t.execute?n.id=e.get("dataset_id_job"):n.id=e.get("dataset_id");var r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n},_template:function(){return'<div style="height: 100%; min-height: 50px;"><div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_template_svg:function(){return'<svg style="height: calc(100% - 80px)"/>'}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Customize",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show();r.chart.state("wait","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){var u=this;this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}}),this.table=new t.View({header:!1,onconfirm:function(e){u.chart.groups.length>0?u.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){u.app.modal.hide()},Continue:function(){u.app.modal.hide(),u.table.value(e)}}}):u.table.value(e)},onchange:function(e){u.chart.groups.reset(),u.chart.settings.clear(),u.chart.set({type:e})},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"});var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),h.execute?this.table.add(h.title+" (requires processing)"):this.table.add(h.title),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.chart.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/_nvd3/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/_nvd3/config.js @@ -0,0 +1,218 @@ +define([], function() { + +return { + title : '', + columns : { + y : { + title : 'Values for y-axis' + } + }, + settings : { + separator_label : { + title : 'X axis', + type : 'separator' + }, + x_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'X-axis', + placeholder : 'Axis label' + }, + x_axis_type : { + title : 'Axis value type', + info : 'Select the value type of the axis.', + type : 'select', + init : 'auto', + data : [ + { + label : '-- Do not show values --', + value : 'hide', + hide : 'x_axis_tick' + }, + { + label : 'Auto', + value : 'auto', + hide : 'x_axis_tick' + }, + { + label : 'Float', + value : 'f', + show : 'x_axis_tick' + }, + { + label : 'Exponent', + value : 'e', + show : 'x_axis_tick' + }, + { + label : 'Integer', + value : 'd', + hide : 'x_axis_tick' + }, + { + label : 'Percentage', + value : 'p', + show : 'x_axis_tick' + }, + { + label : 'Rounded', + value : 'r', + show : 'x_axis_tick' + }, + { + label : 'SI-prefix', + value : 's', + show : 'x_axis_tick' + } + ] + }, + x_axis_tick : { + title : 'Axis tick format', + info : 'Select the tick format for the axis.', + type : 'select', + init : '.1', + data : [ + { + label : '0.00001', + value : '.5' + }, + { + label : '0.0001', + value : '.4' + }, + { + label : '0.001', + value : '.3' + }, + { + label : '0.01', + value : '.2' + }, + { + label : '0.1', + value : '.1' + }, + { + label : '1', + value : '1' + } + ] + + }, + separator_tick : { + title : 'Y axis', + type : 'separator' + }, + y_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'Y-axis', + placeholder : 'Axis label' + }, + y_axis_type : { + title : 'Axis value type', + info : 'Select the value type of the axis.', + type : 'select', + init : 'auto', + data : [ + { + label : '-- Do not show values --', + value : 'hide', + hide : 'y_axis_tick' + }, + { + label : 'Auto', + value : 'auto', + hide : 'y_axis_tick' + }, + { + label : 'Float', + value : 'f', + show : 'y_axis_tick' + }, + { + label : 'Exponent', + value : 'e', + show : 'y_axis_tick' + }, + { + label : 'Integer', + value : 'd', + hide : 'y_axis_tick' + }, + { + label : 'Percentage', + value : 'p', + show : 'y_axis_tick' + }, + { + label : 'Rounded', + value : 'r', + show : 'y_axis_tick' + }, + { + label : 'SI-prefix', + value : 's', + show : 'y_axis_tick' + } + ] + }, + y_axis_tick : { + title : 'Axis tick format', + info : 'Select the tick format for the axis.', + type : 'select', + init : '.1', + data : [ + { + label : '0.00001', + value : '.5' + }, + { + label : '0.0001', + value : '.4' + }, + { + label : '0.001', + value : '.3' + }, + { + label : '0.01', + value : '.2' + }, + { + label : '0.1', + value : '.1' + }, + { + label : '1', + value : '1' + } + ] + + }, + separator_legend : { + title : 'Others', + type : 'separator' + }, + show_legend : { + title : 'Show legend', + info : 'Would you like to add a legend?', + type : 'select', + init : 'true', + data : [ + { + label : 'Yes', + value : 'true' + }, + { + label : 'No', + value : 'false' + } + ] + }, + } +}; + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js @@ -0,0 +1,80 @@ +// dependencies +define([], function() { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, nvd3_model, chart, request_dictionary, callback) + { + // request data + var self = this; + this.app.datasets.request(request_dictionary, function(data) { + nv.addGraph(function() { + // x axis + self._axis(nvd3_model.xAxis, chart.settings.get('x_axis_type'), chart.settings.get('x_axis_tick')); + + // x axis label + nvd3_model.xAxis.axisLabel(chart.settings.get('x_axis_label')); + + // y axis + self._axis(nvd3_model.yAxis, chart.settings.get('y_axis_type'), chart.settings.get('y_axis_tick')); + + // y axis label + nvd3_model.yAxis.axisLabel(chart.settings.get('y_axis_label')) + .axisLabelDistance(30); + + // controls + if (chart.groups.length == 1) { + nvd3_model.options({ showControls: false }); + } + + // legend + var legend_visible = true; + if (chart.settings.get('show_legend') == 'false') { + legend_visible = false; + } + nvd3_model.showLegend(legend_visible); + + // custom callback + if (callback) { + callback(nvd3_model); + } + + // parse data to svg + self.options.svg.datum(data) + .call(nvd3_model); + + // refresh on window resize + nv.utils.windowResize(nvd3_model.update); + + // set chart state + chart.state('ok', 'Chart has been drawn.'); + + // unregister process + chart.deferred.done(process_id); + }); + }); + }, + + // make axis + _axis: function(axis, type, tick) { + switch (type) { + case 'hide': + axis.tickFormat(function() { return '' }); + break; + case 'auto': + break; + default: + axis.tickFormat(d3.format(tick + type)); + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/bardiagram.js --- a/config/plugins/visualizations/charts/static/charts/bardiagram.js +++ /dev/null @@ -1,33 +0,0 @@ -// dependencies -define([], function() { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - self.d3_chart = nv.models.multiBarChart(); - - self.d3_chart.xAxis.tickFormat(d3.format('.2f')) - self.d3_chart.yAxis.tickFormat(d3.format('.1f')) - - d3.select(self.options.svg_id) - .datum(data) - .call(self.d3_chart); - - nv.utils.windowResize(self.d3_chart.update); - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/bardiagram/bardiagram.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/bardiagram/bardiagram.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/bardiagram/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/bardiagram/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Bar diagram', +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/histogram/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/histogram/config.js @@ -0,0 +1,21 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Histogram', + execute : true, + columns : { + y : { + title : 'Observations' + } + }, + settings : { + x_axis_label : { + init : 'Breaks' + }, + y_axis_label : { + init : 'Density' + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/histogram/histogram.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/histogram/histogram.js @@ -0,0 +1,31 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + // configure request + var index = 0; + for (var i in request_dictionary.groups) { + var group = request_dictionary.groups[i]; + group.columns = { + x: index++, + y: index++ + } + } + + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/horizontal.js --- a/config/plugins/visualizations/charts/static/charts/horizontal.js +++ /dev/null @@ -1,33 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - self.d3_chart = nv.models.multiBarHorizontalChart(); - - self.d3_chart.xAxis.tickFormat(function() { return ''; }); - - d3.select(self.options.svg_id) - .datum(data) - .call(self.d3_chart); - - nv.utils.windowResize(self.d3_chart.update); - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/horizontal/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/horizontal/config.js @@ -0,0 +1,12 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Bar diagram (horizontal)', + settings : { + x_axis_type : { + init : 'hide' + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/horizontal/horizontal.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/horizontal/horizontal.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarHorizontalChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/line.js --- a/config/plugins/visualizations/charts/static/charts/line.js +++ /dev/null @@ -1,39 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - self.chart_3d = nv.models.lineChart(); - - self.chart_3d.xAxis - .tickFormat(d3.format(',f')); - - self.chart_3d.yAxis - .tickFormat(d3.format(',.2f')); - - d3.select(self.options.svg_id) - .datum(data) - .call(self.chart_3d); - - nv.utils.windowResize(self.chart_3d.update); - - return self.chart_3d; - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/line/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/line/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Line chart', +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/line/line.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/line/line.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.lineChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/linewithfocus.js --- a/config/plugins/visualizations/charts/static/charts/linewithfocus.js +++ /dev/null @@ -1,37 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - self.chart_3d = nv.models.lineWithFocusChart(); - - self.chart_3d.xAxis - .tickFormat(d3.format(',f')); - - self.chart_3d.yAxis - .tickFormat(d3.format(',.2f')); - - d3.select(self.options.svg_id) - .datum(data) - .call(self.chart_3d); - - nv.utils.windowResize(self.chart_3d.update); - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/linewithfocus/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/linewithfocus/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Line with focus', +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/linewithfocus/linewithfocus.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/linewithfocus/linewithfocus.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.lineWithFocusChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/piechart.js --- a/config/plugins/visualizations/charts/static/charts/piechart.js +++ /dev/null @@ -1,51 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // loop through data groups - for (var key in data) { - // get group - var group = data[key]; - - // format chart data - var pie_data = []; - for (var key in group.values) { - var value = group.values[key]; - pie_data.push ({ - key : value.x, - y : value.y - }); - } - - // add graph to screen - var self = this; - nv.addGraph(function() { - self.chart_3d = nv.models.pieChart() - .donut(true) - .showLegend(false); - - d3.select(self.options.svg_id) - .datum(pie_data) - .call(self.chart_3d); - - nv.utils.windowResize(self.chart_3d.update); - - return self.chart_3d; - }); - } - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/piechart/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/piechart/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Pie chart', +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/piechart/piechart.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/piechart/piechart.js @@ -0,0 +1,57 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + // request data + var self = this; + this.app.datasets.request(request_dictionary, function(data) { + + // loop through data groups + for (var key in request_dictionary.groups) { + // get group + var group = request_dictionary.groups[key]; + + // format chart data + var pie_data = []; + for (var key in group.values) { + var value = group.values[key]; + pie_data.push ({ + key : value.x, + y : value.y + }); + } + + // add graph to screen + nv.addGraph(function() { + self.chart_3d = nv.models.pieChart() + .donut(true) + .showLegend(false); + + self.options.svg.datum(pie_data) + .call(self.chart_3d); + + nv.utils.windowResize(self.chart_3d.update); + + // set chart state + chart.state('ok', 'Pie chart drawn.'); + + // unregister process + chart.deferred.done(process_id); + }); + } + }); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/scatterplot.js --- a/config/plugins/visualizations/charts/static/charts/scatterplot.js +++ /dev/null @@ -1,37 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - self.d3_chart = nv.models.scatterChart() - .showDistX(true) - .showDistY(true) - .color(d3.scale.category10().range()); - - self.d3_chart.xAxis.tickFormat(d3.format('.02f')) - self.d3_chart.yAxis.tickFormat(d3.format('.02f')) - - d3.select(self.options.svg_id) - .datum(data) - .call(self.d3_chart); - - nv.utils.windowResize(self.d3_chart.update); - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/scatterplot/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/scatterplot/config.js @@ -0,0 +1,12 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Scatter plot', + columns : { + x : { + title : 'Values for x-axis' + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/scatterplot/scatterplot.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/scatterplot/scatterplot.js @@ -0,0 +1,25 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.scatterChart(), chart, request_dictionary, function(nvd3_model) { + nvd3_model.showDistX(true) + .showDistY(true) + .color(d3.scale.category10().range()); + }); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/stackedarea.js --- a/config/plugins/visualizations/charts/static/charts/stackedarea.js +++ /dev/null @@ -1,59 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - this.chart = options.chart; - }, - - // render - refresh : function(data) - { - // add graph to screen - var self = this; - nv.addGraph(function() { - // check data - var valid = true; - var length = 0; - for (var key in data) { - // evalute length - if (length == 0) { - length = data[key].values.length; - } else { - if (length != data[key].values.length) { - valid = false; - break; - } - } - } - if (!valid) { - return; - } - - // make plot - self.d3_chart = nv.models.stackedAreaChart() - .x(function(d) { - return d.x - }) - .y(function(d) { - return d.y - }) - .clipEdge(true); - - self.d3_chart.xAxis.tickFormat(function() { return ''; }); - - d3.select(self.options.svg_id) - .datum(data) - .call(self.d3_chart); - - nv.utils.windowResize(self.d3_chart.update); - }); - } -}); - -}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/stackedarea/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/stackedarea/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/_nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Stacked area' +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/stackedarea/stackedarea.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/stackedarea/stackedarea.js @@ -0,0 +1,26 @@ +// dependencies +define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.stackedAreaChart(), chart, request_dictionary, function(nvd3_model) { + // make plot + nvd3_model.x(function(d) { return d.x }) + .y(function(d) { return d.y }) + .clipEdge(true); + }); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/charts/types.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/types.js @@ -0,0 +1,39 @@ +// dependencies +define(['plugin/charts/bardiagram/config', + //'plugin/charts/boxplot/config', + 'plugin/charts/histogram/config', + 'plugin/charts/horizontal/config', + 'plugin/charts/line/config', + 'plugin/charts/linewithfocus/config', + 'plugin/charts/piechart/config', + 'plugin/charts/scatterplot/config', + 'plugin/charts/stackedarea/config', + ], function(bardiagram, + //boxplot, + histogram, + horizontal, + line, + linewithfocus, + piechart, + scatterplot, + stackedarea + ) { + +// widget +return Backbone.Model.extend( +{ + // types + defaults: { + 'bardiagram' : bardiagram, + //'boxplot' : boxplot, + 'horizontal' : horizontal, + 'histogram' : histogram, + 'line' : line, + 'linewithfocus' : linewithfocus, + 'piechart' : piechart, + 'scatterplot' : scatterplot, + 'stackedarea' : stackedarea + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/library/datasets.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/library/datasets.js @@ -0,0 +1,149 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// widget +return Backbone.Collection.extend( +{ + // list of datasets + list: {}, + + // initialize + initialize: function(app, options) + { + // link app + this.app = app; + + // configure options + this.options = Utils.merge(options, this.optionsDefault); + }, + + // wait + request: function(options, success, error) { + // link this + var self = this; + + // check if column data is requested + if (options.groups) { + this._fetch(options, success); + } else { + // check if dataset is available from cache + var dataset = this.list[options.id]; + if (dataset) { + success(dataset); + return; + } + + // request dataset + Utils.request('GET', config.root + 'api/datasets/' + options.id, {}, function(dataset) { + switch (dataset.state) { + case 'error': + if (error) { + error(dataset); + } + break; + default: + self.list[options.id] = dataset; + success(dataset); + } + }); + } + }, + + // fetch data columns into dataset object + _fetch: function(options, callback) { + // set offset + var offset = options.start ? options.start : 0; + + // set limit + var limit = Math.abs(options.end - options.start); + var query_limit = this.app.config.get('query_limit'); + if (!limit || limit > query_limit) { + limit = query_limit; + } + + // get column indices + var index_string = ''; + var index_map = {}; + var index_count = 0; + for (var i in options.groups) { + var group = options.groups[i]; + for (var key in group.columns) { + var column = group.columns[key]; + + // add to index string + index_string += column + ','; + + // add to dictionary + index_map[column] = index_count; + + // increase counter + index_count++; + } + } + if (index_count == 0) { + callback({}); + return; + } + index_string = index_string.substring(0, index_string.length - 1); + + // initialize result dictionary + var result = options.groups.slice(0); + for (var i in result) { + result[i].values = []; + } + + // make request + var self = this; + Utils.request('GET', config.root + 'api/datasets/' + options.id, { + data_type : 'raw_data', + provider : 'dataset-column', + limit : limit, + offset : offset, + indeces : index_string + }, function(response) { + + // loop through rows + for (var i in response.data) { + // get row + var row = response.data[i]; + + // collect all data into the defined groups + for (var j in options.groups) { + // get group + var group = options.groups[j]; + + // initialize value + var value = { + x : parseInt(i) + offset + }; + + // fill value + for (var key in group.columns) { + // get column + var column = group.columns[key]; + + // identify column + var index = index_map[column]; + + // read value from row + var v = row[index]; + if(isNaN(v) || !v) { + v = 0; + } + + // add value to dictionary + value[key] = v; + } + + // add to result + result[j].values.push(value); + } + } + + // callback + callback(result); + }); + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/library/deferred.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/library/deferred.js @@ -0,0 +1,85 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// deferred process handler +return Backbone.Model.extend( +{ + // queue + queue: [], + + // list of currently registered processes + process: {}, + + // process counter + counter: 0, + + // initialize + initialize: function() + { + // loop through queue and check states + this.on('refresh', function() { + if (this.counter == 0) { + for (var index in this.queue) { + // execute callback + this.queue[index](); + + // remove callback + this.queue.splice(index, 1); + } + } + }); + }, + + // executes callback once all processes are unregistered + execute: function(callback) { + // add wrapper to queue + this.queue.push(callback); + + // trigger change + this.trigger('refresh'); + }, + + // register process + register: function() { + // create unique id + var id = Utils.uuid(); + + // add process to queue + this.process[id] = true; + + // increase process counter + this.counter++; + + // log + console.debug('Deferred:register() - Registering ' + id); + + // return unique id + return id; + }, + + // unregister process + done: function(id) { + // delete tag + delete this.process[id]; + + // decrease process counter + this.counter--; + + // log + console.debug('Deferred:done() - Unregistering ' + id); + + // trigger change + this.trigger('refresh'); + }, + + // ready + ready: function() { + if (this.counter == 0) { + return true; + } else { + return false; + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/library/jobs.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/library/jobs.js @@ -0,0 +1,152 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// widget +return Backbone.Model.extend( +{ + // initialize + initialize: function(app, options) { + // link app + this.app = app; + + // link options + this.options = Utils.merge(options, this.optionsDefault); + }, + + // clean + cleanup: function(chart) { + // cleanup previous dataset file + var previous = chart.get('dataset_id_job'); + if (previous != '') { + var self = this; + Utils.request('PUT', config.root + 'api/histories/none/contents/' + previous, { deleted: true }, function() { + // update galaxy history + self._refreshHdas(); + }); + + // reset id + chart.set('dataset_id_job', ''); + } + }, + + // create job + submit: function(chart, settings_string, columns_string, success, error) { + // link this + var self = this; + + // backup chart details + var chart_id = chart.id; + var chart_type = chart.get('type'); + + // get chart settings + var chart_settings = this.app.types.get(chart_type); + + // configure tool + data = { + 'tool_id' : 'chartskit', + 'inputs' : { + 'input' : { + 'id' : chart.get('dataset_id'), + 'src' : 'hda' + }, + 'module' : chart_type, + 'columns' : columns_string, + 'settings' : settings_string + } + } + + // set chart state + chart.state('wait', 'Sending job request...'); + + // post job + Utils.request('POST', config.root + 'api/tools', data, + // success handler + function(response) { + if (!response.outputs || response.outputs.length == 0) { + chart.state('failed', 'Job submission failed. No response.'); + + // call error + error && error(); + } else { + // update galaxy history + self._refreshHdas(); + + // get dataset + var job = response.outputs[0]; + + // check dataset + chart.state('wait', 'Job has been queued...'); + + // backup resulting dataset id + chart.set('dataset_id_job', job.id); + + // save + this.app.storage.save(); + + // wait for job completion + self._loop(job.id, function(job) { + switch (job.state) { + case 'ok': + // update state + chart.state('wait', 'Job completed successfully...'); + + // execute success + success(job); + + // stop loop + return true; + case 'error': + // update state + chart.state('failed', 'Job has failed. Please check the history for details.'); + + // call error + error && error(); + + // stop loop + return true; + case 'running': + // wait + chart.state('wait', 'Job is running...'); + + // continue loop + return false; + } + }); + } + }, + // error handler + function(response) { + var message = ''; + if (response && response.message && response.message.data && response.message.data.input) { + message = response.message.data.input + '.'; + } + // update state + chart.state('failed', 'This visualization requires the Charts-Kit. Please make sure it is installed. ' + message); + + // call error + error && error(); + + } + ); + }, + + // request job details + _loop: function(id, callback) { + var self = this; + Utils.request('GET', config.root + 'api/jobs/' + id, {}, function(job) { + if (!callback(job)) { + setTimeout(function() { self._loop(id, callback); }, self.app.config.get('query_timeout')); + } + }); + }, + + // refresh history panel + _refreshHdas: function() { + // update galaxy history + if (Galaxy && Galaxy.currHistoryPanel) { + Galaxy.currHistoryPanel.refreshHdas(); + } + } +}); + +}); \ No newline at end of file
diff -r e45c2616e207e25e4978d14343bd5bff495a16b0 -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 config/plugins/visualizations/charts/static/library/storage.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/library/storage.js @@ -0,0 +1,120 @@ +// dependencies +define(['utils/utils', 'plugin/models/chart', 'plugin/models/group'], function(Utils, Chart, Group) { + +// collection +return Backbone.Model.extend( +{ + // viz model + vis: null, + + // initialize + initialize: function(app) { + // link app + this.app = app; + + // link chart + this.chart = this.app.chart; + + // link options + this.options = this.app.options; + + // initialize parameters + this.id = this.options.id; + + // create visualization + this.vis = new Visualization({ + type : 'charts', + config : { + dataset_id : this.options.config.dataset_id, + chart_dict : {} + } + }); + + // add visualization id + if (this.id) { + this.vis.id = this.id; + } + + // add charts + var chart_dict = this.options.config.chart_dict; + if (chart_dict) { + this.vis.get('config').chart_dict = chart_dict; + } + }, + + // pack and save nested chart model + save: function() { + + // link chart + var chart = this.app.chart; + + // reset + this.vis.get('config').chart_dict = {}; + + // set title + var title = chart.get('title'); + if (title != '') { + this.vis.set('title', title); + } + + // create chart dictionary + var chart_dict = { + attributes : chart.attributes, + settings : chart.settings.attributes, + groups : [] + }; + + // append groups + chart.groups.each(function(group) { + chart_dict.groups.push(group.attributes); + }); + + // add chart to charts array + this.vis.get('config').chart_dict = chart_dict; + + // save visualization + var self = this; + this.vis.save() + .fail(function(xhr, status, message) { + console.error(xhr, status, message); + }) + .then(function(response) { + if (response && response.id) { + self.id = response.id; + } + }); + }, + + // load nested models/collections from packed dictionary + load: function() { + // get charts array + var chart_dict = this.vis.get('config').chart_dict; + + // check + if (!chart_dict.attributes) { + return false; + } + + // main + this.chart.set(chart_dict.attributes); + + // set state + this.chart.state('ok', 'Loading saved visualization...'); + + // get settings + this.chart.settings.set(chart_dict.settings); + + // get groups + for (var j in chart_dict.groups) { + this.chart.groups.add(new Group(chart_dict.groups[j])); + } + + // reset modified flag + this.chart.set('modified', false); + + // return + return true; + } +}); + +}); \ No newline at end of file
This diff is so big that we needed to truncate the remainder.
https://bitbucket.org/galaxy/galaxy-central/commits/19e8344a0497/ Changeset: 19e8344a0497 User: dannon Date: 2014-04-21 23:10:23 Summary: Convert cloudlaunch over to bioblend egg/launching, unifying the two approaches. The bioblend codebase will be where improvements (vpc, etc) happen moving forward. Affected #: 3 files
diff -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 eggs.ini --- a/eggs.ini +++ b/eggs.ini @@ -35,6 +35,7 @@ amqp = 1.4.3 anyjson = 0.3.3 Beaker = 1.4 +bioblend = 0.4.2 boto = 2.27.0 decorator = 3.1.2 docutils = 0.7
diff -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py --- a/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py +++ b/lib/galaxy/webapps/galaxy/controllers/cloudlaunch.py @@ -16,16 +16,16 @@ from galaxy.util.json import to_json_string
eggs.require('boto') -import boto -import boto.vpc -from boto.ec2.regioninfo import RegionInfo -from boto.exception import EC2ResponseError, S3ResponseError -from boto.s3.connection import OrdinaryCallingFormat, S3Connection +eggs.require('bioblend') +eggs.require('pyyaml') + +from boto.exception import EC2ResponseError + + +from bioblend import cloudman
log = logging.getLogger(__name__)
-logging.getLogger('boto').setLevel(logging.INFO) -
PKEY_PREFIX = 'gxy_pkey' DEFAULT_KEYPAIR = 'cloudman_keypair' @@ -55,71 +55,29 @@ Get EC2 Account Info """ account_info = {} - try: - ec2_conn = connect_ec2(key_id, secret) - kps = ec2_conn.get_all_key_pairs() - except EC2ResponseError, e: - log.error("Problem starting an instance: %s\n%s" % (e, e.body)) - trans.response.status = 400 - return e.error_message or "Error retrieving account information. Please verify your credentials are correct, and contact galaxy support to report this issue." + cml = cloudman.launch.CloudManLauncher(key_id, secret) + ec2_conn = cml.connect_ec2(key_id, secret) + kps = ec2_conn.get_all_key_pairs() + account_info['clusters'] = cml.get_clusters_pd() account_info['keypairs'] = [akp.name for akp in kps] - #Existing Clusters - s3_conn = S3Connection(key_id, secret, calling_format=OrdinaryCallingFormat()) - buckets = s3_conn.get_all_buckets() - clusters = [] - for bucket in buckets: - try: - pd = bucket.get_key('persistent_data.yaml') - except S3ResponseError, e: - # This can fail for a number of reasons for non-us and/or CNAME'd buckets. - log.error("Problem fetching persistent_data.yaml from bucket: %s \n%s" % (e, e.body)) - continue - if pd: - # This is a cloudman bucket. - # We need to get persistent data, and the cluster name. - # DBTODO: Add pyyaml egg, and rewrite this. - # This will also allow for much more sophisticated rendering of existing clusters - # Currently, this zone detection is a hack. - pd_contents = pd.get_contents_as_string() - zone = get_zone_from_pd(pd_contents, ec2_conn) - for key in bucket.list(): - if key.name.endswith('.clusterName'): - clusters.append({'name': key.name.split('.clusterName')[0], - 'persistent_data': pd_contents, - 'zone': zone}) - account_info['clusters'] = clusters - account_info['zones'] = [z.name for z in ec2_conn.get_all_zones()] return to_json_string(account_info)
@web.expose - def launch_instance(self, trans, cluster_name, password, key_id, secret, instance_type, share_string, keypair, ami=None, zone=None, bucket_default=None, **kwargs): - ec2_error = None - try: - # Create security group & key pair used when starting an instance - ec2_conn = connect_ec2(key_id, secret) - sg = get_or_create_cm_security_group(ec2_conn) - kp_name, kp_material = create_key_pair(ec2_conn, key_name=keypair) - except EC2ResponseError, err: - ec2_error = err.error_message - if ec2_error: - trans.response.status = 400 - return ec2_error - #Get an elastic ip, add to UserData. - user_provided_data = _format_user_data(cluster_name, key_id, secret, password, share_string, bucket_default) - if not ami: - ami = trans.app.config.cloudlaunch_default_ami - rs = _run_instance(ec2_conn=ec2_conn, - image_id=ami, - user_provided_data=user_provided_data, - key_name=kp_name, - security_group_ids=[sg.id], - placement=zone, - instance_type=instance_type, - subnet_id=get_or_create_cm_subnet(key_id, secret, zone).id) - if not rs: + def launch_instance(self, trans, cluster_name, password, key_id, secret, + instance_type, share_string, keypair, ami=None, + zone=None, bucket_default=None, **kwargs): + ami = ami or trans.app.config.cloudlaunch_default_ami + cfg = cloudman.CloudManConfig(key_id, secret, cluster_name, ami, + instance_type, password, placement=zone) + cml = cloudman.launch.CloudManLauncher(key_id, secret) + result = cml.launch(cluster_name, ami, instance_type, password, + cfg.kernel_id, cfg.ramdisk_id, cfg.key_name, + cfg.security_groups, cfg.placement) + #result is a dict with sg_names, kp_name, kp_material, rs, and instance_id + if not result['rs']: trans.response.status = 400 return "Instance failure, but no specific error was detected. Please check your AWS Console." - instance = rs.instances[0] + instance = result['rs'].instances[0] while not instance.public_dns_name: try: instance.update() @@ -127,20 +85,20 @@ # This can happen when update is invoked before the instance is fully registered. pass time.sleep(1) - if kp_material: + if result['kp_material']: #We have created a keypair. Save to tempfile for one time retrieval. (fd, fname) = tempfile.mkstemp(prefix=PKEY_PREFIX, dir=trans.app.config.new_file_path) f = os.fdopen(fd, 'wt') - f.write(kp_material) + f.write(result['kp_material']) f.close() kp_material_tag = fname[fname.rfind(PKEY_PREFIX) + len(PKEY_PREFIX):] else: kp_material_tag = None return to_json_string({'cluster_name': cluster_name, - 'instance_id': rs.instances[0].id, - 'image_id': rs.instances[0].image_id, - 'public_dns_name': rs.instances[0].public_dns_name, - 'kp_name': kp_name, + 'instance_id': result['rs'].instances[0].id, + 'image_id': result['rs'].instances[0].image_id, + 'public_dns_name': result['rs'].instances[0].public_dns_name, + 'kp_name': result['kp_name'], 'kp_material_tag': kp_material_tag})
@web.expose @@ -158,188 +116,3 @@ return kp_material trans.response.status = 400 return "Invalid identifier" - - -def get_zone_from_pd(pd_contents, ec2_conn): - try: - for line in pd_contents.split('\n'): - if 'vol_id' in line: - vol_id = line.split(':')[1].strip() - v = ec2_conn.get_all_volumes(volume_ids=[vol_id]) - if v: - return v[0].zone - except: - # Things can go wrong with Zone detection outside of our control. Use - # the default zone if this happens. - pass - return '' - - -def connect_ec2(a_key, s_key): - """ - Create and return an EC2 connection object. - """ - # Use variables for forward looking flexibility - # AWS connection values - region_name = 'us-east-1' - region_endpoint = 'ec2.amazonaws.com' - is_secure = True - ec2_port = None - ec2_conn_path = '/' - r = RegionInfo(name=region_name, endpoint=region_endpoint) - ec2_conn = boto.connect_ec2(aws_access_key_id=a_key, - aws_secret_access_key=s_key, - is_secure=is_secure, - region=r, - port=ec2_port, - path=ec2_conn_path) - return ec2_conn - - -def get_or_create_cm_security_group(ec2_conn, sg_name='CloudManVPC'): - """ - Create a security group with all authorizations required to run CloudMan. - If the group already exists, check its rules and add the missing ones. - Return the name of the created security group. - """ - cm_sg = None - # Check if this security group already exists. We can't use the built-in - # filtering here, because VPC security groups can't be filtered by name. - sg = ec2_conn.get_all_security_groups(filters={'group_name': sg_name}) - if sg: - cm_sg = sg[0] - else: - # If it does not exist, create security group - log.debug("Creating Security Group %s" % sg_name) - cm_sg = ec2_conn.create_security_group(sg_name, 'A security group for CloudMan', vpc_id=get_or_create_cm_vpc(ec2_conn.access_key, ec2_conn.secret_key).id) - # Add appropriate authorization rules - # If these rules already exist, nothing will be changed in the SG - ports = (('80', '80'), # Web UI - ('20', '21'), # FTP - ('22', '22'), # ssh - ('30000', '30100'), # FTP transfer - ('42284', '42284')) # CloudMan UI - for port in ports: - if not rule_exists(cm_sg.rules, from_port=port[0], to_port=port[1]): - cm_sg.authorize(ip_protocol='tcp', from_port=port[0], to_port=port[1], cidr_ip='0.0.0.0/0') - else: - log.debug("Rule (%s:%s) already exists in the SG" % (port[0], port[1])) - # Add rule that allows communication between instances in the same SG - g_rule_exists = False # Flag to indicate if group rule already exists - for rule in cm_sg.rules: - for grant in rule.grants:#[g for g in rule.grants if g.name == cm_sg.name]: - print grant.name - if grant.name == cm_sg.name: - g_rule_exists = True - log.debug("Group rule already exists in the SG") - if g_rule_exists: - break - #if g_rule_exists is False: - # cm_sg.authorize(src_group=cm_sg) - log.info("Done configuring '%s' security group" % cm_sg.name) - return cm_sg - - - -def get_or_create_cm_vpc(a_key, s_key): - vpc_conn = boto.vpc.VPCConnection(a_key, s_key) - vpcs = vpc_conn.get_all_vpcs() - cloudman_vpc = None - for vpc in vpcs: - if CLOUDMAN_TAG_KEY in vpc.tags: - cloudman_vpc = vpc - if not cloudman_vpc: - #create a new one. - cloudman_vpc = vpc_conn.create_vpc('10.0.0.0/16') - cloudman_vpc.add_tag(CLOUDMAN_TAG_KEY, '') - return cloudman_vpc - - -def get_or_create_cm_subnet(a_key, s_key, availability_zone): - log.debug("GETTING SUBNET in %s" % availability_zone) - vpc_conn = boto.vpc.VPCConnection(a_key, s_key) - subnets = vpc_conn.get_all_subnets() - cloudman_subnet = None - for subnet in subnets: - log.debug("SN: %s, SNAZ:AZ: %s:%s:%s" % (subnet, subnet.availability_zone, availability_zone, subnet.availability_zone == availability_zone)) - if (not availability_zone or subnet.availability_zone == availability_zone) and CLOUDMAN_TAG_KEY in subnet.tags: - cloudman_subnet = subnet - if not cloudman_subnet: - #create a new one. - cloudman_subnet = vpc_conn.create_subnet(get_or_create_cm_vpc(a_key, s_key).id, '10.0.0.0/24', availability_zone) - cloudman_subnet.add_tag(CLOUDMAN_TAG_KEY, '') - return cloudman_subnet - - -def _format_user_data(cluster_name, key_id, secret, password, share_string, bucket_default): - user_provided_data = {'cluster_name': cluster_name, - 'access_key': key_id, - 'secret_key': secret} - if password: - user_provided_data['password'] = password - if share_string: - user_provided_data['share_string'] = share_string - if bucket_default: - user_provided_data['bucket_default'] = bucket_default - return "\n".join(['%s: %s' % (key, value) for key, value in user_provided_data.iteritems() if key != 'kp_material']) - - -def rule_exists(rules, from_port, to_port, ip_protocol='tcp', cidr_ip='0.0.0.0/0'): - """ A convenience method to check if an authorization rule in a security - group exists. - """ - for rule in rules: - if rule.ip_protocol == ip_protocol and rule.from_port == from_port and \ - rule.to_port == to_port and cidr_ip in [ip.cidr_ip for ip in rule.grants]: - return True - return False - - -def create_key_pair(ec2_conn, key_name=DEFAULT_KEYPAIR): - """ Create a key pair with the provided name. - Return the name of the key or None if there was an error creating the key. - """ - kp = None - # Check if a key pair under the given name already exists. If it does not, - # create it, else return. - kps = ec2_conn.get_all_key_pairs() - for akp in kps: - if akp.name == key_name: - log.debug("Key pair '%s' already exists; not creating it again." % key_name) - return akp.name, None - try: - kp = ec2_conn.create_key_pair(key_name) - except EC2ResponseError, e: - log.error("Problem creating key pair '%s': %s" % (key_name, e)) - return None, None - return kp.name, kp.material - - -def _run_instance(ec2_conn, user_provided_data, instance_type, image_id=None, - kernel_id=None, ramdisk_id=None, key_name=DEFAULT_KEYPAIR, - placement=None, security_group_ids=None, subnet_id=None): - """ - Start an instance. If instance start was OK, return the ResultSet object - else return None. - """ - rs = None - try: - rs = ec2_conn.run_instances(image_id=image_id, - instance_type=instance_type, - key_name=key_name, - security_group_ids=security_group_ids, - user_data=user_provided_data, - kernel_id=kernel_id, - subnet_id=subnet_id, - ramdisk_id=ramdisk_id, - placement=placement) - except EC2ResponseError, e: - log.error("Problem starting an instance: %s\n%s" % (e, e.body)) - if rs: - try: - log.info("Started an instance with ID %s" % rs.instances[0].id) - except Exception, e: - log.error("Problem with the started instance object: %s" % e) - else: - log.warning("Problem starting an instance?") - return rs
diff -r 347a9169e3ec43a5719a4ca57d7de04ea50cd0e7 -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 templates/webapps/galaxy/cloud/index.mako --- a/templates/webapps/galaxy/cloud/index.mako +++ b/templates/webapps/galaxy/cloud/index.mako @@ -65,7 +65,7 @@ clusterlist.append($('<option/>').val('New Cluster').text('New Cluster')); if (_.size(result.clusters) > 0){ _.each(result.clusters, function(cluster, index){ - clusterlist.append($('<option/>').val(cluster.name).text(cluster.name)); + clusterlist.append($('<option/>').val(cluster.cluster_name).text(cluster.cluster_name)); }); $('#existing_instance_wrapper').show(); } @@ -95,13 +95,13 @@ type: 'POST', dataType: 'json', beforeSubmit: function(data, form){ - // Dig up zone info for selected cluster, set hidden input. + // Dig up placement info for selected cluster, set hidden input. // This is not necessary to present to the user though the interface may prove useful. var ei_val = _.find(data, function(f_obj){return f_obj.name === 'existing_instance'}); if( ei_val && (ei_val.value !== "New Cluster")){ - var cluster = _.find(cloudlaunch_clusters, function(cluster){return cluster.name === ei_val.value}); - var zdata = _.find(data, function(f_obj){return f_obj.name === 'zone'}); - zdata.value = cluster.zone; + var cluster = _.find(cloudlaunch_clusters, function(cluster){return cluster.cluster_name === ei_val.value}); + var placement_field = _.find(data, function(f_obj){return f_obj.name === 'placement'}); + placement_field.value = cluster.placement; }else if($('#id_cluster_name').val() === ''){ // If we're not using an existing cluster, this must be set. form.prepend('<div class="errormessage">You must specify a cluster name</div>'); @@ -188,7 +188,7 @@ <label for="id_existing_instance">Instances in your account</label><select name="existing_instance" id="id_existing_instance" style="min-width: 228px"></select> - <input id='id_zone' type='hidden' name='zone' value=''/> + <input id='id_placement' type='hidden' name='placement' value=''/></div> %endif <div id='cluster_name_wrapper' class="form-row">
https://bitbucket.org/galaxy/galaxy-central/commits/557c0f2c6129/ Changeset: 557c0f2c6129 User: dannon Date: 2014-04-21 23:10:48 Summary: Merge. Affected #: 372 files
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 .hgtags --- a/.hgtags +++ b/.hgtags @@ -6,3 +6,4 @@ 1ae95b3aa98d1ccf15b243ac3ce6a895eb7efc53 release_2013.08.12 26f58e05aa1068761660681583821e21e6cbf7ab release_2013.11.04 5e605ed6069fe4c5ca9875e95e91b2713499e8ca release_2014.02.10 +9e53251b0b7e93b9563008a2b112f2e815a04bbc release_2014.04.14
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/app.js --- a/config/plugins/visualizations/charts/static/app.js +++ b/config/plugins/visualizations/charts/static/app.js @@ -51,7 +51,7 @@ // append views this.$el.append(this.viewer_view.$el); this.$el.append(this.editor_view.$el); - + // pick start screen if (!this.storage.load()) { // show editor
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/build-app.js --- a/config/plugins/visualizations/charts/static/build-app.js +++ b/config/plugins/visualizations/charts/static/build-app.js @@ -3,4 +3,4 @@ // (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc. // Underscore may be freely distributed under the MIT license.
-(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\":"\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),i=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),s=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),o=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),u=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),a=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),f=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),c=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:r,Icon:i,ButtonIcon:s,Input:c,Anchor:o,Message:u,Searchbox:a,Title:f,Select:t,ButtonMenu:l}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n!=""){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()}),t.set("dataset_id_job","")}},submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"chartskit",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:a,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Job has been queued..."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._loop(n.id,function(e){switch(e.state){case"ok":return t.state("wait","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),s&&s(),!0;case"running":return t.state("wait","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the Charts-Kit. Please make sure it is installed. "+n),s&&s()})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/jobs/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._fetch(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o="",u={},a=0;for(var f in t.groups){var l=t.groups[f];for(var c in l.columns){var h=l.columns[c];o+=h+",",u[h]=a,a++}}if(a==0){n({});return}o=o.substring(0,o.length-1);var p=t.groups.slice(0);for(var f in p)p[f].values=[];var d=this;e.request("GET",config.root+"api/datasets/"+t.id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:o},function(e){for(var i in e.data){var s=e.data[i];for(var o in t.groups){var a=t.groups[o],f={x:parseInt(i)+r};for(var l in a.columns){var c=a.columns[l],h=u[c],d=s[h];if(isNaN(d)||!d)d=0;f[l]=d}p[o].values.push(f)}}n(p)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh")},ready:function(){return this.counter==0?!0:!1}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._create_svg();var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=e.find("#icon");t.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info"));var n=r.chart.get("state");switch(n){case"ok":e.hide();break;case"failed":t.addClass("fa fa-warning");break;default:t.addClass("fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_create_svg:function(){this.svg&&this.svg.remove(),this.$el.append($(this._template_svg())),this.svg_el=this.$el.find("svg"),this.svg=d3.select(this.svg_el[0])},_draw:function(e){var t=this;this._create_svg(),e.state("wait","Please wait...");var n=e.deferred.register(),r=e.get("type"),i=this.app.types.get(r);if(!i.execute||i.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/"+r],function(r){var s=new r(t.app,{svg:t.svg});i.execute?e.get("dataset_id_job")==""?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){s.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):s.draw(n,e,t._defaultRequestDictionary(e)):s.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t=this.app.types.get(e.get("type")),n="",r=0;return e.groups.each(function(e){for(var i in t.columns)n+=i+"_"+ ++r+":"+(parseInt(e.get(i))+1)+", "}),n.substring(0,n.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t=this.app.types.get(e.get("type")),n={groups:[]};t.execute?n.id=e.get("dataset_id_job"):n.id=e.get("dataset_id");var r=0;return e.groups.each(function(e){var i={};for(var s in t.columns)i[s]=e.get(s);n.groups.push({key:++r+":"+e.get("key"),columns:i})}),n},_template:function(){return'<div style="height: 100%; min-height: 50px;"><div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_template_svg:function(){return'<svg style="height: calc(100% - 80px)"/>'}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Customize",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t){var n=$("<td></td>");t&&n.css("width",t),n.append(e),this.row.append(n)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({columns:[],initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){r.columns=[];var t=e.metadata_column_types;for(var n in t)(t[n]=="int"||t[n]=="float")&&r.columns.push({label:"Column: "+(parseInt(n)+1)+" ["+t[n]+"]",value:n});for(var n in s)s[n].update(r.columns),s[n].show();r.chart.state("wait","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){var u=this;this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}}),this.table=new t.View({header:!1,onconfirm:function(e){u.chart.groups.length>0?u.app.modal.show({title:"Switching to another chart type?",body:"If you continue your settings and selections will be cleared.",buttons:{Cancel:function(){u.app.modal.hide()},Continue:function(){u.app.modal.hide(),u.table.value(e)}}}):u.table.value(e)},onchange:function(e){u.chart.groups.reset(),u.chart.settings.clear(),u.chart.set({type:e})},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"});var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),h.execute?this.table.add(h.title+" (requires processing)"):this.table.add(h.title),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.chart.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/_nvd3/config",[],function(){return{title:"",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/bardiagram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/histogram/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:!0,columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"}}})}),define("plugin/charts/horizontal/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/line/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/linewithfocus/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/piechart/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Pie chart"})}),define("plugin/charts/scatterplot/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/stackedarea/config",["plugin/charts/_nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/types",["plugin/charts/bardiagram/config","plugin/charts/histogram/config","plugin/charts/horizontal/config","plugin/charts/line/config","plugin/charts/linewithfocus/config","plugin/charts/piechart/config","plugin/charts/scatterplot/config","plugin/charts/stackedarea/config"],function(e,t,n,r,i,s,o,u){return Backbone.Model.extend({defaults:{bardiagram:e,horizontal:n,histogram:t,line:r,linewithfocus:i,piechart:s,scatterplot:o,stackedarea:u}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})}); \ No newline at end of file +(function(){var e=this,t=e._,n={},r=Array.prototype,i=Object.prototype,s=Function.prototype,o=r.push,u=r.slice,a=r.concat,f=i.toString,l=i.hasOwnProperty,c=r.forEach,h=r.map,p=r.reduce,d=r.reduceRight,v=r.filter,m=r.every,g=r.some,y=r.indexOf,b=r.lastIndexOf,w=Array.isArray,E=Object.keys,S=s.bind,x=function(e){if(e instanceof x)return e;if(!(this instanceof x))return new x(e);this._wrapped=e};typeof exports!="undefined"?(typeof module!="undefined"&&module.exports&&(exports=module.exports=x),exports._=x):e._=x,x.VERSION="1.4.4";var T=x.each=x.forEach=function(e,t,r){if(e==null)return;if(c&&e.forEach===c)e.forEach(t,r);else if(e.length===+e.length){for(var i=0,s=e.length;i<s;i++)if(t.call(r,e[i],i,e)===n)return}else for(var o in e)if(x.has(e,o)&&t.call(r,e[o],o,e)===n)return};x.map=x.collect=function(e,t,n){var r=[];return e==null?r:h&&e.map===h?e.map(t,n):(T(e,function(e,i,s){r.push(t.call(n,e,i,s))}),r)};var N="Reduce of empty array with no initial value";x.reduce=x.foldl=x.inject=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(p&&e.reduce===p)return r&&(t=x.bind(t,r)),i?e.reduce(t,n):e.reduce(t);T(e,function(e,s,o){i?n=t.call(r,n,e,s,o):(n=e,i=!0)});if(!i)throw new TypeError(N);return n},x.reduceRight=x.foldr=function(e,t,n,r){var i=arguments.length>2;e==null&&(e=[]);if(d&&e.reduceRight===d)return r&&(t=x.bind(t,r)),i?e.reduceRight(t,n):e.reduceRight(t);var s=e.length;if(s!==+s){var o=x.keys(e);s=o.length}T(e,function(u,a,f){a=o?o[--s]:--s,i?n=t.call(r,n,e[a],a,f):(n=e[a],i=!0)});if(!i)throw new TypeError(N);return n},x.find=x.detect=function(e,t,n){var r;return C(e,function(e,i,s){if(t.call(n,e,i,s))return r=e,!0}),r},x.filter=x.select=function(e,t,n){var r=[];return e==null?r:v&&e.filter===v?e.filter(t,n):(T(e,function(e,i,s){t.call(n,e,i,s)&&r.push(e)}),r)},x.reject=function(e,t,n){return x.filter(e,function(e,r,i){return!t.call(n,e,r,i)},n)},x.every=x.all=function(e,t,r){t||(t=x.identity);var i=!0;return e==null?i:m&&e.every===m?e.every(t,r):(T(e,function(e,s,o){if(!(i=i&&t.call(r,e,s,o)))return n}),!!i)};var C=x.some=x.any=function(e,t,r){t||(t=x.identity);var i=!1;return e==null?i:g&&e.some===g?e.some(t,r):(T(e,function(e,s,o){if(i||(i=t.call(r,e,s,o)))return n}),!!i)};x.contains=x.include=function(e,t){return e==null?!1:y&&e.indexOf===y?e.indexOf(t)!=-1:C(e,function(e){return e===t})},x.invoke=function(e,t){var n=u.call(arguments,2),r=x.isFunction(t);return x.map(e,function(e){return(r?t:e[t]).apply(e,n)})},x.pluck=function(e,t){return x.map(e,function(e){return e[t]})},x.where=function(e,t,n){return x.isEmpty(t)?n?void 0:[]:x[n?"find":"filter"](e,function(e){for(var n in t)if(t[n]!==e[n])return!1;return!0})},x.findWhere=function(e,t){return x.where(e,t,!0)},x.max=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.max.apply(Math,e);if(!t&&x.isEmpty(e))return-Infinity;var r={computed:-Infinity,value:-Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o>=r.computed&&(r={value:e,computed:o})}),r.value},x.min=function(e,t,n){if(!t&&x.isArray(e)&&e[0]===+e[0]&&e.length<65535)return Math.min.apply(Math,e);if(!t&&x.isEmpty(e))return Infinity;var r={computed:Infinity,value:Infinity};return T(e,function(e,i,s){var o=t?t.call(n,e,i,s):e;o<r.computed&&(r={value:e,computed:o})}),r.value},x.shuffle=function(e){var t,n=0,r=[];return T(e,function(e){t=x.random(n++),r[n-1]=r[t],r[t]=e}),r};var k=function(e){return x.isFunction(e)?e:function(t){return t[e]}};x.sortBy=function(e,t,n){var r=k(t);return x.pluck(x.map(e,function(e,t,i){return{value:e,index:t,criteria:r.call(n,e,t,i)}}).sort(function(e,t){var n=e.criteria,r=t.criteria;if(n!==r){if(n>r||n===void 0)return 1;if(n<r||r===void 0)return-1}return e.index<t.index?-1:1}),"value")};var L=function(e,t,n,r){var i={},s=k(t==null?x.identity:t);return T(e,function(t,o){var u=s.call(n,t,o,e);r(i,u,t)}),i};x.groupBy=function(e,t,n){return L(e,t,n,function(e,t,n){(x.has(e,t)?e[t]:e[t]=[]).push(n)})},x.countBy=function(e,t,n){return L(e,t,n,function(e,t){x.has(e,t)||(e[t]=0),e[t]++})},x.sortedIndex=function(e,t,n,r){n=n==null?x.identity:k(n);var i=n.call(r,t),s=0,o=e.length;while(s<o){var u=s+o>>>1;n.call(r,e[u])<i?s=u+1:o=u}return s},x.toArray=function(e){return e?x.isArray(e)?u.call(e):e.length===+e.length?x.map(e,x.identity):x.values(e):[]},x.size=function(e){return e==null?0:e.length===+e.length?e.length:x.keys(e).length},x.first=x.head=x.take=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,0,t):e[0]},x.initial=function(e,t,n){return u.call(e,0,e.length-(t==null||n?1:t))},x.last=function(e,t,n){return e==null?void 0:t!=null&&!n?u.call(e,Math.max(e.length-t,0)):e[e.length-1]},x.rest=x.tail=x.drop=function(e,t,n){return u.call(e,t==null||n?1:t)},x.compact=function(e){return x.filter(e,x.identity)};var A=function(e,t,n){return T(e,function(e){x.isArray(e)?t?o.apply(n,e):A(e,t,n):n.push(e)}),n};x.flatten=function(e,t){return A(e,t,[])},x.without=function(e){return x.difference(e,u.call(arguments,1))},x.uniq=x.unique=function(e,t,n,r){x.isFunction(t)&&(r=n,n=t,t=!1);var i=n?x.map(e,n,r):e,s=[],o=[];return T(i,function(n,r){if(t?!r||o[o.length-1]!==n:!x.contains(o,n))o.push(n),s.push(e[r])}),s},x.union=function(){return x.uniq(a.apply(r,arguments))},x.intersection=function(e){var t=u.call(arguments,1);return x.filter(x.uniq(e),function(e){return x.every(t,function(t){return x.indexOf(t,e)>=0})})},x.difference=function(e){var t=a.apply(r,u.call(arguments,1));return x.filter(e,function(e){return!x.contains(t,e)})},x.zip=function(){var e=u.call(arguments),t=x.max(x.pluck(e,"length")),n=new Array(t);for(var r=0;r<t;r++)n[r]=x.pluck(e,""+r);return n},x.unzip=function(e){var t=[];return x.each(e,function(e,n){x.each(e,function(e,r){t.length<=r&&(t[r]=[]),t[r][n]=e})}),t},x.object=function(e,t){if(e==null)return{};var n={};for(var r=0,i=e.length;r<i;r++)t?n[e[r]]=t[r]:n[e[r][0]]=e[r][1];return n},x.indexOf=function(e,t,n){if(e==null)return-1;var r=0,i=e.length;if(n){if(typeof n!="number")return r=x.sortedIndex(e,t),e[r]===t?r:-1;r=n<0?Math.max(0,i+n):n}if(y&&e.indexOf===y)return e.indexOf(t,n);for(;r<i;r++)if(e[r]===t)return r;return-1},x.lastIndexOf=function(e,t,n){if(e==null)return-1;var r=n!=null;if(b&&e.lastIndexOf===b)return r?e.lastIndexOf(t,n):e.lastIndexOf(t);var i=r?n:e.length;while(i--)if(e[i]===t)return i;return-1},x.range=function(e,t,n){arguments.length<=1&&(t=e||0,e=0),n=arguments[2]||1;var r=Math.max(Math.ceil((t-e)/n),0),i=0,s=new Array(r);while(i<r)s[i++]=e,e+=n;return s};var O=function(){};x.bind=function(e,t){var n,r;if(e.bind===S&&S)return S.apply(e,u.call(arguments,1));if(!x.isFunction(e))throw new TypeError;return n=u.call(arguments,2),r=function(){if(this instanceof r){O.prototype=e.prototype;var i=new O;O.prototype=null;var s=e.apply(i,n.concat(u.call(arguments)));return Object(s)===s?s:i}return e.apply(t,n.concat(u.call(arguments)))}},x.partial=function(e){var t=u.call(arguments,1);return function(){return e.apply(this,t.concat(u.call(arguments)))}},x.bindAll=function(e){var t=u.call(arguments,1);if(t.length===0)throw new Error("bindAll must be passed function names");return T(t,function(t){e[t]=x.bind(e[t],e)}),e},x.memoize=function(e,t){var n={};return t||(t=x.identity),function(){var r=t.apply(this,arguments);return x.has(n,r)?n[r]:n[r]=e.apply(this,arguments)}},x.delay=function(e,t){var n=u.call(arguments,2);return setTimeout(function(){return e.apply(null,n)},t)},x.defer=function(e){return x.delay.apply(x,[e,1].concat(u.call(arguments,1)))},x.throttle=function(e,t,n){var r,i,s,o,u=0,a=function(){u=new Date,s=null,o=e.apply(r,i)};return function(){var f=new Date;!u&&n===!1&&(u=f);var l=t-(f-u);return r=this,i=arguments,l<=0?(clearTimeout(s),s=null,u=f,o=e.apply(r,i)):s||(s=setTimeout(a,l)),o}},x.debounce=function(e,t,n){var r,i;return function(){var s=this,o=arguments,u=function(){r=null,n||(i=e.apply(s,o))},a=n&&!r;return clearTimeout(r),r=setTimeout(u,t),a&&(i=e.apply(s,o)),i}},x.once=function(e){var t=!1,n;return function(){return t?n:(t=!0,n=e.apply(this,arguments),e=null,n)}},x.wrap=function(e,t){return function(){var n=[e];return o.apply(n,arguments),t.apply(this,n)}},x.compose=function(){var e=arguments;return function(){var t=arguments;for(var n=e.length-1;n>=0;n--)t=[e[n].apply(this,t)];return t[0]}},x.after=function(e,t){return e<=0?t():function(){if(--e<1)return t.apply(this,arguments)}},x.keys=E||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var n in e)x.has(e,n)&&t.push(n);return t},x.values=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push(e[n]);return t},x.pairs=function(e){var t=[];for(var n in e)x.has(e,n)&&t.push([n,e[n]]);return t},x.invert=function(e){var t={};for(var n in e)x.has(e,n)&&(t[e[n]]=n);return t},x.functions=x.methods=function(e){var t=[];for(var n in e)x.isFunction(e[n])&&t.push(n);return t.sort()},x.extend=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]=t[n]}),e},x.pick=function(e){var t={},n=a.apply(r,u.call(arguments,1));return T(n,function(n){n in e&&(t[n]=e[n])}),t},x.omit=function(e){var t={},n=a.apply(r,u.call(arguments,1));for(var i in e)x.contains(n,i)||(t[i]=e[i]);return t},x.defaults=function(e){return T(u.call(arguments,1),function(t){if(t)for(var n in t)e[n]===void 0&&(e[n]=t[n])}),e},x.clone=function(e){return x.isObject(e)?x.isArray(e)?e.slice():x.extend({},e):e},x.tap=function(e,t){return t(e),e};var M=function(e,t,n,r){if(e===t)return e!==0||1/e==1/t;if(e==null||t==null)return e===t;e instanceof x&&(e=e._wrapped),t instanceof x&&(t=t._wrapped);var i=f.call(e);if(i!=f.call(t))return!1;switch(i){case"[object String]":return e==String(t);case"[object Number]":return e!=+e?t!=+t:e==0?1/e==1/t:e==+t;case"[object Date]":case"[object Boolean]":return+e==+t;case"[object RegExp]":return e.source==t.source&&e.global==t.global&&e.multiline==t.multiline&&e.ignoreCase==t.ignoreCase}if(typeof e!="object"||typeof t!="object")return!1;var s=n.length;while(s--)if(n[s]==e)return r[s]==t;n.push(e),r.push(t);var o=0,u=!0;if(i=="[object Array]"){o=e.length,u=o==t.length;if(u)while(o--)if(!(u=M(e[o],t[o],n,r)))break}else{var a=e.constructor,l=t.constructor;if(a!==l&&!(x.isFunction(a)&&a instanceof a&&x.isFunction(l)&&l instanceof l))return!1;for(var c in e)if(x.has(e,c)){o++;if(!(u=x.has(t,c)&&M(e[c],t[c],n,r)))break}if(u){for(c in t)if(x.has(t,c)&&!(o--))break;u=!o}}return n.pop(),r.pop(),u};x.isEqual=function(e,t){return M(e,t,[],[])},x.isEmpty=function(e){if(e==null)return!0;if(x.isArray(e)||x.isString(e))return e.length===0;for(var t in e)if(x.has(e,t))return!1;return!0},x.isElement=function(e){return!!e&&e.nodeType===1},x.isArray=w||function(e){return f.call(e)=="[object Array]"},x.isObject=function(e){return e===Object(e)},T(["Arguments","Function","String","Number","Date","RegExp"],function(e){x["is"+e]=function(t){return f.call(t)=="[object "+e+"]"}}),x.isArguments(arguments)||(x.isArguments=function(e){return!!e&&!!x.has(e,"callee")}),typeof /./!="function"&&(x.isFunction=function(e){return typeof e=="function"}),x.isFinite=function(e){return isFinite(e)&&!isNaN(parseFloat(e))},x.isNaN=function(e){return x.isNumber(e)&&e!=+e},x.isBoolean=function(e){return e===!0||e===!1||f.call(e)=="[object Boolean]"},x.isNull=function(e){return e===null},x.isUndefined=function(e){return e===void 0},x.has=function(e,t){return l.call(e,t)},x.noConflict=function(){return e._=t,this},x.identity=function(e){return e},x.times=function(e,t,n){var r=Array(e);for(var i=0;i<e;i++)r[i]=t.call(n,i);return r},x.random=function(e,t){return t==null&&(t=e,e=0),e+Math.floor(Math.random()*(t-e+1))};var _={escape:{"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"}};_.unescape=x.invert(_.escape);var D={escape:new RegExp("["+x.keys(_.escape).join("")+"]","g"),unescape:new RegExp("("+x.keys(_.unescape).join("|")+")","g")};x.each(["escape","unescape"],function(e){x[e]=function(t){return t==null?"":(""+t).replace(D[e],function(t){return _[e][t]})}}),x.result=function(e,t){if(e==null)return void 0;var n=e[t];return x.isFunction(n)?n.call(e):n},x.mixin=function(e){T(x.functions(e),function(t){var n=x[t]=e[t];x.prototype[t]=function(){var e=[this._wrapped];return o.apply(e,arguments),F.call(this,n.apply(x,e))}})};var P=0;x.uniqueId=function(e){var t=++P+"";return e?e+t:t},x.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var H=/(.)^/,B={"'":"'","\":"\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},j=/\|'|\r|\n|\t|\u2028|\u2029/g;x.template=function(e,t,n){var r;n=x.defaults({},n,x.templateSettings);var i=new RegExp([(n.escape||H).source,(n.interpolate||H).source,(n.evaluate||H).source].join("|")+"|$","g"),s=0,o="__p+='";e.replace(i,function(t,n,r,i,u){return o+=e.slice(s,u).replace(j,function(e){return"\"+B[e]}),n&&(o+="'+\n((__t=("+n+"))==null?'':_.escape(__t))+\n'"),r&&(o+="'+\n((__t=("+r+"))==null?'':__t)+\n'"),i&&(o+="';\n"+i+"\n__p+='"),s=u+t.length,t}),o+="';\n",n.variable||(o="with(obj||{}){\n"+o+"}\n"),o="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+o+"return __p;\n";try{r=new Function(n.variable||"obj","_",o)}catch(u){throw u.source=o,u}if(t)return r(t,x);var a=function(e){return r.call(this,e,x)};return a.source="function("+(n.variable||"obj")+"){\n"+o+"}",a},x.chain=function(e){return x(e).chain()};var F=function(e){return this._chain?x(e).chain():e};x.mixin(x),T(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=r[e];x.prototype[e]=function(){var n=this._wrapped;return t.apply(n,arguments),(e=="shift"||e=="splice")&&n.length===0&&delete n[0],F.call(this,n)}}),T(["concat","join","slice"],function(e){var t=r[e];x.prototype[e]=function(){return F.call(this,t.apply(this._wrapped,arguments))}}),x.extend(x.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this),define("libs/underscore",function(e){return function(){var t,n;return t||e._}}(this)),define("utils/utils",["libs/underscore"],function(e){function t(e,t,r){n("GET",e,{},t,r)}function n(e,t,n,r,i){if(e=="GET"||e=="DELETE")t.indexOf("?")==-1?t+="?":t+="&",t+=$.param(n);var s=new XMLHttpRequest;s.open(e,t,!0),s.setRequestHeader("Accept","application/json"),s.setRequestHeader("Cache-Control","no-cache"),s.setRequestHeader("X-Requested-With","XMLHttpRequest"),s.setRequestHeader("Content-Type","application/json"),s.onloadend=function(){var e=s.status;try{response=jQuery.parseJSON(s.responseText)}catch(t){response=s.responseText}e==200?r&&r(response):i&&i(response)},e=="GET"||e=="DELETE"?s.send():s.send(JSON.stringify(n))}function r(e,t){var n=$('<div class="'+e+'"></div>');n.appendTo(":eq(0)");var r=n.css(t);return n.remove(),r}function i(e){$('link[href^="'+e+'"]').length||$('<link href="'+galaxy_config.root+e+'" rel="stylesheet">').appendTo("head")}function s(t,n){return t?e.defaults(t,n):n}function o(e,t){var n="";if(e>=1e11)e/=1e11,n="TB";else if(e>=1e8)e/=1e8,n="GB";else if(e>=1e5)e/=1e5,n="MB";else if(e>=100)e/=100,n="KB";else{if(!(e>0))return"<strong>-</strong>";e*=10,n="b"}var r=Math.round(e)/10;return t?r+" "+n:"<strong>"+r+"</strong> "+n}function u(){return(new Date).getTime().toString(36)}function a(e){var t=$("<p></p>");return t.append(e),t}function f(){var e=new Date,t=(e.getHours()<10?"0":"")+e.getHours(),n=(e.getMinutes()<10?"0":"")+e.getMinutes(),r=e.getDate()+"/"+(e.getMonth()+1)+"/"+e.getFullYear()+", "+t+":"+n;return r}return{cssLoadFile:i,cssGetAttribute:r,get:t,merge:s,bytesToString:o,uuid:u,time:f,wrap:a,request:n}}),define("mvc/ui/ui-modal",["utils/utils"],function(e){var t=Backbone.View.extend({elMain:"body",optionsDefault:{title:"ui-modal",body:"",backdrop:!0,height:null,width:null,closing_events:!1},buttonList:{},initialize:function(e){e&&this._create(e)},show:function(e){this.initialize(e),this.options.height?(this.$body.css("height",this.options.height),this.$body.css("overflow","hidden")):this.$body.css("max-height",$(window).height()/2),this.options.width&&this.$dialog.css("width",this.options.width),this.visible?this.$el.show():this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.visible=!1,this.$el.fadeOut("fast")},enableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!1)},disableButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).prop("disabled",!0)},showButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).show()},hideButton:function(e){var t=this.buttonList[e];this.$buttons.find("#"+t).hide()},getButton:function(e){var t=this.buttonList[e];return this.$buttons.find("#"+t)},scrollTop:function(){return this.$body.scrollTop()},_create:function(e){var t=this;this.options=_.defaults(e,this.optionsDefault),this.options.body=="progress"&&(this.options.body=$('<div class="progress progress-striped active"><div class="progress-bar progress-bar-info" style="width:100%"></div></div>')),this.$el&&(this.$el.remove(),$(document).off("keyup.ui-modal")),this.setElement(this._template(this.options.title)),this.$dialog=this.$el.find(".modal-dialog"),this.$body=this.$el.find(".modal-body"),this.$footer=this.$el.find(".modal-footer"),this.$buttons=this.$el.find(".buttons"),this.$backdrop=this.$el.find(".modal-backdrop"),this.$body.html(this.options.body),this.options.backdrop||this.$backdrop.removeClass("in");if(this.options.buttons){this.buttonList={};var n=0;$.each(this.options.buttons,function(e,r){var i="button-"+n++;t.$buttons.append($('<button id="'+i+'"></button>').text(e).click(r)).append(" "),t.buttonList[e]=i})}else this.$footer.hide();$(this.elMain).append($(this.el)),this.options.closing_events&&($(document).on("keyup.ui-modal",function(e){e.keyCode==27&&t.hide()}),this.$el.find(".modal-backdrop").on("click",function(){t.hide()}))},_template:function(e){return'<div class="modal"><div class="modal-backdrop fade in" style="z-index: -1;"></div><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><button type="button" class="close" style="display: none;">×</button><h4 class="title">'+e+"</h4>"+"</div>"+'<div class="modal-body" style="position: static;"></div>'+'<div class="modal-footer">'+'<div class="buttons" style="float: right;"></div>'+"</div>"+"</div"+"</div>"+"</div>"}});return{View:t}}),define("mvc/ui/ui-portlet",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,optionsDefault:{title:"",icon:"",buttons:null,body:null,height:null,operations:null,placement:"bottom",overflow:"auto"},$title:null,$content:null,$buttons:null,$operations:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$content=this.$el.find("#content"),this.$title=this.$el.find("#title-text"),this.options.height&&(this.$el.find("#body").css("height",this.options.height),this.$el.find("#content").css("overflow",this.options.overflow)),this.$buttons=$(this.el).find("#buttons");if(this.options.buttons){var n=this;$.each(this.options.buttons,function(e,t){t.$el.prop("id",e),n.$buttons.append(t.$el)})}else this.$buttons.remove();this.$operations=$(this.el).find("#operations");if(this.options.operations){var n=this;$.each(this.options.operations,function(e,t){t.$el.prop("id",e),n.$operations.append(t.$el)})}this.options.body&&this.append(this.options.body)},append:function(t){this.$content.append(e.wrap(t))},content:function(){return this.$content},show:function(){this.$el.fadeIn("fast"),this.visible=!0},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},enableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!1)},disableButton:function(e){this.$buttons.find("#"+e).prop("disabled",!0)},hideOperation:function(e){this.$operations.find("#"+e).hide()},showOperation:function(e){this.$operations.find("#"+e).show()},setOperation:function(e,t){var n=this.$operations.find("#"+e);n.off("click"),n.on("click",t)},title:function(e){var t=this.$title;return e&&t.html(e),t.html()},_template:function(e){var t='<div class="toolForm portlet-view no-highlight">';if(e.title||e.icon)t+='<div id="title" class="toolFormTitle portlet-title"><div id="operations" class="portlet-operations"/><div style="overflow: hidden;">',e.icon&&(t+='<div class="portlet-title-icon fa '+e.icon+'"> </div>'),t+='<div id="title-text" class="portlet-title-text">'+e.title+"</div>",t+="</div></div>";return t+='<div id="body" class="toolFormBody portlet-body">',e.placement=="top"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+='<div id="content" class="portlet-content"/>',e.placement=="bottom"&&(t+='<div id="buttons" class="portlet-buttons"/>'),t+="</div></div>",t}});return{View:t}}),define("plugin/library/ui-select",["utils/utils"],function(e){var t=Backbone.View.extend({optionsDefault:{id:"",cls:"",empty:"No data available",visible:!0,wait:!1},selected:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.$select=this.$el.find("#select"),this.$icon=this.$el.find("#icon"),this.selected=this.options.value;var n=this;this.options.onchange&&this.$select.on("change",function(){n.value(n.$select.val())}),this._refresh(),this.options.visible||this.hide(),this.options.wait?this.wait():this.show()},value:function(e){var t=this.selected;e!==undefined&&(this.selected=e,this.$select.val(e));var n=this.selected;return n&&n!=t&&this.options.onchange&&this.options.onchange(n),n},text:function(){return this.$select.find("option:selected").text()},show:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-caret-down"),this.$select.show(),this.$el.show()},hide:function(){this.$el.hide()},wait:function(){this.$icon.removeClass(),this.$icon.addClass("fa fa-spinner fa-spin"),this.$select.hide()},disabled:function(){return this.$select.is(":disabled")},enable:function(){this.$select.prop("disabled",!1)},disable:function(){this.$select.prop("disabled",!0)},add:function(e){this.$select.append(this._templateOption(e)),this._refresh()},del:function(e){this.$select.find("option[value="+e+"]").remove(),this.$select.trigger("change"),this._refresh()},update:function(e){this.$select.find("option").remove();for(var t in e)this.$select.append(this._templateOption(e[t]));!this.selected&&e.length>0&&this.value(e[0].value),this._refresh()},_refresh:function(){this.$select.find("option[value=null]").remove();var e=this.$select.find("option").length;e==0?(this.$select.append(this._templateOption({value:"null",label:this.options.empty})),this.disable()):(this.enable(),this.selected&&this.$select.val(this.selected))},_exists:function(e){return 0!=this.$select.find("option[value="+e+"]").length},_templateOption:function(e){return'<option value="'+e.value+'">'+e.label+"</option>"},_template:function(e){var t='<div id="'+e.id+'" class="styled-select">'+'<div class="button">'+'<i id="icon"/>'+"</div>"+'<select id="select" class="select '+e.cls+" "+e.id+'">';for(key in e.data){var n=e.data[key],r="";if(n.value==e.value||n.value=="")r="selected";t+='<option value="'+n.value+'" '+r+">"+n.label+"</option>"}return t+="</select></div>",t}});return{View:t}}),define("plugin/library/ui",["utils/utils","plugin/library/ui-select"],function(e,t){var n=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.find("b").html(e)},_template:function(e){return"<label><b>"+e.title+"</b></label>"},value:function(){return options.title}}),r=Backbone.View.extend({optionsDefault:{title:"",cls:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options))},title:function(e){this.$el.html(e)},_template:function(e){return'<div class="'+e.cls+'">'+e.title+"</div>"},value:function(){return options.title}}),i=Backbone.View.extend({optionsDefault:{id:null,title:"","float":"right",cls:"btn-default",icon:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t='<button id="'+e.id+'" type="submit" style="margin-right: 5px; float: '+e.float+';" type="button" class="btn '+e.cls+'">';return e.icon&&(t+='<i class="icon fa '+e.icon+'"></i> '),t+=e.title+"</button>",t}}),s=Backbone.View.extend({optionsDefault:{"float":"right",icon:"",tooltip:"",placement:"bottom",title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){return'<div><span class="fa '+e.icon+'" style="font-size: 1.2em;"/> '+e.title+"</div>"}}),o=Backbone.View.extend({optionsDefault:{title:"",id:null,"float":"right",cls:"icon-btn",icon:"",tooltip:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick),$(this.el).tooltip({title:t.tooltip,placement:"bottom"})},_template:function(e){var t="";e.title&&(t="width: auto;");var n='<div id="'+e.id+'" style="margin-right: 5px; float: '+e.float+"; "+t+'" class="'+e.cls+'">';return e.title?n+='<div style="margin-right: 5px; margin-left: 5px;"><i class="icon fa '+e.icon+'"/> '+'<span style="position: relative; font-size: 0.8em; font-weight: normal; top: -1px;">'+e.title+"</span>"+"</div>":n+='<i class="icon fa '+e.icon+'"/>',n+="</div>",n}}),u=Backbone.View.extend({optionsDefault:{title:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),$(this.el).on("click",t.onclick)},_template:function(e){return'<div><a href="javascript:void(0)">'+e.title+"</a></div>"}}),a=Backbone.View.extend({optionsDefault:{message:"",status:"info",persistent:!1},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement("<div></div>")},update:function(t){this.options=e.merge(t,this.optionsDefault);if(t.message!=""){this.$el.html(this._template(this.options)),this.$el.fadeIn();if(!t.persistent){var n=this;window.setTimeout(function(){n.$el.is(":visible")?n.$el.fadeOut():n.$el.hide()},3e3)}}else this.$el.fadeOut()},_template:function(e){return'<div class="alert alert-'+e.status+'" style="padding: 2px 2px 2px 10px;">'+e.message+"</div>"}}),f=Backbone.View.extend({optionsDefault:{onclick:null,searchword:""},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options));var n=this;this.options.onclick&&this.$el.on("submit",function(e){var t=n.$el.find("#search");n.options.onclick(t.val())})},_template:function(e){return'<div class="search"><form onsubmit="return false;"><input id="search" class="form-control input-sm" type="text" name="search" placeholder="Search..." value="'+e.searchword+'">'+'<button type="submit" class="btn search-btn">'+'<i class="fa fa-search"></i>'+"</button>"+"</form>"+"</div>"}}),l=Backbone.View.extend({optionsDefault:{title:"Unlabeled",body:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.body&&this.$el.find(".body").append(this.options.body)},_template:function(e){return'<div id="title" class="title">'+e.title+":"+"</div>"}}),c=Backbone.View.extend({optionsDefault:{id:"",title:"",target:"",href:"",onunload:null,onclick:null,visible:!0,icon:null,tag:""},$menu:null,initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement($(this._template(this.options)));var n=$(this.el).find(".root"),r=this;n.on("click",function(e){e.preventDefault(),r.options.onclick&&r.options.onclick()}),this.options.visible||this.hide()},show:function(){$(this.el).show()},hide:function(){$(this.el).hide()},addMenu:function(t){var n={title:"",target:"",href:"",onclick:null,divider:!1,icon:null};n=e.merge(t,n),this.$menu||($(this.el).append(this._templateMenu()),this.$menu=$(this.el).find(".menu"));var r=$(this._templateMenuItem(n));r.on("click",function(e){e.preventDefault(),n.onclick&&n.onclick()}),this.$menu.append(r),n.divider&&this.$menu.append($(this._templateDivider()))},_templateMenuItem:function(e){var t='<li><a href="'+e.href+'" target="'+e.target+'">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),t+=" "+e.title+"</a>"+"</li>",t},_templateMenu:function(){return'<ul class="menu dropdown-menu pull-right" role="menu"></ul>'},_templateDivider:function(){return'<li class="divider"></li>'},_template:function(e){var t='<div id="'+e.id+'" class="button-menu btn-group">'+'<button type="button" class="root btn btn-default dropdown-toggle" data-toggle="dropdown">';return e.icon&&(t+='<i class="fa '+e.icon+'"></i>'),"</button></div>",t}}),h=Backbone.View.extend({optionsDefault:{value:"",type:"text",placeholder:"",disabled:!1,visible:!0},initialize:function(t){this.options=e.merge(t,this.optionsDefault),this.setElement(this._template(this.options)),this.options.disabled&&this.$el.prop("disabled",!0),this.options.visible||this.$el.hide();var n=this;this.options.onchange&&this.$el.on("input",function(){n.options.onchange()})},value:function(e){return e!==undefined&&this.$el.val(e),this.$el.val()},_template:function(e){return'<input id="'+e.id+'" type="'+e.type+'" value="'+e.value+'" placeholder="'+e.placeholder+'" class="form-control">'}});return{Label:n,Button:i,Icon:s,ButtonIcon:o,Input:h,Anchor:u,Message:a,Searchbox:f,Title:l,Text:r,Select:t,ButtonMenu:c}}),define("plugin/library/jobs",["utils/utils"],function(e){return Backbone.Model.extend({initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},cleanup:function(t){var n=t.get("dataset_id_job");if(n!=""){var r=this;e.request("PUT",config.root+"api/histories/none/contents/"+n,{deleted:!0},function(){r._refreshHdas()}),t.set("dataset_id_job","")}},submit:function(t,n,r,i,s){var o=this,u=t.id,a=t.get("type"),f=this.app.types.get(a);data={tool_id:"charts",inputs:{input:{id:t.get("dataset_id"),src:"hda"},module:f.execute,columns:r,settings:n}},t.state("wait","Sending job request..."),e.request("POST",config.root+"api/tools",data,function(e){if(!e.outputs||e.outputs.length==0)t.state("failed","Job submission failed. No response."),s&&s();else{o._refreshHdas();var n=e.outputs[0];t.state("wait","Job has been queued..."),t.set("dataset_id_job",n.id),this.app.storage.save(),o._loop(n.id,function(e){switch(e.state){case"ok":return t.state("wait","Job completed successfully..."),i(e),!0;case"error":return t.state("failed","Job has failed. Please check the history for details."),s&&s(),!0;case"running":return t.state("wait","Job is running..."),!1}})}},function(e){var n="";e&&e.message&&e.message.data&&e.message.data.input&&(n=e.message.data.input+"."),t.state("failed","This visualization requires the 'charts' tool. Please make sure it is installed. "+n),s&&s()})},_loop:function(t,n){var r=this;e.request("GET",config.root+"api/datasets/"+t,{},function(e){n(e)||setTimeout(function(){r._loop(t,n)},r.app.config.get("query_timeout"))})},_refreshHdas:function(){Galaxy&&Galaxy.currHistoryPanel&&Galaxy.currHistoryPanel.refreshHdas()}})}),define("plugin/library/datasets",["utils/utils"],function(e){return Backbone.Collection.extend({list:{},cache:{},initialize:function(t,n){this.app=t,this.options=e.merge(n,this.optionsDefault)},request:function(t,n,r){var i=this;if(t.groups)this._get(t,n);else{var s=this.list[t.id];if(s){n(s);return}e.request("GET",config.root+"api/datasets/"+t.id,{},function(e){switch(e.state){case"error":r&&r(e);break;default:i.list[t.id]=e,n(e)}})}},_block_id:function(e,t){return e.id+"_"+e.start+"_"+e.end+"_"+t},_get:function(e,t){e.start||(e.start=0),e.end||(e.end=this.app.config.get("query_limit"));var n=[],r={},i=0;for(var s in e.groups){var o=e.groups[s];for(var u in o.columns){var a=o.columns[u].index,f=this._block_id(e,a);if(this.cache[f])continue;!r[a]&&a!==undefined&&(r[a]=i,n.push(a),i++)}}if(n.length==0){this._fill_from_cache(e),t(e);return}var l={dataset_id:e.id,start:e.start,end:e.end,columns:n},c=this;this._fetch(l,function(r){for(var i in r){var s=n[i],o=c._block_id(e,s);c.cache[o]=r[i]}c._fill_from_cache(e),t(e)})},_fill_from_cache:function(e){console.debug("Datasets::_fill_from_cache() - Filling request from cache.");for(var t in e.groups){var n=e.groups[t];n.values=[];for(var r in n.columns){var i=n.columns[r],s=this._block_id(e,i.index),o=this.cache[s];for(k in o){var u=n.values[k];u===undefined&&(u={x:parseInt(k)+e.start},n.values[k]=u);var a=o[k];isNaN(a)&&!i.is_label&&(a=0),u[r]=a}}}},_fetch:function(t,n){var r=t.start?t.start:0,i=Math.abs(t.end-t.start),s=this.app.config.get("query_limit");if(!i||i>s)i=s;var o=0;t.columns&&(o=t.columns.length,console.debug("Datasets::_fetch() - Fetching "+o+" column(s)")),o==0&&console.debug("Datasets::_fetch() - No columns requested");var u="";for(var a in t.columns)u+=t.columns[a]+",";u=u.substring(0,u.length-1);var f=this;e.request("GET",config.root+"api/datasets/"+t.dataset_id,{data_type:"raw_data",provider:"dataset-column",limit:i,offset:r,indeces:u},function(e){var t=new Array(o);for(var r=0;r<o;r++)t[r]=[];for(var r in e.data){var i=e.data[r];for(var s in i){var u=i[s];u!==undefined&&u!=2147483647&&t[s].push(u)}}console.debug("Datasets::_fetch() - Fetching complete."),n(t)})}})}),define("plugin/models/group",[],function(){return Backbone.Model.extend({defaults:{key:"Data label",date:""},reset:function(){this.clear({silent:!0}).set(this.defaults),this.trigger("reset",this)}})}),define("plugin/models/groups",["plugin/models/group"],function(e){return Backbone.Collection.extend({model:e})}),define("plugin/library/deferred",["utils/utils"],function(e){return Backbone.Model.extend({queue:[],process:{},counter:0,initialize:function(){this.on("refresh",function(){if(this.counter==0)for(var e in this.queue)this.queue[e](),this.queue.splice(e,1)})},execute:function(e){this.queue.push(e),this.trigger("refresh")},register:function(){var t=e.uuid();return this.process[t]=!0,this.counter++,console.debug("Deferred:register() - Registering "+t),t},done:function(e){this.process[e]&&(delete this.process[e],this.counter--,console.debug("Deferred:done() - Unregistering "+e),this.trigger("refresh"))},ready:function(){return this.counter==0?!0:!1}})});var Visualization=Backbone.Model.extend({defaults:{config:{}},urlRoot:function(){var e="/api/visualizations";return window.galaxy_config&&galaxy_config.root?galaxy_config.root+e:e},initialize:function(e){_.isObject(e.config)&&_.isObject(this.defaults.config)&&_.defaults(e.config,this.defaults.config),this._setUpListeners()},_setUpListeners:function(){},set:function(e,t){if(e==="config"){var n=this.get("config");_.isObject(n)&&(t=_.extend(_.clone(n),t))}return Backbone.Model.prototype.set.call(this,e,t),this},toString:function(){var e=this.get("id")||"";return this.get("title")&&(e+=":"+this.get("title")),"Visualization("+e+")"}}),VisualizationCollection=Backbone.Collection.extend({model:Visualization,url:function(){return galaxy_config.root+"api/visualizations"},initialize:function(e,t){t=t||{}},set:function(e,t){var n=this;e=_.map(e,function(e){var t=n.get(e.id);if(!t)return e;var r=t.toJSON();return _.extend(r,e),r}),Backbone.Collection.prototype.set.call(this,e,t)},toString:function(){return["VisualizationCollection(",[this.historyId,this.length].join(),")"].join("")}});define("mvc/visualization/visualization-model",function(){}),define("plugin/models/chart",["plugin/models/groups","plugin/library/deferred","mvc/visualization/visualization-model"],function(e,t){return Backbone.Model.extend({defaults:{id:null,title:"",type:"",date:null,state:"",state_info:"",modified:!1,dataset_id:"",dataset_id_job:""},initialize:function(n){this.groups=new e,this.settings=new Backbone.Model,this.deferred=new t},reset:function(){this.clear({silent:!0}).set(this.defaults),this.groups.reset(),this.settings.clear(),this.trigger("reset",this)},copy:function(e){var t=this;t.clear({silent:!0}).set(this.defaults),t.set(e.attributes),t.settings=e.settings.clone(),t.groups.reset(),e.groups.each(function(e){t.groups.add(e.clone())}),t.trigger("change",t)},state:function(e,t){this.set("state",e),this.set("state_info",t),this.trigger("set:state"),console.debug("Chart:state() - "+t+" ("+e+")")}})}),define("plugin/library/storage",["utils/utils","plugin/models/chart","plugin/models/group"],function(e,t,n){return Backbone.Model.extend({vis:null,initialize:function(e){this.app=e,this.chart=this.app.chart,this.options=this.app.options,this.id=this.options.id,this.vis=new Visualization({type:"charts",config:{dataset_id:this.options.config.dataset_id,chart_dict:{}}}),this.id&&(this.vis.id=this.id);var t=this.options.config.chart_dict;t&&(this.vis.get("config").chart_dict=t)},save:function(){var e=this.app.chart;this.vis.get("config").chart_dict={};var t=e.get("title");t!=""&&this.vis.set("title",t);var n={attributes:e.attributes,settings:e.settings.attributes,groups:[]};e.groups.each(function(e){n.groups.push(e.attributes)}),this.vis.get("config").chart_dict=n;var r=this;this.vis.save().fail(function(e,t,n){console.error(e,t,n)}).then(function(e){e&&e.id&&(r.id=e.id)})},load:function(){var e=this.vis.get("config").chart_dict;if(!e.attributes)return!1;this.chart.set(e.attributes),this.chart.state("ok","Loading saved visualization..."),this.chart.settings.set(e.settings);for(var t in e.groups)this.chart.groups.add(new n(e.groups[t]));return this.chart.set("modified",!1),!0}})}),define("plugin/views/viewport",["mvc/ui/ui-portlet","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({canvas:[],initialize:function(e,t){this.app=e,this.chart=this.app.chart,this.options=n.merge(t,this.optionsDefault),this.setElement($(this._template())),this._fullscreen(this.$el,80),this._create_canvas("div");var r=this;this.chart.on("redraw",function(){r._draw(r.chart)}),this.chart.on("set:state",function(){var e=r.$el.find("#info"),t=e.find("#icon");t.removeClass(),e.show(),e.find("#text").html(r.chart.get("state_info"));var n=r.chart.get("state");switch(n){case"ok":e.hide();break;case"failed":t.addClass("fa fa-warning");break;default:t.addClass("fa fa-spinner fa-spin")}})},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_fullscreen:function(e,t){e.css("height",$(window).height()-t),$(window).resize(function(){e.css("height",$(window).height()-t)})},_create_canvas:function(e,t){t=t||1;for(var n in this.canvas)this.canvas[n].remove(),this.canvas.slice(n,0);for(var n=0;n<t;n++){var r=$(this._template_canvas(e,parseInt(100/t)));this.$el.append(r),e=="svg"?this.canvas[n]=d3.select(r[0]):this.canvas[n]=r}},_draw:function(e){var t=this,n=e.deferred.register(),r=e.get("type");this.chart_settings=this.app.types.get(r);var i=this.chart_settings.use_panels,s=1;i&&(s=e.groups.length),this._create_canvas(this.chart_settings.tag,s),e.state("wait","Please wait...");if(!this.chart_settings.execute||this.chart_settings.execute&&e.get("modified"))this.app.jobs.cleanup(e),e.set("modified",!1);var t=this;require(["plugin/charts/"+r+"/"+r],function(r){var i=new r(t.app,{canvas:t.canvas});t.chart_settings.execute?e.get("dataset_id_job")==""?t.app.jobs.submit(e,t._defaultSettingsString(e),t._defaultRequestString(e),function(){i.draw(n,e,t._defaultRequestDictionary(e))},function(){e.deferred.done(n)}):i.draw(n,e,t._defaultRequestDictionary(e)):i.draw(n,e,t._defaultRequestDictionary(e))})},_defaultRequestString:function(e){var t="",n=0,r=this;return e.groups.each(function(e){for(var i in r.chart_settings.columns)t+=i+"_"+ ++n+":"+(parseInt(e.get(i))+1)+", "}),t.substring(0,t.length-2)},_defaultSettingsString:function(e){var t="";for(key in e.settings.attributes)t+=key+":"+e.settings.get(key)+", ";return t.substring(0,t.length-2)},_defaultRequestDictionary:function(e){var t={groups:[]};this.chart_settings.execute?t.id=e.get("dataset_id_job"):t.id=e.get("dataset_id");var n=0,r=this;return e.groups.each(function(e){var i={};for(var s in r.chart_settings.columns){var o=r.chart_settings.columns[s];i[s]={index:e.get(s),is_label:o.is_label}}t.groups.push({key:++n+":"+e.get("key"),columns:i})}),t},_template:function(){return'<div style="height: inherit; min-height: 50px;"><div id="info" style="position: absolute; margin-left: 10px; margin-top: 10px; margin-bottom: 50px;"><span id="icon" style="font-size: 1.2em; display: inline-block;"/><span id="text" style="position: relative; margin-left: 5px; top: -1px; font-size: 1.0em;"/></div></div>'},_template_canvas:function(e,t){return"<"+e+' class="canvas" style="float: left; display: block; width:'+t+'%; height: 100%;"/>'}})}),define("plugin/views/viewer",["utils/utils","plugin/library/ui","mvc/ui/ui-portlet","plugin/models/group","plugin/views/viewport"],function(e,t,n,r,i){return Backbone.View.extend({initialize:function(e,r){this.app=e,this.chart=this.app.chart,this.viewport_view=new i(e);var s=this;this.portlet=new n.View({icon:"fa-bar-chart-o",title:"Viewport",operations:{edit_button:new t.ButtonIcon({icon:"fa-edit",tooltip:"Customize this chart",title:"Editor",onclick:function(){s._wait(s.chart,function(){s.app.go("editor")})}})}}),this.portlet.append(this.viewport_view.$el),this.setElement(this.portlet.$el);var s=this;this.chart.on("change:title",function(){s._refreshTitle()})},show:function(){this.$el.show(),$(window).trigger("resize")},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e)},_screenshot:function(){var e=new XMLSerializer,t=e.serializeToString(this.viewport_view.svg.node()),n="data:image/svg+xml;base64,"+btoa(t);window.location.href="data:application/x-download/;charset=utf-8,"+encodeURIComponent(t)},_wait:function(e,t){if(e.deferred.ready())t();else{var n=this;this.app.modal.show({title:"Please wait!",body:"Your chart is currently being processed. Please wait and try again.",buttons:{Close:function(){n.app.modal.hide()},Retry:function(){n.app.modal.hide(),setTimeout(function(){n._wait(e,t)},n.app.config.get("query_timeout"))}}})}}})}),define("mvc/ui/ui-tabs",["utils/utils"],function(e){var t=Backbone.View.extend({visible:!1,list:{},$nav:null,$content:null,first_tab:null,optionsDefault:{title_new:"",operations:null,onnew:null},initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(this.options));this.$nav=n.find(".tab-navigation"),this.$content=n.find(".tab-content"),this.setElement(n),this.list={};var r=this;this.options.operations&&$.each(this.options.operations,function(e,t){t.$el.prop("id",e),r.$nav.find(".operations").append(t.$el)});if(this.options.onnew){var i=$(this._template_tab_new(this.options));this.$nav.append(i),i.tooltip({title:"Add a new tab",placement:"bottom",container:r.$el}),i.on("click",function(e){i.tooltip("hide"),r.options.onnew()})}},add:function(e){var t=e.id,n={$title:$(this._template_tab(e)),$content:$(this._template_tab_content(e)),removable:e.ondel?!0:!1};this.list[t]=n,this.options.onnew?this.$nav.find("#new-tab").before(n.$title):this.$nav.append(n.$title),n.$content.append(e.$el),this.$content.append(n.$content),_.size(this.list)==1&&(n.$title.addClass("active"),n.$content.addClass("active"),this.first_tab=t);if(e.ondel){var r=this,i=n.$title.find("#delete");i.tooltip({title:"Delete this tab",placement:"bottom",container:r.$el}),i.on("click",function(){return i.tooltip("destroy"),r.$el.find(".tooltip").remove(),e.ondel(),!1})}e.onclick&&n.$title.on("click",function(){e.onclick()})},del:function(e){var t=this.list[e];t.$title.remove(),t.$content.remove(),delete t,this.first_tab==e&&(this.first_tab=null),this.first_tab!=null&&this.show(this.first_tab)},delRemovable:function(){for(var e in this.list){var t=this.list[e];t.removable&&this.del(e)}},show:function(e){this.$el.fadeIn("fast"),this.visible=!0,e&&this.list[e].$title.find("a").tab("show")},hide:function(){this.$el.fadeOut("fast"),this.visible=!1},hideOperation:function(e){this.$nav.find("#"+e).hide()},showOperation:function(e){this.$nav.find("#"+e).show()},setOperation:function(e,t){var n=this.$nav.find("#"+e);n.off("click"),n.on("click",t)},title:function(e,t){var n=this.list[e].$title.find("#text");return t&&n.html(t),n.html()},_template:function(e){return'<div class="tabbable tabs-left"><ul class="tab-navigation nav nav-tabs"><div class="operations" style="float: right; margin-bottom: 4px;"></div></ul><div class="tab-content"/></div>'},_template_tab_new:function(e){return'<li id="new-tab"><a href="javascript:void(0);"><i style="font-size: 0.8em; margin-right: 5px;" class="fa fa-plus-circle"/>'+e.title_new+"</a>"+"</li>"},_template_tab:function(e){var t='<li id="title-'+e.id+'">'+'<a title="" href="#tab-'+e.id+'" data-toggle="tab" data-original-title="">'+'<span id="text">'+e.title+"</span>";return e.ondel&&(t+='<i id="delete" style="font-size: 0.8em; margin-left: 5px; cursor: pointer;" class="fa fa-minus-circle"/>'),t+="</a></li>",t},_template_tab_content:function(e){return'<div id="tab-'+e.id+'" class="tab-pane"/>'}});return{View:t}}),define("plugin/library/ui-table",["utils/utils"],function(e){var t=Backbone.View.extend({row:null,row_count:0,optionsDefault:{content:"No content available.",onchange:null,ondblclick:null,onconfirm:null},events:{click:"_onclick",dblclick:"_ondblclick"},first:!0,initialize:function(t){this.options=e.merge(t,this.optionsDefault);var n=$(this._template(t));this.$thead=n.find("thead"),this.$tbody=n.find("tbody"),this.$tmessage=n.find("tmessage"),this.setElement(n),this.row=$("<tr></tr>")},addHeader:function(e){var t=$("<th></th>");t.append(e),this.row.append(t)},appendHeader:function(){this.$thead.append(this.row),this.row=$("<tr></tr>")},add:function(e,t,n){var r=$("<td></td>");t&&r.css("width",t),n&&r.css("text-align",n),r.append(e),this.row.append(r)},append:function(e){this._commit(e)},prepend:function(e){this._commit(e,!0)},remove:function(e){var t=this.$tbody.find("#"+e);t.length>0&&(t.remove(),this.row_count--,this._refresh())},removeAll:function(){this.$tbody.html(""),this.row_count=0,this._refresh()},value:function(e){this.before=this.$tbody.find(".current").attr("id"),e!==undefined&&(this.$tbody.find("tr").removeClass("current"),e&&this.$tbody.find("#"+e).addClass("current"));var t=this.$tbody.find(".current").attr("id");return t===undefined?null:(t!=this.before&&this.options.onchange&&this.options.onchange(e),t)},size:function(){return this.$tbody.find("tr").length},_commit:function(e,t){this.remove(e),this.row.attr("id",e),t?this.$tbody.prepend(this.row):this.$tbody.append(this.row),this.row=$("<tr></tr>"),this.row_count++,this._refresh()},_onclick:function(e){var t=this.value(),n=$(e.target).closest("tr").attr("id");n&&t!=n&&(this.options.onconfirm?this.options.onconfirm(n):this.value(n))},_ondblclick:function(e){var t=this.value();t&&this.options.ondblclick&&this.options.ondblclick(t)},_refresh:function(){this.row_count==0?this.$tmessage.show():this.$tmessage.hide()},_template:function(e){return'<div><table class="grid"><thead></thead><tbody style="cursor: pointer;"></tbody></table><tmessage>'+e.content+"</tmessage>"+"<div>"}});return{View:t}}),define("plugin/views/group",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(r,i){this.app=r;var s=this;this.chart=this.app.chart,this.group=i.group,this.group_key=new t.Input({placeholder:"Data label",onchange:function(){s.group.set("key",s.group_key.value())}}),this.table=new e.View({content:"No data column."});var o=$("<div/>");o.append(n.wrap((new t.Label({title:"Provide a label:"})).$el)),o.append(n.wrap(this.group_key.$el)),o.append(n.wrap((new t.Label({title:"Select columns:"})).$el)),o.append(n.wrap(this.table.$el)),this.setElement(o);var s=this;this.chart.on("change:dataset_id",function(){s._refreshTable()}),this.chart.on("change:type",function(){s._refreshTable()}),this.group.on("change:key",function(){s._refreshGroupKey()}),this.group.on("change",function(){s._refreshGroup()}),this._refreshTable(),this._refreshGroupKey(),this._refreshGroup()},_refreshTable:function(){var e=this.chart.get("dataset_id"),n=this.chart.get("type");if(!e||!n)return;var r=this,i=this.app.types.get(n);this.table.removeAll();var s={};for(var o in i.columns){var u=this.group.get(o);u||this.group.set(o,0);var a=i.columns[o],f=new t.Select.View({id:"select_"+o,gid:o,onchange:function(e){r.group.set(this.gid,e),r.chart.set("modified",!0)},value:u,wait:!0});this.table.add(a.title,"25%"),this.table.add(f.$el),this.table.append(o),s[o]=f}this.chart.state("wait","Loading metadata...");var l=this.chart.deferred.register();this.app.datasets.request({id:e},function(e){for(var t in s){var n=i.columns[t].is_label,o=[],u=e.metadata_column_types;for(var a in u)(!n&&(u[a]=="int"||u[a]=="float")||n)&&o.push({label:"Column: "+(parseInt(a)+1)+" ["+u[a]+"]",value:a});s[t].update(o),s[t].show()}r.chart.state("ok","Metadata initialized..."),r.chart.deferred.done(l)})},_refreshGroup:function(){this.group.set("date",n.time())},_refreshGroupKey:function(){var e=this.group.get("key");e===undefined&&(e=""),this.group_key.value(e)}})}),define("plugin/library/ui-table-form",["plugin/library/ui-table","plugin/library/ui","utils/utils"],function(e,t,n){var r=Backbone.View.extend({list:[],initialize:function(r){this.table_title=new t.Label({title:r.title}),this.table=new e.View({content:r.content});var i=$("<div/>");i.append(n.wrap(this.table_title.$el)),i.append(n.wrap(this.table.$el)),this.setElement(i)},title:function(e){this.table_title.title(e)},update:function(e,t){this.table.removeAll(),this.list=[];for(var n in e)this._add(n,e[n],t);for(var n in this.list){var r=this.list[n].options.onchange;r&&r()}},_add:function(e,n,r){var i=this,s=null,o=n.type;switch(o){case"text":s=new t.Input({id:e,placeholder:n.placeholder,onchange:function(){r.set(e,s.value())}});break;case"select":s=new t.Select.View({id:e,data:n.data,onchange:function(){var t=s.value();r.set(e,t);var o=_.findWhere(n.data,{value:t});o&&(o.show&&i.$el.find("#"+o.show).fadeIn("fast"),o.hide&&i.$el.find("#"+o.hide).fadeOut("fast"))}});break;case"separator":s=$("<div/>");break;default:console.log("ui-table-form:_add","Unknown setting type ("+n.type+")");return}if(o!="separator"){r.get(e)||r.set(e,n.init),s.value(r.get(e)),this.list[e]=s;var u=$("<div/>");u.append(s.$el),u.append('<div class="toolParamHelp" style="font-size: 0.9em;">'+n.info+"</div>"),this.table.add('<span style="white-space: nowrap;">'+n.title+"</span>","25%"),this.table.add(u)}else this.table.add('<h6 style="white-space: nowrap;">'+n.title+":<h6/>"),this.table.add($("<div/>"));this.table.append(e)}});return{View:r}}),define("plugin/views/settings",["plugin/library/ui","plugin/library/ui-table-form","utils/utils"],function(e,t,n){return Backbone.View.extend({initialize:function(e,n){this.app=e;var r=this;this.chart=this.app.chart,this.form=new t.View({title:"Chart options:",content:"This chart type does not provide any options."}),this.setElement(this.form.$el);var r=this;this.chart.on("change",function(){r._refreshTable()})},_refreshTable:function(){var e=this.chart.get("type");if(!e)return;var t=this.app.types.get(e);this.form.title(t.title+":"),this.form.update(t.settings,this.chart.settings)}})}),define("plugin/views/editor",["mvc/ui/ui-tabs","plugin/library/ui-table","plugin/library/ui","mvc/ui/ui-portlet","utils/utils","plugin/models/chart","plugin/models/group","plugin/views/group","plugin/views/settings"],function(e,t,n,r,i,s,o,u,a){return Backbone.View.extend({optionsDefault:{header:!0,content:"No content available."},initialize:function(s,o){var u=this;this.app=s,this.chart=this.app.chart,this.options=i.merge(o,this.optionsDefault),this.portlet=new r.View({icon:"fa-bar-chart-o",title:"Editor",operations:{save:new n.ButtonIcon({icon:"fa-save",tooltip:"Draw Chart",title:"Draw",onclick:function(){u.app.go("viewer"),u._saveChart()}}),back:new n.ButtonIcon({icon:"fa-caret-left",tooltip:"Return to Viewer",title:"Return",onclick:function(){u.app.go("viewer"),u.app.storage.load()}})}}),this.table=new t.View({header:!1,onchange:function(e){u.chart.settings.clear(),u.chart.set({type:e}),u.chart.set("modified",!0)},ondblclick:function(e){u.tabs.show("settings")},content:"No chart types available"}),this.table.addHeader("No."),this.table.addHeader("Type"),this.table.addHeader("Library"),this.table.addHeader("Processing*"),this.table.appendHeader();var f=0,l=s.types.attributes;for(var c in l){var h=l[c];this.table.add(++f+"."),this.table.add(h.title),this.table.add(h.library,"10%"),h.execute?this.table.add((new n.Icon({icon:"fa-check"})).$el,"10%","center"):this.table.add(""),this.table.append(c)}this.tabs=new e.View({title_new:"Add Data",onnew:function(){var e=u._addGroupModel();u.tabs.show(e.id)}}),this.title=new n.Input({placeholder:"Chart title",onchange:function(){u.chart.set("title",u.title.value())}});var p=$("<div/>");p.append(i.wrap((new n.Label({title:"Provide a chart title:"})).$el)),p.append(i.wrap(this.title.$el)),p.append(i.wrap((new n.Label({title:"Select a chart type:"})).$el)),p.append(i.wrap(this.table.$el)),p.append((new n.Text({title:"*Certain chart types pre-process data before rendering the visualization. The pre-processing is done using the chartskit available in the Toolshed.",cls:"toolParamHelp"})).$el),this.tabs.add({id:"main",title:"Start",$el:p}),this.settings=new a(this.app),this.tabs.add({id:"settings",title:"Configuration",$el:this.settings.$el}),this.portlet.append(this.tabs.$el),this.setElement(this.portlet.$el),this.tabs.hideOperation("back");var u=this;this.chart.on("change:title",function(e){u._refreshTitle()}),this.chart.on("change:type",function(e){u.table.value(e.get("type"))}),this.chart.on("reset",function(e){u._resetChart()}),this.app.chart.on("redraw",function(e){u.portlet.showOperation("back")}),this.app.chart.groups.on("add",function(e){u._addGroup(e)}),this.app.chart.groups.on("remove",function(e){u._removeGroup(e)}),this.app.chart.groups.on("reset",function(e){u._removeAllGroups()}),this.app.chart.groups.on("change:key",function(e){u._refreshGroupKey()}),this._resetChart()},show:function(){this.$el.show()},hide:function(){this.$el.hide()},_refreshTitle:function(){var e=this.chart.get("title");this.portlet.title(e),this.title.value(e)},_refreshGroupKey:function(){var e=this,t=0;this.chart.groups.each(function(n){var r=n.get("key","");r==""&&(r="Chart data"),e.tabs.title(n.id,++t+": "+r)})},_addGroupModel:function(){var e=new o({id:i.uuid()});return this.chart.groups.add(e),e},_addGroup:function(e){var t=this,n=new u(this.app,{group:e}),r=t.chart.groups.length;this.tabs.add({id:e.id,$el:n.$el,ondel:function(){t.chart.groups.remove(e.id)}}),this._refreshGroupKey()},_removeGroup:function(e){this.tabs.del(e.id),this._refreshGroupKey(),this.chart.set("modified",!0)},_removeAllGroups:function(e){this.tabs.delRemovable()},_resetChart:function(){this.chart.set("id",i.uuid()),this.chart.set("type","nvd3_bardiagram"),this.chart.set("dataset_id",this.app.options.config.dataset_id),this.chart.set("title","New Chart"),this.portlet.hideOperation("back")},_saveChart:function(){this.chart.set({type:this.table.value(),title:this.title.value(),date:i.time()}),this.chart.groups.length==0&&this._addGroupModel();var e=this;this.chart.deferred.execute(function(){e.app.storage.save(),e.chart.trigger("redraw")})}})}),define("plugin/models/config",[],function(){return Backbone.Model.extend({defaults:{query_limit:1e3,query_timeout:500}})}),define("plugin/charts/nvd3/config",[],function(){return{title:"",library:"nvd3.js",tag:"svg",columns:{y:{title:"Values for y-axis"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},x_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"x_axis_tick"},{label:"Auto",value:"auto",hide:"x_axis_tick"},{label:"Float",value:"f",show:"x_axis_tick"},{label:"Exponent",value:"e",show:"x_axis_tick"},{label:"Integer",value:"d",hide:"x_axis_tick"},{label:"Percentage",value:"p",show:"x_axis_tick"},{label:"Rounded",value:"r",show:"x_axis_tick"},{label:"SI-prefix",value:"s",show:"x_axis_tick"}]},x_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"},y_axis_type:{title:"Axis value type",info:"Select the value type of the axis.",type:"select",init:"auto",data:[{label:"-- Do not show values --",value:"hide",hide:"y_axis_tick"},{label:"Auto",value:"auto",hide:"y_axis_tick"},{label:"Float",value:"f",show:"y_axis_tick"},{label:"Exponent",value:"e",show:"y_axis_tick"},{label:"Integer",value:"d",hide:"y_axis_tick"},{label:"Percentage",value:"p",show:"y_axis_tick"},{label:"Rounded",value:"r",show:"y_axis_tick"},{label:"SI-prefix",value:"s",show:"y_axis_tick"}]},y_axis_tick:{title:"Axis tick format",info:"Select the tick format for the axis.",type:"select",init:".1",data:[{label:"0.00001",value:".5"},{label:"0.0001",value:".4"},{label:"0.001",value:".3"},{label:"0.01",value:".2"},{label:"0.1",value:".1"},{label:"1",value:"1"}]},separator_legend:{title:"Others",type:"separator"},show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"true",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_bardiagram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram"})}),define("plugin/charts/nvd3_histogram/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Histogram",execute:"histogram",columns:{y:{title:"Observations"}},settings:{x_axis_label:{init:"Breaks"},y_axis_label:{init:"Density"},y_axis_type:{init:"f"},y_axis_tick:{init:".2"}}})}),define("plugin/charts/nvd3_horizontal/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Bar diagram (horizontal)",settings:{x_axis_type:{init:"hide"}}})}),define("plugin/charts/nvd3_line/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line chart"})}),define("plugin/charts/nvd3_linewithfocus/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Line with focus"})}),define("plugin/charts/nvd3_piechart/config",[],function(){return{title:"Pie chart",library:"nvd3.js",tag:"svg",use_panels:!0,columns:{label:{title:"Labels",is_label:!0},y:{title:"Values"}},settings:{show_legend:{title:"Show legend",info:"Would you like to add a legend?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]},donut_ratio:{title:"Donut ratio",info:"Determine how large the donut hole will be.",type:"select",init:"0.5",data:[{label:"50%",value:"0.5"},{label:"25%",value:"0.25"},{label:"10%",value:"0.10"},{label:"0%",value:"0"}]},label_separator:{type:"separator",title:"Label settings"},label_type:{title:"Donut label",info:"What would you like to show for each slice?",type:"select",init:"percent",data:[{label:"-- Nothing --",value:"hide",hide:"label_outside"},{label:"Label column",value:"key",show:"label_outside"},{label:"Value column",value:"value",show:"label_outside"},{label:"Percentage",value:"percent",show:"label_outside"}]},label_outside:{title:"Show outside",info:"Would you like to show labels outside the donut?",type:"select",init:"false",data:[{label:"Yes",value:"true"},{label:"No",value:"false"}]}}}}),define("plugin/charts/nvd3_scatterplot/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Scatter plot",columns:{x:{title:"Values for x-axis"}}})}),define("plugin/charts/nvd3_stackedarea/config",["plugin/charts/nvd3/config"],function(e){return $.extend(!0,{},e,{title:"Stacked area"})}),define("plugin/charts/highcharts_boxplot/config",[],function(){return{title:"Box plot",library:"highcharts.js",element:"div",execute:"boxplot",columns:{y:{title:"Observations"}},settings:{separator_label:{title:"X axis",type:"separator"},x_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"X-axis",placeholder:"Axis label"},separator_tick:{title:"Y axis",type:"separator"},y_axis_label:{title:"Axis label",info:"Provide a label for the axis.",type:"text",init:"Y-axis",placeholder:"Axis label"}}}}),define("plugin/charts/types",["plugin/charts/nvd3_bardiagram/config","plugin/charts/nvd3_histogram/config","plugin/charts/nvd3_horizontal/config","plugin/charts/nvd3_line/config","plugin/charts/nvd3_linewithfocus/config","plugin/charts/nvd3_piechart/config","plugin/charts/nvd3_scatterplot/config","plugin/charts/nvd3_stackedarea/config","plugin/charts/highcharts_boxplot/config"],function(e,t,n,r,i,s,o,u,a){return Backbone.Model.extend({defaults:{nvd3_bardiagram:e,nvd3_horizontal:n,nvd3_histogram:t,nvd3_line:r,nvd3_linewithfocus:i,nvd3_piechart:s,nvd3_scatterplot:o,nvd3_stackedarea:u,highcharts_boxplot:a}})}),define("plugin/app",["mvc/ui/ui-modal","mvc/ui/ui-portlet","plugin/library/ui","utils/utils","plugin/library/jobs","plugin/library/datasets","plugin/library/storage","plugin/views/viewer","plugin/views/editor","plugin/models/config","plugin/models/chart","plugin/charts/types"],function(e,t,n,r,i,s,o,u,a,f,l,c){return Backbone.View.extend({initialize:function(t){this.options=t,Galaxy&&Galaxy.modal?this.modal=Galaxy.modal:this.modal=new e.View,this.config=new f,this.types=new c,this.chart=new l,this.jobs=new i(this),this.datasets=new s(this),this.storage=new o(this),this.viewer_view=new u(this),this.editor_view=new a(this),this.$el.append(this.viewer_view.$el),this.$el.append(this.editor_view.$el);if(!this.storage.load())this.go("editor");else{this.go("viewer");var n=this;this.chart.deferred.execute(function(){n.chart.trigger("redraw")})}},go:function(e){$(".tooltip").hide();switch(e){case"editor":this.editor_view.show(),this.viewer_view.hide();break;case"viewer":this.editor_view.hide(),this.viewer_view.show()}},execute:function(e){},onunload:function(){},log:function(e,t){console.log(e+" "+t)}})}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/_nvd3/config.js --- a/config/plugins/visualizations/charts/static/charts/_nvd3/config.js +++ /dev/null @@ -1,218 +0,0 @@ -define([], function() { - -return { - title : '', - columns : { - y : { - title : 'Values for y-axis' - } - }, - settings : { - separator_label : { - title : 'X axis', - type : 'separator' - }, - x_axis_label : { - title : 'Axis label', - info : 'Provide a label for the axis.', - type : 'text', - init : 'X-axis', - placeholder : 'Axis label' - }, - x_axis_type : { - title : 'Axis value type', - info : 'Select the value type of the axis.', - type : 'select', - init : 'auto', - data : [ - { - label : '-- Do not show values --', - value : 'hide', - hide : 'x_axis_tick' - }, - { - label : 'Auto', - value : 'auto', - hide : 'x_axis_tick' - }, - { - label : 'Float', - value : 'f', - show : 'x_axis_tick' - }, - { - label : 'Exponent', - value : 'e', - show : 'x_axis_tick' - }, - { - label : 'Integer', - value : 'd', - hide : 'x_axis_tick' - }, - { - label : 'Percentage', - value : 'p', - show : 'x_axis_tick' - }, - { - label : 'Rounded', - value : 'r', - show : 'x_axis_tick' - }, - { - label : 'SI-prefix', - value : 's', - show : 'x_axis_tick' - } - ] - }, - x_axis_tick : { - title : 'Axis tick format', - info : 'Select the tick format for the axis.', - type : 'select', - init : '.1', - data : [ - { - label : '0.00001', - value : '.5' - }, - { - label : '0.0001', - value : '.4' - }, - { - label : '0.001', - value : '.3' - }, - { - label : '0.01', - value : '.2' - }, - { - label : '0.1', - value : '.1' - }, - { - label : '1', - value : '1' - } - ] - - }, - separator_tick : { - title : 'Y axis', - type : 'separator' - }, - y_axis_label : { - title : 'Axis label', - info : 'Provide a label for the axis.', - type : 'text', - init : 'Y-axis', - placeholder : 'Axis label' - }, - y_axis_type : { - title : 'Axis value type', - info : 'Select the value type of the axis.', - type : 'select', - init : 'auto', - data : [ - { - label : '-- Do not show values --', - value : 'hide', - hide : 'y_axis_tick' - }, - { - label : 'Auto', - value : 'auto', - hide : 'y_axis_tick' - }, - { - label : 'Float', - value : 'f', - show : 'y_axis_tick' - }, - { - label : 'Exponent', - value : 'e', - show : 'y_axis_tick' - }, - { - label : 'Integer', - value : 'd', - hide : 'y_axis_tick' - }, - { - label : 'Percentage', - value : 'p', - show : 'y_axis_tick' - }, - { - label : 'Rounded', - value : 'r', - show : 'y_axis_tick' - }, - { - label : 'SI-prefix', - value : 's', - show : 'y_axis_tick' - } - ] - }, - y_axis_tick : { - title : 'Axis tick format', - info : 'Select the tick format for the axis.', - type : 'select', - init : '.1', - data : [ - { - label : '0.00001', - value : '.5' - }, - { - label : '0.0001', - value : '.4' - }, - { - label : '0.001', - value : '.3' - }, - { - label : '0.01', - value : '.2' - }, - { - label : '0.1', - value : '.1' - }, - { - label : '1', - value : '1' - } - ] - - }, - separator_legend : { - title : 'Others', - type : 'separator' - }, - show_legend : { - title : 'Show legend', - info : 'Would you like to add a legend?', - type : 'select', - init : 'true', - data : [ - { - label : 'Yes', - value : 'true' - }, - { - label : 'No', - value : 'false' - } - ] - }, - } -}; - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js --- a/config/plugins/visualizations/charts/static/charts/_nvd3/nvd3.js +++ /dev/null @@ -1,80 +0,0 @@ -// dependencies -define([], function() { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, nvd3_model, chart, request_dictionary, callback) - { - // request data - var self = this; - this.app.datasets.request(request_dictionary, function(data) { - nv.addGraph(function() { - // x axis - self._axis(nvd3_model.xAxis, chart.settings.get('x_axis_type'), chart.settings.get('x_axis_tick')); - - // x axis label - nvd3_model.xAxis.axisLabel(chart.settings.get('x_axis_label')); - - // y axis - self._axis(nvd3_model.yAxis, chart.settings.get('y_axis_type'), chart.settings.get('y_axis_tick')); - - // y axis label - nvd3_model.yAxis.axisLabel(chart.settings.get('y_axis_label')) - .axisLabelDistance(30); - - // controls - if (chart.groups.length == 1) { - nvd3_model.options({ showControls: false }); - } - - // legend - var legend_visible = true; - if (chart.settings.get('show_legend') == 'false') { - legend_visible = false; - } - nvd3_model.showLegend(legend_visible); - - // custom callback - if (callback) { - callback(nvd3_model); - } - - // parse data to svg - self.options.svg.datum(data) - .call(nvd3_model); - - // refresh on window resize - nv.utils.windowResize(nvd3_model.update); - - // set chart state - chart.state('ok', 'Chart has been drawn.'); - - // unregister process - chart.deferred.done(process_id); - }); - }); - }, - - // make axis - _axis: function(axis, type, tick) { - switch (type) { - case 'hide': - axis.tickFormat(function() { return '' }); - break; - case 'auto': - break; - default: - axis.tickFormat(d3.format(tick + type)); - } - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/bardiagram/bardiagram.js --- a/config/plugins/visualizations/charts/static/charts/bardiagram/bardiagram.js +++ /dev/null @@ -1,21 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/bardiagram/config.js --- a/config/plugins/visualizations/charts/static/charts/bardiagram/config.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Bar diagram', -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/highcharts_boxplot/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/highcharts_boxplot/config.js @@ -0,0 +1,39 @@ +define([], function() { + +return { + title : 'Box plot', + library : 'highcharts.js', + element : 'div', + execute : 'boxplot', + columns : { + y : { + title : 'Observations' + } + }, + settings : { + separator_label : { + title : 'X axis', + type : 'separator' + }, + x_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'X-axis', + placeholder : 'Axis label' + }, + separator_tick : { + title : 'Y axis', + type : 'separator' + }, + y_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'Y-axis', + placeholder : 'Axis label' + } + } +}; + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/highcharts_boxplot/highcharts_boxplot.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/highcharts_boxplot/highcharts_boxplot.js @@ -0,0 +1,122 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// widget +return Backbone.View.extend( +{ + // highcharts configuration + hc_config : { + chart: { + type: 'boxplot' + }, + + title: { + text: '' + }, + + legend: { + enabled: false + }, + + credits: { + enabled: false + }, + + plotOptions: { + series: { + animation: false + } + }, + + xAxis: { + categories: [], + title: { + text: '' + } + }, + + yAxis: { + title: { + text: '' + } + }, + + series: [{ + name: 'Details:', + data: [], + tooltip: { + headerFormat: '<em>{point.key}</em><br/>' + } + }] + }, + + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + // configure request + var index = 0; + for (var i in request_dictionary.groups) { + var group = request_dictionary.groups[i]; + group.columns = null; + group.columns = { + x: { + index: index++ + } + } + } + + // set axis labels + this.hc_config.xAxis.title.text = chart.settings.get('x_axis_label'); + this.hc_config.yAxis.title.text = chart.settings.get('y_axis_label'); + + // request data + var self = this; + this.app.datasets.request(request_dictionary, function() { + + // reset data/categories + var data = []; + var categories = []; + + // loop through data groups + for (var key in request_dictionary.groups) { + // get group + var group = request_dictionary.groups[key]; + + // add category + categories.push(group.key); + + // format chart data + var point = []; + for (var key in group.values) { + point.push(group.values[key].x); + } + + // add to data + data.push (point); + } + + // categories + self.hc_config.xAxis.categories = categories; + + // update data + self.hc_config.series[0].data = data; + + // draw plot + self.options.canvas[0].highcharts(self.hc_config); + + // set chart state + chart.state('ok', 'Box plot drawn.'); + + // unregister process + chart.deferred.done(process_id); + }); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/histogram/config.js --- a/config/plugins/visualizations/charts/static/charts/histogram/config.js +++ /dev/null @@ -1,21 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Histogram', - execute : true, - columns : { - y : { - title : 'Observations' - } - }, - settings : { - x_axis_label : { - init : 'Breaks' - }, - y_axis_label : { - init : 'Density' - } - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/histogram/histogram.js --- a/config/plugins/visualizations/charts/static/charts/histogram/histogram.js +++ /dev/null @@ -1,31 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - // configure request - var index = 0; - for (var i in request_dictionary.groups) { - var group = request_dictionary.groups[i]; - group.columns = { - x: index++, - y: index++ - } - } - - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/horizontal/config.js --- a/config/plugins/visualizations/charts/static/charts/horizontal/config.js +++ /dev/null @@ -1,12 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Bar diagram (horizontal)', - settings : { - x_axis_type : { - init : 'hide' - } - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/horizontal/horizontal.js --- a/config/plugins/visualizations/charts/static/charts/horizontal/horizontal.js +++ /dev/null @@ -1,21 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.multiBarHorizontalChart(), chart, request_dictionary); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/line/config.js --- a/config/plugins/visualizations/charts/static/charts/line/config.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Line chart', -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/line/line.js --- a/config/plugins/visualizations/charts/static/charts/line/line.js +++ /dev/null @@ -1,21 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.lineChart(), chart, request_dictionary); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/linewithfocus/config.js --- a/config/plugins/visualizations/charts/static/charts/linewithfocus/config.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Line with focus', -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/linewithfocus/linewithfocus.js --- a/config/plugins/visualizations/charts/static/charts/linewithfocus/linewithfocus.js +++ /dev/null @@ -1,21 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.lineWithFocusChart(), chart, request_dictionary); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3/config.js @@ -0,0 +1,220 @@ +define([], function() { + +return { + title : '', + library : 'nvd3.js', + tag : 'svg', + columns : { + y : { + title : 'Values for y-axis' + } + }, + settings : { + separator_label : { + title : 'X axis', + type : 'separator' + }, + x_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'X-axis', + placeholder : 'Axis label' + }, + x_axis_type : { + title : 'Axis value type', + info : 'Select the value type of the axis.', + type : 'select', + init : 'auto', + data : [ + { + label : '-- Do not show values --', + value : 'hide', + hide : 'x_axis_tick' + }, + { + label : 'Auto', + value : 'auto', + hide : 'x_axis_tick' + }, + { + label : 'Float', + value : 'f', + show : 'x_axis_tick' + }, + { + label : 'Exponent', + value : 'e', + show : 'x_axis_tick' + }, + { + label : 'Integer', + value : 'd', + hide : 'x_axis_tick' + }, + { + label : 'Percentage', + value : 'p', + show : 'x_axis_tick' + }, + { + label : 'Rounded', + value : 'r', + show : 'x_axis_tick' + }, + { + label : 'SI-prefix', + value : 's', + show : 'x_axis_tick' + } + ] + }, + x_axis_tick : { + title : 'Axis tick format', + info : 'Select the tick format for the axis.', + type : 'select', + init : '.1', + data : [ + { + label : '0.00001', + value : '.5' + }, + { + label : '0.0001', + value : '.4' + }, + { + label : '0.001', + value : '.3' + }, + { + label : '0.01', + value : '.2' + }, + { + label : '0.1', + value : '.1' + }, + { + label : '1', + value : '1' + } + ] + + }, + separator_tick : { + title : 'Y axis', + type : 'separator' + }, + y_axis_label : { + title : 'Axis label', + info : 'Provide a label for the axis.', + type : 'text', + init : 'Y-axis', + placeholder : 'Axis label' + }, + y_axis_type : { + title : 'Axis value type', + info : 'Select the value type of the axis.', + type : 'select', + init : 'auto', + data : [ + { + label : '-- Do not show values --', + value : 'hide', + hide : 'y_axis_tick' + }, + { + label : 'Auto', + value : 'auto', + hide : 'y_axis_tick' + }, + { + label : 'Float', + value : 'f', + show : 'y_axis_tick' + }, + { + label : 'Exponent', + value : 'e', + show : 'y_axis_tick' + }, + { + label : 'Integer', + value : 'd', + hide : 'y_axis_tick' + }, + { + label : 'Percentage', + value : 'p', + show : 'y_axis_tick' + }, + { + label : 'Rounded', + value : 'r', + show : 'y_axis_tick' + }, + { + label : 'SI-prefix', + value : 's', + show : 'y_axis_tick' + } + ] + }, + y_axis_tick : { + title : 'Axis tick format', + info : 'Select the tick format for the axis.', + type : 'select', + init : '.1', + data : [ + { + label : '0.00001', + value : '.5' + }, + { + label : '0.0001', + value : '.4' + }, + { + label : '0.001', + value : '.3' + }, + { + label : '0.01', + value : '.2' + }, + { + label : '0.1', + value : '.1' + }, + { + label : '1', + value : '1' + } + ] + + }, + separator_legend : { + title : 'Others', + type : 'separator' + }, + show_legend : { + title : 'Show legend', + info : 'Would you like to add a legend?', + type : 'select', + init : 'true', + data : [ + { + label : 'Yes', + value : 'true' + }, + { + label : 'No', + value : 'false' + } + ] + } + } +}; + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3/nvd3.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3/nvd3.js @@ -0,0 +1,80 @@ +// dependencies +define([], function() { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, nvd3_model, chart, request_dictionary, callback) + { + // request data + var self = this; + this.app.datasets.request(request_dictionary, function() { + nv.addGraph(function() { + // x axis + self._axis(nvd3_model.xAxis, chart.settings.get('x_axis_type'), chart.settings.get('x_axis_tick')); + + // x axis label + nvd3_model.xAxis.axisLabel(chart.settings.get('x_axis_label')); + + // y axis + self._axis(nvd3_model.yAxis, chart.settings.get('y_axis_type'), chart.settings.get('y_axis_tick')); + + // y axis label + nvd3_model.yAxis.axisLabel(chart.settings.get('y_axis_label')) + .axisLabelDistance(30); + + // controls + if (chart.groups.length == 1) { + nvd3_model.options({ showControls: false }); + } + + // legend + var legend_visible = true; + if (chart.settings.get('show_legend') == 'false') { + legend_visible = false; + } + nvd3_model.showLegend(legend_visible); + + // custom callback + if (callback) { + callback(nvd3_model); + } + + // parse data to canvas + self.options.canvas[0].datum(request_dictionary.groups) + .call(nvd3_model); + + // refresh on window resize + nv.utils.windowResize(nvd3_model.update); + + // set chart state + chart.state('ok', 'Chart has been drawn.'); + + // unregister process + chart.deferred.done(process_id); + }); + }); + }, + + // make axis + _axis: function(axis, type, tick) { + switch (type) { + case 'hide': + axis.tickFormat(function() { return '' }); + break; + case 'auto': + break; + default: + axis.tickFormat(d3.format(tick + type)); + } + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_bardiagram/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_bardiagram/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Bar diagram', +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_bardiagram/nvd3_bardiagram.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_bardiagram/nvd3_bardiagram.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_histogram/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_histogram/config.js @@ -0,0 +1,27 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Histogram', + execute : 'histogram', + columns : { + y : { + title : 'Observations' + } + }, + settings : { + x_axis_label : { + init : 'Breaks' + }, + y_axis_label : { + init : 'Density' + }, + y_axis_type : { + init : 'f' + }, + y_axis_tick : { + init : '.2' + } + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_histogram/nvd3_histogram.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_histogram/nvd3_histogram.js @@ -0,0 +1,39 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + // configure request + var index = 1; + for (var i in request_dictionary.groups) { + var group = request_dictionary.groups[i]; + group.columns = { + x: { + index: 0 + }, + y: { + index: index++ + }, + } + } + + // link this + var self = this; + + // load nvd3 + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_horizontal/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_horizontal/config.js @@ -0,0 +1,12 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Bar diagram (horizontal)', + settings : { + x_axis_type : { + init : 'hide' + } + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_horizontal/nvd3_horizontal.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_horizontal/nvd3_horizontal.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.multiBarHorizontalChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_line/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_line/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Line chart', +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_line/nvd3_line.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_line/nvd3_line.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.lineChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_linewithfocus/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_linewithfocus/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Line with focus', +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_linewithfocus/nvd3_linewithfocus.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_linewithfocus/nvd3_linewithfocus.js @@ -0,0 +1,21 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.lineWithFocusChart(), chart, request_dictionary); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_piechart/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_piechart/config.js @@ -0,0 +1,114 @@ +define([], function() { + +return { + title : 'Pie chart', + library : 'nvd3.js', + tag : 'svg', + use_panels : true, + columns : { + label : { + title : 'Labels', + is_label : true + }, + y : { + title : 'Values' + } + }, + + settings : { + show_legend : { + title : 'Show legend', + info : 'Would you like to add a legend?', + type : 'select', + init : 'false', + data : [ + { + label : 'Yes', + value : 'true' + }, + { + label : 'No', + value : 'false' + } + ] + }, + + donut_ratio : { + title : 'Donut ratio', + info : 'Determine how large the donut hole will be.', + type : 'select', + init : '0.5', + data : [ + { + label : '50%', + value : '0.5' + }, + { + label : '25%', + value : '0.25' + }, + { + label : '10%', + value : '0.10' + }, + { + label : '0%', + value : '0' + } + ] + }, + + label_separator : { + type : 'separator', + title : 'Label settings' + }, + + label_type : { + title : 'Donut label', + info : 'What would you like to show for each slice?', + type : 'select', + init : 'percent', + data : [ + { + label : '-- Nothing --', + value : 'hide', + hide : 'label_outside' + }, + { + label : 'Label column', + value : 'key', + show : 'label_outside' + }, + { + label : 'Value column', + value : 'value', + show : 'label_outside' + }, + { + label : 'Percentage', + value : 'percent', + show : 'label_outside' + } + ], + }, + + label_outside : { + title : 'Show outside', + info : 'Would you like to show labels outside the donut?', + type : 'select', + init : 'false', + data : [ + { + label : 'Yes', + value : 'true' + }, + { + label : 'No', + value : 'false' + } + ] + } + } +}; + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_piechart/nvd3_piechart.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_piechart/nvd3_piechart.js @@ -0,0 +1,115 @@ +// dependencies +define(['utils/utils'], function(Utils) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + // request data + var self = this; + this.app.datasets.request(request_dictionary, function() { + + // loop through data groups + for (var group_index in request_dictionary.groups) { + // get group + var group = request_dictionary.groups[group_index]; + + // draw group + self._draw_group(chart, group, self.options.canvas[group_index]); + } + + // set chart state + chart.state('ok', 'Pie chart has been drawn.'); + + // unregister process + chart.deferred.done(process_id); + }); + }, + + // draw group + _draw_group: function(chart, group, canvas) { + + // add title + var title = canvas.append('text'); + + // configure title attributes + this._fix_title(chart, canvas, title, group.key); + + // format chart data + var pie_data = []; + for (var key in group.values) { + var value = group.values[key]; + pie_data.push ({ + y : value.y, + x : value.label + }); + } + + // add graph to screen + var self = this; + nv.addGraph(function() { + // legend + var legend_visible = true; + if (chart.settings.get('show_legend') == 'false') { + legend_visible = false; + } + + // legend + var label_outside = true; + if (chart.settings.get('label_outside') == 'false') { + label_outside = false; + } + + // label type + var label_type = chart.settings.get('label_type'); + + // ratio + var donut_ratio = parseFloat(chart.settings.get('donut_ratio')) + + // create chart model + var chart_3d = nv.models.pieChart() + .donut(true) + .labelThreshold(.05) + .showLegend(legend_visible) + .labelType(label_type) + .donutRatio(donut_ratio) + .donutLabelsOutside(label_outside); + + // add data to canvas + canvas.datum(pie_data) + .call(chart_3d); + + // add resize trigger + nv.utils.windowResize(function() { + // update chart + chart_3d.update(); + + // fix title + self._fix_title(chart, canvas, title, group.key); + }); + }); + }, + + // fix title + _fix_title: function(chart, canvas, title_element, title_text) { + // update title + var width = parseInt(canvas.style('width')); + var height = parseInt(canvas.style('height')); + + // add title + title_element.attr('x', width / 2) + .attr('y', height - 10) + .attr('text-anchor', 'middle') + .text(title_text); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_scatterplot/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_scatterplot/config.js @@ -0,0 +1,12 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Scatter plot', + columns : { + x : { + title : 'Values for x-axis' + } + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_scatterplot/nvd3_scatterplot.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_scatterplot/nvd3_scatterplot.js @@ -0,0 +1,25 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.scatterChart(), chart, request_dictionary, function(nvd3_model) { + nvd3_model.showDistX(true) + .showDistY(true) + .color(d3.scale.category10().range()); + }); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_stackedarea/config.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_stackedarea/config.js @@ -0,0 +1,7 @@ +define(['plugin/charts/nvd3/config'], function(nvd3_config) { + +return $.extend(true, {}, nvd3_config, { + title : 'Stacked area' +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/nvd3_stackedarea/nvd3_stackedarea.js --- /dev/null +++ b/config/plugins/visualizations/charts/static/charts/nvd3_stackedarea/nvd3_stackedarea.js @@ -0,0 +1,26 @@ +// dependencies +define(['plugin/charts/nvd3/nvd3'], function(NVD3) { + +// widget +return Backbone.View.extend( +{ + // initialize + initialize: function(app, options) { + this.app = app; + this.options = options; + }, + + // render + draw : function(process_id, chart, request_dictionary) + { + var nvd3 = new NVD3(this.app, this.options); + nvd3.draw(process_id, nv.models.stackedAreaChart(), chart, request_dictionary, function(nvd3_model) { + // make plot + nvd3_model.x(function(d) { return d.x }) + .y(function(d) { return d.y }) + .clipEdge(true); + }); + } +}); + +}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/piechart/config.js --- a/config/plugins/visualizations/charts/static/charts/piechart/config.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Pie chart', -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/piechart/piechart.js --- a/config/plugins/visualizations/charts/static/charts/piechart/piechart.js +++ /dev/null @@ -1,57 +0,0 @@ -// dependencies -define(['utils/utils'], function(Utils) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - // request data - var self = this; - this.app.datasets.request(request_dictionary, function(data) { - - // loop through data groups - for (var key in request_dictionary.groups) { - // get group - var group = request_dictionary.groups[key]; - - // format chart data - var pie_data = []; - for (var key in group.values) { - var value = group.values[key]; - pie_data.push ({ - key : value.x, - y : value.y - }); - } - - // add graph to screen - nv.addGraph(function() { - self.chart_3d = nv.models.pieChart() - .donut(true) - .showLegend(false); - - self.options.svg.datum(pie_data) - .call(self.chart_3d); - - nv.utils.windowResize(self.chart_3d.update); - - // set chart state - chart.state('ok', 'Pie chart drawn.'); - - // unregister process - chart.deferred.done(process_id); - }); - } - }); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/scatterplot/config.js --- a/config/plugins/visualizations/charts/static/charts/scatterplot/config.js +++ /dev/null @@ -1,12 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Scatter plot', - columns : { - x : { - title : 'Values for x-axis' - } - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/scatterplot/scatterplot.js --- a/config/plugins/visualizations/charts/static/charts/scatterplot/scatterplot.js +++ /dev/null @@ -1,25 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.scatterChart(), chart, request_dictionary, function(nvd3_model) { - nvd3_model.showDistX(true) - .showDistY(true) - .color(d3.scale.category10().range()); - }); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/stackedarea/config.js --- a/config/plugins/visualizations/charts/static/charts/stackedarea/config.js +++ /dev/null @@ -1,7 +0,0 @@ -define(['plugin/charts/_nvd3/config'], function(nvd3_config) { - -return $.extend(true, {}, nvd3_config, { - title : 'Stacked area' -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/stackedarea/stackedarea.js --- a/config/plugins/visualizations/charts/static/charts/stackedarea/stackedarea.js +++ /dev/null @@ -1,26 +0,0 @@ -// dependencies -define(['plugin/charts/_nvd3/nvd3'], function(NVD3) { - -// widget -return Backbone.View.extend( -{ - // initialize - initialize: function(app, options) { - this.app = app; - this.options = options; - }, - - // render - draw : function(process_id, chart, request_dictionary) - { - var nvd3 = new NVD3(this.app, this.options); - nvd3.draw(process_id, nv.models.stackedAreaChart(), chart, request_dictionary, function(nvd3_model) { - // make plot - nvd3_model.x(function(d) { return d.x }) - .y(function(d) { return d.y }) - .clipEdge(true); - }); - } -}); - -}); \ No newline at end of file
diff -r 19e8344a0497c1dc8009b93bbef3ce3ca4e8ece5 -r 557c0f2c6129026d8a6738292a4ae26e681e1391 config/plugins/visualizations/charts/static/charts/types.js --- a/config/plugins/visualizations/charts/static/charts/types.js +++ b/config/plugins/visualizations/charts/static/charts/types.js @@ -1,22 +1,22 @@ // dependencies -define(['plugin/charts/bardiagram/config', - //'plugin/charts/boxplot/config', - 'plugin/charts/histogram/config', - 'plugin/charts/horizontal/config', - 'plugin/charts/line/config', - 'plugin/charts/linewithfocus/config', - 'plugin/charts/piechart/config', - 'plugin/charts/scatterplot/config', - 'plugin/charts/stackedarea/config', - ], function(bardiagram, - //boxplot, - histogram, - horizontal, - line, - linewithfocus, - piechart, - scatterplot, - stackedarea +define(['plugin/charts/nvd3_bardiagram/config', + 'plugin/charts/nvd3_histogram/config', + 'plugin/charts/nvd3_horizontal/config', + 'plugin/charts/nvd3_line/config', + 'plugin/charts/nvd3_linewithfocus/config', + 'plugin/charts/nvd3_piechart/config', + 'plugin/charts/nvd3_scatterplot/config', + 'plugin/charts/nvd3_stackedarea/config', + 'plugin/charts/highcharts_boxplot/config', + ], function(nvd3_bardiagram, + nvd3_histogram, + nvd3_horizontal, + nvd3_line, + nvd3_linewithfocus, + nvd3_piechart, + nvd3_scatterplot, + nvd3_stackedarea, + highcharts_boxplot ) {
// widget @@ -24,15 +24,15 @@ { // types defaults: { - 'bardiagram' : bardiagram, - //'boxplot' : boxplot, - 'horizontal' : horizontal, - 'histogram' : histogram, - 'line' : line, - 'linewithfocus' : linewithfocus, - 'piechart' : piechart, - 'scatterplot' : scatterplot, - 'stackedarea' : stackedarea + 'nvd3_bardiagram' : nvd3_bardiagram, + 'nvd3_horizontal' : nvd3_horizontal, + 'nvd3_histogram' : nvd3_histogram, + 'nvd3_line' : nvd3_line, + 'nvd3_linewithfocus' : nvd3_linewithfocus, + 'nvd3_piechart' : nvd3_piechart, + 'nvd3_scatterplot' : nvd3_scatterplot, + 'nvd3_stackedarea' : nvd3_stackedarea, + 'highcharts_boxplot' : highcharts_boxplot } });
This diff is so big that we needed to truncate the remainder.
Repository URL: https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.