File: ia\factories\StackedTimeSeriesFactory.js
/**
* Factory for creating stacked time series charts.
*
* @author J Clare
* @class ia.StackedTimeSeriesFactory
* @extends ia.ChartFactory
* @param {ia.ComponentConfig} config The component config.
* @param {ia.Report} report The report object.
* @param {Object} componentGroup Hash table containing the Data and Interaction Groups that the component belongs to:
* {dataGroup:ia.DataGroup, interactionGroup:ia.InteractionGroup, comparisonInteractionGroup:ia.InteractionGroup}.
*/
ia.StackedTimeSeriesFactory = function(config, report, componentGroup)
{
ia.StackedTimeSeriesFactory.baseConstructor.call(this, config, report, componentGroup);
var me = this;
// Data and Interaction groups that the components belongs to.
var interactionGroup = componentGroup.interactionGroup;
var dataGroup = componentGroup.dataGroup;
var comparisonInteractionGroup = componentGroup.comparisonInteractionGroup;
// This code executes every time the data groups data has changed.
dataGroup.addEventListener(ia.DataEvent.DATA_CHANGED, function(event)
{
me.update();
me.render();
});
// This code executes every time the comparison selection has changed.
comparisonInteractionGroup.addEventListener(ia.InteractionEvent.SELECTION_CHANGED, function(event)
{
me.update();
me.render();
});
// Panel.
var panel = report.getWidget(config.id);
panel.exportFunction = function() {chart.exportData(report.config.getProperty("saveImageText"));};
// Chart.
var chart;
var layer;
var dataFields;
var legend;
/**
* Builds the component.
*
* @method build
* @param {Function} callbackFunction Called on completion of function, with the component id as the parameter.
*/
this.build = function(callbackFunction)
{
// Empty panel.
panel.content.empty();
// Legend.
var legendConfig = report.config.getComponent("stackedLegend"+dataGroup.suffix);
if (legendConfig)
{
legend = new ia.ProfileLegend(legendConfig.id);
if (legendConfig.getProperty("layout")) legend.layout = legendConfig.getProperty("layout");
var legendPanel = report.getWidget(legendConfig.id);
legendPanel.append(legend.container);
report.addComponent(legendConfig.id, legend);
}
// Chart.
chart = new ia.StackedTimeChart(config.id);
chart.drawBarsFromZero = true;
chart.wrapXAxisLabels = true;
// Layer.
layer = new ia.StackedTimeLayer();
// Add common chart properties.
me.buildChart(chart, layer);
// Wait till charts ready before returning.
chart.addEventListener(ia.Event.MAP_READY, function()
{
if (callbackFunction !== undefined) callbackFunction.call(null, config.id);
});
panel.append(chart.container); // Append the chart.
};
/**
* Updates the component.
*
* @method update
* @param {Function} callbackFunction Called on completion of function, with the component id as the parameter.
*/
this.update = function(callbackFunction)
{
// Update common chart properties.
me.updateChart(chart, layer);
if (config.getProperty("highlightSelectedDate") !== undefined) layer.highlightSelectedDate = config.getProperty("highlightSelectedDate");
// Color palette.
var colorSchemeId = config.getProperty("colorSchemeId");
var palette = report.config.getMapPalette().getColorScheme(colorSchemeId);
var theme = dataGroup.theme;
var indicator = dataGroup.indicator;
dataFields = [];
var ignoreAssociateIds = config.getProperty("ignoreAssociateIds");
if (ignoreAssociateIds) // Ignore specified associates.
{
var associates = indicator.getAssociates();
for (var i = 0; i < associates.length; i++)
{
var associate = associates[i];
var includeAssociate = true;
for (var j = 0; j < ignoreAssociateIds.length; j++)
{
if (associate.id === ignoreAssociateIds[j])
{
includeAssociate = false;
break;
}
}
if (includeAssociate && (associate.type !== ia.Thematic.CATEGORIC))
{
dataFields[dataFields.length] = associate.id;
}
}
}
else // Use all associates
{
var associates = indicator.getAssociates();
for (var i = 0; i < associates.length; i++)
{
var associate = associates[i];
if (associate.type !== ia.Thematic.CATEGORIC)
{
dataFields[dataFields.length] = associate.id;
}
}
}
layer.dataFields = dataFields;
// Check for specified associate labels.
var associateLabels = config.getProperty("associateLabels");
var legendClasses = new Array();
for (var i = 0; i < dataFields.length; i++)
{
var legendClass = new ia.CategoricClass(dataFields[i]);
legendClass.color = palette.getColorAtIndex(i);
legendClass.symbol = ia.Shape.SQUARE;
legendClass.size = 10;
legendClass.value = dataFields[i];
if (associateLabels && associateLabels.length > i) legendClass.setLabel(associateLabels[i]);
legendClasses[legendClasses.length] = legendClass;
}
layer.legendClasses = legendClasses;
// Associated legend created in above code.
if (legend) legend.legendClasses = legendClasses;
// Axis labels.
if (chart.orientation === "vertical")
{
chart.yAxisLabels = undefined;
chart.xAxisLabels = theme.getIndicatorDates(indicator.id);
}
else
{
chart.yAxisLabels = theme.getIndicatorDates(indicator.id);
chart.xAxisLabels = undefined;
}
// Layer data.
layer.selectedDate = indicator.date;
layer.setData(dataGroup.themeData);
if (callbackFunction !== undefined) callbackFunction.call(null, config.id);
};
/**
* Renders the component.
*
* @method render
* @param {Function} callbackFunction Called on completion of function, with the component id as the parameter.
*/
this.render = function(callbackFunction)
{
if (dataGroup.indicator.date !== undefined && dataFields.length > 0)
{
// Show.
panel.text("");
chart.show();
chart.render();
if (legend) legend.render();
}
else
{
// Hide.
chart.hide();
panel.text(config.getProperty("notAvailableText"));
}
if (callbackFunction !== undefined) callbackFunction.call(null, config.id);
};
};
ia.extend(ia.ChartFactory, ia.StackedTimeSeriesFactory);