mirror of
https://github.com/lucaspalomodevelop/indico-plugins.git
synced 2026-03-14 16:04:36 +00:00
Register css/js bundles and add static files
This commit is contained in:
parent
9170fc2989
commit
da34111815
@ -27,6 +27,10 @@ class StatisticsPlugin(IndicoPlugin):
|
||||
def get_blueprints(self):
|
||||
return blueprint
|
||||
|
||||
def register_assets(self):
|
||||
self.register_css_bundle('statistics_css', 'css/statistics.css')
|
||||
self.register_js_bundle('statistics_js', 'js/statistics.js')
|
||||
|
||||
|
||||
blueprint = IndicoPluginBlueprint('statistics', __name__)
|
||||
blueprint.add_url_rule('/event/<confId>/manage/statistics_new', 'view', RHStatisticsView)
|
||||
|
||||
167
piwik/indico_statistics/static/css/statistics.css
Normal file
167
piwik/indico_statistics/static/css/statistics.css
Normal file
@ -0,0 +1,167 @@
|
||||
div.test {
|
||||
background: red;
|
||||
}
|
||||
|
||||
div#statsHeader {
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
padding-bottom: 10px;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
div#statsWidgetsWrapper {
|
||||
width: 740px;
|
||||
height: auto;
|
||||
padding: 10px 0px 10px 0px;
|
||||
}
|
||||
|
||||
div.statsInfo {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
div#statsInfoHidden {
|
||||
padding-top: 5px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div#statsFilter {
|
||||
clear: both;
|
||||
padding-top: 5px;
|
||||
display: none;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
div.statsTopBordered {
|
||||
border-top: 1px solid #EFEFEF;
|
||||
padding-top: 5px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.statsRow {
|
||||
width: 100%;
|
||||
display: block;
|
||||
height: 320px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.statsWidget {
|
||||
display: block;
|
||||
border-left: 1px solid #EFEFEF;
|
||||
padding: 0px 5px 0px 5px;
|
||||
margin: 0px 16px 15px 0px;
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.statsFilterOption {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
div.statsWidget iframe {
|
||||
width: 100%;
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
div.statsWidget.full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.statsWidget.edge {
|
||||
margin-right: 0px !important;
|
||||
}
|
||||
|
||||
div.statsWidget.large {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
div.statsWidget.medium {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
div.statsWidget.small {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
div.statsWidgetTitle {
|
||||
background: #EFEFEF;
|
||||
font-weight: bold;
|
||||
padding: 5px;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
div.statsWidgetContent {
|
||||
width: auto;
|
||||
height: 100%;
|
||||
padding: 5px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
div.statsTableDivider {
|
||||
padding: 10px 0px 5px 0px;
|
||||
margin-bottom: 5px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #DDDDEF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div#statsGenerated {
|
||||
font-style: italic;
|
||||
font-size: 0.8em;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
div#materialTree {
|
||||
display: block;
|
||||
width: 190px;
|
||||
height: 80%;
|
||||
overflow: auto;
|
||||
float: left;
|
||||
padding: 15px 10px 10px 10px;
|
||||
}
|
||||
|
||||
div#materialContainer {
|
||||
display: block;
|
||||
width: 510px;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
height: 90%;
|
||||
}
|
||||
|
||||
/* jqTree Formatting */
|
||||
|
||||
div#materialTree ul {
|
||||
margin: 0px;
|
||||
padding: 0 0 0px 10px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
div#marginTree ul ul {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
span.selectableNode {
|
||||
color: #0B63A5 !important;
|
||||
font-size: 0.9em;
|
||||
display: block;
|
||||
width: auto;
|
||||
border-bottom: 1px solid #EFEFEF;
|
||||
}
|
||||
|
||||
ul.tree .title {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
/* jqPlot Formatting */
|
||||
|
||||
div#materialDownloadChart {
|
||||
width: auto;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
div#visitorChart {
|
||||
margin-left: 15px;
|
||||
width: 95%;
|
||||
height: 270px;
|
||||
}
|
||||
314
piwik/indico_statistics/static/js/statistics.js
Normal file
314
piwik/indico_statistics/static/js/statistics.js
Normal file
@ -0,0 +1,314 @@
|
||||
$(function() {
|
||||
$('#statsModify').click(function() {
|
||||
var text = ($(this).html() == str_modif_query)
|
||||
? str_hide_query : str_modif_query;
|
||||
$(this).html(text);
|
||||
$('#statsFilter').slideToggle('fast');
|
||||
});
|
||||
|
||||
$('.statsDates').datepicker({
|
||||
dateFormat : 'yy-mm-dd',
|
||||
defaultDate : $(this).attr('data-default')
|
||||
});
|
||||
|
||||
var buildURI = function() {
|
||||
var params = {'confId' : $('#confId').val(),
|
||||
'startDate' : $('#statsFilterStartDate').val(),
|
||||
'endDate' : $('#statsFilterEndDate').val(),
|
||||
'tab' : 'Piwik'
|
||||
};
|
||||
|
||||
var updateContrib = $('#updateContribution').val();
|
||||
|
||||
if (updateContrib != 'None') {
|
||||
params['contribId'] = updateContrib;
|
||||
}
|
||||
|
||||
return $.param(params);
|
||||
};
|
||||
|
||||
/**
|
||||
* Reconstruct the query string based on local values and force relocation.
|
||||
*/
|
||||
$('#updateQuery').click(function() {
|
||||
var url = 'statistics?';
|
||||
url += buildURI();
|
||||
window.location.href = url;
|
||||
});
|
||||
|
||||
/**
|
||||
* Provides the 'info' tooltip handling for Visitor Hit Rates
|
||||
*/
|
||||
$('#visitsInfoHelp').qtip({
|
||||
content: $('#statsInfoHidden').html(),
|
||||
position: {
|
||||
my: 'top middle',
|
||||
at: 'bottom middle'
|
||||
},
|
||||
style: {
|
||||
classes: 'qtip-rounded qtip-shadow qtip-light'
|
||||
}
|
||||
});
|
||||
|
||||
/* jqPlot Specifics */
|
||||
|
||||
/**
|
||||
* This method extracts the data from the JSON returned via the API into
|
||||
* the array format which jqPlot requires. Specifying 'withDate' as true
|
||||
* makes each element of the array a key-pair value of date-hits for the
|
||||
* renderer jqPlot provides.
|
||||
*/
|
||||
var getArrayValues = function(data, key, withDate) {
|
||||
output = [];
|
||||
withDate = typeof withDate !== 'undefined' ? withDate : true;
|
||||
|
||||
for (var date in data) {
|
||||
hits = data[date];
|
||||
value = (withDate) ? [date, hits[key]] : hits[key];
|
||||
output.push(value);
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the DOM element for the graph and then initiates a jqPlot render
|
||||
* in the target area.
|
||||
*
|
||||
* @param source - JSON of dates: {total / unique} hits
|
||||
*/
|
||||
var drawGraph = function(source, DOMTarget, replot) {
|
||||
|
||||
// Clear the DOM target
|
||||
$('#' + DOMTarget).html('');
|
||||
|
||||
var plotOptions = {
|
||||
axes: {
|
||||
xaxis: {
|
||||
renderer:$.jqplot.DateAxisRenderer,
|
||||
min: reportDates.start,
|
||||
max: reportDates.end
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
numberTicks: 10
|
||||
}
|
||||
},
|
||||
cursor: {
|
||||
show: true,
|
||||
zoom: true,
|
||||
showTooltip: false
|
||||
},
|
||||
highlighter: {
|
||||
show: true,
|
||||
sizeAdjust: 5
|
||||
},
|
||||
legend: {
|
||||
show: true,
|
||||
location: 'nw'
|
||||
},
|
||||
grid: {
|
||||
background: '#FFFFFF',
|
||||
shadow: false
|
||||
},
|
||||
series: [{
|
||||
showMarker:false,
|
||||
lineWidth: 1,
|
||||
color: '#CCCCCC',
|
||||
label: $T('Total Hits')
|
||||
}, {
|
||||
showMarker:false,
|
||||
lineWidth: 1,
|
||||
color: '#0B63A5',
|
||||
label: $T('Unique Hits')
|
||||
}]
|
||||
};
|
||||
|
||||
// Create the plot here
|
||||
if (replot) {
|
||||
$.jqplot(DOMTarget, source, plotOptions).replot();
|
||||
} else {
|
||||
$.jqplot(DOMTarget, source, plotOptions);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Base values for API requests, to be extended as needed.
|
||||
*/
|
||||
var getIndicoBaseParams = function() {
|
||||
var indicoBaseParams = {
|
||||
startDate: $('#statsFilterStartDate').val(),
|
||||
endDate: $('#statsFilterEndDate').val(),
|
||||
confId: $('#confId').val()
|
||||
};
|
||||
|
||||
var contribId = $('#contribId').val();
|
||||
|
||||
// We only want to append if it's not the internal 'None' flag.
|
||||
if (contribId != 'None') {
|
||||
indicoBaseParams['contribId'] = contribId;
|
||||
}
|
||||
|
||||
return indicoBaseParams;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads hit rate data via AJAX to propagate the main Visitors Graph.
|
||||
*/
|
||||
var loadVisitorsGraph = function(data) {
|
||||
var DOMTarget = 'visitorChart';
|
||||
$('#' + DOMTarget).html(progressIndicator(true, true).dom);
|
||||
|
||||
indicoRequest('piwik.getEventVisits', getIndicoBaseParams(),
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
var source = [getArrayValues(result, 'total_hits'),
|
||||
getArrayValues(result, 'unique_hits')]
|
||||
|
||||
drawGraph(source, DOMTarget, false);
|
||||
} else {
|
||||
$('#' + DOMTarget).html($T('No data found.'));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads material data via AJAX to propagate Material Graph(s)
|
||||
*/
|
||||
var loadMaterialGraph = function(uri, replot) {
|
||||
replot = typeof replot !== 'undefined' ? replot : false;
|
||||
var DOMTarget = 'materialDownloadChart';
|
||||
var graphParams = getIndicoBaseParams();
|
||||
graphParams['materialURL'] = uri;
|
||||
|
||||
indicoRequest('piwik.getMaterialStatistics', graphParams,
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
if (result !== null) {
|
||||
var materialHits = [getArrayValues(result['individual'],
|
||||
'total_hits'),
|
||||
getArrayValues(result['individual'],
|
||||
'unique_hits')];
|
||||
|
||||
drawGraph(materialHits, DOMTarget, replot);
|
||||
// Write to the title the total material downloads
|
||||
$('#materialTotalDownloads').html(result['cumulative']['total_hits']);
|
||||
}
|
||||
} else {
|
||||
$('#dialogNoGraphData').dialog('open');
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/* jqTree Specifics */
|
||||
var treeDOMTarget = '#materialTree';
|
||||
|
||||
/**
|
||||
* Handles all the specific jqTree customization required.
|
||||
*/
|
||||
var drawTree = function(treeData) {
|
||||
$(treeDOMTarget).tree(
|
||||
{
|
||||
data: treeData,
|
||||
autoOpen: 0,
|
||||
saveState: true,
|
||||
onCanSelectNode: function(node) {
|
||||
/* If this node has no children, it is material - ergo, make it
|
||||
* selectable so that the event binding can work. */
|
||||
return (node.children.length == 0)
|
||||
},
|
||||
onCreateLi: function(node, $li) {
|
||||
if (node.id !== undefined) {
|
||||
$li.find('.title').addClass('selectableNode');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the data required for jqTree via AJAX and then delegates this
|
||||
* data to drawTree for DOM insertion.
|
||||
*/
|
||||
var loadTree = function() {
|
||||
var materialTreeData = null;
|
||||
|
||||
/* Placeholder loading spinner for larger events. */
|
||||
$(treeDOMTarget).html(progressIndicator(true, true).dom);
|
||||
|
||||
indicoRequest('piwik.getMaterialTreeData',
|
||||
{
|
||||
confId: $('#confId').val()
|
||||
},
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
if (result !== null) {
|
||||
drawTree(result);
|
||||
} else {
|
||||
/* There is no material present */
|
||||
$(treeDOMTarget).html($T('No Material Found.'));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler for clicking 'selectable' elements from the jqTree.
|
||||
*/
|
||||
$(treeDOMTarget).bind('tree.click', function(event) {
|
||||
$('#materialTitle').html(event.node.name);
|
||||
$('#materialDownloadChart').html(progressIndicator(true, true).dom);
|
||||
loadMaterialGraph(event.node.id, true);
|
||||
});
|
||||
|
||||
/**
|
||||
* jQuery UI Dialog if no data is received via AJAX (timeout)
|
||||
*/
|
||||
$('#dialogNoGraphData').dialog({
|
||||
modal: true,
|
||||
resizable: false,
|
||||
autoOpen: false,
|
||||
buttons: {
|
||||
Ok: function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Static graph data being retrieved by the API. */
|
||||
var staticGraphs = [{
|
||||
'apiMethod': 'piwik.getGeographyGraph',
|
||||
'el': 'graphGeography'
|
||||
}, {
|
||||
'apiMethod': 'piwik.getDevicesGraph',
|
||||
'el': 'graphDevices'
|
||||
}];
|
||||
|
||||
/* Iterates through the objects relating to static graphs and calls them
|
||||
* to populate page. @todo: Move this to Backbone.js
|
||||
**/
|
||||
var loadStaticGraphs = function() {
|
||||
$.each(staticGraphs, function(index, graph) {
|
||||
indicoRequest(graph.apiMethod, getIndicoBaseParams(),
|
||||
function(result, error) {
|
||||
if (!error) {
|
||||
$('#' + graph.el).attr('src', result);
|
||||
} else {
|
||||
$('#' + graph.el).html($T('No Graph Data Received'));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializer to begin the dynamic loading of widgets etc on pageload.
|
||||
*/
|
||||
var statsInit = function() {
|
||||
loadStaticGraphs();
|
||||
loadVisitorsGraph();
|
||||
loadTree();
|
||||
};
|
||||
|
||||
statsInit();
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user