File: ia\factories\PyramidChartFactory.js
/**
* Factory for creating pyramid charts.
*
* @author J Clare
* @class ia.PyramidChartFactory
* @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.PyramidChartFactory = function(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;
// Event handlers.
// This code executes every time a geography has changed.
dataGroup.addEventListener(ia.DataEvent.GEOG_CHANGED, function(event)
{
updateGeography();
me.render();
});
// 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 selection has changed.
interactionGroup.addEventListener(ia.InteractionEvent.SELECTION_CHANGED, function(event)
{
var selectedFeatures = interactionGroup.getSelection();
if (selectedFeatures.length > 0)
{
var id = selectedFeatures[0];
var pData = dataGroup.geography.getProfileData([id]);
for (var i = 0; i < mLayers.length; i++)
{
mLayers[i].setData(pData.themes[0].indicators); // Males.
fLayers[i].setData(pData.themes[1].indicators); // Females.
}
}
else
{
for (var i = 0; i < mLayers.length; i++)
{
mLayers[i].setData({}); // Males.
fLayers[i].setData({}); // Females.
}
}
me.render();
});
// This code executes every time the comparison selection has changed.
comparisonInteractionGroup.addEventListener(ia.InteractionEvent.SELECTION_CHANGED, function(event)
{
me.update();
me.render();
});
// Components.
// Panel.
var panel = report.getWidget(config.id);
panel.exportFunction = function() {if (chart.isVisible) chart.exportData(report.config.getProperty("saveImageText"));};
// Chart.
var legendConfig;
var legend;
var chart;
var mLayers;
var mLayer;
var mComparisonLayer;
var fLayers;
var fLayer;
var fComparisonLayer
/**
* 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.
legendConfig = report.config.getComponent("pyramidLegend"+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.PyramidChart(config.id);
chart.formatter = report.locale.formatter;
panel.append(chart.container);
// Arrays to hold the layers.
fLayers = [];
mLayers = [];
// Male layer.
mLayer = new ia.PyramidLayer();
mLayer.setVisible(true);
mLayer.interactive = true;
mLayer.highlightColor = report.highlightColor;
mLayer.selectionColor = report.selectionColor;
// Set styles after layer added to chart otherwise it gets override by the ia-chart-item style.
chart.addLayer(mLayer);
mLayers[mLayers.length] = mLayer;
// Female layer.
fLayer = new ia.PyramidLayer();
fLayer.gender = "female";
fLayer.setVisible(true);
fLayer.interactive = true;
fLayer.highlightColor = report.highlightColor;
fLayer.selectionColor = report.selectionColor;
// Set styles after layer added to chart otherwise it gets override by the ia-chart-item style.
chart.addLayer(fLayer);
fLayers[fLayers.length] = fLayer;
// Male Comparison layer.
mComparisonLayer = new ia.ComparisonPyramidLayer();
mComparisonLayer.setVisible(true);
mComparisonLayer.interactive = true;
mComparisonLayer.thematic = dataGroup.comparisonThematic;
mComparisonLayer.highlightColor = report.highlightColor;
mComparisonLayer.selectionColor = report.selectionColor;
chart.addLayer(mComparisonLayer);
comparisonInteractionGroup.addComponent(mComparisonLayer);
// Female Comparison layer.
fComparisonLayer = new ia.ComparisonPyramidLayer();
fComparisonLayer.gender = "female";
fComparisonLayer.setVisible(true);
fComparisonLayer.interactive = true;
fComparisonLayer.thematic = dataGroup.comparisonThematic;
fComparisonLayer.highlightColor = report.highlightColor;
fComparisonLayer.selectionColor = report.selectionColor;
chart.addLayer(fComparisonLayer);
comparisonInteractionGroup.addComponent(fComparisonLayer);
var legendClasses = [];
var label = config.getProperty("femaleLabel")
var legendClass = new ia.CategoricClass(label);
legendClass.color = config.getProperty("femaleColor");
legendClass.symbol = ia.Shape.SQUARE;
legendClass.size = 12;
legendClass.value = label;
legendClasses[legendClasses.length] = legendClass;
var legendClass = new ia.CategoricClass(config.getProperty("maleLabel"));
var label = config.getProperty("maleLabel")
var legendClass = new ia.CategoricClass(label);
legendClass.color = config.getProperty("maleColor");
legendClass.symbol = ia.Shape.SQUARE;
legendClass.size = 12;
legendClass.value = label;
legendClasses[legendClasses.length] = legendClass;
// Associate Layers.
for (var i = 1; i <= 3; i++)
{
if (config.getProperty("line_value_"+i) !== undefined)
{
var dataField = config.getProperty("line_value_"+i);
var color = config.getProperty("line_color_"+i);
var label = config.getProperty("line_label_"+i);
// Male Associate layer.
var mAssociateLayer = new ia.ComparisonPyramidLayer();
mAssociateLayer.dataField = dataField;
mAssociateLayer.setVisible(true);
mAssociateLayer.interactive = true;
mAssociateLayer.displayAll = true;
mAssociateLayer.tip = config.getProperty("tip");
mAssociateLayer.highlightColor = report.highlightColor;
chart.addLayer(mAssociateLayer);
mAssociateLayer.style.strokeStyle = color;
// Female Associate layer.
var fAssociateLayer = new ia.ComparisonPyramidLayer();
fAssociateLayer.gender = "female";
fAssociateLayer.dataField = dataField;
fAssociateLayer.setVisible(true);
fAssociateLayer.interactive = true;
fAssociateLayer.tip = config.getProperty("tip");
fAssociateLayer.displayAll = true;
fAssociateLayer.highlightColor = report.highlightColor;
chart.addLayer(fAssociateLayer);
fAssociateLayer.style.strokeStyle = color;
fLayers[fLayers.length] = fAssociateLayer;
mLayers[mLayers.length] = mAssociateLayer;
// For pyramid key.
var legendClass = new ia.CategoricClass(label);
legendClass.color = color;
legendClass.symbol = ia.Shape.HORIZONTAL_LINE;
legendClass.size = 12;
legendClass.value = label;
legendClasses[legendClasses.length] = legendClass;
}
}
if (report.url.params["select"+dataGroup.suffix]) // select=_00CE,_00CF,_00DA
{
var arr = report.url.params["select"+dataGroup.suffix].toString().split(",");
var id = arr[arr.length-1];
var pData = dataGroup.geography.getProfileData([id]);
for (var i = 0; i < mLayers.length; i++)
{
mLayers[i].setData(pData.themes[0].indicators); // Males.
fLayers[i].setData(pData.themes[1].indicators); // Females.
}
}
// Associated legend created in above code.
if (legend)
{
legend.legendClasses = legendClasses;
legend.render();
}
report.addComponent(config.id, chart);
updateGeography();
// Wait till charts ready before returning.
chart.addEventListener(ia.Event.MAP_READY, function()
{
if (callbackFunction !== undefined) callbackFunction.call(null, config.id);
});
};
/**
* Updates the component.
*
* @method update
* @param {Function} callbackFunction Called on completion of function, with the component id as the parameter.
*/
this.update = function(callbackFunction)
{
chart.orientation = "horizontal";
chart.drawBarsFromZero = config.getProperty("drawBarsFromZero");
chart.showYAxisLabels = config.getProperty("showYAxisLabels");
mLayer.dataField = config.getProperty("data") || "value";
mLayer.tip = config.getProperty("tip");
mLayer.style.fillStyle = ia.Color.toRGBA(config.getProperty("maleColor"), 0.8);
mLayer.style.strokeStyle = config.getProperty("maleColor");
fLayer.dataField = config.getProperty("data") || "value";
fLayer.tip = config.getProperty("tip");
fLayer.style.fillStyle = ia.Color.toRGBA(config.getProperty("femaleColor"), 0.8);
fLayer.style.strokeStyle = config.getProperty("femaleColor");
mComparisonLayer.dataField = config.getProperty("data") || "value";
mComparisonLayer.displayAll = config.getProperty("showComparison");
mComparisonLayer.tip = config.getProperty("tip");
fComparisonLayer.dataField = config.getProperty("data") || "value";
fComparisonLayer.tip = config.getProperty("tip");
fComparisonLayer.displayAll = config.getProperty("showComparison");
var indicator = dataGroup.indicator;
// Check for custom fixed values.
var fixedMaxValue = indicator.getProperty(config.getProperty("maxChartValue"));
if (fixedMaxValue)
{
chart.useTightLabels = true;
chart.fixedMaxValue = fixedMaxValue;
}
else
{
// If theres no custom values then check for config.xml fixed values.
if (config.getProperty("useFixedValues"))
{
chart.useTightLabels = true;
chart.fixedMaxValue = config.getProperty("fixedMaxValue");
}
else chart.useTightLabels = config.getProperty("useTightLabels");
}
// Axis titles.
var xTitle = config.getProperty("xAxisTitle");
if (xTitle) chart.xAxisTitle = report.textSubstitution.formatMessage(xTitle);
var yTitle = config.getProperty("yAxisTitle");
if (yTitle) chart.yAxisTitle = report.textSubstitution.formatMessage(yTitle);
// Data.
var themes = dataGroup.geography.getThemes();
var mTheme = themes[0];
chart.yAxisLabels = mTheme.getIndicatorNames().reverse();
chart.date = indicator.date;
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)
{
chart.render();
if (callbackFunction !== undefined) callbackFunction.call(null, config.id);
};
// Update the data when the geography changes.
function updateGeography()
{
var geography = dataGroup.geography;
chart.geography = geography;
var comparisonFeatures = geography.getComparisonFeatures();
var comparisonFeatureIds = [];
for (var i = 0; i < comparisonFeatures.length; i++)
{
comparisonFeatureIds.push(comparisonFeatures[i].id)
}
var pData = geography.getProfileData(comparisonFeatureIds);
mComparisonLayer.setData(pData.themes[0].indicators); // Males.
fComparisonLayer.setData(pData.themes[1].indicators); // Females.
};
};