Commit cce8baed authored by Romain Loth's avatar Romain Loth

Merge branch 'unstable' into romain-refactoring

parents eee27166 6c438c85
......@@ -69,7 +69,6 @@ INDEXED_HYPERDATA = {
, 'convert_from_db': str
},
'authors':
{ 'id' : 4
, 'type' : str
......
......@@ -8,6 +8,7 @@ from re import sub
def parse(corpus):
try:
documents_count = 0
corpus.status('Docs', progress=0)
# will gather info about languages
......
This diff is collapsed.
......@@ -15,9 +15,11 @@ import csv
_node_available_fields = ['id', 'parent_id', 'name', 'typename', 'hyperdata', 'ngrams']
_node_default_fields = ['id', 'parent_id', 'name', 'typename']
_node_available_formats = ['json', 'csv', 'bibex']
_node_available_types = NODETYPES
#_hyperdata_available_fields = ['title', 'resourcetype']
#_node_available_formats = ['json', 'csv', 'bibex']
def _query_nodes(request, node_id=None):
user = cache.User[request.user.id]
......@@ -25,6 +27,9 @@ def _query_nodes(request, node_id=None):
parameters = get_parameters(request)
parameters = validate(parameters, {'type': dict, 'items': {
'formated': {'type': str, 'required' : False, 'default': 'json'},
# 'hyperdata': {'type': list, 'default' : _hyperdata_available_fields, 'items': {
# 'type': str, 'range' : _node_available_fields,
# }},
'pagination_limit': {'type': int, 'default': 10},
'pagination_offset': {'type': int, 'default': 0},
'fields': {'type': list, 'default': _node_default_fields, 'items': {
......@@ -75,7 +80,7 @@ class NodeListResource(APIView):
'parameters': parameters,
'count': count,
'records': [
{field: getattr(node, field) for field in parameters['fields']}
{ field: getattr(node, field) for field in parameters['fields'] }
for node in query
]
})
......
......@@ -2,28 +2,34 @@ from django.conf.urls import url
from . import nodes
from . import ngramlists
from . import analytics
urlpatterns = [ url(r'^nodes$' , nodes.NodeListResource.as_view())
, url(r'^nodes/(\d+)$' , nodes.NodeResource.as_view() )
, url(r'^nodes/(\d+)/having$' , nodes.NodeListHaving.as_view() )
urlpatterns = [ url(r'^nodes$' , nodes.NodeListResource.as_view() )
, url(r'^nodes/(\d+)$' , nodes.NodeResource.as_view() )
, url(r'^nodes/(\d+)/having$' , nodes.NodeListHaving.as_view() )
# Analytics
, url(r'^nodes/(\d+)/histories$', analytics.NodeNgramsQueries.as_view())
, url(r'^ngrams/$' , analytics.ApiNgrams.as_view() )
, url(r'hyperdata$' , analytics.ApiHyperdata.as_view() )
# get a list of ngram_ids or ngram_infos by list_id
# url(r'^ngramlists/(\d+)$', ngramlists.List.as_view()),
, url(r'^nodes/(\d+)/facets$' , nodes.CorpusFacet.as_view() )
, url(r'^nodes/(\d+)/favorites$', nodes.CorpusFavorites.as_view() )
, url(r'^nodes/(\d+)/facets$' , nodes.CorpusFacet.as_view() )
, url(r'^nodes/(\d+)/favorites$', nodes.CorpusFavorites.as_view() )
# in these two routes the node is supposed to be a *corpus* node
, url(r'^ngramlists/change$', ngramlists.ListChange.as_view() )
, url(r'^ngramlists/change$', ngramlists.ListChange.as_view() )
# add or remove ngram from a list
# ex: add <=> PUT ngramlists/change?list=42&ngrams=1,2
# rm <=> DEL ngramlists/change?list=42&ngrams=1,2
, url(r'^ngramlists/groups$', ngramlists.GroupChange.as_view())
, url(r'^ngramlists/groups$', ngramlists.GroupChange.as_view() )
# modify grouping couples of a group node
# ex: POST ngramlists/groups?node=43
# post data looks like : {"767":[209,640],"779":[436,265,385]}"
, url(r'^ngramlists/family$' , ngramlists.ListFamily.as_view())
, url(r'^ngramlists/family$' , ngramlists.ListFamily.as_view() )
# entire combination of lists from a corpus, dedicated to termtable
# (or any combination of lists that go together :
# - a mainlist
......@@ -31,6 +37,6 @@ urlpatterns = [ url(r'^nodes$' , nodes.NodeListResource.as_view()
# - an optional maplist
# - an optional grouplist
, url(r'^ngramlists/maplist$' , ngramlists.MapListGlance.as_view())
, url(r'^ngramlists/maplist$' , ngramlists.MapListGlance.as_view() )
# fast access to maplist, similarly formatted for termtable
]
......@@ -43,12 +43,6 @@ def docs_by_titles(request, project_id, corpus_id):
},
)
@requires_auth
def chart(request, project_id, corpus_id):
authorized, user, project, corpus = _get_user_project_corpus(request, project_id, corpus_id)
@requires_auth
def docs_by_journals(request, project_id, corpus_id):
'''
......@@ -76,3 +70,25 @@ def docs_by_journals(request, project_id, corpus_id):
},
)
@requires_auth
def analytics(request, project_id, corpus_id):
authorized, user, project, corpus = _get_user_project_corpus(request, project_id, corpus_id)
if not authorized:
return HttpResponseForbidden()
# response!
return render(
template_name = 'pages/analytics/histories.html',
request = request,
context = {
'debug': DEBUG,
'date': datetime.now(),
'project': project,
'corpus': corpus,
'resourcename' : resourcename(corpus),
'view': 'analytics',
'user': request.user
},
)
......@@ -22,12 +22,13 @@ urlpatterns = [
# corpora
url(r'^projects/(\d+)/corpora/(\d+)/?$', corpora.docs_by_titles),
url(r'^projects/(\d+)/corpora/(\d+)/chart/?$', corpora.chart),
# corpus by journals
url(r'^projects/(\d+)/corpora/(\d+)/journals/?$', corpora.docs_by_journals),
# terms table for the corpus
url(r'^projects/(\d+)/corpora/(\d+)/terms/?$', terms.ngramtable),
# Analytics
url(r'^projects/(\d+)/corpora/(\d+)/analytics/?$', corpora.analytics),
]
......@@ -5,128 +5,99 @@ from gargantext.util.db import session, aliased, bulk_insert, func
from gargantext.util.lists import WeightedMatrix, UnweightedList, Translations
from gargantext.util.http import JsonHttpResponse
from sqlalchemy import desc, asc, or_, and_
from sqlalchemy import desc, asc, or_, and_, func
import datetime
import ast
import networkx as nx
def doc_freq(corpus_id, node_ids):
'''
doc_freq :: Corpus_id -> [(Ngram_id, Int)]
Given a corpus, compute number of documents that have the ngram in it.
'''
return ( session.query(NodeNgram.ngram_id, func.count(NodeNgram.node_id))
.join(Node, NodeNgram.node_id == Node.id)
.filter( Node.parent_id == corpus_id
, Node.typename== 'DOCUMENT')
.filter( NodeNgram.weight > 0
, NodeNgram.ngram_id.in_(node_ids) )
.group_by(NodeNgram.ngram_id)
.all()
)
def doc_ngram_representativity(corpus_id, node_ids):
'''
doc_ngram_representativity :: Corpus_ID -> Dict Ngram_id Float
Given a corpus, compute part of of documents that have the ngram it it.
'''
nodes_count = ( session.query(Node)
.filter( Node.parent_id == corpus_id
, Node.typename == 'DOCUMENT'
)
.count()
)
result = dict()
for ngram_id, somme in doc_freq(corpus_id, node_ids):
result[ngram_id] = somme / nodes_count
return result
def compare_corpora(Corpus_id_A, Corpus_id_B, node_ids):
'''
compare_corpora :: Corpus_id -> Corpus_id -> Dict Ngram_id Float
Given two corpus :
- if corpora are the same, it return :
(dict of document frequency per ngram as key)
- if corpora are different, it returns :
doc_ngram_representativit(Corpus_id_A) / doc_ngram_representativity(Corpus_id_B)
(as dict per ngram as key)
'''
result = dict()
if int(Corpus_id_A) == int(Corpus_id_B):
for ngram_id, somme in doc_freq(Corpus_id_A, node_ids):
result[ngram_id] = somme
else:
data_A = doc_ngram_representativity(Corpus_id_A, node_ids)
data_B = doc_ngram_representativity(Corpus_id_B, node_ids)
queue = list()
for k in data_A.keys():
if k not in data_B.keys():
queue.append(k)
else:
result[k] = data_B[k] / data_A[k]
maximum = max([ result[k] for k in result.keys()])
minimum = min([ result[k] for k in result.keys()])
for k in queue:
result[k] = minimum
return result
def intersection(request , corpuses_ids, measure='cooc'):
FinalDict = False
'''
intersection :: (str(Int) + "a" str(Int)) -> Dict(Ngram.id :: Int, Score :: Int)
intersection = returns as Json Http Response the intersection of two graphs
'''
if request.method == 'POST' and "nodeids" in request.POST and len(request.POST["nodeids"])>0 :
import ast
import networkx as nx
node_ids = [int(i) for i in (ast.literal_eval( request.POST["nodeids"] )) ]
# Here are the visible nodes of the initial semantic map.
corpuses_ids = corpuses_ids.split('a')
corpuses_ids = [int(i) for i in corpuses_ids]
print(corpuses_ids)
# corpus[1] will be the corpus to compare
def get_score(corpus_id):
cooc_ids = (session.query(Node.id)
.filter(Node.user_id == request.user.id
, Node.parent_id==corpus_id
, Node.typename == 'COOCCURRENCES' )
.first()
)
if len(cooc_ids)==0:
return JsonHttpResponse(FinalDict)
# If corpus[1] has a coocurrence.id then lets continue
Coocs = {}
G = nx.Graph()
# undirected graph only
# because direction doesnt matter here
# coocs is triangular matrix
ngrams_data = ( session.query(NodeNgramNgram)
.filter( NodeNgramNgram.node_id==cooc_ids[0]
, or_( NodeNgramNgram.ngram1_id.in_( node_ids )
, NodeNgramNgram.ngram2_id.in_( node_ids )
)
)
.group_by(NodeNgramNgram)
.all()
)
for ngram in ngrams_data :
# are there visible nodes in the X-axis of corpus to compare ?
G.add_edge( ngram.ngram1_id , ngram.ngram2_id , weight=ngram.weight)
print(corpus_id, ngram)
for e in G.edges_iter() :
n1 = e[0]
n2 = e[1]
# print( G[n1][n2]["weight"] , "\t", n1,",",n2 )
if n1 not in Coocs :
Coocs[n1] = 0
if n2 not in Coocs :
Coocs[n2] = 0
Coocs[n1] += G[n1][n2]["weight"]
Coocs[n2] += G[n1][n2]["weight"]
return(Coocs,G)
Coocs_0,G_0 = get_score( corpuses_ids[0] )
Coocs_1,G_1 = get_score( corpuses_ids[1] )
FinalDict = {}
if measure == 'jacquard':
for node in node_ids :
if node in G_1.nodes() and node in G_0.nodes():
neighbors_0 = set(G_0.neighbors(node))
neighbors_1 = set(G_1.neighbors(node))
jacquard = len(neighbors_0.intersection(neighbors_1)) / len(neighbors_0.union(neighbors_1))
FinalDict[node] = jacquard * 3
elif node in G_0.nodes() and node not in G_1.nodes() :
FinalDict[node] = 2
elif node not in G_0.nodes() and node in G_1.nodes() :
FinalDict[node] = 1
else:
FinalDict[node] = 0
elif measure == 'degree':
for node in node_ids :
if node in G_1.nodes() and node in G_0.nodes():
score_0 = Coocs_0[node] / G_0.degree(node)
score_1 = Coocs_1[node] / G_1.degree(node)
FinalDict[node] = 5 * score_0 / score_1
elif node in G_0.nodes() and node not in G_1.nodes() :
FinalDict[node] = 0.5
elif node not in G_0.nodes() and node in G_1.nodes() :
FinalDict[node] = 0.2
else:
FinalDict[node] = 0
elif measure == 'cooc':
for node in node_ids :
if node in G_1.nodes() and node in G_0.nodes():
#FinalDict[node] = Coocs_1[node] / Coocs_0[node]
FinalDict[node] = Coocs_0[node] / Coocs_1[node]
elif node in G_0.nodes() and node not in G_1.nodes() :
FinalDict[node] = 0.0
elif node not in G_0.nodes() and node in G_1.nodes() :
FinalDict[node] = 0.0
else:
FinalDict[node] = 0
print(FinalDict)
#print(node,score)
# Getting AVG-COOC of each ngram that exists in the cooc-matrix of the compared-corpus.
return JsonHttpResponse(FinalDict)
return JsonHttpResponse(compare_corpora(corpuses_ids[0], corpuses_ids[1], node_ids))
......@@ -82,8 +82,7 @@ def create_user(username, email, user=None, password=None, active=False, notify=
session.commit()
if notify == True:
pass
#notify_user(username, email, password)
notify_user(username, email, password)
return user
......
......@@ -22,7 +22,7 @@
-- create INDEX on nodes (user_id, typename, parent_id) ;
-- create INDEX on nodes_hyperdata (node_id, key);
-- create INDEX on ngrams (id, n) ;
create INDEX on ngrams (n) ;
-- create INDEX on ngrams (n) ;
-- create INDEX on nodes_ngrams (node_id, ngram_id) ;
-- create INDEX on nodes_ngrams (node_id) ;
-- create INDEX on nodes_ngrams (ngram_id) ;
......@@ -42,6 +42,14 @@ create INDEX on ngrams (n) ;
-- Maybe needed soon:
-- create INDEX on nodes_nodes_ngrams (node1_id, node2_id);
----------------------------------------------------------------------
-- Analytics
-- create INDEX on nodes_hyperdata (node_id,value_utc); -- remove ?
-- create INDEX on nodes_hyperdata (node_id,key,value_utc);
-- create INDEX on nodes_hyperdata (node_id,key,value_int);
-- create INDEX on nodes_hyperdata (node_id,key,value_flt);
-- create INDEX on nodes_hyperdata (node_id,key,value_str);
----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------
This diff is collapsed.
This diff is collapsed.
from django.conf.urls import patterns, url
from gargantext_web import views_optimized
from rest_v1_0 import api, ngrams, graph
from annotations import views
import tests.ngramstable.views as samtest
urlpatterns = patterns('',
# REST URLS
# What is REST ?
# https://en.wikipedia.org/wiki/Representational_state_transfer
#url(r'^api$', rest_v1_0.api.Root), # = ?
url(r'nodes$', api.NodesList.as_view()),
url(r'nodes/(\d+)$', api.Nodes.as_view()),
url(r'nodes/(\d+)/children/ngrams$', api.NodesChildrenNgrams.as_view()), # => repeated children ?
url(r'nodes/(\d+)/children/ids$', api.NodesChildrenNgramsIds.as_view()), # => repeated children ?
# NGRAMS table & annotations
url(r'node/(\d+)/ngrams$' , ngrams.Ngrams.as_view()),
url(r'node/(\d+)/ngrams/group$', ngrams.Group.as_view()),
url(r'node/(\d+)/ngrams/keep$', ngrams.Keep.as_view()),
# url(r'node/(?P<list_id>[0-9]+)/ngrams/keep/(?P<ngram_ids>[0-9,\+]+)+$' , ngrams.Keep.as_view()),
url(r'node/(?P<list_id>[0-9]+)/ngrams/(?P<ngram_ids>[0-9,\+]+)+$', views.NgramEdit.as_view()),
url(r'node/(?P<corpus_id>[0-9]+)/ngrams/list/(?P<list_name>\w+)$' , ngrams.List.as_view()),
url(r'node/corpus/(?P<node_ids>[0-9,\+]+)+$' , samtest.get_corpuses),
#url(r'nodes/(\d+)/children/hyperdata$', api.NodesChildrenMetatadata.as_view()),
#url(r'nodes/(\d+)/children/hyperdata$', api.NodesChildrenMetatadata.as_view()),
url(r'nodes/(\d+)/children/queries$', api.NodesChildrenQueries.as_view()),
url(r'nodes/(\d+)/children/duplicates$', api.NodesChildrenDuplicates.as_view()),
# url(r'^api/nodes/(\d+)/children/duplicates/delete$', api.NodesChildrenDuplicates.delete ),
url(r'nodes/(\d+)/ngrams$', api.CorpusController.ngrams),
url(r'nodes/(\d+)/graph$', graph.Graph.as_view()),
url(r'corpus/(\d+)/graph$', graph.Graph.as_view()),
url(r'hyperdata$', api.ApiHyperdata.as_view()),
url(r'ngrams$', api.ApiNgrams.as_view()),
url(r'tfidf/(\d+)/(\w+)$', views_optimized.tfidf),
)
This source diff could not be displayed because it is too large. You can view the blob instead.
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.
......@@ -815,6 +815,7 @@ function GetUserPortfolio() {
return true;
var query_url = window.location.origin+'/api/nodes?types[]=PROJECT&types[]=CORPUS&pagination_limit=100'
// var query_url = window.location.origin+'/api/nodes?types[]=PROJECT&types[]=CORPUS&pagination_limit=100&fields[]=hyperdata'
$.ajax({
type: 'GET',
dataType : 'JSON',
......
:after,:before,tags-input *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}tags-input .host{position:relative;margin-top:5px;margin-bottom:5px}tags-input .host:active{outline:0}tags-input .tags{-moz-appearance:textfield;-webkit-appearance:textfield;padding:1px;overflow:hidden;word-wrap:break-word;cursor:text;background-color:#fff;border:1px solid #a9a9a9;box-shadow:1px 1px 1px 0 #d3d3d3 inset}tags-input .tags.focused{outline:0;-webkit-box-shadow:0 0 3px 1px rgba(5,139,242,.6);-moz-box-shadow:0 0 3px 1px rgba(5,139,242,.6);box-shadow:0 0 3px 1px rgba(5,139,242,.6)}tags-input .tags .tag-list{margin:0;padding:0;list-style-type:none}tags-input .tags .tag-item{margin:2px;padding:0 5px;display:inline-block;float:left;font:14px "Helvetica Neue",Helvetica,Arial,sans-serif;height:26px;line-height:25px;border:1px solid #acacac;border-radius:3px;background:-webkit-linear-gradient(top,#f0f9ff 0,#cbebff 47%,#a1dbff 100%);background:linear-gradient(to bottom,#f0f9ff 0,#cbebff 47%,#a1dbff 100%)}tags-input .tags .tag-item.selected{background:-webkit-linear-gradient(top,#febbbb 0,#fe9090 45%,#ff5c5c 100%);background:linear-gradient(to bottom,#febbbb 0,#fe9090 45%,#ff5c5c 100%)}tags-input .tags .tag-item .remove-button{margin:0 0 0 5px;padding:0;border:none;background:0 0;cursor:pointer;vertical-align:middle;font:700 16px Arial,sans-serif;color:#585858}tags-input .tags .tag-item .remove-button:active{color:red}tags-input .tags .input{border:0;outline:0;margin:2px;padding:0;padding-left:5px;float:left;height:26px;font:14px "Helvetica Neue",Helvetica,Arial,sans-serif}tags-input .tags .input.invalid-tag{color:red}tags-input .tags .input::-ms-clear{display:none}tags-input.ng-invalid .tags{-webkit-box-shadow:0 0 3px 1px rgba(255,0,0,.6);-moz-box-shadow:0 0 3px 1px rgba(255,0,0,.6);box-shadow:0 0 3px 1px rgba(255,0,0,.6)}tags-input .autocomplete{margin-top:5px;position:absolute;padding:5px 0;z-index:999;width:100%;background-color:#fff;border:1px solid rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}tags-input .autocomplete .suggestion-list{margin:0;padding:0;list-style-type:none}tags-input .autocomplete .suggestion-item{padding:5px 10px;cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font:16px "Helvetica Neue",Helvetica,Arial,sans-serif;color:#000;background-color:#fff}tags-input .autocomplete .suggestion-item.selected,tags-input .autocomplete .suggestion-item.selected em{color:#fff;background-color:#0097cf}tags-input .autocomplete .suggestion-item em{font:normal bold 16px "Helvetica Neue",Helvetica,Arial,sans-serif;color:#000;background-color:#fff}
\ No newline at end of file
This diff is collapsed.
{% extends "pages/menu.html" %}
{% block content %}
{% load staticfiles %}
<div class="container">
<h3>
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
Small tutorial here and links toward documentation.
</h3>
</div>
<!-- All the templates used by the Javascript framework -->
{% verbatim %}
{% endverbatim %}
<script type="text/javascript" src="{% static "lib/jquery/2.2.0/jquery.min.js" %}"></script>
{% verbatim %}
<style type="text/css">
div.controller div.autocomplete {margin: 0; padding: 0; }
div.controller div.autocomplete * {background: transparent; }
div.controller div.autocomplete ul.suggestion-list {background: rgba(255,255,255,.75); }
div.controller .tags li.tag-item {background: transparent; border: solid 1px rgba(0,0,0,.1); box-shadow: inset .05em .1em .4em rgba(0,0,0,.4); border-radius: 0; font-weight: bold; }
div.controller div.autocomplete li.suggestion-item:hover, div.controller div.autocomplete li.suggestion-item.selected {background: rgba(0,0,0,.5)}
div.controller div.autocomplete li.suggestion-item em {background: transparent; }
div.controller div.tags>input {padding: 0; border: 0; outline: 0; box-shadow: none; background: transparent;}
div.controller div.tags>input::-webkit-input-placeholder,div.controller div.tags input::-webkit-input-placeholder {color: rgba(0,0,0,.25); }
div.controller, div.controller * {color: rgba(0,0,0,.75); }
div.controller button {background: none; border: solid 1px rgba(0,0,0,.25); box-shadow: .05em .1em .4em rgba(0,0,0,.5); opacity: .5; }
div.controller button:hover {opacity: .65; }
div.controller button:active {opacity: .8; }
div.controller>button {width: 100%; }
div.controller input[type=checkbox] {position: relative; top: .125em; }
div.controller input[type=text], div.controller select, div.controller div.tags {font-weight: bold; box-shadow: inset .05em .1em .4em rgba(0,0,0,.2); outline: solid 1px rgba(0,0,0,.125); border: 0; background: rgba(255,255,255,.5); }
div.controller input[type=text] {padding-left: 0.5em;}
ul.datasets {padding: 0; margin: 0; list-style: none; }
li.dataset {padding: 0.3em; border: solid 1px rgba(0,0,0,.125); margin-bottom: 0.5em; box-shadow: inset .1em .2em .8em rgba(0,0,0,.1) }
li.dataset * { }
li.dataset button {float: right; position: relative; top: -.15em; margin-left: .25em; }
li.dataset select {cursor: pointer; border: 0; padding: 0; }
ul.filters {list-style: none; margin: 0; padding: 0; margin-top: .25em;}
ul.filters>li {padding-top: .5em; margin-top: .5em; border-top: solid 1px rgba(0,0,0,.125);}
ul.filters>li>ul {list-style: none; padding-left: 0; margin-top: .5em; }
ul.filters>li>ul>li.inline {width: 30%; display: inline-block; }
ul.filters>li>ul>li>label {font-weight: normal; cursor: pointer; }
ul.filters>li input[type=checkbox] {opacity: .8;}
</style>
<div class="container">
<div ng-app="Gargantext" ng-controller="GraphController" class="controller">
<ul class="datasets">
<li class="dataset" ng-controller="DatasetController" ng-repeat="dataset in datasets" style="background-color:{{ getColor($index, datasets.length) }}">
<!-- main part -->
<div class="main">
<!-- buttons -->
<button ng-click="show_filters = !show_filters">{{ show_filters ? 'Hide' : 'Show' }} filters</button>
<button ng-click="removeDataset($index)">Remove dataset</button>
<!-- description of Y values -->
Evolution of the
<select ng-model="query_y.value" ng-options="value as key for (key, value) in {'documents count': 'documents_count', 'expressions count': 'ngrams_count'}" ng-change="updateDataset()"></select>
<select ng-model="query_y.is_relative" ng-options="value as key for (key, value) in {'in absolute terms': false, 'relative to the': true}" ng-change="updateDataset()"></select>
<span ng-if="query_y.is_relative">
<select ng-model="query_y.divided_by" ng-options="value as key for (key, value) in {'total expressions count': 'total_ngrams_count', 'total documents count': 'total_documents_count'}" ng-change="updateDataset()"></select>
</span>
</div>
<!-- filters -->
<ul class="filters" ng-show="show_filters">
<!-- filter corpora -->
<li>
<button ng-click="corporaSelectAll()">select all</button>
<button ng-click="corporaSelectNone()">select none</button>
...restrict to the following corpora:
<ul>
<li ng-repeat="corpus in corpora" class="inline">
<label>
<input type="checkbox" ng-model="corpus.is_selected" ng-change="updateHyperdataList();updateDataset()"/>
<span style="font-weight: {{ corpus.is_selected ? 'bold' : 'normal' }}">{{ corpus.name }}</span>
</label>
</li>
</ul>
</li>
<!-- filter ngrams -->
<li class="ngrams">
...only consider documents containing the following expressions:
<tags-input ng-model="query_y.ngrams" display-property="terms" placeholder="Add an expression" on-tag-added="updateDataset()" on-tag-removed="updateDataset()" add-from-autocomplete-only="true">
<auto-complete source="getNgrams($query)"></auto-complete>
</tags-input ng-model="tags">
</li>
<!-- filter hyperdata -->
<li>
<ul>
<li ng-repeat="hyperdata in hyperdataList">
...where
<span ng-if="!hyperdata.operator &amp;&amp; (!hyperdata.values || !hyperdata.value)">"{{ hyperdata.name }}"</span>
<strong ng-if="hyperdata.operator || (hyperdata.values &amp;&amp; hyperdata.value)">{{ hyperdata.name }}</strong>
<span ng-if="hyperdata.values">
is
<select ng-model="hyperdata.value" ng-options="value for value in hyperdata.values" ng-change="updateDataset()"></select>
</span>
<span ng-if="!hyperdata.values">
<select ng-model="hyperdata.operator" ng-options="operator.key as operator.label for operator in operators[hyperdata.type]"></select>
<input type="text" ng-if="hyperdata.operator" ng-model="hyperdata.value" ng-change="updateDataset()" placeholder="type a value here..." />
</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<!-- add a new dataset -->
<button ng-click="addDataset()">Add a dataset</button>
<!-- X-axis (time) resolution -->
<p>
(group results by
<select ng-model="query_x.resolution" ng-options="period as period for period in periods" ng-change="updateDatasets(true)"></select>)
</p>
<!-- data representation -->
Represent data with
<select ng-model="seriesOptions.type" ng-options="type for type in ['column', 'area', 'line']" ng-change="updateDatasets()"></select>
<span ng-show="seriesOptions.type == 'area' || seriesOptions.type == 'column'">
(<select ng-model="options.stacking" ng-options="value as key for (key, value) in {'with':true, 'without':false}" ng-change="updateDatasets()"></select> stacking)
</span>
<div class="graph">
<linechart data="graph.data" options="graph.options"></linechart>
</div>
</div>
{% endverbatim %}
<script type="text/javascript" src="{% static "lib/angular/1.2.26/angular.min.js" %}"></script>
<script type="text/javascript" src="{% static "lib/angular-cookies/1.2.29/angular-cookies.min.js" %}"></script>
<!-- <script type="text/javascript" src="{% static "lib/d3/d3/d3.v2.min.js" %}"></script> -->
<script type="text/javascript" src="{% static "lib/d3/n3.line-chart.min.js" %}"></script>
<script type="text/javascript" src="{% static "lib/ng-tags//ng-tags-input.min.js" %}"></script>
<link rel="stylesheet" href="{% static "lib/ng-tags/ng-tags-input.min.css" %}">
<script type="text/javascript" src="{% static "lib/gargantext/gargantext.angular.js" %}"></script>
{% endblock %}
......@@ -111,7 +111,7 @@
</a>
<i class="caret"></i>
<ul class="dropdown-menu">
{% if view != "graph" %}
{% if view == "titles" %}
<li>
<a tabindex="-1"
data-url="/projects/{{project.id}}/corpora/{{ corpus.id }}/explorer?field1=ngrams&amp;field2=ngrams&amp;distance=conditional&amp;bridgeness=5" onclick='gotoexplorer(this)' >With conditional distance </a>
......@@ -133,10 +133,21 @@
{% endif %}
</ul>
</li>
<li>
<a type="button" class="btn btn-default {% if view == 'analytics' %} active {% endif %}"
onclick="javascript:location.href='/projects/{{project.id}}/corpora/{{ corpus.id }}/analytics'"
data-target='#' href='#'>Analytics
</a>
</li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
......@@ -176,36 +187,14 @@
</div>
<div class="col-md-5">
<h3>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
Author(s):
</h3>
<h4>
<div class="row">
<span class="glyphicon glyphicon-hand-right" aria-hidden="true"></span>
{{ user.username | truncatechars:15}}
</div>
</h4>
</div>
<div class="col-md-1">
<div class="row"><br>
<a class="btn btn-default" role="button" href="/api/nodes?parent_id={{corpus.id}}&types[]=DOCUMENT&pagination_limit=100000&formated=csv">Download</a>
<!--<a class="btn btn-default" role="button" href="/project/{{project.id}}/corpus/{{corpus.id}}/{{view}}/update">Update</a>--!>
<!--
<a type="button" class="btn btn-default" data-container="body" data-toggle="popover" data-placement="bottom"
data-content='
<ul>
<li> Rename </li>
<li> Add new documents </li>
<li><a href="/delete/{{corpus.id}}">Delete</a></li>
</ul>
'>Manage</a>
<a class="btn btn-primary btn-lg" role="button" href="/admin/documents/corpus/{{ corpus.id }}/">Add documents</a></p>
--!>
</div>
<h3>
<span class="glyphicon glyphicon-calendar" aria-hidden="true"></span> {{ corpus.date }}
</h3>
<h3>
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
Author(s): {{ user.username | truncatechars:15}}
</h3>
</div>
</div>
</div>
......
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