Commit ae53c793 authored by Castillo's avatar Castillo

old files

parent 5b59fecc
import networkx as nx
from itertools import combinations
class Utils:
def __init__(self):
self.G = nx.Graph()
def unique(self,a):
""" return the list with duplicate elements removed """
return list(set(a))
def intersect(self,a, b):
""" return the intersection of two lists """
return list(set(a) & set(b))
def union(self,a, b):
""" return the union of two lists """
return list(set(a) | set(b))
def addCompleteSubGraph(self,terms):
G=self.G
# <addnode> #
for i in terms:
G.add_node(i)
# </addnode> #
# <addedge> #
edges = combinations(terms, 2)
for n in edges:
n1=n[0]
n2=n[1]
one=float(1)
if G.has_edge(n1,n2):
G[n1][n2]['weight']+=one
else: G.add_edge(n1,n2,weight=one)
self.G = G
\ No newline at end of file
import sqlite3
class SQL:
def __init__(self , dbname):
self.db = dbname
def Bulk_Select( self, connection , cursor , target , table , source , groupby , data , k=490):
results = {}
for i in range(0, len(data), k):
chunk = list(map(str,data[i:i+k]))
query = "SELECT "+target+" from "+table
conditions = " WHERE ("+source+"=\""
concats = "\" OR "+source+"=\""
conditions += concats.join( chunk ) +'")'
query = query+conditions
cursor.execute( query )
rows = cursor.fetchall()
for r in rows:
# print dict( r )
results[r[groupby]] = dict( r )
return results
# # # = = = = = = INSERT STUFF = = = = = # # #
def insertFromDict(self , table, d):
"""Return SQL statement and data vector for insertion into table."""
fields = []
for k in d:
fields.append( k )
sql = 'INSERT OR IGNORE INTO %s (%s) VALUES(%s)' % ( table, ", ".join(fields), ", ".join("?" for f in fields))
#if d["c"] > 2:
# print( sql, d.values() )
return sql, d.values()
# # # = = = = = = INSERT STUFF = = = = = # # #
def InsertInto_modular(self , connection , cursor , tablename , data , step=490):
print [ tablename , len(data.keys()) ]
from itertools import izip_longest, ifilter
step_chunks = [data.iteritems()]*step
chunks = (dict(ifilter(None, v)) for v in izip_longest(*step_chunks))
for chunk in chunks:
connection.execute('BEGIN TRANSACTION')
for item in chunk:
sql, data = self.insertFromDict( tablename , chunk[item])
try:
cursor.execute(sql, data)
except Exception as e:
print e
print "FAIL:\t",data
print (" - - - - - - - - - ")
connection.execute('COMMIT TRANSACTION')
connection.commit()
results = [ tablename, "OK"]
print "\t", results
return results
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import time
import simplejson as json
import json as jsonold
import pprint
import dateutil.parser
import sys
import sqlite3
import unicodedata
class Hola:
def __init___(self):
self.hola = "mundo"
def make_conditions( self , what , elems , merge ):
if what==False or len(elems)==0:
return False
exact_match = []
partial_match = []
partial_match_d = {}
for w in elems:
if "*" in w:
partial_match.append( w.replace("*","%") )
else:
exact_match.append( w )
conditions = []
if len(partial_match)>0:
partial_ = what+" like \""
concats = "\" OR "+what+" like \""
partial_ += concats.join( partial_match ) +'"'
conditions.append( partial_ )
if merge:
for w in partial_match:
wc = w[:]
partial_match_d[wc.replace("%","").lower()] = w.replace("%","*")
if len(exact_match)>0:
exact_ = what+"=\""
concats = "\" OR "+what+"=\""
exact_ += concats.join( exact_match ) +'"'
conditions.append( exact_ )
conditions = " OR ".join(conditions)
conditions = " WHERE ("+ conditions +")"
return conditions , partial_match_d
def querier( self , what=False , elems = [] , time = [] , merge=False):
table = "tweet_"+what
query = "SELECT * FROM "+table
conditions , partial_match_d = self.make_conditions( what , elems , merge)
query = query+conditions
print(query)
conn=sqlite3.connect( "bogota.sqlite" )
conn.row_factory = sqlite3.Row# Magic line!
cursor=conn.cursor()
# cursor.execute("PRAGMA case_sensitive_like=1")
cursor.execute(query)
rows = cursor.fetchall()
P = 0
T = {}
for r in rows:
# print( dict(r) )
ID = str(r["id"])
if ID not in T:
T[ID] = {
"c": 0,
"hashtags": {},
"date": ""
}
T[ID]["c"] += 1
lower_hash = r["hashtag"].lower()
if merge:
for w in partial_match_d:
if w in lower_hash:
lower_hash = partial_match_d[w]
T[ID]["hashtags"][ lower_hash ] = True
T[ID]["date"] = r["day"]
conn.close()
# print( query )
Priority = {}
for i in T:
nb_hashs = len( T[i]["hashtags"].keys() )
if nb_hashs not in Priority:
Priority[nb_hashs] = []
Priority[nb_hashs].append( i )
results = {
"tweets": T,
"tweets_priority": Priority
}
return results
def get_metadata( self , data=[] , extra=False ):
conn=sqlite3.connect( "bogota.sqlite" )
conn.row_factory = sqlite3.Row# Magic line!
cursor=conn.cursor()
from Twitter.SQLite import SQL
inst = SQL("")
T = inst.Bulk_Select( conn, cursor ,"*", "tweet","id","id",data )
if extra!=False:
H = inst.Bulk_Select( conn, cursor ,"rowid, *", "tweet_"+extra , "id","rowid",data )
for i in H:
ID = H[i]["id"]
h = H[i][extra]
if extra not in T[ID]:
T[ID][extra] = []
try:
T[ID][extra].append( str(h) )
except:
T[ID][extra].append( str(self.strip_accents(h)) )
conn.close()
return T
def formatData ( self , RES ):
FinalArray = {}
T = RES["tweets"]
T_meta = self.get_metadata( data=list(T.keys()) )
Priority = RES["tweets_priority"]
data = []
for i in sorted(Priority.keys() , reverse=True):
if i>1:
print(i ,":",len(Priority[i]),"tweets" )
for t in Priority[i]:
info = {}
info["id"] = t
info["created_at"] = T_meta[t]["created_at"]
info["text"] = T_meta[t]["text"]
info["score"] = i
info["author"] = {
"screen_name":T_meta[t]["user"],
"lang": "es",
"name": T_meta[t]["text"],
"profile_image_url": "http://img.com"
}
info["query"] = sorted(list(T[t]["hashtags"].keys()))
info["FV"] = T_meta[t]["fv"]
info["RT"] = T_meta[t]["rt"]
data.append(info)
Ngrams = {}
Days_x_Tweets = {}
for ID in T:
tweet = T[ID]
dateiso = dateutil.parser.parse( tweet["date"] )
# jour = dateiso.strftime('%Y-%m-%dT%H:%M:%S')
jour = dateiso.strftime('%Y-%m-%d')
if jour not in Days_x_Tweets:
Days_x_Tweets[jour] = {
"tweets":[]
}
Days_x_Tweets[jour]["tweets"].append( ID )
for h in tweet["hashtags"] :
Ngrams[h] = True
Ngrams = Ngrams.keys()
DatesIndex = sorted(Days_x_Tweets.keys())
for jour in DatesIndex:
# print jour
Scores = {}
t_ids = Days_x_Tweets[jour]["tweets"]
for t in t_ids:
tweet = T[str(t)]
# print "\t", tweet["query"] ,t,"RT:",tweet["retweet_count"]
for h in tweet["hashtags"] :
if h not in Scores:
Scores[ h ] = 0
Scores[ h ] += 1
Days_x_Tweets[jour]["scores"] = Scores
# print
finaldata = []
Date_vs_Tweets = []
for jour in DatesIndex:
tweet = []
the_timestamp = jour
# the_timestamp = jour.replace("T"," ")
tweet.append( the_timestamp )
Date_vs_Tweets.append( Days_x_Tweets[jour]["tweets"] )
t_scores = Days_x_Tweets[jour]["scores"]
for ng in Ngrams:
score = -1
if ng not in t_scores:
score = 0
else:
score = t_scores[ng]
tweet.append(score)
finaldata.append(tweet)
FinalArray = {
"data":finaldata,
"labels":Ngrams,
"dates_tweets":Date_vs_Tweets,
"raw" : data
}
print("END")
return FinalArray
def strip_accents(self , s):
return ''.join(c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn')
def users_X_hashtags ( self , Tweets):
User_Term = {}
Term_User = {}
U_I = {}
for i in Tweets:
T = Tweets[i]
if T["user"] not in U_I:
U_I[ T["user"] ] = {
"T": 0,
"RT": 0,
"FV": 0
}
U_I[ T["user"] ]["T"] +=1
U_I[ T["user"] ]["RT"] += T["rt"]
U_I[ T["user"] ]["FV"] += T["fv"]
if "hashtag" in T:
# Users[ T["user-id"] ] = T["screen-name"]
u = T["user"]
if u not in User_Term:
User_Term[ u ] = {}
for t_raw in T["hashtag"]:
try:
t = t_raw.lower()
except:
t = self.strip_accents ( t_raw.lower() )
# = = = REL(User,Term+Freq) = = =
if t not in User_Term[ u ]:
User_Term[ u ][ t ] = 0
User_Term[ u ][ t ] += 1
# = = = / REL(User,Term+Freq) = = =
if t not in Term_User:
Term_User[t] = {}
if u not in Term_User[t]:
Term_User[t][u] = 0
Term_User[t][u] += 1
del User_Term["SectorSalud"]
for t in Term_User:
if "SectorSalud" in Term_User[t]:
del Term_User[t]["SectorSalud"]
from Twitter.n_partite_graph import nPartiteGraph
Args = { "nodesA" : False , "filternodesby": False , "max_oppos": 9999 , "normalization": True }
generate = nPartiteGraph()
graphArray = generate.BiGraph( Args , ["users" , "terms"] , [User_Term , Term_User] )
# Nodes = {}
# file_1 = open( "z_hashtags_positions.json" , "r")
# _nodes = jsonold.load( file_1 )
# for n in _nodes:
# Nodes[n] = _nodes[n]
# file_1.close()
# file_2 = open( "z_users_positions.json" , "r")
# _nodes = jsonold.load( file_2 )
# for n in _nodes:
# Nodes[n] = _nodes[n]
# file_2.close()
# for i in graphArray[0]["nodes"]:
# if i["r_id"] in Nodes:
# i["x"] = Nodes[i["r_id"]]["x"]
# i["y"] = Nodes[i["r_id"]]["y"]
# i["color"] = Nodes[i["r_id"]]["color"]
# if i["color"] == "undefined": i["color"] = "#FFFFFF"
# # for i in graphArray[0]["nodes"]:
# # print( i )
return graphArray
\ No newline at end of file
# -*- coding: utf-8 -*-
import simplejson as json
import pprint
from InterUnion import Utils
import math
import operator
import networkx as nx
class nPartiteGraph:
def __init__(self):
self.dummy = "bleh"
self.dbname = "CNRS.sqlite"
def SameKindNodes( self, Nodes_str2int , OutputGraph , Type , Shape, Nodes , Links , ExtraAtts ):
# print( NodesxColor )
ExtrAttsFlag = False
if ExtraAtts!=False: ExtrAttsFlag=True
Metadata_Nodes_str2num = {}
C = len(Nodes)
for n in OutputGraph.nodes_iter():
node = {
"attributes":{},
"r_id": n,
"id": Nodes_str2int[n],
"label": str(n),
"type": Type,
"size": OutputGraph.degree(n)
}
if Shape:
node["shape"] = Shape
if ExtrAttsFlag and n in ExtraAtts:
for key in ExtraAtts[n]:
if key=="color":
node["color"] = ExtraAtts[n][key]
else:
node["attributes"][key] = ExtraAtts[n][key]
else:
node["attributes"]["clust_default"] = 1
Nodes.append(node)
Metadata_Nodes_str2num[n] = C
C += 1
c = len( Links )+1
for e in OutputGraph.edges_iter():
s = e[0]
t = e[1]
link = {
"id": str(c),
"s":Nodes_str2int[s],
"t":Nodes_str2int[t],
"w": OutputGraph[s][t]["weight"]
}
Links.append(link)
c += 1
return Nodes,Links
#
# for a in AxB*:
# Keys = IDF ( AxB*[a] , BxA* , N_docs , threshold )
# addCompleteSubGraph ( Keys ) #filling the B-graph.
#
# = = = = = = = = = = = = = = = = = = = = = = = =
# so From AxB* i'm building my B-graph, where :
# = = = = = = = = = = = = = = = = = = = = = = = =
# OpposNeigh_i <-> AxB*[a] : b-neighborhood of node-a
# SameNeigh <-> BxA* : A-neighborhood of Nodes-B , for getting the number of Nodes-A/opposites of each b in b-neighborhood
# N_docs : number of Nodes-A (like nb of Documents in tf-idf)
# threshold : Max neighborhood size
def IDF (self , OpposNeigh_i , SameNeigh , N_docs , threshold):
TFIDFs = {}
for d in OpposNeigh_i:
GlobalCount_term = len(SameNeigh[d].keys() )
tf = 1
idf = math.log( N_docs/float(GlobalCount_term) )
TFIDFs[d] = tf*idf
sorted_x = sorted( TFIDFs.items() , key = operator.itemgetter(1) , reverse=True )
Keys = []
for t in sorted_x[:threshold]:
Keys.append( t[0] )
# print ID , ":" , len(Keys)
return Keys
def OCC (self , OpposNeigh_i , SameNeigh , N_docs , threshold):
OCCs = {}
for d in OpposNeigh_i:
OCCs[d] = len(SameNeigh[d].keys() )
sorted_x = sorted( OCCs.items() , key = operator.itemgetter(1) , reverse=True )
Keys = []
for t in sorted_x[:threshold]:
Keys.append( t[0] )
return Keys
def normalize_edges( self , nxGraph ):
links = []
max_w = -1
for e in nxGraph.edges_iter():
weight = nxGraph[e[0]][e[1]]["weight"]
if weight>max_w:
max_w=weight
for e in nxGraph.edges_iter():
s = e[0]
t = e[1]
nxGraph[s][t]["weight"] = (nxGraph[s][t]["weight"]/max_w)
return nxGraph
def BiGraph(self , Args , nodeTypes , nodeDicts ):
nodesA_toB = nodeDicts[0]
nodesB_toA = nodeDicts[1]
nodesA = Args["nodesA"]
filter_method = Args["filternodesby"]
max_opposneigh = Args["max_oppos"]
weight_normalization = Args["normalization"]
print("")
print( "= = = = = = = = = = = = = = ")
print( "nodesA:",nodesA)
print( "filter by:",filter_method)
print( "max voisinage:",max_opposneigh)
print( "normalize?:",weight_normalization)
print( "= = = = = = = = = = = = = = ")
print("")
Nodes_str2int = {}
Nodes_int2str = {}
it = 1
# B -> B depuis AxB*
Graph = Utils()
nb_A = len( nodesA_toB.keys() )
for ID in nodesA_toB:
Nodes_int2str[it] = ID
Nodes_str2int[ID] = it
it +=1
if len(nodesA_toB[ID].keys())>0:
# Keys = getattr(self, filter_method)( nodesA_toB[ID] , nodesB_toA , nb_A , max_opposneigh )
Keys = list(nodesA_toB[ID].keys())
Graph.addCompleteSubGraph ( Keys )
GraphB = Graph.G
GraphB.remove_nodes_from(nx.isolates(GraphB))
GraphB = self.normalize_edges( GraphB )
print (len(GraphB))
# A -> A depuis BxA*
Graph = Utils()
nb_B = len( nodesB_toA.keys() )
for ID in nodesB_toA:
Nodes_int2str[it] = ID
Nodes_str2int[ID] = it
it +=1
if len(nodesB_toA[ID].keys())>0:
# Keys = getattr(self, filter_method)( nodesB_toA[ID] , nodesA_toB , nb_B , max_opposneigh )
Keys = list(nodesB_toA[ID].keys())
Graph.addCompleteSubGraph ( Keys )
GraphA = Graph.G
GraphA.remove_nodes_from(nx.isolates(GraphA))
GraphA = self.normalize_edges( GraphA )
print (len(GraphA))
Nodes = []
Links = []
# JSON B -> B
Nodes,Links = self.SameKindNodes( Nodes_str2int , GraphB , nodeTypes[1] , False , Nodes , Links , False)
# JSON A -> A
Nodes,Links = self.SameKindNodes( Nodes_str2int , GraphA , nodeTypes[0] , "square" , Nodes , Links , False)
# JSON A -> B
c = len( Links )+1
for s in GraphA.nodes_iter():
# print s , "->"
# print "\t" , nodesA_toB[s].keys()
for t in nodesA_toB[s]:
if GraphB.nodes(Nodes_str2int[t]):
link = {
"id": str(c),
"s":Nodes_str2int[s],
"t":Nodes_str2int[t],
"w": 1
}
Links.append(link)
c += 1
graphArray = {
"nodes":Nodes,
"links":Links,
}
# pprint.pprint(graphArray["clusters"])
print ("nodesA:",len(nodesA_toB.keys()))
print ("nodesB:",len(nodesB_toA.keys()))
print ("fini")
# results = [len(nodesA_toB.keys()) , len(nodesB_toA.keys()) , len(Links)]
return [graphArray , nodesA_toB.keys() , nodesB_toA.keys() , len(Links)]
# if __name__ == "__main__":
# main()
# # from CNRS.Main import CNRSQuerier
\ No newline at end of file
/var/www/DBs/SectorSalud/bogota.sqlite
\ No newline at end of file
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask, request, redirect, url_for, render_template , current_app, jsonify
import os
import time
import simplejson as json
import glob
from uuid import uuid4
import datetime
import pprint
import time
import dateutil.parser
import base64
#from werkzeug.contrib.fixers import ProxyFix
app = Flask(__name__)
app.TWJSrealmainpath = "/home/pksm3/www"
app.TWJSlocalpath = "/i7/CNRS/"
app.TWJSdata = "data/cnrsfolder"
app.serverpath = "http://localhost"
# app.TWJSrealmainpath = "/var/www"
# app.TWJSlocalpath = "/CNRSdemo/"
# app.TWJSdata = "data/cnrsfolder"
# app.serverpath = "http://tina.iscpif.fr"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/dygraph_exp")
def dygraph_index():
return render_template("dygraph_exp.html")
@app.route("/dygraph_julian")
def dygraph_julian():
return render_template("dygraph_julian.html")
@app.route("/dygraph_julian_json")
def dygraph_julian_json():
queries = json.loads(request.args['motscles'])
original_query = list( map(str,queries) )
merge = False
try:
merge_ = list( map(str, json.loads(request.args['merge']) ) )
if merge_[0].lower() == "yes":
merge = True
except:
pass
print(queries,"\t",merge)
from Twitter.julian import Hola
inst = Hola()
RES = inst.querier( "hashtag" , original_query , ["2013-03-12","2016-03-12"] , merge)
data_final = inst.formatData( RES )
return json.dumps( data_final )
@app.route("/bigraph_julian_json" , methods=['POST'] )
def bigraph_julian_json():
results = ["hola","OK"]
if request.method == 'POST':
print( "'right, i did a POST" )
Tweets = []
for i in request.form:
Tweets.append(request.form[i])
print(len(Tweets))
from Twitter.julian import Hola
inst = Hola()
T_meta = inst.get_metadata( data=Tweets , extra = "hashtag" )
graphArray = inst.users_X_hashtags( T_meta )
path = "/var/www/phylum/data/bogota/"
graphname = datetime.datetime.now().isoformat()+"_graph.json"
f = open(path+graphname,"w")
f.write( json.dumps(graphArray[0]) )
f.close()
results[0] = "phylum/"+"explorerjs.html?file="+"data/bogota"+"/"+graphname
return json.dumps( results )
@app.route("/dynatable/")
def dynatable_index():
return render_template("dynatable.html")
@app.route("/myAPIstatus/<int:user>/<item>")
def getAPIstatus( user , item ):
results = ["hola" , "mundo"]
from Twitter.Main import TwitterClass
twitter = TwitterClass( user )
results = twitter.getRateLimitStatus_global( user ,str(item) )
return jsonify(results)
@app.route("/clicks")
def clicks():
return json.dumps(["ok"])
# # http://localhost:2020/twitterquery_dygraph?motscles=[%22climate%20change%22,%22cop21%22]
# @app.route("/twitterquery_dygraph")
@app.route("/twitterquery_dygraph")
def scan_dygraph():
results = []
queries = [
"greece",
"france"
]
FinalArray = {}
queries = json.loads(request.args['motscles'])
original_query = queries[:]
directory = "../../tweets_buffer/"+time.strftime("%Y-%m-%d")
if not os.path.exists(directory):
os.makedirs(directory)
for i in range(len(queries)):
q = queries[i]
queryfile = base64.urlsafe_b64encode(q)
if os.path.isfile( directory+"/"+queryfile+".json" ):
queries[i] = False
# Ngram = True, then retrieve tweets from twitter!
from Twitter.Main import TwitterClass
twitter = TwitterClass( -1 )
for i in range(len(queries)):
q = queries[i]
if q!=False:
try:
twitter.Query(q)
except:
time.sleep(1)
twitter.Query(q)
if len(twitter.Tweets.keys())>0:
for q in twitter.Tweets:
if len( twitter.Tweets[q].keys() )>0:
json.dump(twitter.Tweets[q], open(directory+"/"+base64.urlsafe_b64encode(q)+".json",'w'))
for q in original_query:
queryfile = base64.urlsafe_b64encode(q)
if q not in twitter.Tweets:
if os.path.isfile( directory+"/"+queryfile+".json" ):
print "previous query already done:",q,(directory+"/"+queryfile+".json")
with open((directory+"/"+queryfile+".json")) as data_file:
twitter.Tweets[q] = json.load(data_file)
else:
print "file doesn't exist:",q,(directory+"/"+queryfile+".json")
data = {}
for q in twitter.Tweets:
for t in twitter.Tweets[q]:
if t not in data:
data[str(t)] = {}
data[str(t)] = twitter.Tweets[q][t]
json.dump(data, open("lalala.json",'w'))
# for t in data:
# print t,"--->",data[t]["query"]
Ngrams = {}
Days_x_Tweets = {}
for i in data:
# print i
tweet = data[i]
dateiso = dateutil.parser.parse( tweet["created_at"] )
# jour = dateiso.strftime('%Y-%m-%dT%H:%M:%S')
jour = dateiso.strftime('%Y-%m-%d')
if jour not in Days_x_Tweets:
Days_x_Tweets[jour] = {
"tweets":[]
}
Days_x_Tweets[jour]["tweets"].append( tweet["id"] )
Ngrams[tweet["query"]] = True
Ngrams = Ngrams.keys()
DatesIndex = sorted(Days_x_Tweets.keys())
for jour in DatesIndex:
# print jour
Scores = {}
t_ids = Days_x_Tweets[jour]["tweets"]
for t in t_ids:
tweet = data[str(t)]
# print "\t", tweet["query"] ,t,"RT:",tweet["retweet_count"]
if tweet["query"] not in Scores:
Scores[ tweet["query"] ] = 0
Scores[ tweet["query"] ] += tweet["retweet_count"]
Days_x_Tweets[jour]["scores"] = Scores
# print
finaldata = []
Date_vs_Tweets = []
for jour in DatesIndex:
info = []
the_timestamp = jour
# the_timestamp = jour.replace("T"," ")
info.append( the_timestamp )
Date_vs_Tweets.append( Days_x_Tweets[jour]["tweets"] )
t_scores = Days_x_Tweets[jour]["scores"]
for ng in Ngrams:
score = -1
if ng not in t_scores:
score = 0
else:
score = t_scores[ng]
info.append(score)
finaldata.append(info)
FinalArray = {
"data":finaldata,
"labels":Ngrams,
"dates_tweets":Date_vs_Tweets,
"raw" : data
}
return json.dumps(FinalArray)
# return json.dumps(results)
def ajax_response(status, msg):
status_code = "ok" if status else "error"
return json.dumps(dict(
status=status_code,
msg=msg,
))
#application = app
#app.wsgi_app = ProxyFix(app.wsgi_app)
#if __name__ == '__main__':
# #app.run(host='0.0.0.0')
# from flask_reverse_proxy import FlaskReverseProxied
# proxied = FlaskReverseProxied()
# proxied.init_app(app)
# app.run()
from reverseproxy import ReverseProxied
app.wsgi_app = ReverseProxied(app.wsgi_app)
\ No newline at end of file
```js
inkscape -z -e output.png -w 8192 input.svg
¡```
This diff is collapsed.
class ReverseProxied(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
script_name = environ.get('HTTP_X_SCRIPT_NAME', '')
if script_name:
environ['SCRIPT_NAME'] = script_name
path_info = environ['PATH_INFO']
if path_info.startswith(script_name):
environ['PATH_INFO'] = path_info[len(script_name):]
scheme = environ.get('HTTP_X_SCHEME', '')
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
.checkbox label .toggle,
.checkbox-inline .toggle {
margin-left: -20px;
margin-right: 5px;
}
.toggle {
position: relative;
overflow: hidden;
}
.toggle input[type="checkbox"] {
display: none;
}
.toggle-group {
position: absolute;
width: 200%;
top: 0;
bottom: 0;
left: 0;
transition: left 0.35s;
-webkit-transition: left 0.35s;
-moz-user-select: none;
-webkit-user-select: none;
}
.toggle.off .toggle-group {
left: -100%;
}
.toggle-on {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 50%;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-off {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
right: 0;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-handle {
position: relative;
margin: 0 auto;
padding-top: 0px;
padding-bottom: 0px;
height: 100%;
width: 0px;
border-width: 0 1px;
}
.toggle.btn { min-width: 59px; min-height: 34px; }
.toggle-on.btn { padding-right: 24px; }
.toggle-off.btn { padding-left: 24px; }
.toggle.btn-lg { min-width: 79px; min-height: 45px; }
.toggle-on.btn-lg { padding-right: 31px; }
.toggle-off.btn-lg { padding-left: 31px; }
.toggle-handle.btn-lg { width: 40px; }
.toggle.btn-sm { min-width: 50px; min-height: 30px;}
.toggle-on.btn-sm { padding-right: 20px; }
.toggle-off.btn-sm { padding-left: 20px; }
.toggle.btn-xs { min-width: 35px; min-height: 22px;}
.toggle-on.btn-xs { padding-right: 12px; }
.toggle-off.btn-xs { padding-left: 12px; }
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function ($) {
'use strict';
// TOGGLE PUBLIC CLASS DEFINITION
// ==============================
var Toggle = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, this.defaults(), options)
this.render()
}
Toggle.VERSION = '2.2.0'
Toggle.DEFAULTS = {
on: 'On',
off: 'Off',
onstyle: 'primary',
offstyle: 'default',
size: 'normal',
style: '',
width: null,
height: null
}
Toggle.prototype.defaults = function() {
return {
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
}
}
Toggle.prototype.render = function () {
this._onstyle = 'btn-' + this.options.onstyle
this._offstyle = 'btn-' + this.options.offstyle
var size = this.options.size === 'large' ? 'btn-lg'
: this.options.size === 'small' ? 'btn-sm'
: this.options.size === 'mini' ? 'btn-xs'
: ''
var $toggleOn = $('<label class="btn">').html(this.options.on)
.addClass(this._onstyle + ' ' + size)
var $toggleOff = $('<label class="btn">').html(this.options.off)
.addClass(this._offstyle + ' ' + size + ' active')
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
.addClass(size)
var $toggleGroup = $('<div class="toggle-group">')
.append($toggleOn, $toggleOff, $toggleHandle)
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
.addClass(size).addClass(this.options.style)
this.$element.wrap($toggle)
$.extend(this, {
$toggle: this.$element.parent(),
$toggleOn: $toggleOn,
$toggleOff: $toggleOff,
$toggleGroup: $toggleGroup
})
this.$toggle.append($toggleGroup)
var width = this.options.width || Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
var height = this.options.height || Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
$toggleOn.addClass('toggle-on')
$toggleOff.addClass('toggle-off')
this.$toggle.css({ width: width, height: height })
if (this.options.height) {
$toggleOn.css('line-height', $toggleOn.height() + 'px')
$toggleOff.css('line-height', $toggleOff.height() + 'px')
}
this.update(true)
this.trigger(true)
}
Toggle.prototype.toggle = function () {
if (this.$element.prop('checked')) this.off()
else this.on()
}
Toggle.prototype.on = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
this.$element.prop('checked', true)
if (!silent) this.trigger()
}
Toggle.prototype.off = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
this.$element.prop('checked', false)
if (!silent) this.trigger()
}
Toggle.prototype.enable = function () {
this.$toggle.removeAttr('disabled')
this.$element.prop('disabled', false)
}
Toggle.prototype.disable = function () {
this.$toggle.attr('disabled', 'disabled')
this.$element.prop('disabled', true)
}
Toggle.prototype.update = function (silent) {
if (this.$element.prop('disabled')) this.disable()
else this.enable()
if (this.$element.prop('checked')) this.on(silent)
else this.off(silent)
}
Toggle.prototype.trigger = function (silent) {
this.$element.off('change.bs.toggle')
if (!silent) this.$element.change()
this.$element.on('change.bs.toggle', $.proxy(function() {
this.update()
}, this))
}
Toggle.prototype.destroy = function() {
this.$element.off('change.bs.toggle')
this.$toggleGroup.remove()
this.$element.removeData('bs.toggle')
this.$element.unwrap()
}
// TOGGLE PLUGIN DEFINITION
// ========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.toggle')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
if (typeof option == 'string' && data[option]) data[option]()
})
}
var old = $.fn.bootstrapToggle
$.fn.bootstrapToggle = Plugin
$.fn.bootstrapToggle.Constructor = Toggle
// TOGGLE NO CONFLICT
// ==================
$.fn.toggle.noConflict = function () {
$.fn.bootstrapToggle = old
return this
}
// TOGGLE DATA-API
// ===============
$(function() {
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
})
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
var $checkbox = $(this).find('input[type=checkbox]')
$checkbox.bootstrapToggle('toggle')
e.preventDefault()
})
}(jQuery);
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
body {
background-color: #FFFFFF;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: small;
color: #000000;
}
#dropbox {
border: 2px dashed #000000;
padding: 20px;
}
#dropbox.active {
border: 4px dashed #FF0000;
}
.progress-trough {
border: 1px solid #000000;
height: 24px;
width: 100%;
position: relative;
}
.progress-bar {
width: 50%;
height: 100%;
background-color: #0099FF;
}
\ No newline at end of file
.text-core {
position: relative;
}
.text-core .text-wrap {
background: #fff;
position: absolute;
}
.text-core .text-wrap textarea,
.text-core .text-wrap input {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
border: 1px solid #9daccc;
outline: none;
resize: none;
position: absolute;
z-index: 1;
background: none;
overflow: hidden;
margin: 0;
padding: 3px 5px 4px 5px;
white-space: nowrap;
font: 11px "lucida grande", tahoma, verdana, arial, sans-serif;
line-height: 13px;
height: auto;
}
.text-core .text-wrap .text-arrow {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
top: 0;
right: 0;
width: 22px;
height: 22px;
background: url("arrow.png") 50% 50% no-repeat;
cursor: pointer;
z-index: 2;
}
.text-core .text-wrap .text-dropdown {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
position: absolute;
z-index: 3;
background: #fff;
border: 1px solid #9daccc;
width: 100%;
max-height: 100px;
padding: 1px;
font: 11px "lucida grande", tahoma, verdana, arial, sans-serif;
display: none;
overflow-x: hidden;
overflow-y: auto;
}
.text-core .text-wrap .text-dropdown.text-position-below {
margin-top: 1px;
}
.text-core .text-wrap .text-dropdown.text-position-above {
margin-bottom: 1px;
}
.text-core .text-wrap .text-dropdown .text-list .text-suggestion {
padding: 3px 5px;
cursor: pointer;
}
.text-core .text-wrap .text-dropdown .text-list .text-suggestion em {
font-style: normal;
text-decoration: underline;
}
.text-core .text-wrap .text-dropdown .text-list .text-suggestion.text-selected {
color: #fff;
background: #6d84b4;
}
.text-core .text-wrap .text-clear {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
top: 0;
right: 14px;
width: 22px;
height: 22px;
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAYUlEQVR42mP4////P1IwA5RBNIBr+Pj5+/9Tlx78v373OYoCkBgIY2gACWr7tP63CO8BanoBlmyfuQssBsIYGtAVLNpwEsMADA0gAFMIw+hOpEwDSU4i2dMkByvJEUcsAABHaALCQIZDrAAAAABJRU5ErkJggg==") 50% 50% no-repeat;
cursor: pointer;
z-index: 2;
}
\ No newline at end of file
.text-core .text-wrap .text-focus {
-webkit-box-shadow: 0px 0px 6px #6d84b4;
-moz-box-shadow: 0px 0px 6px #6d84b4;
box-shadow: 0px 0px 6px #6d84b4;
position: absolute;
width: 100%;
height: 100%;
display: none;
}
.text-core .text-wrap .text-focus.text-show-focus {
display: block;
}
.text-core .text-wrap .text-prompt {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
margin: 1px 0 0 2px;
font: 11px "lucida grande", tahoma, verdana, arial, sans-serif;
color: #c0c0c0;
overflow: hidden;
white-space: pre;
}
.text-core .text-wrap .text-prompt.text-hide-prompt {
display: none;
}
.text-core .text-wrap .text-tags {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
padding: 3px 35px 3px 3px;
cursor: text;
}
.text-core .text-wrap .text-tags.text-tags-on-top {
z-index: 2;
}
.text-core .text-wrap .text-tags .text-tag {
float: left;
}
.text-core .text-wrap .text-tags .text-tag .text-button {
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
position: relative;
float: left;
border: 1px solid #9daccc;
background: #e2e6f0;
color: #000;
padding: 0px 17px 0px 3px;
margin: 0 2px 2px 0;
cursor: pointer;
height: 16px;
font: 11px "lucida grande", tahoma, verdana, arial, sans-serif;
}
.text-core .text-wrap .text-tags .text-tag .text-button a.text-remove {
position: absolute;
right: 3px;
top: 2px;
display: block;
width: 11px;
height: 11px;
background: url("close.png") 0 0 no-repeat;
}
.text-core .text-wrap .text-tags .text-tag .text-button a.text-remove:hover {
background-position: 0 -11px;
}
.text-core .text-wrap .text-tags .text-tag .text-button a.text-remove:active {
background-position: 0 -22px;
}
This diff is collapsed.
th { background: #71af5a; color: #fff; }
th a {
color: #fff;
font-weight: normal;
font-style: italic;
font-size: 0.9em;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/*
* jQuery Dynatable plugin 0.3.1
*
* Copyright (c) 2014 Steve Schwartz (JangoSteve)
*
* Dual licensed under the AGPL and Proprietary licenses:
* http://www.dynatable.com/license/
*
* Date: Tue Jan 02 2014
*/
th {
background: #006a72;
}
th a {
color: #fff;
}
th a:hover {
color: #fff;
text-decoration: underline;
}
.dynatable-search {
float: right;
margin-bottom: 10px;
}
.dynatable-pagination-links {
float: right;
}
.dynatable-record-count {
display: block;
padding: 5px 0;
}
.dynatable-pagination-links span,
.dynatable-pagination-links li {
display: inline-block;
}
.dynatable-page-link,
.dynatable-page-break {
display: block;
padding: 5px 7px;
}
.dynatable-page-link {
cursor: pointer;
}
.dynatable-active-page,
.dynatable-disabled-page {
cursor: text;
}
.dynatable-active-page:hover,
.dynatable-disabled-page:hover {
text-decoration: none;
}
.dynatable-active-page {
background: #006a72;
border-radius: 5px;
color: #fff;
}
.dynatable-active-page:hover {
color: #fff;
}
.dynatable-disabled-page,
.dynatable-disabled-page:hover {
background: none;
color: #999;
}
This diff is collapsed.
This diff is collapsed.
var MyTable;
var RecDict={};
function getElement(rec_id) {
return MyTable.data('dynatable').settings.dataset.originalRecords[rec_id];
}
function transformContent2(rec_id) {
var elem = getElement(rec_id);
var result = {}
if (elem["del"]) {
result["id"] = elem["id"]
result["date"] = '<strike>'+elem["date"]+'</strike>'
result["name"] = '<strike>'+elem["name"]+'</strike>'
result["del"] = '<input id='+rec_id+' onclick="overRide(this)" type="checkbox" checked/>'
} else {
result["id"] = elem["id"]
result["date"] = elem["date"]
result["name"] = elem["name"]
result["del"] = '<input id='+rec_id+' onclick="overRide(this)" type="checkbox"/>'
}
return result;
}
function overRide(elem) {
var id = elem.id
var val = elem.checked
MyTable.data('dynatable').settings.dataset.originalRecords[id]["del"] = val;
console.log(MyTable.data('dynatable').settings.dataset.originalRecords[id])
MyTable.data('dynatable').dom.update();
}
function transformContent(rec_id , header , content) {
if(header=="del") {
if(content==true) return '<input id='+rec_id+' onclick="overRide(this)" type="checkbox" checked/>'
if(content==false) return '<input id='+rec_id+' onclick="overRide(this)" type="checkbox"/>'
} else return content;
}
//generic enough
function ulWriter(rowIndex, record, columns, cellWriter) {
var tr = '';
var cp_rec = {}
if(!MyTable) {
for(var i in record) {
cp_rec[i] = transformContent(RecDict[record.id], i , record[i])
}
} else cp_rec = transformContent2(RecDict[record.id])
// grab the record's attribute for each column
for (var i = 0, len = columns.length; i < len; i++) {
tr += cellWriter(columns[i], cp_rec);
}
return '<tr>' + tr + '</tr>';
}
$.ajax({
url: '/static/dynatable/dynatableajax.json',
success: function(data){
console.log(data)
for(var i in data.records) {
var orig_id = parseInt(data.records[i].id)
var arr_id = parseInt(i)
RecDict[orig_id] = arr_id
data.records[i]["del"] = false
// console.log(data.records[i]["date"]+" : originalRecords["+arr_id+"] <- "+orig_id+" | "+data.records[i]["name"])
}
MyTable = $('#my-ajax-table').dynatable({
dataset: {
records: data.records
},
features: {
sort: false //i need to fix the sorting function... it sucks
},
writers: {
_rowWriter: ulWriter
// _cellWriter: customCellWriter
}
});
console.log(RecDict)
// MyTable.data('dynatable').dom.update();
// MyTable.data('dynatable').dom.update();
// $.doTimeout( 1, function(){
// console.log("holaaaaaa")
// MyTable.data('dynatable').sorts.clear();
// MyTable.data('dynatable').process();
// MyTable.data('dynatable').process();
// // $.doTimeout( 2000, function(){
// // console.log("mundo")
// // MyTable.data('dynatable').process();
// // MyTable.data('dynatable').process();
// // });
// });
}
});
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
/* remember to define focus styles! */
:focus {
outline: 0;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
/* tables still need 'cellspacing="0"' in the markup */
table {
border-collapse: separate;
border-spacing: 0;
}
caption, th, td {
text-align: left;
font-weight: normal;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: "";
}
blockquote, q {
quotes: "" "";
}
This diff is collapsed.
This diff is collapsed.
/*global Gallery,Dygraph,data */
Gallery.register(
'annotations',
{
name: 'Annotations',
title: 'Dynamic Annotations Demo',
setup: function(parent) {
parent.innerHTML = [
"<p>Click any point to add an annotation to it or click 'Add Annotation'.</p>",
"<button id='add'>Add Annotation></button>",
"<button id='bottom'>Shove to bottom</button>",
"<div id='list'></div>",
"<div id='g_div'></div>",
"<div id='events'></div>" ].join("\n");
},
run: function() {
var eventDiv = document.getElementById("events");
function nameAnnotation(ann) {
return "(" + ann.series + ", " + ann.x + ")";
}
var g = new Dygraph(
document.getElementById("g_div"),
function() {
var zp = function(x) { if (x < 10) return "0"+x; else return x; };
var r = "date,parabola,line,another line,sine wave\n";
for (var i=1; i<=31; i++) {
r += "200610" + zp(i);
r += "," + 10*(i*(31-i));
r += "," + 10*(8*i);
r += "," + 10*(250 - 8*i);
r += "," + 10*(125 + 125 * Math.sin(0.3*i));
r += "\n";
}
return r;
},
{
rollPeriod: 1,
showRoller: true,
width: 480,
height: 320,
drawCallback: function(g) {
var ann = g.annotations();
var html = "";
for (var i = 0; i < ann.length; i++) {
var name = nameAnnotation(ann[i]);
html += "<span id='" + name + "'>";
html += name + ": " + (ann[i].shortText || '(icon)');
html += " -> " + ann[i].text + "</span><br/>";
}
document.getElementById("list").innerHTML = html;
}
}
);
var last_ann = 0;
var annotations = [];
for (var x = 10; x < 15; x += 2) {
annotations.push( {
series: 'sine wave',
x: "200610" + x,
shortText: x,
text: 'Stock Market Crash ' + x
} );
last_ann = x;
}
annotations.push( {
series: 'another line',
x: "20061013",
icon: 'images/dollar.png',
width: 18,
height: 23,
tickHeight: 4,
text: 'Another one',
cssClass: 'annotation',
clickHandler: function() {
eventDiv.innerHTML += "special handler<br/>";
}
} );
g.setAnnotations(annotations);
document.getElementById('add').onclick = function() {
var x = last_ann + 2;
annotations.push( {
series: 'line',
x: "200610" + x,
shortText: x,
text: 'Line ' + x,
tickHeight: 10
} );
last_ann = x;
g.setAnnotations(annotations);
};
var bottom = document.getElementById('bottom');
bottom.onclick = function() {
var to_bottom = bottom.textContent == 'Shove to bottom';
var anns = g.annotations();
for (var i = 0; i < anns.length; i++) {
anns[i].attachAtBottom = to_bottom;
}
g.setAnnotations(anns);
if (to_bottom) {
bottom.textContent = 'Lift back up';
} else {
bottom.textContent = 'Shove to bottom';
}
};
var saveBg = '';
var num = 0;
g.updateOptions( {
annotationClickHandler: function(ann, point, dg, event) {
eventDiv.innerHTML += "click: " + nameAnnotation(ann) + "<br/>";
},
annotationDblClickHandler: function(ann, point, dg, event) {
eventDiv.innerHTML += "dblclick: " + nameAnnotation(ann) + "<br/>";
},
annotationMouseOverHandler: function(ann, point, dg, event) {
document.getElementById(nameAnnotation(ann)).style.fontWeight = 'bold';
saveBg = ann.div.style.backgroundColor;
ann.div.style.backgroundColor = '#ddd';
},
annotationMouseOutHandler: function(ann, point, dg, event) {
document.getElementById(nameAnnotation(ann)).style.fontWeight = 'normal';
ann.div.style.backgroundColor = saveBg;
},
pointClickCallback: function(event, p) {
// Check if the point is already annotated.
if (p.annotation) return;
// If not, add one.
var ann = {
series: p.name,
xval: p.xval,
shortText: num,
text: "Annotation #" + num
};
var anns = g.annotations();
anns.push(ann);
g.setAnnotations(anns);
num++;
}
});
}
});
This diff is collapsed.
/*global Gallery,Dygraph,data */
Gallery.register(
'drawing',
{
name: 'Time Series Drawing Demo',
title: 'Time Series Drawing Demo',
setup: function(parent) {
parent.innerHTML = [
"<div id='toolbar'>",
"<div id='tool_zoom'></div>",
"<div id='tool_pencil'></div>",
"<div id='tool_eraser'></div>",
"</div>",
"<div id='draw_div' style='width: 600px; height: 300px;'></div>",
"<p style='font-size: 10pt'>Toolbar/cursor icons are CC-licensed from ",
"<a href='http://www.fatcow.com/free-icons'>FatCow</a>.</p>"].join("\n");
},
run: function() {
var change_tool; // defined below.
var zoom = document.getElementById('tool_zoom');
zoom.onclick = function() { change_tool(zoom); };
var pencil = document.getElementById('tool_pencil');
pencil.onclick = function() { change_tool(pencil); };
var eraser = document.getElementById('tool_eraser');
eraser.onclick = function() { change_tool(eraser); };
var start_date = new Date("2002/12/29").getTime();
var end_date = new Date().getTime();
var data = [];
for (var d = start_date; d < end_date; d += 604800 * 1000) {
var millis = d + 2 * 3600 * 1000;
data.push( [ new Date(Dygraph.dateString_(millis)), 50 ]);
}
var isDrawing = false;
var lastDrawRow = null, lastDrawValue = null;
var tool = 'pencil';
var valueRange = [0, 100];
function setPoint(event, g, context) {
var graphPos = Dygraph.findPos(g.graphDiv);
var canvasx = Dygraph.pageX(event) - graphPos.x;
var canvasy = Dygraph.pageY(event) - graphPos.y;
var xy = g.toDataCoords(canvasx, canvasy);
var x = xy[0], value = xy[1];
var rows = g.numRows();
var closest_row = -1;
var smallest_diff = -1;
// TODO(danvk): binary search
for (var row = 0; row < rows; row++) {
var date = g.getValue(row, 0); // millis
var diff = Math.abs(date - x);
if (smallest_diff < 0 || diff < smallest_diff) {
smallest_diff = diff;
closest_row = row;
}
}
if (closest_row != -1) {
if (lastDrawRow === null) {
lastDrawRow = closest_row;
lastDrawValue = value;
}
var coeff = (value - lastDrawValue) / (closest_row - lastDrawRow);
if (closest_row == lastDrawRow) coeff = 0.0;
var minRow = Math.min(lastDrawRow, closest_row);
var maxRow = Math.max(lastDrawRow, closest_row);
for (var row = minRow; row <= maxRow; row++) {
if (tool == 'pencil') {
var val = lastDrawValue + coeff * (row - lastDrawRow);
val = Math.max(valueRange[0], Math.min(val, valueRange[1]));
data[row][1] = val;
if (val === null || value === undefined || isNaN(val)) {
console.log(val);
}
} else if (tool == 'eraser') {
data[row][1] = null;
}
}
lastDrawRow = closest_row;
lastDrawValue = value;
g.updateOptions({ file: data });
g.setSelection(closest_row); // prevents the dot from being finnicky.
}
}
function finishDraw() {
isDrawing = false;
lastDrawRow = null;
lastDrawValue = null;
}
change_tool = function(tool_div) {
var ids = ['tool_zoom', 'tool_pencil', 'tool_eraser'];
for (var i = 0; i < ids.length; i++) {
var div = document.getElementById(ids[i]);
if (div == tool_div) {
div.style.backgroundPosition = -(i * 32) + 'px -32px';
} else {
div.style.backgroundPosition = -(i * 32) + 'px 0px';
}
}
tool = tool_div.id.replace('tool_', '');
var dg_div = document.getElementById("draw_div");
if (tool == 'pencil') {
dg_div.style.cursor = 'url(images/cursor-pencil.png) 2 30, auto';
} else if (tool == 'eraser') {
dg_div.style.cursor = 'url(images/cursor-eraser.png) 10 30, auto';
} else if (tool == 'zoom') {
dg_div.style.cursor = 'crosshair';
}
};
change_tool(document.getElementById("tool_pencil"));
new Dygraph(document.getElementById("draw_div"), data,
{
valueRange: valueRange,
labels: [ 'Date', 'Value' ],
interactionModel: {
mousedown: function (event, g, context) {
if (tool == 'zoom') {
Dygraph.defaultInteractionModel.mousedown(event, g, context);
} else {
// prevents mouse drags from selecting page text.
if (event.preventDefault) {
event.preventDefault(); // Firefox, Chrome, etc.
} else {
event.returnValue = false; // IE
event.cancelBubble = true;
}
isDrawing = true;
setPoint(event, g, context);
}
},
mousemove: function (event, g, context) {
if (tool == 'zoom') {
Dygraph.defaultInteractionModel.mousemove(event, g, context);
} else {
if (!isDrawing) return;
setPoint(event, g, context);
}
},
mouseup: function(event, g, context) {
if (tool == 'zoom') {
Dygraph.defaultInteractionModel.mouseup(event, g, context);
} else {
finishDraw();
}
},
mouseout: function(event, g, context) {
if (tool == 'zoom') {
Dygraph.defaultInteractionModel.mouseout(event, g, context);
}
},
dblclick: function(event, g, context) {
Dygraph.defaultInteractionModel.dblclick(event, g, context);
},
mousewheel: function(event, g, context) {
var normal = event.detail ? event.detail * -1 : event.wheelDelta / 40;
var percentage = normal / 50;
var axis = g.xAxisRange();
var xOffset = g.toDomCoords(axis[0], null)[0];
var x = event.offsetX - xOffset;
var w = g.toDomCoords(axis[1], null)[0] - xOffset;
var xPct = w === 0 ? 0 : (x / w);
var delta = axis[1] - axis[0];
var increment = delta * percentage;
var foo = [increment * xPct, increment * (1 - xPct)];
var dateWindow = [ axis[0] + foo[0], axis[1] - foo[1] ];
g.updateOptions({
dateWindow: dateWindow
});
Dygraph.cancelEvent(event);
}
},
strokeWidth: 1.5,
gridLineColor: 'rgb(196, 196, 196)',
drawYGrid: false,
drawYAxis: false
});
window.onmouseup = finishDraw;
}
});
/**
* @license
* Copyright 2011 Dan Vanderkam (danvdk@gmail.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
// A dygraph "auto-loader".
// Check where this script was sourced from. If it was sourced from
// '../dygraph-dev.js', then we should source all the other scripts with the
// same relative path ('../dygraph.js', '../dygraph-canvas.js', ...)
(function() {
var src=document.getElementsByTagName('script');
var script = src[src.length-1].getAttribute("src");
// This list needs to be kept in sync w/ the one in generate-combined.sh
// and the one in jsTestDriver.conf.
var source_files = [
"polyfills/console.js",
"dashed-canvas.js",
"dygraph-options.js",
"dygraph-layout.js",
"dygraph-canvas.js",
"dygraph.js",
"dygraph-utils.js",
"dygraph-gviz.js",
"dygraph-interaction-model.js",
"dygraph-tickers.js",
"dygraph-plugin-base.js",
"plugins/annotations.js",
"plugins/axes.js",
"plugins/chart-labels.js",
"plugins/grid.js",
"plugins/legend.js",
"plugins/range-selector.js",
"dygraph-plugin-install.js",
"dygraph-options-reference.js", // Shouldn't be included in generate-combined.sh
"datahandler/datahandler.js",
"datahandler/default.js",
"datahandler/default-fractions.js",
"datahandler/bars.js",
"datahandler/bars-error.js",
"datahandler/bars-custom.js",
"datahandler/bars-fractions.js"
];
for (var i = 0; i < source_files.length; i++) {
document.write('<script type="text/javascript" src="' + script.replace('dygraph-dev.js', source_files[i]) + '"></script>\n');
}
})();
This source diff could not be displayed because it is too large. You can view the blob instead.
/*global Gallery,Dygraph,data */
Gallery.register(
'dynamic-update',
{
name: 'Dynamic Update',
title: 'Live random data',
setup: function(parent) {
parent.innerHTML = [
"<div id='div_g' style='width:600px; height:300px;'></div>",
"<p>This test is modeled after a ",
"<a href='http://www.highcharts.com/demo/?example=dynamic-update&theme=default'>highcharts",
"test</a>. New points should appear once per second. Try zooming and ",
"panning over to the right edge to watch them show up.</p>"].join("\n");
},
run: function() {
var data = [];
var t = new Date();
for (var i = 10; i >= 0; i--) {
var x = new Date(t.getTime() - i * 1000);
data.push([x, Math.random()]);
}
var g = new Dygraph(document.getElementById("div_g"), data,
{
drawPoints: true,
showRoller: true,
valueRange: [0.0, 1.2],
labels: ['Time', 'Random']
});
// It sucks that these things aren't objects, and we need to store state in window.
window.intervalId = setInterval(function() {
var x = new Date(); // current time
var y = Math.random();
data.push([x, y]);
g.updateOptions( { 'file': data } );
}, 1000);
},
clean: function() {
clearInterval(window.intervalId);
}
});
/*global Gallery,Dygraph,data */
Gallery.register(
'edge-padding',
{
name: 'Edge Padding',
title: 'Graph edge padding and axis position',
setup: function(parent) {
parent.innerHTML = (
"<p>" +
" <b>Mode:</b>" +
" <input type='radio' name='mode'>use {x,y}RangePad</input>" +
" <input type='radio' name='mode'>original</input>" +
" <br /><b>Settings:</b>" +
" <input type='checkbox' id='yrange'>valueRange=[-2,2]</input>" +
"</p>" +
"<div id='demodiv'></div>"
);
},
run: function() {
var parent = document.getElementById("demodiv");
var graphs = [];
var nrows = 50;
for (var oy = -2; oy <= 2; ++oy) {
for (var ox = -1; ox <= 1; ++ox) {
var gdiv = document.createElement('div');
gdiv.style.display = 'inline-block';
gdiv.style.margin = '2px';
parent.appendChild(gdiv);
var data = [];
for (var row = 0; row < nrows; ++row) {
var x = row * 5 / (nrows - 1);
data.push([ox * 2.5 + x - 2.5,
oy + Math.sin(x),
oy + Math.round(Math.cos(x))]);
}
var g = new Dygraph(gdiv, data, {
labels: ['x', 'A', 'B'],
labelDivWidth: 100,
gridLineColor: '#ccc',
includeZero: true,
width: 250,
height: 130
});
graphs.push(g);
}
parent.appendChild(document.createElement('br'));
}
var updateGraphOpts = function(opts) {
for (var i = 0; i < graphs.length; ++i) {
graphs[i].updateOptions(opts);
}
};
var mode = document.getElementsByName('mode');
mode[0].onchange = function() {
updateGraphOpts({
avoidMinZero: false,
xRangePad: 3,
yRangePad: 10,
drawAxesAtZero: true});
};
mode[1].onchange = function() {
updateGraphOpts({
avoidMinZero: true,
xRangePad: 0,
yRangePad: null,
drawAxesAtZero: false});
};
mode[0].checked = true;
mode[0].onchange();
var yrange = document.getElementById('yrange');
yrange.onchange = function(ev) {
updateGraphOpts({
valueRange: ev.target.checked ? [-2, 2] : null});
};
}
});
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*global Gallery,Dygraph,data */
/*global NoisyData */
Gallery.register(
'resize',
{
name: 'Resizable Graph',
title: 'Resize the window. The dygraph will resize with it.',
setup: function(parent) {
parent.innerHTML = "<div id='div_g'>";
},
run: function() {
new Dygraph(
document.getElementById("div_g"),
NoisyData, {
rollPeriod: 7,
errorBars: true
}
);
}
});
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
.google-visualization-toolbar{font-size:100%}.google-visualization-toolbar .google-visualization-toolbar-export-igoogle,.google-visualization-toolbar .google-visualization-toolbar-export-data,.google-visualization-toolbar .google-visualization-toolbar-html-code{margin-right:.1em}.google-visualization-toolbar-html-code-explanation{font-weight:bold}.google-visualization-toolbar-ok-button{padding:2px}.google-visualization-toolbar-triangle{position:absolute;right:0;top:0}.google-visualization-toolbar-caption-table{width:100%;padding:0;margin:0;border:0;border-collapse:collapse}.google-visualization-toolbar-small-dialog{width:500px}.google-visualization-toolbar-big-dialog{width:800px}.google-visualization-toolbar-small-dialog,.google-visualization-toolbar-big-dialog{position:absolute;background-color:#c1d9ff;border:1px solid #3a5774;padding:8px}.google-visualization-toolbar-small-dialog-bg,.google-visualization-toolbar-big-dialog-bg{background-color:#ddd;position:absolute;top:0;left:0}.google-visualization-toolbar-small-dialog-title,.google-visualization-toolbar-big-dialog-title{background-color:#e0edfe;color:#000;cursor:pointer;padding:8px;position:relative;font-size:12pt;font-weight:bold;vertical-align:middle}.google-visualization-toolbar-small-dialog-content,.google-visualization-toolbar-big-dialog-content{background-color:#fff;padding:4px;font-weight:normal;overflow:auto}.google-visualization-toolbar-small-dialog-title-close,.google-visualization-toolbar-big-dialog-title-close{background:transparent url(close_box.gif) no-repeat scroll center;height:15px;position:absolute;right:10px;top:8px;width:15px}.google-visualization-toolbar-small-dialog-content iframe,.google-visualization-toolbar-big-dialog-content iframe{width:500px;height:700px;border:1px solid black}.charts-inline-block{position:relative;display:-moz-inline-box;display:inline-block}* html .charts-inline-block,*:first-child+html .charts-inline-block{display:inline}.charts-menu{background:#fff;border-color:#ccc #666 #666 #ccc;border-style:solid;border-width:1px;cursor:default;font:normal 13px Arial,sans-serif;margin:0;outline:none;padding:4px 0;position:absolute;z-index:20000}.charts-menu-button{background:#ddd url(//ssl.gstatic.com/editor/button-bg.png) repeat-x top left;border:0;color:#000;cursor:pointer;list-style:none;margin:2px;outline:none;padding:0;text-decoration:none;vertical-align:middle}.charts-menu-button-outer-box,.charts-menu-button-inner-box{border-style:solid;border-color:#aaa;vertical-align:top}.charts-menu-button-outer-box{margin:0;border-width:1px 0;padding:0}.charts-menu-button-inner-box{margin:0 -1px;border-width:0 1px;padding:3px 4px}* html .charts-menu-button-inner-box{left:-1px}* html .charts-menu-button-rtl .charts-menu-button-outer-box{left:-1px;right:auto}* html .charts-menu-button-rtl .charts-menu-button-inner-box{right:auto}*:first-child+html .charts-menu-button-inner-box{left:-1px}*:first-child+html .charts-menu-button-rtl .charts-menu-button-inner-box{left:1px;right:auto}::root .charts-menu-button{line-height:0}::root .charts-menu-button-outer-box{line-height:0}::root .charts-menu-button-inner-box{line-height:0}::root .charts-menu-button-caption{line-height:normal}::root .charts-menu-button-dropdown{line-height:normal}.charts-menu-button-disabled{background-image:none!important;opacity:.3;-moz-opacity:.3;filter:alpha(opacity=30)}.charts-menu-button-disabled .charts-menu-button-outer-box,.charts-menu-button-disabled .charts-menu-button-inner-box,.charts-menu-button-disabled .charts-menu-button-caption,.charts-menu-button-disabled .charts-menu-button-dropdown{color:#333!important;border-color:#999!important}* html .charts-menu-button-disabled,*:first-child+html .charts-menu-button-disabled{margin:2px 1px!important;padding:0 1px!important}.charts-menu-button-hover .charts-menu-button-outer-box,.charts-menu-button-hover .charts-menu-button-inner-box{border-color:#9cf #69e #69e #7af!important}.charts-menu-button-active,.charts-menu-button-open{background-color:#bbb;background-position:bottom left}.charts-menu-button-focused .charts-menu-button-outer-box,.charts-menu-button-focused .charts-menu-button-inner-box{border-color:orange}.charts-menu-button-caption{padding:0 4px 0 0;vertical-align:top}.charts-menu-button-dropdown{height:15px;width:7px;background:url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -388px 0;vertical-align:top}.charts-menu-button-collapse-right,.charts-menu-button-collapse-right .charts-menu-button-outer-box,.charts-menu-button-collapse-right .charts-menu-button-inner-box{margin-right:0}.charts-menu-button-collapse-left,.charts-menu-button-collapse-left .charts-menu-button-outer-box{margin-left:0}.charts-menu-button-collapse-left .charts-menu-button-inner-box{margin-left:0;border-left:1px solid #fff}.charts-menu-button-collapse-left.charts-menu-button-checked .charts-menu-button-inner-box{border-left:1px solid #ddd}.charts-menuitem{color:#000;font:normal 13px Arial,sans-serif;list-style:none;margin:0;padding:4px 7em 4px 28px;white-space:nowrap}.charts-menuitem.charts-menuitem-rtl{padding-left:7em;padding-right:28px}.charts-menu-nocheckbox .charts-menuitem,.charts-menu-noicon .charts-menuitem{padding-left:12px}.charts-menu-noaccel .charts-menuitem{padding-right:20px}.charts-menuitem-content{color:#000;font:normal 13px Arial,sans-serif}.charts-menuitem-disabled .charts-menuitem-accel,.charts-menuitem-disabled .charts-menuitem-content{color:#ccc!important}.charts-menuitem-disabled .charts-menuitem-icon{opacity:.3;-moz-opacity:.3;filter:alpha(opacity=30)}.charts-menuitem-highlight,.charts-menuitem-hover{background-color:#d6e9f8;border-color:#d6e9f8;border-style:dotted;border-width:1px 0;padding-bottom:3px;padding-top:3px}.charts-menuitem-checkbox,.charts-menuitem-icon{background-repeat:no-repeat;height:16px;left:6px;position:absolute;right:auto;vertical-align:middle;width:16px}.charts-menuitem-rtl .charts-menuitem-checkbox,.charts-menuitem-rtl .charts-menuitem-icon{left:auto;right:6px}.charts-option-selected .charts-menuitem-checkbox,.charts-option-selected .charts-menuitem-icon{background:url(//ssl.gstatic.com/editor/editortoolbar.png) no-repeat -512px 0}.charts-menuitem-accel{color:#999;direction:ltr;left:auto;padding:0 6px;position:absolute;right:0;text-align:right}.charts-menuitem-rtl .charts-menuitem-accel{left:0;right:auto;text-align:left}.charts-menuitem-mnemonic-hint{text-decoration:underline}.charts-menuitem-mnemonic-separator{color:#999;font-size:12px;padding-left:4px}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment