/**
* Copyright (C) 2005-2016 Alfresco Software Limited.
*
* This file is part of Alfresco
*
* Alfresco is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Alfresco is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* A base class for charts
*
* @module alfresco/charts/css/ChartsView
* @extends external:dijit/_WidgetBase
* @mixes external:dojo/_TemplatedMixin
* @mixes module:alfresco/core/Core
* @mixes module:alfresco/core/CoreWidgetProcessing
* @author Erik Winlöf
*/
define(["dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/text!./templates/ChartsView.html",
"./Chart",
"alfresco/core/Core",
"alfresco/core/CoreWidgetProcessing",
"dojo/_base/lang",
"dojo/_base/array",
"dojo/dom-construct",
"dojo/dom-class",
"dojo/date",
"dojo/date/stamp"],
function(declare, _WidgetBase, _TemplatedMixin, template, Chart,
AlfCore, CoreWidgetProcessing, lang, array, domConstruct, domClass, date, stamp) {
return declare([_WidgetBase, _TemplatedMixin, AlfCore, CoreWidgetProcessing], {
/**
* The base css class to use for this widget
*
* @instance
* @type {string}
* @default
*/
baseClass: "alfresco-charts-ccc-ChartsView",
/**
* The HTML template to use for the widget.
*
* @instance
* @type {string}
*/
templateString: template,
/**
* The container element that holds the charts (will be set by dojo)
* @instance
* @type {HTMLElement}
*/
chartsNode: null,
/**
* Publication of this topic will cause this widget to publish an event with the same name as
* [dataRequestTopic]{@link module:alfresco/charts/css/ChartsView#dataRequestTopic} and with a payload set to the payload merged with
* all previous payloads.
*
* @instance
*/
subscriptionTopic: null,
/**
* The topic to publish to request chart data.
*
* @instance
*/
dataRequestTopic: null,
/**
* The initial payload of the [dataRequestTopic]{@link module:alfresco/charts/css/ChartsView#dataRequestTopic}.
*
* @instance
*/
dataRequestPayload: {},
/**
* The current payload of the [dataRequestTopic]{@link module:alfresco/charts/css/ChartsView#dataRequestTopic}
*/
_currentDataRequestPayload: {},
/**
* Instance of the chart currently being displayed
*
* @instance
*/
_chart: null,
/**
* Instances of the charts to display
*
* @instance
*/
_chartMap: null,
/**
* The topic to publish when a chart selection has been made
*
* @instance
*/
chartSelectionTopic: null,
/**
* The currently selected chart
*
* @instance
*/
_currentlySelectedChart: null,
/**
* Sets up subscriptions to the topics
*/
postMixInProperties: function() {
if (this.subscriptionTopic)
{
this.alfSubscribe(this.subscriptionTopic, lang.hitch(this, this.onSubscriptionTopic));
}
if (this.dataRequestTopic)
{
this.alfSubscribe(this.dataRequestTopic + "_SUCCESS", lang.hitch(this, this.onDataRequestTopicSuccess));
this.alfSubscribe(this.dataRequestTopic + "_FAILURE", lang.hitch(this, this.onDataRequestTopicFailure));
}
},
/**
* Iterates over the widgets processed and calls the [registerChart]{@link module:alfresco/charts/ccc/ChartsView#registerChart}
* function with each one.
*
* @instance
* @param {object[]} The widgets to create
*/
allWidgetsProcessed: function(widgets) {
array.forEach(widgets, lang.hitch(this, this.registerChart));
if (this.chartSelectionTopic) {
this.alfPublish(this.chartSelectionTopic, {
value: this._currentlySelectedChart
});
}
this._currentDataRequestPayload = lang.mixin({}, this.dataRequestPayload);
this.requestData();
},
/**
* Creates the charts as defined in [widgets]{@link module:alfresco/charts/css/ChartsView#widgets}
*
* @instance
*/
postCreate: function() {
this._chartMap = {};
if (this.widgets) {
this.processWidgets(this.widgets);
}
},
/**
* Publishes a topic with the name defined in
* [dataRequestTopic]{@link module:alfresco/charts/css/ChartsView#dataRequestTopic} to request data
*
* @instance
*/
requestData: function() {
this._currentDataRequestPayload.alfResponseTopic = this.dataRequestTopic;
this.alfPublish(this.dataRequestTopic, this._currentDataRequestPayload);
},
/**
* Makes the current chart display new data.
*
* @param data {object} The data
* @param dataDescriptor {object} Metadata describing data
*/
onDataRequestTopic: function(data, dataDescriptor) {
/*jshint eqnull:true*/
var chart = this._chartMap[this._currentlySelectedChart];
if (chart != null) {
chart.showData(data, dataDescriptor);
this.showChart(chart);
}
},
/**
* Called when the chart data has been successfully returned.
*
* @instance
* @param payload
*/
onDataRequestTopicSuccess: function(payload) {
this.onDataRequestTopic(payload.response.data, payload.response.dataDescriptor);
},
/**
* Called when the chart data has been successfully returned.
*
* @instance
*/
onDataRequestTopicFailure: function() {
this.onDataRequestTopic({}, {});
},
/**
* Called when the topic defined in
* [subscriptionTopic]{@link module:alfresco/charts/css/ChartsView#subscriptionTopic} has been called.
*
* @param payload
*/
onSubscriptionTopic: function(payload) {
var now = stamp.toISOString(new Date(), { selector: "date" });
var startDate = payload.startDate, endDate = payload.endDate;
var getStartDate = function(timePeriod) {
switch (timePeriod)
{
case "TODAY":
return now;
case "7D":
return stamp.toISOString(date.add(new Date(), "day", -7), { selector: "date" });
case "30D":
return stamp.toISOString(date.add(new Date(), "day", -30), { selector: "date" });
case "YEAR":
return stamp.toISOString(date.add(new Date(), "year", -1), { selector: "date" });
case "CUSTOM":
return startDate;
default:
break;
}
return startDate;
};
var getEndDate = function(timePeriod) {
if (timePeriod === "CUSTOM") {
return endDate;
} else {
return now;
}
};
if (payload.timePeriod) {
payload.startDate = getStartDate(payload.timePeriod);
payload.endDate = getEndDate(payload.timePeriod);
}
lang.mixin(this._currentDataRequestPayload, payload);
this.requestData();
},
/**
* Registers a chart with a given name.
*
* @instance
* @param chart
* @param name
*/
registerChart: function (chart, name) {
if (chart instanceof Chart)
{
this.alfLog("log", "Registering Chart", chart);
var chartName = name;
// Check if this is the initially requested chart...
if (chartName === this._chart || (!this._currentlySelectedChart && !this._chart))
{
this._currentlySelectedChart = chartName;
}
// Step 2: Add the chart to the map of known charts...
this._chartMap[chartName] = chart;
}
else
{
this.alfLog("warn", "The following widget was provided as a chart, but it does not inherit from 'alfresco/charts/ccc/Chart'", chart);
}
},
/**
* Shows a chart and hiddes the pother charts using the CSS class "share-hidden".
*
* @instance
* @param chart
*/
showChart: function(chart) {
this.hideChildren(this.domNode);
if (this.chartsNode.children.length > 0)
{
this.chartsNode.removeChild(this.chartsNode.children[0]);
}
// Add the new chart...
domConstruct.place(chart.domNode, this.chartsNode);
domClass.remove(this.chartsNode, "share-hidden");
},
/**
* Hides all the children of the supplied DOM node by applying the "share-hidden" CSS class to them.
*
* @instance
* @param {Element} targetNode The DOM node to hide the children of.
*/
hideChildren: function(targetNode) {
array.forEach(targetNode.children, function(node) {
domClass.add(node, "share-hidden");
});
}
});
});