Files
line_chart_demo/fusioncharts.gantt.js

5473 lines
242 KiB
JavaScript

(function (factory) {
if (typeof module === 'object' && typeof module.exports !== "undefined") {
module.exports = factory;
} else {
factory(FusionCharts);
}
}(function (FusionCharts) {
/**!
* @license FusionCharts JavaScript Library - Gantt Chart
* Copyright FusionCharts Technologies LLP
* License Information at <http://www.fusioncharts.com/license>
*
* @version 3.12.0
*/
/**
* @private
* @module fusioncharts.renderer.javascript.gantt
* @export fusioncharts.gantt.js
*/
FusionCharts.register ('module', ['private', 'modules.renderer.js-gantt', function () {
var global = this,
lib = global.hcLib,
win = global.window,
userAgent = win.navigator.userAgent,
isIE = /msie/i.test (userAgent) && !win.opera,
chartapi = lib.chartAPI,
extend2 = lib.extend2,
pluck = lib.pluck,
pluckNumber = lib.pluckNumber,
pluckFontSize = lib.pluckFontSize,
getFirstColor = lib.getFirstColor,
parseConfiguration = lib.parseConfiguration,
setAttribDefs = lib.setAttribDefs,
//hasAttribDefs = lib.hasAttribDefs,
graphics = lib.graphics,
convertColor = graphics.convertColor,
getDarkColor = graphics.getDarkColor,
parseUnsafeString = lib.parseUnsafeString,
getFirstValue = lib.getFirstValue,
getValidValue = lib.getValidValue,
toPrecision = lib.toPrecision,
R = lib.Raphael,
chartPaletteStr = lib.chartPaletteStr,
componentDispose = lib.componentDispose,
schedular = lib.schedular,
COMMA = lib.COMMASTRING,
setLineHeight = lib.setLineHeight,
getDashStyle = lib.getDashStyle,
toRaphaelColor = lib.toRaphaelColor,
each = lib.each,
ROLLOVER = 'DataPlotRollOver',
ROLLOUT = 'DataPlotRollOut',
attrTypeNum = lib.attrTypeNum,
attrTypeBool = lib.attrTypeBool,
PXSTRING = 'px',
BLANK = '',
MAX_MITER_LINEJOIN = 2,
dropHash = lib.dropHash,
HASHSTRING = lib.HASHSTRING,
creditLabel = false && !lib.CREDIT_REGEX.test (win.location.hostname),
TRACKER_FILL = 'rgba(192,192,192,'+ (isIE ? 0.002 : 0.000001) +')', // invisible but clickable
UNDEF,
// The default value for stroke-dash attribute.
DASH_DEF = 'none',
mapSymbolName = graphics.mapSymbolName,
math = Math,
mathMax = math.max,
mathMin = math.min,
mathAbs = math.abs,
pInt = parseInt,
toFloat = parseFloat,
M = 'M',
L = 'L',
v = 'v',
H = 'H',
PX = 'px',
ATTRFN = 'attr',
BOLD = 'bold',
ITALIC = 'italic',
NORMAL = 'normal',
NONE = 'none',
UND_LINE = 'underline',
POSITION_BOTTOM = 'bottom',
getLightColor = lib.graphics.getLightColor,
plotEventHandler = lib.plotEventHandler,
hoverTimeout,
lastHoverEle,
merge = function () { /** @todo refactor dependency */
var args = arguments;
return lib.extend2 (lib.extend2 (lib.extend2 (lib.extend2 ( { }, args[0]), args[1]), args[2]), args[3]);
},
UNDEFINED,
defined = function (obj) {
return obj !== UNDEFINED && obj !== null;
},
isPercent = function (srt) {
return (/%/g).test (srt);
},
align = {
left: 'start',
right: 'end',
center: 'middle'
},
xAlign = {
left: 0,
right: 1,
center: 0.5,
'undefined': 0.5
},
alignGutter = {
left: 5,
right: -5,
center: 0,
'undefined': 0
},
emptyFn = function () {
},
checkInvalidValue = function () {
var i = 0,
ii = arguments.length,
allValuesValid = false,
val;
for (i = 0; i < ii; i++) {
val = arguments[i];
if (isNaN(val)) {
return false;
}
else {
allValuesValid = true;
}
}
return allValuesValid;
},
stylePropValues = {
fontWeight: [NORMAL, BOLD],
fontStyle: [NORMAL, ITALIC]
},
extractLabelStyle = function (styleObj) {
var style,
prop;
for (prop in styleObj) {
if (styleObj[prop] !== UNDEFINED) {
style = style || {};
switch (prop) {
case 'fontWeight':
case 'fontStyle':
style[prop] = stylePropValues[prop][styleObj[prop]];
break;
default:
style[prop] = styleObj[prop];
}
}
}
return style;
};
// New gantt API
chartapi('gantt', {
defaultDatasetType: 'task',
applicableDSList: {'task': true, 'milestone': true, 'connectors': true},
fireGroupEvent: true,
aligncaptionwithcanvas: 0,
hasInteractiveLegend: false,
creditLabel: creditLabel,
//init: function (){},
//configure: function(){},
//manageSpace: function(){},
//draw: function(){}
_createDatasets : function () {
var iapi = this,
config = iapi.config,
components = iapi.components,
dataObj = iapi.jsonData,
dataset = [],
length,
i,
datasetStore,
datasetStoreLen,
datasetObj,
datasets,
defaultSeriesType = iapi.defaultDatasetType,
applicableDSList = iapi.applicableDSList,
dsType,
DsClass,
datasetJSON,
JSONData,
datasetMap = config.datasetMap || (config.datasetMap = {
'task': [],
'milestone': [],
'connectors': []
}),
tempMap = {
'task': [],
'milestone': [],
'connectors': []
},
dsTypeRef,
dsRef,
prevDataLength,
currDataLength,
dataType,
dsCount = { };
if (dataObj.tasks) {
dataset = dataset.concat(dataObj.tasks);
}
if (dataObj.milestones) {
dataset = dataset.concat(dataObj.milestones);
}
if (dataObj.connectors) {
dataset = dataset.concat(dataObj.connectors);
}
length = dataset && dataset.length;
if(dataset && !(dataset instanceof Array)){
dataset = [dataset];
length = 1;
}
if (!length) {
iapi.setChartMessage();
}
iapi.config.categories = dataObj.categories && dataObj.categories[0].category;
datasetStore = components.dataset = [];
datasetStoreLen = datasetStore.length;
for (i=0; i<length; i++) {
datasetJSON = dataset[i];
if (datasetJSON.task) {
dsType = 'task';
dataType = dsType;
}
else if (datasetJSON.milestone) {
dsType = 'milestone';
dataType = dsType;
}
else if (datasetJSON.connector) {
dsType = 'connectors';
dataType = 'connector';
}
dsType = dsType && dsType.toLowerCase ();
if (!applicableDSList[dsType]) {
dsType = defaultSeriesType;
}
/// get the DsClass
DsClass = FusionCharts.get('component', ['dataset', dsType]);
if (DsClass) {
if (dsCount[dsType] === UNDEFINED) {
dsCount[dsType] = 0;
}
else {
dsCount[dsType]++;
}
dsTypeRef = datasetMap[dsType];
dsRef = dsTypeRef[0];
// If the dataset does not exists.
if (!dsRef) {
// create the dataset Object
datasetObj = new DsClass ();
tempMap[dsType].push(datasetObj);
datasetStore.push (datasetObj);
datasetObj.chart = iapi;
datasetObj.index = i;
datasetObj.init (datasetJSON);
}
// If the dataset exists incase the chart is updated using setChartData() method.
else {
JSONData = dsRef.JSONData;
prevDataLength = JSONData[dataType].length;
currDataLength = datasetJSON[dataType].length;
tempMap[dsType].push(dsRef);
datasetStore.push(dsRef);
dsRef.index = i;
// Removing data plots if the number of current data plots is more than the existing ones.
if (prevDataLength > currDataLength) {
dsRef.removeData(currDataLength - 1, prevDataLength - currDataLength, false);
}
dsRef.JSONData = datasetJSON;
dsRef.configure();
dsTypeRef.shift();
}
}
}
iapi._createLegendItems();
// Removing unused datasets if any
for (dsType in datasetMap) {
datasets = datasetMap[dsType];
length = datasets.length;
if (length) {
for (i = 0; i < length; i++) {
datasetObj = datasets[i];
if (datasetObj) {
// legend.removeItem(datasets[j].legendItemId);
componentDispose.call(datasetObj);
}
}
}
}
config.datasetMap = tempMap;
},
configure: function () {
var iapi = this,
config = iapi.config,
jsonData = iapi.jsonData,
background = iapi.components.background,
bConfig = background.config,
chartAttrs = jsonData.chart;
this.__setDefaultConfig();
chartapi.mscartesian.configure.call(this);
config.showBorder = pluckNumber(chartAttrs.showborder, 0);
config.borderWidth = config.showBorder ? pluckNumber (chartAttrs.borderthickness, 1) : 0;
bConfig.borderWidth = config.borderWidth;
config.lastVScrollPosition = UNDEFINED;
config.lastHScrollPosition = UNDEFINED;
},
_createLegendItems: function () {
var iapi = this,
components = iapi.components,
dataObj = iapi.jsonData,
legend = components.legend,
length,
i,
strokeColor,
lightColor,
color,
fillColor,
itemObj,
config,
prevLen,
currLen,
legendItem,
legendItemsArray = components.legendItems,
items = dataObj.legend && dataObj.legend.item || [];
prevLen = components.legendItems && components.legendItems.length || 0;
currLen = items.length;
if (prevLen > currLen) {
legend.emptyItems(currLen, prevLen - currLen);
legendItemsArray && legendItemsArray.splice(currLen, prevLen - currLen);
}
if (!legendItemsArray) {
components.legendItems = legendItemsArray = [];
}
for (i = 0, length = items.length; i < length; i++) {
itemObj = items[i];
legendItem = legendItemsArray[i];
color = itemObj.color;
strokeColor = getLightColor(color, 60).replace(dropHash, HASHSTRING);
lightColor = getLightColor(color, 40);
fillColor = {
FCcolor: {
color: color + ',' + color + ',' + lightColor + ',' + color + ',' + color,
ratio: '0,70,30',
angle: 270,
alpha: '100,100,100,100,100'
}
};
!legendItem && (legendItem = legendItemsArray[i] = {});
config = {
fillColor : toRaphaelColor(fillColor),
strokeColor: toRaphaelColor(strokeColor),
label : itemObj.label,
interactiveLegend: false,
legendItemId: legendItem.legendItemId
};
legendItemsArray[i].legendItemId = legend.addItems(iapi, emptyFn, config);
}
},
_setAxisLimits: function () {
},
_createAxes : function () {
var iapi = this,
components = iapi.components,
TimeAxis = FusionCharts.get ('component', ['axis', 'time']),
ProcessAxis = FusionCharts.get ('component', ['axis', 'process']),
yAxis,
xAxis;
components.yAxis = [];
components.xAxis = [];
components.yAxis[0] = yAxis = new ProcessAxis ();
components.xAxis[0] = xAxis = new TimeAxis ();
yAxis.chart = iapi;
xAxis.chart = iapi;
yAxis.init ();
xAxis.init ();
},
_feedAxesRawData : function () {
var iapi = this,
components = iapi.components,
colorM = components.colorManager,
dataObj = iapi.jsonData,
chartAttrs = dataObj.chart,
xAxisConf,
yAxisConf,
is3d = iapi.is3d,
palleteString = is3d ? chartPaletteStr.chart3D : chartPaletteStr.chart2D,
yAxis,
xAxis;
xAxisConf = {
outCanfontFamily: pluck (chartAttrs.outcnvbasefont, chartAttrs.basefont, 'Verdana,sans'),
outCanfontSize: pluckFontSize (chartAttrs.outcnvbasefontsize, chartAttrs.basefontsize, 10),
outCancolor: pluck (chartAttrs.outcnvbasefontcolor, chartAttrs.basefontcolor,
colorM.getColor (palleteString.baseFontColor)).replace (/^#? ([a-f0-9]+)/ig, '#$1'),
axisBreaks : chartAttrs.xaxisbreaks,
axisNamePadding: chartAttrs.xaxisnamepadding,
axisValuePadding: chartAttrs.labelpadding,
axisNameFont: chartAttrs.xaxisnamefont,
axisNameFontSize: chartAttrs.xaxisnamefontsize,
axisNameFontColor: chartAttrs.xaxisnamefontcolor,
axisNameFontBold: chartAttrs.xaxisnamefontbold,
axisNameFontItalic: chartAttrs.xaxisnamefontitalic,
axisNameBgColor: chartAttrs.xaxisnamebgcolor,
axisNameBorderColor: chartAttrs.xaxisnamebordercolor,
axisNameAlpha: chartAttrs.xaxisnamealpha,
axisNameFontAlpha: chartAttrs.xaxisnamefontalpha,
axisNameBgAlpha: chartAttrs.xaxisnamebgalpha,
axisNameBorderAlpha: chartAttrs.xaxisnameborderalpha,
axisNameBorderPadding: chartAttrs.xaxisnameborderpadding,
axisNameBorderRadius: chartAttrs.xaxisnameborderradius,
axisNameBorderThickness: chartAttrs.xaxisnameborderthickness,
axisNameBorderDashed: chartAttrs.xaxisnameborderdashed,
axisNameBorderDashLen: chartAttrs.xaxisnameborderdashlen,
axisNameBorderDashGap: chartAttrs.xaxisnameborderdashgap,
useEllipsesWhenOverflow: chartAttrs.useellipseswhenoverflow,
divLineColor: pluck (chartAttrs.vdivlinecolor, colorM.getColor (palleteString.divLineColor)),
divLineAlpha: pluck (chartAttrs.vdivlinealpha, is3d ? colorM.getColor('divLineAlpha3D') :
colorM.getColor ('divLineAlpha')),
divLineThickness: pluckNumber (chartAttrs.vdivlinethickness, 1),
divLineIsDashed: Boolean (pluckNumber (chartAttrs.vdivlinedashed, chartAttrs.vdivlineisdashed, 0)),
divLineDashLen: pluckNumber (chartAttrs.vdivlinedashlen, 4),
divLineDashGap: pluckNumber (chartAttrs.vdivlinedashgap, 2),
showAlternateGridColor: pluckNumber (chartAttrs.showalternatevgridcolor, 0),
alternateGridColor: pluck (chartAttrs.alternatevgridcolor, colorM.getColor ('altVGridColor')),
alternateGridAlpha: pluck (chartAttrs.alternatevgridalpha, colorM.getColor ('altVGridAlpha')),
numDivLines: pluckNumber(chartAttrs.numvdivlines, iapi.numVDivLines),
labelFont: chartAttrs.labelfont,
labelFontSize: chartAttrs.labelfontsize,
labelFontColor: chartAttrs.labelfontcolor,
labelFontAlpha: chartAttrs.labelalpha,
labelFontBold: chartAttrs.labelfontbold,
labelFontItalic: chartAttrs.labelfontitalic,
maxLabelHeight : chartAttrs.maxlabelheight,
axisName: chartAttrs.xaxisname,
axisMinValue: chartAttrs.xaxisminvalue,
axisMaxValue: chartAttrs.xaxismaxvalue,
setAdaptiveMin: chartAttrs.setadaptivexmin,
adjustDiv: chartAttrs.adjustvdiv,
labelDisplay: chartAttrs.labeldisplay,
showLabels: chartAttrs.showlabels,
rotateLabels: chartAttrs.rotatelabels,
slantLabel: pluckNumber (chartAttrs.slantlabels, chartAttrs.slantlabel),
labelStep: pluckNumber (chartAttrs.labelstep, chartAttrs.xaxisvaluesstep),
showAxisValues: pluckNumber (chartAttrs.showxaxisvalues, chartAttrs.showxaxisvalue),
showLimits: pluckNumber(chartAttrs.showvlimits, iapi.showvlimits),
showDivLineValues: pluckNumber (chartAttrs.showvdivlinevalues, chartAttrs.showvdivlinevalues),
//showZeroPlane: chartAttrs.showvzeroplane,
zeroPlaneColor: chartAttrs.vzeroplanecolor,
zeroPlaneThickness: chartAttrs.vzeroplanethickness || 2,
zeroPlaneAlpha: chartAttrs.vzeroplanealpha,
showZeroPlaneValue: chartAttrs.showvzeroplanevalue,
trendlineColor: chartAttrs.trendlinecolor,
trendlineToolText: chartAttrs.trendlinetooltext,
trendlineThickness: chartAttrs.trendlinethickness,
trendlineAlpha: chartAttrs.trendlinealpha,
showTrendlinesOnTop: chartAttrs.showtrendlinesontop,
showAxisLine: pluckNumber (chartAttrs.showxaxisline, chartAttrs.showaxislines,
chartAttrs.drawAxisLines, 0),
axisLineThickness: pluckNumber (chartAttrs.xaxislinethickness, chartAttrs.axislinethickness, 1),
axisLineAlpha: pluckNumber (chartAttrs.xaxislinealpha, chartAttrs.axislinealpha, 100),
axisLineColor: pluck (chartAttrs.xaxislinecolor, chartAttrs.axislinecolor, '#000000')
};
yAxisConf = {
outCanfontFamily: pluck (chartAttrs.outcnvbasefont, chartAttrs.basefont, 'Verdana,sans'),
outCanfontSize: pluckFontSize (chartAttrs.outcnvbasefontsize, chartAttrs.basefontsize, 10),
outCancolor: pluck (chartAttrs.outcnvbasefontcolor, chartAttrs.basefontcolor,
colorM.getColor (palleteString.baseFontColor)).replace (/^#? ([a-f0-9]+)/ig, '#$1'),
axisBreaks : chartAttrs.yaxisbreaks,
axisNamePadding: chartAttrs.yaxisnamepadding,
axisValuePadding: chartAttrs.yaxisvaluespadding,
axisNameFont: chartAttrs.yaxisnamefont,
axisNameFontSize: chartAttrs.yaxisnamefontsize,
axisNameFontColor: chartAttrs.yaxisnamefontcolor,
axisNameFontBold: chartAttrs.yaxisnamefontbold,
axisNameFontItalic: chartAttrs.yaxisnamefontitalic,
axisNameBgColor: chartAttrs.yaxisnamebgcolor,
axisNameBorderColor: chartAttrs.yaxisnamebordercolor,
axisNameAlpha: chartAttrs.yaxisnamealpha,
axisNameFontAlpha: chartAttrs.yaxisnamefontalpha,
axisNameBgAlpha: chartAttrs.yaxisnamebgalpha,
axisNameBorderAlpha: chartAttrs.yaxisnameborderalpha,
axisNameBorderPadding: chartAttrs.yaxisnameborderpadding,
axisNameBorderRadius: chartAttrs.yaxisnameborderradius,
axisNameBorderThickness: chartAttrs.yaxisnameborderthickness,
axisNameBorderDashed: chartAttrs.yaxisnameborderdashed,
axisNameBorderDashLen: chartAttrs.yaxisnameborderdashlen,
axisNameBorderDashGap: chartAttrs.yaxisnameborderdashgap,
axisNameWidth: chartAttrs.yaxisnamewidth,
useEllipsesWhenOverflow: chartAttrs.useellipseswhenoverflow,
rotateAxisName: pluckNumber (chartAttrs.rotateyaxisname, 1),
axisName: chartAttrs.yaxisname,
divLineColor: pluck (chartAttrs.divlinecolor, colorM.getColor (palleteString.divLineColor)),
divLineAlpha: pluck (chartAttrs.divlinealpha, is3d ? colorM.getColor('divLineAlpha3D') :
colorM.getColor ('divLineAlpha')),
divLineThickness: pluckNumber (chartAttrs.divlinethickness, 1),
divLineIsDashed: Boolean (pluckNumber (chartAttrs.divlinedashed, chartAttrs.divlineisdashed, 0)),
divLineDashLen: pluckNumber (chartAttrs.divlinedashlen, 4),
divLineDashGap: pluckNumber (chartAttrs.divlinedashgap, 2),
showAlternateGridColor: pluckNumber (chartAttrs.showalternatehgridcolor, 1),
alternateGridColor: pluck (chartAttrs.alternatehgridcolor, colorM.getColor ('altHGridColor')),
alternateGridAlpha: pluck (chartAttrs.alternatehgridalpha, colorM.getColor ('altHGridAlpha')),
numDivLines: pluckNumber(chartAttrs.numdivlines, iapi.numDivLines),
axisMinValue: chartAttrs.yaxisminvalue,
axisMaxValue: chartAttrs.yaxismaxvalue,
setAdaptiveMin: chartAttrs.setadaptiveymin,
adjustDiv: chartAttrs.adjustdiv,
labelStep: chartAttrs.yaxisvaluesstep,
showAxisValues: pluckNumber (chartAttrs.showyaxisvalues, chartAttrs.showyaxisvalue),
showLimits: pluckNumber(chartAttrs.showlimits, iapi.showLimits),
showDivLineValues: pluckNumber (chartAttrs.showdivlinevalues, chartAttrs.showdivlinevalue),
//showZeroPlane: chartAttrs.showzeroplane,
zeroPlaneColor: chartAttrs.zeroplanecolor,
zeroPlaneThickness: chartAttrs.zeroplanethickness || 2,
zeroPlaneAlpha: chartAttrs.zeroplanealpha,
showZeroPlaneValue: chartAttrs.showzeroplanevalue,
trendlineColor: chartAttrs.trendlinecolor,
trendlineToolText: chartAttrs.trendlinetooltext,
trendlineThickness: chartAttrs.trendlinethickness,
trendlineAlpha: chartAttrs.trendlinealpha,
showTrendlinesOnTop: chartAttrs.showtrendlinesontop,
showAxisLine: pluckNumber (chartAttrs.showyaxisline, chartAttrs.showaxislines,
chartAttrs.drawAxisLines, 0),
axisLineThickness: pluckNumber (chartAttrs.yaxislinethickness, chartAttrs.axislinethickness, 1),
axisLineAlpha: pluckNumber (chartAttrs.yaxislinealpha, chartAttrs.axislinealpha, 100),
axisLineColor: pluck (chartAttrs.yaxislinecolor, chartAttrs.axislinecolor, '#000000')
};
xAxisConf.vtrendlines = dataObj.trendlines;
//yAxisConf.trendlines = dataObj.trendlines;
yAxis = components.yAxis[0];
xAxis = components.xAxis[0];
yAxis.setCommonConfigArr (yAxisConf, true, true, false);
xAxis.setCommonConfigArr (xAxisConf, false, false, true);
yAxis.configure();
xAxis.configure();
},
_setCategories: function(){
var iapi = this,
components = iapi.get('components'),
dataObj = iapi.jsonData,
xAxis = components.xAxis,
yAxis = components.yAxis,
processes = dataObj.processes,
dataTable = dataObj.datatable,
categories = dataObj.categories;
yAxis[0].setAxisPadding(0.5, 0.5);
yAxis[0].setProcess(processes);
yAxis[0].setDataTable(dataTable);
xAxis[0].setCategory(categories);
},
_setAxisValuePadding: function () {
var iapi = this,
datasets = iapi.components.dataset,
len = datasets.length,
i,
datasetObj,
axisPaddingLeft = -Infinity,
axisPaddingRight = -Infinity,
//yAxis = iapi.components.yAxis,
paddingObj;
for (i = 0; i < len; i++) {
datasetObj = datasets[i];
paddingObj = datasetObj.getAxisValuePadding && datasetObj.getAxisValuePadding() || {};
axisPaddingLeft = mathMax(axisPaddingLeft, paddingObj.left || -Infinity);
axisPaddingRight = mathMax(axisPaddingRight, paddingObj.right || -Infinity);
}
if (axisPaddingLeft === -Infinity) {
axisPaddingLeft = 0;
}
if (axisPaddingRight === -Infinity) {
axisPaddingRight = 0;
}
//xAxis && xAxis[0].setAxisPadding(axisPaddingLeft, axisPaddingLeft);
},
_spaceManager: function () {
// todo marge _allocateSpace and _spacemanager
var availableWidth,
availableHeight,
iapi = this,
config = iapi.config,
components = iapi.components,
xAxis = components.xAxis && components.xAxis[0],
yAxis = components.yAxis && components.yAxis[0],
legend = components.legend,
legendPosition = legend.config.legendPos,
allottedSpace,
ganttWidthPercent = config.ganttwidthpercent,
processWidthPercent = 100 - (ganttWidthPercent || 67),
chartBorderWidth = config.borderWidth,
spaceUsed,
processHeight,
totalWidth = 0,
totalHeight = 0;
iapi._resetViewPortConfig && iapi._resetViewPortConfig();
xAxis.resetTransletAxis();
yAxis.resetTransletAxis();
iapi._allocateSpace ( {
top : chartBorderWidth,
bottom : chartBorderWidth,
left : chartBorderWidth,
right : chartBorderWidth
});
iapi._allocateSpace(iapi._manageActionBarSpace &&
iapi._manageActionBarSpace(config.availableHeight * 0.225) || {});
availableHeight = (legendPosition === POSITION_BOTTOM) ? config.canvasHeight * 0.6 :
config.canvasWidth * 0.6;
// a space manager that manages the space for the tools as well as the captions.
iapi._manageChartMenuBar(availableHeight);
if (legendPosition === 'right') {
allottedSpace = config.canvasWidth * 0.3;
}
else {
allottedSpace = config.canvasHeight * 0.3;
}
//Manage space for legend
iapi._manageLegendSpace(allottedSpace);
config.actualCanvasTop = config.canvasTop;
config.actualCanvasLeft = config.canvasLeft;
//****** Manage space for y axis here y axis is the process column
availableWidth = config.canvasWidth * (processWidthPercent / 100);
spaceUsed = yAxis.placeAxis (availableWidth);
totalWidth += (spaceUsed.left || 0) + (spaceUsed.right || 0);
yAxis && iapi._allocateSpace (spaceUsed);
availableHeight = (legendPosition === POSITION_BOTTOM) ? config.canvasHeight * 0.6 :
config.canvasWidth * 0.6;
availableHeight = config.canvasHeight * 0.6;
spaceUsed = xAxis.placeAxis (availableHeight);
totalHeight += (spaceUsed.top || 0);
config.totalWidth = totalWidth;
config.totalHeight = totalHeight;
xAxis && iapi._allocateSpace (spaceUsed);
processHeight = yAxis && yAxis.setProcessHeight();
yAxis.setAxisConfig({
processTotalHeight : processHeight
});
},
_drawCanvas: function () {
var iapi = this,
jsonData = iapi.jsonData,
chartAttrs = jsonData.chart,
components = iapi.components,
chartConfig = iapi.config,
chartGraphics = iapi.graphics,
paper = components.paper,
canvas = components.canvas,
graphics = canvas.graphics,
config = canvas.config,
clip = config.clip = { },
canvasBorderElement = graphics.canvasBorderElement,
animationObj = iapi.get('config', 'animationObj'),
animationDuration = animationObj.duration,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animType = animationObj.animType,
canvasElement = graphics.canvasElement,
canvasLeft = chartConfig.actualCanvasLeft,
canvasTop = chartConfig.actualCanvasTop,
actualCanvasWidth = chartConfig.canvasWidth,
actualCanvasHeight = chartConfig.canvasHeight,
actualCanvasLeft = chartConfig.canvasLeft,
actualCanvasTop = chartConfig.canvasTop,
canvasWidth = chartConfig.canvasWidth + chartConfig.totalWidth,
canvasHeight = chartConfig.canvasHeight + chartConfig.totalHeight,
canvasGroup = chartGraphics.canvasGroup,
canvasBorderRadius = config.canvasBorderRadius,
canvasBorderWidth = config.canvasBorderWidth,
borderWHlf = canvasBorderWidth * 0.5,
canvasBorderColor = config.canvasBorderColor,
canBGColor = config.canBGColor,
shadow = config.shadow,
canvasBgColor,
attr,
showCanvasBg = config.showCanvasBG = Boolean (pluckNumber (chartAttrs.showcanvasbg, 1)),
shadowOnCanvasFill = config.shadowOnCanvasFill,
showCanvasBorder = config.showCanvasBorder;
canvasBgColor = canBGColor;
attr = {
x: canvasLeft - borderWHlf,
y: canvasTop - borderWHlf,
width: canvasWidth + canvasBorderWidth,
height: canvasHeight + canvasBorderWidth,
r: canvasBorderRadius,
'stroke-width': canvasBorderWidth,
stroke: canvasBorderColor,
'stroke-linejoin': canvasBorderWidth > MAX_MITER_LINEJOIN ? 'round' : 'miter'
};
if (showCanvasBorder) {
if (!canvasBorderElement) {
graphics.canvasBorderElement = paper.rect (attr, canvasGroup)
.shadow(shadow);
}
else {
canvasBorderElement.show();
canvasBorderElement.animateWith(dummyAnimElem, dummyAnimObj, {
x: canvasLeft - borderWHlf,
y: canvasTop - borderWHlf,
width: canvasWidth + canvasBorderWidth,
height: canvasHeight + canvasBorderWidth,
r: canvasBorderRadius
}, animationDuration, animType);
canvasBorderElement.attr ({
'stroke-width': canvasBorderWidth,
stroke: canvasBorderColor,
'stroke-linejoin': canvasBorderWidth > MAX_MITER_LINEJOIN ? 'round' : 'miter'
});
canvasBorderElement.shadow(shadow);
}
}
else {
canvasBorderElement && canvasBorderElement.hide();
}
//create a clip-rect to clip canvas for later use
clip['clip-canvas'] = [
mathMax (0, actualCanvasLeft),
mathMax (0, actualCanvasTop),
mathMax (1, actualCanvasWidth),
mathMax (1, actualCanvasHeight)
];
clip['clip-canvas-init'] = [
mathMax (0, actualCanvasLeft),
mathMax (0, actualCanvasTop),
1,
mathMax (1, actualCanvasHeight)
];
if (showCanvasBg) {
attr = {
x: canvasLeft,
y: canvasTop,
width: canvasWidth,
height: canvasHeight,
r: canvasBorderRadius,
'stroke-width': 0,
'stroke': NONE,
fill: toRaphaelColor (canvasBgColor)
};
if (!canvasElement) {
graphics.canvasElement = paper.rect (attr, canvasGroup)
.shadow (shadowOnCanvasFill);
}
else {
canvasElement.show();
if (animationDuration) {
canvasElement.animateWith(dummyAnimElem, dummyAnimObj, {
x: canvasLeft,
y: canvasTop,
width: canvasWidth,
height: canvasHeight,
r: canvasBorderRadius
}, animationDuration, animType);
}
canvasElement.attr (attr);
canvasElement.shadow (shadowOnCanvasFill);
}
}
else {
canvasElement && canvasElement.hide();
}
},
_postSpaceManagement : function () {
var iapi = this,
config = iapi.config,
components = iapi.components,
xAxis = components.xAxis && components.xAxis[0],
yAxis = components.yAxis && components.yAxis[0],
processTotalHeight = yAxis.getAxisConfig('processTotalHeight'),
canvasHeight = config.canvasHeight,
legend = components.legend,
xDepth = config.xDepth,
canvasConfig = components.canvas.config,
canvasBorderWidth = canvasConfig.canvasBorderWidth,
canvasPadding = canvasConfig.canvasPadding,
vScrollBar = components.vScrollBar,
conf = vScrollBar.userConf,
vScrollWidth,
vScrollEnabled,
canvasPaddingLeft = canvasConfig.canvasPaddingLeft,
canvasPaddingRight = canvasConfig.canvasPaddingRight,
gPaneDuration = Number(config.ganttpaneduration),
gPaneDurationUnit = config.ganttpanedurationunit,
hProcessScrollBar = components.hProcessScrollBar,
hScrollBar = components.hScrollBar,
hScrollBarHeight = hScrollBar && hScrollBar.userConf.height || 0,
hProcessScrollHeight = hProcessScrollBar && hProcessScrollBar.userConf.height || 0,
totalProcessWidth,
totalVisiblelProcessWidth,
hScrollEnabled,
hProcessScrollEnabled,
maxHScrollBarHeight,
actualCanvasHeight,
axisLength;
if (gPaneDuration !== UNDEF && gPaneDurationUnit !== UNDEF) {
hScrollEnabled = true;
}
else {
hScrollEnabled = false;
}
totalProcessWidth = yAxis.getAxisConfig('totalWidth');
totalVisiblelProcessWidth = yAxis.getAxisConfig('totalVisiblelWidth');
if (totalProcessWidth > totalVisiblelProcessWidth) {
hProcessScrollEnabled = true;
}
else {
hProcessScrollEnabled = false;
}
maxHScrollBarHeight = mathMax(hProcessScrollEnabled ? hProcessScrollHeight : 0,
hScrollEnabled ? hScrollBarHeight : 0);
actualCanvasHeight = canvasHeight - maxHScrollBarHeight;
// Need to call manageScrollerPosition here for knowing whether vertical scroll bar is there
if (processTotalHeight > actualCanvasHeight) {
vScrollEnabled = true;
}
vScrollWidth = vScrollEnabled ? conf.width || 0 : 0;
axisLength = config.canvasWidth - (xDepth || 0) - mathMax(canvasPaddingLeft, canvasPadding) -
mathMax(canvasPaddingRight, canvasPadding) - vScrollWidth;
xAxis && xAxis.setAxisDimention ( {
x : config.canvasLeft + (xDepth || 0) + mathMax(canvasPaddingLeft, canvasPadding),
y : config.canvasTop - (config.shift || 0),
opposite : config.canvasBottom + canvasBorderWidth,
axisLength : axisLength
});
config.currentCanvasWidth = axisLength;
yAxis && yAxis.setAxisDimention ( {
x : config.canvasLeft - (config.shift || 0),
y : config.canvasTop,
opposite : config.canvasRight + canvasBorderWidth,
axisLength : config.canvasHeight
});
iapi._manageScrollerPosition();
legend.postSpaceManager();
},
_resetViewPortConfig: function () {
var iapi = this;
iapi.config.viewPortConfig = {
scaleX: 1,
scaleY: 1,
x: 0,
y: 0
};
},
_manageScrollerPosition: function () {
var iapi = this,
config = iapi.config,
chartComponents = iapi.components,
availableHeight,
availableWidth,
hScrollEnabled,
vScrollEnabled,
hScrollBar = chartComponents.hScrollBar,
vScrollBar = chartComponents.vScrollBar,
hProcessScrollBar = chartComponents.hProcessScrollBar,
totalWidth = config.totalWidth || 0,
totalHeight = config.totalHeight || 0,
scrollDimensions;
iapi._setAxisScale && iapi._setAxisScale();
vScrollEnabled = config.vScrollEnabled;
hScrollEnabled = config.hScrollEnabled;
//manage space for the scroll bar.
// fetch the availble space for the canvas area after other space management is over
availableHeight = config.canvasHeight;
availableWidth = config.canvasWidth;
scrollDimensions = hScrollBar.getLogicalSpace();
//allocate space for toolBox and set the chart configurations.
// shift denotes the amount of shift required by the x-axis
config.hScrollHeight = hScrollEnabled === false ? 0 : scrollDimensions.height + vScrollBar.conf.padding;
scrollDimensions = vScrollBar.getLogicalSpace();
config.vScrollWidth = vScrollEnabled !== false ?
scrollDimensions.width + vScrollBar.conf.padding : 0;
scrollDimensions = hProcessScrollBar.getLogicalSpace();
config.hProcessScrollHeight = config.hProcessScrollEnabled ?
scrollDimensions.height + hProcessScrollBar.conf.padding : 0;
totalHeight += mathMax(config.hProcessScrollHeight, config.hScrollHeight);
iapi._allocateSpace({
bottom: mathMax(config.hProcessScrollHeight, config.hScrollHeight)
});
config.totalWidth = totalWidth;
config.totalHeight = totalHeight;
},
updateManager: function (pos, isHorizontal) {
var iapi = this,
config = iapi.config,
viewPortConfig = iapi.config.viewPortConfig,
scaleX = viewPortConfig.scaleX,
xAxis = iapi.components.xAxis[0],
yAxis = iapi.components.yAxis[0],
datasetLayer = iapi.graphics.datasetGroup,
dataLabelsLayer = iapi.graphics.datalabelsGroup,
trackerGroup = iapi.graphics.trackerGroup,
xOffset = config.xOffset || 0,
yOffset = config.yOffset || 0,
canvasHeight = config.canvasHeight,
currentCanvasWidth = config.currentCanvasWidth,
scaleY = viewPortConfig.scaleY,
transformAttr;
if (isHorizontal) {
config.lastHScrollPosition = pos;
}
else {
config.lastVScrollPosition = pos;
}
if (isHorizontal) {
xOffset = config.xOffset = (currentCanvasWidth * (scaleX - 1) * pos);
viewPortConfig.x = xOffset / scaleX;
xAxis.translateAxis(-xOffset, undefined);
}
else {
yOffset = config.yOffset = (canvasHeight * (scaleY - 1) * pos);
viewPortConfig.y = yOffset / scaleY;
yAxis.translateAxis(undefined, -yOffset);
}
transformAttr = 't' + -xOffset + ', ' + -yOffset;
datasetLayer.attr({
transform: transformAttr
});
dataLabelsLayer.attr({
transform: transformAttr
});
trackerGroup.attr({
transform: transformAttr
});
},
_setAxisScale: function () {
var iapi = this,
components = iapi.components,
config = iapi.config,
xAxis = components.xAxis[0],
limits = xAxis.getLimit(),
max = limits.max,
min = limits.min,
minDt = new Date(min),
yAxis = components.yAxis[0],
numberFormatter = iapi.components.numberFormatter,
gPaneDuration = Number(config.ganttpaneduration),
scrollOptions = config.scrollOptions || (config.scrollOptions = {}),
gPaneDurationUnit = config.ganttpanedurationunit,
// scrollToDate = config.scrolltodate,
scaleX,
ms = max - min,
canvasHeight = config.canvasHeight,
scrollToDate = config.scrolltodate,
canvasWidth = config.canvasWidth,
datems,
canvasLeft = config.canvasLeft,
hProcessScrollBar = components.hProcessScrollBar,
hScrollBar = components.hScrollBar,
maxHScrollBarHeight,
hScrollBarHeight = hScrollBar && hScrollBar.userConf.height || 0,
hProcessScrollHeight = hProcessScrollBar && hProcessScrollBar.userConf.height || 0,
datePixel,
totalWidth = xAxis.getPixel(max) - canvasLeft,
processTotalHeight = yAxis.getAxisConfig('processTotalHeight'),
totalVisiblelProcessWidth,
totalProcessWidth,
actualCanvasHeight,
width,
units;
if (gPaneDuration === UNDEF || gPaneDurationUnit === UNDEF) {
config.hScrollEnabled = false;
}
else {
switch (gPaneDurationUnit) {
case 'y' :
minDt.setFullYear(minDt.getFullYear() + gPaneDuration);
break;
case 'm' :
minDt.setMonth(minDt.getMonth() + gPaneDuration);
break;
case 'd' :
minDt.setDate(minDt.getDate() + gPaneDuration);
break;
case 'h' :
minDt.setHours(minDt.getHours() + gPaneDuration);
break;
case 'mn' :
minDt.setMinutes(minDt.getMinutes() + gPaneDuration);
break;
default :
minDt.setSeconds(minDt.getSeconds() + gPaneDuration);
break;
}
minDt = minDt.getTime();
width = xAxis.getPixel(minDt) - canvasLeft;
config.hScrollEnabled = true;
//update the scaleX for the axis.
config.viewPortConfig.scaleX = scaleX = totalWidth / width;
//parse the scroll properties
scrollOptions.horizontalVxLength = (ms / units) * gPaneDuration;
if (scrollToDate) {
datems = numberFormatter.getDateValue (scrollToDate).ms;
datePixel = xAxis.getPixel(datems);
config.viewPortConfig.x = (mathMin(datePixel - canvasLeft, canvasWidth * (scaleX - 1)) / scaleX);
// console.log(config.viewPortConfig.x);
}
}
totalProcessWidth = yAxis.getAxisConfig('totalWidth');
totalVisiblelProcessWidth = yAxis.getAxisConfig('totalVisiblelWidth');
if (totalProcessWidth > totalVisiblelProcessWidth) {
config.hProcessScrollEnabled = true;
}
else {
config.hProcessScrollEnabled = false;
}
maxHScrollBarHeight = mathMax(config.hProcessScrollEnabled ? hProcessScrollHeight : 0,
config.hScrollEnabled ? hScrollBarHeight : 0);
actualCanvasHeight = canvasHeight - maxHScrollBarHeight;
if (Math.floor(processTotalHeight) > actualCanvasHeight) {
config.viewPortConfig.scaleY = processTotalHeight / actualCanvasHeight;
config.vScrollEnabled = true;
}
else {
config.vScrollEnabled = false;
}
},
drawScrollBar: function () {
var iapi = this,
config = iapi.config,
components = iapi.components,
xAxis = components.xAxis[0],
axisConfig = xAxis.config,
axisRange = xAxis.config.axisRange,
viewPortConfig = config.viewPortConfig,
scrollOptions = config.scrollOptions || (config.scrollOptions = {}),
max = axisRange.max,
min = axisRange.min,
vxLength = scrollOptions.horizontalVxLength,
hScrollBar = components.hScrollBar,
hScrollNode = hScrollBar.node,
vScrollBar = components.vScrollBar,
vScrollNode = vScrollBar.node,
hProcessScrollBar = components.hProcessScrollBar,
hProcessScrollNode = hProcessScrollBar.node,
useVerticalScrollBar = config.useverticalscrolling,
scrollableLength = max - min,
canvasRight = config.canvasRight,
scaleX = viewPortConfig.scaleX,
scaleY = viewPortConfig.scaleY,
canvasLeft,
canvasTop,
canvasHeight,
canvasWidth,
canvasConfig,
canvasBorderWidth,
aXisLineWidth,
aXisLineStartExtension,
aXisLineEndExtension,
scrollRatio,
vScrollRatio,
windowedCanvasHeight,
fullCanvasHeight,
vScrollEnabled = config.vScrollEnabled,
// canvasHeight = config.canvasHeight,
yAxis = components.yAxis[0],
windowedCanvasWidth,
vScrollWidth = vScrollEnabled ? vScrollBar.conf.width : 0,
fullCanvasWidth,
totalProcessWidth,
totalVisiblelProcessWidth,
graphics = iapi.graphics,
scrollBarParentGroup,
paper = components.paper;
canvasLeft = config.canvasLeft;
canvasTop = config.canvasTop;
canvasHeight = config.canvasHeight;
canvasWidth = config.canvasWidth;
canvasConfig = components.canvas.config;
canvasBorderWidth = canvasConfig.canvasBorderWidth;
aXisLineWidth = pluckNumber(canvasBorderWidth, (axisConfig.showLine ? axisConfig.axisLineThickness : 0));
aXisLineStartExtension = pluckNumber(canvasBorderWidth, axisConfig.lineStartExtension);
aXisLineEndExtension = pluckNumber(canvasBorderWidth, axisConfig.lineEndExtension);
scrollOptions.viewPortMin = min;
scrollOptions.viewPortMax = max;
scrollRatio = (scrollOptions.scrollRatio = vxLength / scrollableLength);
windowedCanvasWidth = scrollOptions.windowedCanvasWidth = xAxis.getAxisPosition(vxLength);
fullCanvasWidth = scrollOptions.fullCanvasWidth =
xAxis.getAxisPosition(max - min) - windowedCanvasWidth;
fullCanvasHeight = scrollOptions.fullCanvasHeight = yAxis.getAxisConfig('processTotalHeight');
windowedCanvasHeight = scrollOptions.windowedCanvasHeight = canvasHeight;
totalProcessWidth = yAxis.getAxisConfig('totalWidth');
totalVisiblelProcessWidth = yAxis.getAxisConfig('totalVisiblelWidth');
vScrollRatio = 1 / scaleY;
scrollBarParentGroup = graphics.scrollBarParentGroup;
if (!scrollBarParentGroup) {
scrollBarParentGroup = graphics.scrollBarParentGroup = paper.group('scrollBarParentGroup',
graphics.parentGroup).insertBefore(graphics.datalabelsGroup);
}
//draw the scroller element
// todo padding needs to be included.
if (config.hScrollEnabled !== false) {
hScrollBar.draw (canvasLeft,
canvasTop + canvasHeight,{
width: canvasWidth - vScrollWidth,
scrollRatio: 1 / scaleX,
scrollPosition: (viewPortConfig.x * scaleX) / (canvasWidth * (scaleX - 1)),
roundEdges: canvasConfig.isRoundEdges,
fullCanvasWidth: fullCanvasWidth,
windowedCanvasWidth: windowedCanvasWidth,
parentLayer: scrollBarParentGroup
});
// attach the callback for raising event only for it is a new scroll node.
!hScrollNode && (function () {
var prevPos;
R.eve.on('raphael.scroll.start.' + hScrollBar.node.id, function (pos) {
prevPos = pos;
global.raiseEvent('scrollstart', {
scrollPosition: pos
}, iapi.chartInstance);
});
R.eve.on('raphael.scroll.end.' + hScrollBar.node.id, function (pos) {
global.raiseEvent('scrollend', {
prevScrollPosition: prevPos,
scrollPosition: pos
}, iapi.chartInstance);
});
}());
}
else {
hScrollBar && hScrollBar.node && hScrollBar.node.hide();
}
if (vScrollEnabled !== false && useVerticalScrollBar) {
vScrollBar.draw (canvasRight - vScrollWidth, canvasTop, {
height: canvasHeight,
scrollRatio: vScrollRatio,
roundEdges: canvasConfig.isRoundEdges,
fullCanvasWidth: fullCanvasHeight,
windowedCanvasWidth: windowedCanvasHeight,
parentLayer: scrollBarParentGroup
});
// attach the callback for raising event only for it is a new scroll node.
!vScrollNode && (function () {
var prevPos;
R.eve.on('raphael.scroll.start.' + vScrollBar.node.id, function (pos) {
prevPos = pos;
global.raiseEvent('scrollstart', {
scrollPosition: pos
}, iapi.chartInstance);
});
R.eve.on('raphael.scroll.end.' + vScrollBar.node.id, function (pos) {
global.raiseEvent('scrollend', {
prevScrollPosition: prevPos,
scrollPosition: pos
}, iapi.chartInstance);
});
}());
}
else {
vScrollBar && vScrollBar.node && vScrollBar.node.hide();
}
if (totalVisiblelProcessWidth < totalProcessWidth) {
hProcessScrollBar.draw (canvasLeft - totalVisiblelProcessWidth,
canvasTop + canvasHeight,{
width: totalVisiblelProcessWidth,
scrollRatio: totalVisiblelProcessWidth/totalProcessWidth,
roundEdges: canvasConfig.isRoundEdges,
fullCanvasWidth: fullCanvasWidth,
windowedCanvasWidth: windowedCanvasWidth,
parentLayer: scrollBarParentGroup
});
// attach the callback for raising event only for it is a new scroll node.
!hProcessScrollNode && (function () {
var prevPos;
R.eve.on('raphael.scroll.start.' + hProcessScrollBar.node.id, function (pos) {
prevPos = pos;
global.raiseEvent('scrollstart', {
scrollPosition: pos
}, iapi.chartInstance);
});
R.eve.on('raphael.scroll.end.' + hProcessScrollBar.node.id, function (pos) {
global.raiseEvent('scrollend', {
prevScrollPosition: prevPos,
scrollPosition: pos
}, iapi.chartInstance);
});
}());
}
else {
hProcessScrollBar && hProcessScrollBar.node && hProcessScrollBar.node.hide();
}
},
_createLayers: function () {
var iapi = this,
components = iapi.components,
paper = components.paper,
config = iapi.config,
inCanStyle = config.style.inCanvasStyle,
labelStyle,
datasetGroup,
graphics;
chartapi.mscartesian._createLayers.call(iapi);
graphics = iapi.graphics;
datasetGroup = graphics.datasetGroup;
graphics.parentTaskGroup = graphics.parentTaskGroup || paper.group('parentTaskGroup', datasetGroup);
graphics.parentConnectorsGroup = graphics.parentConnectorsGroup ||
paper.group('parentConnectorsGroup', datasetGroup);
graphics.parentMilestoneGroup = graphics.parentMilestoneGroup ||
paper.group('parentMilestoneGroup', datasetGroup);
labelStyle = iapi.config.milestoneLabelStyle = {
fontSize: pluckNumber (config.milestonefontsize,
inCanStyle.fontSize) + PX,
fontFamily: pluck (config.milestonefont,
inCanStyle.fontFamily),
fontWeight: pluckNumber (config.milestonefontbold, 0) && BOLD || NORMAL,
fontStyle: pluckNumber (config.milestonefontitalic, 0) && ITALIC || NORMAL
};
setLineHeight(labelStyle);
graphics.parentMilestoneGroup.css(labelStyle);
},
_drawDataset: function () {
this._setClipping();
chartapi.mscartesian._drawDataset.call(this);
},
drawLegend: function () {
var iapi = this,
config = iapi.config,
components = iapi.components,
legend = components.legend,
legendConf = legend.config,
legendWidth = legendConf.width,
legendHeight = legendConf.height,
legendPosition = legendConf.legendPos,
marginLeft = config.marginLeft,
marginTop = config.marginTop,
chartWidth = config.width,
marginRight = config.marginRight,
marginBottom = config.marginBottom,
totalWidth = config.totalWidth + config.canvasWidth,
totalHeight = config.totalHeight + config.canvasHeight,
chartHeight = config.height,
spaceLeft,
xPos,
yPos;
if (legendPosition === 'right') {
spaceLeft = totalHeight - legendHeight;
xPos = chartWidth - legendWidth - marginRight;
yPos = marginTop + (spaceLeft < 0 ? 0 : spaceLeft) / 2;
}
else {
spaceLeft = totalWidth - legendWidth;
xPos = marginLeft + (spaceLeft < 0 ? 0 : spaceLeft) / 2;
yPos = chartHeight - legendHeight - marginBottom;
}
legend.drawLegend(xPos, yPos);
},
_setClipping: function () {
var chart = this,
config = chart.config,
datasetLayer = chart.graphics.datasetGroup,
dataLabelsLayer = chart.graphics.datalabelsGroup,
trackerLayer = chart.graphics.trackerGroup,
viewPortConfig = config.viewPortConfig,
scaleX = viewPortConfig.scaleX,
x = viewPortConfig.x,
animationObj = chart.config.animationObj,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animType = animationObj.animType,
animationDuration = animationObj.transposeAnimDuration,
clipCanvas = chart.components.canvas.config.clip['clip-canvas'].slice(0);
if (!chart.config.clipSet) {
datasetLayer.attr({
'clip-rect': clipCanvas
});
dataLabelsLayer.attr({
'clip-rect': clipCanvas
});
trackerLayer.attr({
'clip-rect': clipCanvas
});
}
else {
datasetLayer.animateWith(dummyAnimElem, dummyAnimObj, {
'clip-rect': clipCanvas
}, animationDuration, animType);
dataLabelsLayer.animateWith(dummyAnimElem, dummyAnimObj, {
'clip-rect': clipCanvas
}, animationDuration, animType);
trackerLayer.animateWith(dummyAnimElem, dummyAnimObj, {
'clip-rect': clipCanvas
}, animationDuration, animType);
}
config.xOffset = (x * scaleX);
datasetLayer.attr({
transform: 'T' + -(x * scaleX) + ',0'
});
dataLabelsLayer.attr({
transform: 'T' + -(x * scaleX) + ',0'
});
trackerLayer.attr({
transform: 'T' + -(x * scaleX) + ',0'
});
chart.config.clipSet = true;
},
_createToolBox: function () {
var iapi = this,
components = iapi.components,
yAxis = components.yAxis[0],
_scrollBar = iapi._scrollBar,
chartMenuBar = components.chartMenuBar || {},
actionBar = components.actionBar,
getScrollItems = _scrollBar.get,
addScrollItems = _scrollBar.add,
tb,
Scroller,
ComponentGroup,
hScrollItem,
hScrollItem1,
vScrollItem,
toolBoxAPI;
if (chartMenuBar.drawn || actionBar && actionBar.drawn) {
return;
}
// create the export or print buttons if required.
chartapi.mscartesian._createToolBox.call(iapi);
tb = components.tb;
toolBoxAPI = components.toolBoxAPI;
Scroller = toolBoxAPI.Scroller;
ComponentGroup = toolBoxAPI.ComponentGroup;
// temp code: On update scroll items needs to be reused.
_scrollBar.clear();
// Adding the scroll items in the scroll bar.
addScrollItems({
isHorizontal: true
}, {
// Attach the callback for scroll Interaction.
'scroll' : (function (ref, isHorizontal) {
return function () {
ref.updateManager.call(ref, arguments[0], isHorizontal);
};
})(iapi, true)
});
addScrollItems({
isHorizontal: false
}, {
// Attach the callback for scroll Interaction.
'scroll' : (function (ref, isHorizontal) {
return function () {
ref.updateManager.call(ref, arguments[0], isHorizontal);
};
})(iapi, false)
});
addScrollItems({
isHorizontal: true
}, {
// Attach the callback for scroll Interaction.
'scroll' : (function () {
return function () {
yAxis.manageProcessScroll(arguments[0]);
};
})(iapi, true)
});
// Fetching the scroll Items.
hScrollItem = getScrollItems()[0];
vScrollItem = getScrollItems()[1];
hScrollItem1 = getScrollItems()[2];
// adding the scrollbar. tb.pid is the component pool id
components.hScrollBar = components.hScrollBar || (new Scroller(hScrollItem.conf, 1, tb.pId)
.attachEventHandlers(hScrollItem.handler));
components.vScrollBar = components.vScrollBar || (new Scroller(vScrollItem.conf, 2, tb.pId)
.attachEventHandlers(vScrollItem.handler));
components.hProcessScrollBar = components.hProcessScrollBar || (
new Scroller(hScrollItem1.conf, 3, tb.pId).attachEventHandlers(hScrollItem1.handler));
},
_preDraw : function () {
var iapi = this;
iapi._setAxisValuePadding();
iapi._setCategories();
iapi.chartMenuTools.reset(iapi.components.tb, iapi);
},
defaultPaletteOptions : merge (extend2 ( { }, lib.defaultGaugePaletteOptions), {
//Colors for gauge '339900', 'DD9B02', '943A0A',
paletteColors:
[['AFD8F8', 'F6BD0F', '8BBA00', 'FF8E46', '008E8E',
'D64646', '8E468E', '588526', 'B3AA00', '008ED6', '9D080D',
'A186BE', 'CC6600', 'FDC689', 'ABA000', 'F26D7D', 'FFF200',
'0054A6', 'F7941C', 'CC3300', '006600', '663300', '6DCFF6'],
['AFD8F8', 'F6BD0F', '8BBA00', 'FF8E46', '008E8E',
'D64646', '8E468E', '588526', 'B3AA00', '008ED6', '9D080D',
'A186BE', 'CC6600', 'FDC689', 'ABA000', 'F26D7D', 'FFF200',
'0054A6', 'F7941C', 'CC3300', '006600', '663300', '6DCFF6'],
['AFD8F8', 'F6BD0F', '8BBA00', 'FF8E46', '008E8E',
'D64646', '8E468E', '588526', 'B3AA00', '008ED6', '9D080D',
'A186BE', 'CC6600', 'FDC689', 'ABA000', 'F26D7D', 'FFF200',
'0054A6', 'F7941C', 'CC3300', '006600', '663300', '6DCFF6'],
['AFD8F8', 'F6BD0F', '8BBA00', 'FF8E46', '008E8E',
'D64646', '8E468E', '588526', 'B3AA00', '008ED6', '9D080D',
'A186BE', 'CC6600', 'FDC689', 'ABA000', 'F26D7D', 'FFF200',
'0054A6', 'F7941C', 'CC3300', '006600', '663300', '6DCFF6'],
['AFD8F8', 'F6BD0F', '8BBA00', 'FF8E46', '008E8E',
'D64646', '8E468E', '588526', 'B3AA00', '008ED6', '9D080D',
'A186BE', 'CC6600', 'FDC689', 'ABA000', 'F26D7D', 'FFF200',
'0054A6', 'F7941C', 'CC3300', '006600', '663300', '6DCFF6']],
//Store other colors
// ------------- For 2D Chart ---------------//
//We're storing 5 combinations, as we've 5 defined palettes.
bgColor: ['FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF'],
bgAngle: [270, 270, 270, 270, 270],
bgRatio: ['100', '100', '100', '100', '100'],
bgAlpha: ['100', '100', '100', '100', '100'],
canvasBgColor: ['FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF'],
canvasBgAngle: [0, 0, 0, 0, 0],
canvasBgAlpha: ['100', '100', '100', '100', '100'],
canvasBgRatio: ['', '', '', '', ''],
canvasBorderColor: ['545454', '545454', '415D6F', '845001', '68001B'],
canvasBorderAlpha: [100, 100, 100, 90, 100],
gridColor: ['DDDDDD', 'D8DCC5', '99C4CD', 'DEC49C', 'FEC1D0'],
gridResizeBarColor: ['999999', '545454', '415D6F', '845001', 'D55979'],
categoryBgColor: ['F1F1F1', 'EEF0E6', 'F2F8F9', 'F7F0E6', 'FFF4F8'],
dataTableBgColor: ['F1F1F1', 'EEF0E6', 'F2F8F9', 'F7F0E6', 'FFF4F8'],
toolTipBgColor: ['FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF', 'FFFFFF'],
toolTipBorderColor: ['545454', '545454', '415D6F', '845001', '68001B'],
baseFontColor: ['555555', '60634E', '025B6A', 'A15E01', '68001B'],
borderColor: ['767575', '545454', '415D6F', '845001', '68001B'],
borderAlpha: [50, 50, 50, 50, 50],
legendBgColor: ['ffffff', 'ffffff', 'ffffff', 'ffffff', 'ffffff'],
legendBorderColor: ['666666', '545454', '415D6F', '845001', 'D55979'],
plotBorderColor: ['999999', '8A8A8A', '6BA9B6', 'C1934D', 'FC819F'],
plotFillColor: ['EEEEEE', 'D8DCC5', 'BCD8DE', 'E9D8BE', 'FEDAE3'],
scrollBarColor: ['EEEEEE', 'D8DCC5', '99C4CD', 'DEC49C', 'FEC1D0']
})
}, chartapi.scrollbase, { // @todo: parse this attributes in chart level
taskbarroundradius: 0,
taskbarfillmix: ' { light-10 }, { dark-20 }, { light-50 }, { light-85 }',
taskbarfillratio: '0,8,84,8',
showslackasfill: 1,
dateintooltip: 1,
tasklabelsalign: 'center',
datepadding: 3,
showtasknames: 0,
showpercentlabel: false,
showhovereffect: 1,
slackfillcolor: 'FF5E5E',
connectorextension: 10,
tasklabelspadding: 2,
taskdatepadding: 3,
showlabels: UNDEFINED,
showtooltip: 1,
showtaskhovereffect: undefined,
useverticalscrolling: 1,
ganttpanedurationunit: undefined,
ganttpaneduration: undefined,
showtaskstartdate: undefined,
showtaskenddate: undefined,
ganttwidthpercent: undefined,
showshadow: 1,
enablemousetracking: false
});
// set attribute definations
setAttribDefs && setAttribDefs({
showpercentlabel: {
type: attrTypeBool,
pAttr: 'showpercentlabel'
},
fontsize: {
type: attrTypeNum
},
alpha: {
type: attrTypeNum
},
showborder: {
type: attrTypeBool
},
borderthickness: {
type: attrTypeNum
},
borderalpha: {
type: attrTypeNum
},
showHoverEffect: {
type: attrTypeNum
},
hoverFillAlpha: {
type: attrTypeNum
},
slackHoverFillColor: {
type: attrTypeNum
},
slackHoverFillAlpha: {
type: attrTypeBool
},
showlabels: {
type: attrTypeBool,
pAttr: 'showtasknames'
},
slackfillcolor: {
pAttr: 'slackfillcolor'
},
showtasklabels: {
type: attrTypeBool,
pAttr: 'showtasknames'
},
showtasknames: {
type: attrTypeBool,
pAttr: 'showlabels'
},
showconnectorhovereffect: {
type: attrTypeNum,
pAttr: 'showhovereffect'
},
connectorextension: {
type: attrTypeNum
},
tasklabelspadding: {
type: attrTypeNum
},
taskdatepadding: {
type: attrTypeNum
},
showstartdate: {
type: attrTypeNum,
pAttr: 'showtaskstartdate'
},
showenddate: {
type: attrTypeNum,
pAttr: 'showtaskenddate'
},
showtaskhovereffect: {
type: attrTypeNum,
pAttr: 'showhovereffect'
},
useverticalscrolling: {
type: attrTypeNum
},
taskbarroundradius: {
type: attrTypeNum
},
showshadow: {
type: attrTypeNum
},
showslackasfill: {
type: attrTypeNum
}
});
FusionCharts.register('component', ['dataset', 'Task',{
type: 'task',
configure: function(){
var dataSet = this,
jsonData = dataSet.JSONData,
chart = dataSet.chart,
userConfig = extend2({}, jsonData);
// set the default configurations
dataSet.__setDefaultConfig();
parseConfiguration(userConfig, dataSet.config, dataSet.chart && dataSet.chart.config, {task: true});
dataSet.yAxis = chart.components.yAxis[0];
dataSet._setConfigure();
},
_setConfigure: function (newDataset) {
var dataset = this,
datasetConfig = dataset.config,
chart = dataset.chart,
jsonData = chart.jsonData,
chartAttrs = jsonData.chart,
JSONData = dataset.JSONData,
setDataArr = newDataset || JSONData.task,
processes = jsonData.processes || {},
process = processes.process || [],
setDataLen = setDataArr && setDataArr.length,
colorM = chart.components.colorManager,
chartConfig = chart.get('config'),
numberFormatter = chart.get('components', 'numberFormatter'),
// taskRadius = chartConfig.taskbarroundradius,
taskMix = chartConfig.taskbarfillmix,
taskRatio = chartConfig.taskbarfillratio,
showSlackAsFill = chartConfig.showslackasfill,
dataStore = dataset.components.data,
percentComplete,
eDate,
sDate,
i,
FCDPID = '__FCDPID__',
arrColor,
arrAlpha,
arrRatio,
dataLabel,
serializeProcessId,
dInt = chartConfig.dateintooltip,
dataObj,
taskObj,
proLen = process.length,
alignVal = {
right: 'right',
left: 'left',
'undefined': 'center',
'center': 'center'
},
id,
tAlpha,
tBorderAlpha,
tBorderColor,
label,
color,
fillAngle,
showPercentLabel,
tasksMap = chart.components.tasksMap = {},
inCanStyle = chartConfig.style.inCanvasStyle,
toolText,
slHovColor,
slColor,
tColorObj,
tHovColor,
tHovBorderColor,
taskId,
numTasks = 0,
dataConfig,
dataLabelStyle = chartConfig.dataLabelStyle,
datasetLabelStyle,
setLabelStyle;
if (!dataStore) {
dataStore = dataset.components.data = [];
}
datasetConfig.showlabels = pluck(JSONData.showlabels, JSONData.showlabels, JSONData.showname,
chartAttrs.showtasklabels, chartAttrs.showtasknames, 0);
datasetLabelStyle = datasetConfig.labelStyle = extractLabelStyle({
fontSize: datasetConfig.fontSize,
fontFamily: datasetConfig.font
});
setLineHeight(datasetConfig.labelStyle);
// Tasks
if (setDataLen) {
// dmin = Infinity;
// dmax = -Infinity;
for (i = 0; i < setDataLen; i += 1) {
taskObj = setDataArr[i];
serializeProcessId = numTasks % proLen;
id = pluck (taskObj.processid);
if (id && typeof id === 'string') {
id = id.toLowerCase();
}
taskId = taskObj.id;
percentComplete = taskObj.percentcomplete;
tAlpha = pluckNumber (taskObj.alpha, datasetConfig.alpha);
color = pluck (taskObj.color, datasetConfig.color, colorM.getColor ('plotFillColor'));
tBorderAlpha = pluckNumber (taskObj.borderalpha, datasetConfig.borderalpha, '100');
tBorderColor = pluck (taskObj.bordercolor, datasetConfig.bordercolor,
colorM.getColor('plotBorderColor'));
label = getFirstValue (pluck (taskObj.label, taskObj.name), BLANK);
//Parse the task color, ratio & alpha
arrColor = colorM.parseColorMix (color, taskMix);
arrAlpha = colorM.parseAlphaList (tAlpha.toString (), arrColor.length);
arrRatio = colorM.parseRatioList (taskRatio, arrColor.length);
fillAngle = pluckNumber (taskObj.angle, datasetConfig.angle);
dataObj = dataStore[i] || (dataStore[i] = {
config: {}
});
dataConfig = dataObj.config;
dataConfig.index = i;
dataConfig.link = taskObj.link;
dataConfig.processId = pluck(taskObj.processid, FCDPID + serializeProcessId);
// dataConfig.style = {
// fontSize: pluckNumber (taskObj.fontsize, datasetConfig.fontsize,
// inCanStyle.fontSize) + PX,
// fontFamily: pluck (taskObj.font, datasetConfig.font,
// inCanStyle.fontFamily)
// };
dataConfig.textColor = getFirstColor (pluck (taskObj.fontcolor,
datasetConfig.fontcolor, inCanStyle.color));
dataConfig.style = extractLabelStyle({
fontSize: taskObj.fontsize,
fontFamily: taskObj.font
});
setLineHeight(dataConfig.style);
setLabelStyle = dataConfig.style;
dataConfig.lineHeight = pluck(setLabelStyle && setLabelStyle.lineHeight, datasetLabelStyle &&
datasetLabelStyle.lineHeight, dataLabelStyle && dataLabelStyle.lineHeight);
dataConfig.startMs = numberFormatter.getDateValue (taskObj.start).ms;
dataConfig.endMs = numberFormatter.getDateValue (taskObj.end).ms;
sDate = numberFormatter.getFormattedDate (dataConfig.startMs);
eDate = numberFormatter.getFormattedDate (dataConfig.endMs);
dataConfig.tAlpha = tAlpha;
dataConfig.tBorderColor = tBorderColor;
dataConfig.tBorderAlpha = tBorderAlpha;
dataLabel = BLANK;
dataConfig.percentComplete = percentComplete =
mathMin (pluckNumber (taskObj.percentcomplete, -1), 100);
dataConfig.labelAlign = alignVal[[pluck (taskObj.labelalign,
chartConfig.tasklabelsalign).toLowerCase ()]];
dataConfig.showAsGroup = pluckNumber (taskObj.showasgroup, 0);
showPercentLabel = dataConfig.showPercentLabel = pluckNumber (taskObj.showpercentlabel,
datasetConfig.showpercentlabel);
if (pluckNumber (taskObj.showlabel, taskObj.showname,
datasetConfig.showlabels)) {
dataLabel = label;
}
if (showPercentLabel && percentComplete !== -1) {
dataLabel += ' ' + percentComplete + '%';
}
dataConfig.percentComplete = percentComplete;
tColorObj = {
FCcolor: {
color: arrColor.join (),
alpha: arrAlpha,
ratio: arrRatio,
angle: fillAngle
}
};
slColor = colorM.parseColorMix (pluck (taskObj.slackfillcolor,
datasetConfig.slackfillcolor), taskMix);
slColor = showSlackAsFill ? {
FCcolor: {
color: slColor.join (),
alpha: arrAlpha,
ratio: arrRatio,
angle: fillAngle
}
} : TRACKER_FILL;
tHovColor = {
FCcolor: {
color: colorM.parseColorMix (pluck (taskObj.hoverfillcolor,
datasetConfig.hoverfillcolor, chartConfig.taskhoverfillcolor,
getDarkColor (color, 80)), taskMix).join (),
alpha: colorM.parseAlphaList (pluck (taskObj.hoverfillalpha,
datasetConfig.hoverfillalpha).toString (), arrColor.length),
ratio: arrRatio,
angle: fillAngle
}
};
tHovBorderColor = convertColor (pluck (taskObj.hoverbordercolor,
datasetConfig.hoverbordercolor, getDarkColor (tBorderColor, 80)),
pluck (taskObj.hoverborderalpha, datasetConfig.hoverborderalpha,
tBorderAlpha));
slHovColor = showSlackAsFill ? {
FCcolor: {
color: colorM.parseColorMix (getDarkColor (pluck (taskObj.slackhoverfillcolor,
datasetConfig.slackhoverfillcolor, chartConfig.slackfillcolor), 80), taskMix).join (),
alpha: colorM.parseAlphaList (pluck (taskObj.slackhoverfillalpha,
datasetConfig.slackhoverfillalpha, '100').toString (), arrColor.length),
ratio: arrRatio,
angle: fillAngle
}
} : TRACKER_FILL;
dataConfig.color = toRaphaelColor (tColorObj),
dataConfig.slackColor = toRaphaelColor (slColor),
dataConfig.hoverFillColor = toRaphaelColor (tHovColor),
dataConfig.hoverBorderColor = tHovBorderColor,
dataConfig.slackHoverColor = toRaphaelColor (slHovColor),
dataConfig.showHoverEffect = pluckNumber (taskObj.showhovereffect,
datasetConfig.showhovereffect, chartConfig.showtaskhovereffect, 1);
dataConfig.taskHeight = pluck(taskObj.height, '35%');
dataConfig.topPadding = pluck (taskObj.toppadding, '35%');
dataConfig.showPercentLabel = showPercentLabel;
dataConfig.endDate = pluckNumber (taskObj.showenddate,
datasetConfig.showenddate) ? eDate : UNDEF;
dataConfig._endDate = eDate;
dataConfig.startDate = pluckNumber (taskObj.showstartdate,
datasetConfig.showstartdate) ? sDate : UNDEF;
dataConfig._startDate = sDate;
dataConfig.shadow = {
opacity: mathMax (tAlpha, tBorderAlpha) / 100,
inverted: true
};
dataConfig.id = id;
dataConfig.taskId = taskId;
dataConfig.borderColor = convertColor (tBorderColor,
tBorderAlpha),
dataConfig.borderThickness = pluckNumber (taskObj.showborder,
datasetConfig.showborder) ? pluckNumber (taskObj.borderthickness,
datasetConfig.borderthickness) : 0;
toolText = getValidValue (parseUnsafeString (pluck (
taskObj.tooltext, datasetConfig.hovertext, datasetConfig.plottooltext,
chartAttrs.plottooltext)));
if (toolText !== undefined) {
toolText = lib.parseTooltext (toolText, [3,28,29,30,31], {
end: eDate,
start: sDate,
label: label,
percentComplete: percentComplete !== -1 ?
numberFormatter.percentValue (percentComplete) : BLANK,
processName: ''
}, datasetConfig);
}
else {
toolText = ((label !== BLANK) ?
(label + (dInt ? ', ' : BLANK)) : BLANK) +
(dInt ? (sDate + ' - ' + eDate) : BLANK);
}
dataConfig.label = dataLabel;
dataConfig.toolText = toolText;
typeof taskId === 'string' && (taskId = taskId.toLowerCase());
if (taskId !== UNDEFINED) {
tasksMap[taskId] = dataStore[i];
}
numTasks += 1;
}
}
dataset.visible = pluckNumber(JSONData.visible, 1);
},
getAxisValuePadding: function(){},
draw: function() {
var dataSet = this,
i,
visible = dataSet.visible,
chart = dataSet.chart,
jsonData = chart.jsonData,
chartConfig = chart.get('config'),
animationObj = chart.get('config', 'animationObj'),
animationDuration = animationObj.duration,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animType = animationObj.animType,
chartComponents = chart.components,
canvasTop = chartConfig.canvasTop,
paper = chartComponents.paper,
xAxis = chartComponents.xAxis[0],
len,
yAxis = dataSet.yAxis,
parentContainer = chart.graphics.parentTaskGroup,
components = dataSet.components,
dataStore = components.data,
dataObj,
config,
removeDataArr = components.removeDataArr,
removeDataArrLen = removeDataArr && removeDataArr.length,
dataLabelsLayer = chart.graphics.datalabelsGroup,
dataLabelContainer = dataSet.graphics.dataLabelContainer,
initAnimCallBack = function () {
dataLabelContainer.show();
},
graphics = dataSet.graphics,
container = graphics.container,
shadowContainer = graphics.shadowContainer,
pool = components.pool || [],
endX,
startMs,
endMs,
setLink,
toolText,
height,
id,
pHeight,
width,
width2,
xPos,
yPos,
position,
taskBarElement,
perComElem,
slackElem,
borderThickness,
elemType,
isNewElem,
taskBarElementAttrs,
beforeAnimAttrs,
crispBox,
halfH,
txtAlign,
borderFill,
padding,
eventArgs,
incrementId,
showTooltip = chartConfig.showtooltip,
datePadding = chartConfig.datepadding,
taskHeight,
viewPortConfig = chartConfig.viewPortConfig,
x = viewPortConfig.x,
labelTextAttr,
endLabelTextAttr,
startLabelTextAttr,
jobList = chart.getJobList(),
proLen = jsonData.processes.process && jsonData.processes.process.length,
scaleX = viewPortConfig.scaleX,
taskBarRadius = chartConfig.taskbarroundradius,
shadow = chartConfig.showshadow,
cursor,
processDimention,
conf = dataSet.config,
lineHeight;
/*
* Creating a container group for the graphic element of column plots if
* not present and attaching it to its parent group.
*/
if (!container) {
container = dataSet.graphics.container = paper.group('columns', parentContainer);
if (!visible) {
container.hide();
}
else {
container.show();
}
}
if (!dataLabelContainer) {
dataLabelContainer = dataSet.graphics.dataLabelContainer = paper.group('labels', dataLabelsLayer);
if (!visible) {
dataLabelContainer.hide();
}
else {
dataLabelContainer.show();
}
dataLabelContainer.css(conf.labelStyle);
}
else {
dataLabelContainer.removeCSS();
dataLabelContainer.css(conf.labelStyle);
}
/*
* Creating the shadow element container group for each plots if not present
* and attaching it its parent group.
*/
if (!shadowContainer) {
// Always sending the shadow group to the back of the plots group.
shadowContainer = dataSet.graphics.shadowContainer =
paper.group('shadow', parentContainer).toBack();
if (!visible) {
shadowContainer.hide();
}
}
if (!showTooltip) {
container.trackTooltip(false);
}
else {
container.trackTooltip(true);
}
len = dataStore.length;
incrementId = 0;
// Create plot elements.
for (i = 0; i < len; i++) {
dataObj = dataStore[i];
config = dataObj && dataObj.config;
startMs = config && config.startMs;
endMs = config && config.endMs;
// Condition arises when user has removed data in real time update
if (dataObj === undefined || startMs === undefined || endMs === null) {
continue;
}
toolText = config.toolText;
taskHeight = config.taskHeight;
setLink = config.link;
borderThickness = config.borderThickness;
id = config.id;
borderFill = config.color;
lineHeight = config.lineHeight;
isNewElem = false;
if (incrementId > proLen - 1) {
incrementId = 0;
}
if (config.id !== undefined) {
processDimention = yAxis.getProcessPositionById(id);
} else {
processDimention = yAxis.getProcessPositionByIndex(incrementId);
}
incrementId++;
pHeight = processDimention.height;
padding = (pHeight * (isPercent (config.topPadding) &&
toFloat (config.topPadding, 10) * 0.01)) ||
pluckNumber (config.topPadding, pHeight);
height = config.height = (pHeight * (isPercent(taskHeight) &&
toFloat(taskHeight, 10) * 0.01)) ||
pluckNumber(taskHeight, pHeight);
position = config.id !== undefined ? yAxis.getProcessPositionById(id) : i;
xPos = config.xPos = xAxis.getAxisPosition(config.startMs) + (x * scaleX);
endX = xAxis.getAxisPosition(config.endMs) + (x * scaleX);
width = config.width = mathAbs (width2 = endX - xPos);
yPos = processDimention.bottom + canvasTop - pHeight;
yPos = config.yPos = (yPos + mathMin (padding, pHeight - height));
halfH = height * 0.5;
!dataObj.graphics && (dataObj.graphics = {});
crispBox = R.crispBound (xPos, yPos, width, height, borderThickness);
xPos = crispBox.x;
yPos = crispBox.y;
width = crispBox.width;
height = crispBox.height;
if (checkInvalidValue(xPos, yPos, width, height) === false) {
continue;
}
taskBarElement = dataObj.graphics.element;
if (config.showAsGroup) {
elemType = 'path';
beforeAnimAttrs = {
path: [M, xPos, yPos]
};
taskBarElementAttrs = {
path: [M, xPos, yPos, v, height,
L, xPos + halfH, yPos + halfH, H, xPos + width - halfH,
L, xPos + width, yPos + height, v, -height, H, xPos]
};
}
else {
elemType = 'rect';
taskBarElementAttrs = {
x: crispBox.x,
y: crispBox.y,
width: crispBox.width || 1,
height: height
};
if (animationDuration) {
beforeAnimAttrs = {
x: crispBox.x,
y: crispBox.y,
width: 0,
height: height
};
}
else {
beforeAnimAttrs = taskBarElementAttrs;
}
}
if (taskBarElement && (taskBarElement && taskBarElement.type !== elemType)) {
taskBarElement.hide();
taskBarElement = dataObj.graphics.element = null;
}
if (!taskBarElement) {
elemType = config.showAsGroup ? 'path' : 'rect';
if (pool.element && pool.element.length && (taskBarElement = pool.element[0]).type ===
elemType) {
dataObj.graphics.element = taskBarElement = pool.element.shift();
}
else {
taskBarElement = dataObj.graphics.element = paper[elemType](container)
.attr(beforeAnimAttrs)
.data('dataset', dataSet);
isNewElem = true;
dataSet.slackElemHandlers(taskBarElement, chart);
}
}
eventArgs = config.eventArgs = {
processId: config.processId,
taskId: config.taskId,
start: config._startDate,
end: config._endDate,
showAsGroup: config.showAsGroup,
link: config.link,
sourceType: 'task',
percentComplete: config.percentComplete !== -1
};
if (config.percentComplete !== -1 && !config.showAsGroup) {
width2 = width * config.percentComplete * 0.01;
borderFill = TRACKER_FILL;
perComElem = dataObj.graphics.taskFill;
slackElem = dataObj.graphics.slackElem;
// Percent complete element
if (!perComElem) {
if (pool.taskFill && pool.taskFill.length) {
perComElem = dataObj.graphics.taskFill = pool.taskFill.shift();
}
else {
perComElem = dataObj.graphics.taskFill = paper.rect(container);
dataSet.slackElemHandlers(perComElem, chart);
isNewElem = true;
perComElem.attr({
x: xPos,
y: yPos,
height: height,
width: animationDuration ? 0 : width2
});
}
}
// Slack Element
if (!slackElem) {
// Reuse elemnt from pool if any
if (pool.slackElem && pool.slackElem.length) {
slackElem = dataObj.graphics.slackElem = pool.slackElem.shift();
}
else {
slackElem = dataObj.graphics.slackElem = paper.rect(container);
dataSet.slackElemHandlers(slackElem, chart);
isNewElem = true;
slackElem.attr({
x: xPos,
y: yPos,
width: 0,
height: height
});
}
}
perComElem.show().animateWith(dummyAnimElem, dummyAnimObj, {
x: xPos,
y: yPos,
height: height,
width: width2,
r: 0
}, animationDuration, animType);
perComElem.attr({
fill: config.color,
cursor: setLink ? 'pointer' : BLANK,
ishot: true,
'stroke-width': 0
})
.data('chart', chart)
.data('dataObj', dataObj)
.data('dataset', dataSet)
.tooltip (toolText);
slackElem.show().animateWith(dummyAnimElem, dummyAnimObj, {
x: (xPos + width2) || 1,
y: yPos,
width: width - width2,
height: height,
r: 0
}, animationDuration, animType);
slackElem.attr({
fill: config.slackColor,
cursor: setLink ? 'pointer' : BLANK,
ishot: true,
'stroke-width': 0
});
perComElem && perComElem.data ('eventArgs', eventArgs);
slackElem && slackElem.data ('eventArgs', eventArgs)
.data('dataObj', dataObj)
.data('dataset', dataSet)
.data('chart', chart);
}
else {
// If there are slack elements then hide those
dataObj.graphics.taskFill && dataObj.graphics.taskFill.hide();
dataObj.graphics.slackElem && dataObj.graphics.slackElem.hide();
}
// set the attr
taskBarElement.show().animateWith(dummyAnimElem, dummyAnimObj, taskBarElementAttrs, animationDuration,
animType)
.attr ({
fill: borderFill,
stroke: config.borderColor,
cursor: setLink ? 'pointer' : BLANK,
ishot: true,
r: taskBarRadius,
'stroke-width': borderThickness
})
.shadow({
opacity: shadow
}, shadowContainer)
.tooltip (toolText)
.data('dataObj', dataObj)
.data('chart', chart)
.data('dataset', dataSet)
.data('eventArgs', eventArgs);
if (animationDuration && isNewElem) {
dataLabelContainer.hide();
taskBarElement.animateWith (dummyAnimElem, dummyAnimObj, {
width: crispBox.width || 1
}, animationDuration, animType, initAnimCallBack);
}
cursor = setLink ? 'pointer' : BLANK;
txtAlign = config.labelAlign;
labelTextAttr = config._labelTextAttr || (config._labelTextAttr = {});
labelTextAttr.x = xPos + (width * xAlign[txtAlign]) + alignGutter[txtAlign];
labelTextAttr.y = (yPos - (pInt (lineHeight, 10) * 0.5) - chartConfig.tasklabelspadding);
labelTextAttr.text = config.label;
labelTextAttr.direction = chartConfig.textDirection;
labelTextAttr['text-anchor'] = align[txtAlign];
labelTextAttr.cursor = cursor;
labelTextAttr.ishot = true;
labelTextAttr.fill = config.textColor;
labelTextAttr['line-height'] = lineHeight;
startLabelTextAttr = config._startLabelTextAttr || (config._startLabelTextAttr = {});
startLabelTextAttr.x = xPos - 2 - datePadding,
startLabelTextAttr.y = (yPos + (height * 0.5));
startLabelTextAttr.text = config.startDate;
startLabelTextAttr['text-anchor'] = 'end';
startLabelTextAttr.cursor = cursor;
startLabelTextAttr.ishot = true;
startLabelTextAttr.direction = chartConfig.textDirection;
startLabelTextAttr.fill = config.textColor;
startLabelTextAttr['line-height'] = lineHeight;
endLabelTextAttr = config._endLabelTextAttr || (config._endLabelTextAttr = {});
endLabelTextAttr.x = xPos + width + 2 + datePadding;
endLabelTextAttr.y = (yPos + (height * 0.5));
endLabelTextAttr.text = config.endDate;
endLabelTextAttr.cursor = cursor;
endLabelTextAttr.ishot = true;
endLabelTextAttr.direction = chartConfig.textDirection;
endLabelTextAttr['text-anchor'] = 'start';
endLabelTextAttr.fill = config.textColor;
endLabelTextAttr['line-height'] = lineHeight;
config.cursor = cursor;
isNewElem = false;
}
dataSet.drawn ? dataSet.drawLabel() : jobList.labelDrawID.push(schedular.addJob(dataSet.drawLabel,
dataSet, [], lib.priorityList.label));
// Setting the drawn flag true to draw differently incase of real time draw.
dataSet.drawn = true;
for (i = 0; i < removeDataArrLen; i++) {
dataSet._removeDataVisuals(removeDataArr.shift());
}
},
drawLabel: function () {
var dataset = this,
chart = dataset.chart,
paper = chart.components.paper,
dataStore = dataset.components.data,
pool = dataset.components.pool || {},
valElem,
startValElem,
endValElem,
config,
animationObj = chart.get('config','animationObj'),
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animationDuration = animationObj.duration,
animType = animationObj.animType,
dataObj,
eventArgs,
textAttr,
startLabelTextAttr,
endLabelTextAttr,
cursor,
dataLabelContainer = dataset.graphics.dataLabelContainer,
i,
len = dataStore.length;
for (i = 0; i < len; i++) {
dataObj = dataStore[i];
config = dataObj.config;
graphics = dataObj.graphics;
valElem = graphics.label;
startValElem = graphics.startValElem;
endValElem = graphics.endValElem;
cursor = config.cursor;
eventArgs = config.eventArgs;
if (defined (config.label) && config.label !== BLANK) {
textAttr = config._labelTextAttr;
valElem = graphics.label || (graphics.label = pool.valElem && pool.valElem.shift());
if (!valElem) {
valElem = dataObj.graphics.label = paper.text(textAttr, config.style, dataLabelContainer)
.data('dataset', dataset);
dataset.slackElemHandlers(valElem, chart);
}
else {
valElem.removeCSS();
valElem.show().animateWith(dummyAnimElem, dummyAnimObj, textAttr,
animationDuration, animType)
.css(config.style);
}
valElem.data('dataObj', dataObj)
.data('dataObj', dataObj)
.data('eventArgs', eventArgs);
}
else {
valElem && valElem.hide();
}
textAttr = config._startLabelTextAttr;
// Task start date element
startValElem = dataObj.graphics.startLabel;
if (defined (config.startDate) && config.startDate !== BLANK) {
startLabelTextAttr = config._startLabelTextAttr;
startValElem = graphics.startLabel || (graphics.startLabel = pool.startValElem &&
pool.startValElem.shift());
if (!startValElem) {
startValElem = dataObj.graphics.startLabel = paper.text(startLabelTextAttr, config.style,
dataLabelContainer)
.data('dataset', dataset);
dataset.slackElemHandlers(startValElem, chart);
}
else {
startValElem.removeCSS();
startValElem.show().animateWith(dummyAnimElem, dummyAnimObj, startLabelTextAttr,
animationDuration, animType).css(config.style);
}
startValElem.data('dataObj', dataObj)
.data('chart', chart)
.data('eventArgs', eventArgs);
}
else {
startValElem && startValElem.hide();
}
// Task end date label drawing
endValElem = dataObj.graphics.endLabel;
if (defined (config.endDate) && config.endDate !== BLANK) {
endLabelTextAttr = config._endLabelTextAttr;
endValElem = graphics.endLabel || (graphics.endLabel = pool.endValElem && pool.endValElem.shift());
if (!endValElem) {
endValElem = dataObj.graphics.endLabel = paper.text(endLabelTextAttr, config.style,
dataLabelContainer).data('dataset', dataset);
dataset.slackElemHandlers(endValElem, chart);
}
else {
endValElem.removeCSS();
endValElem.show().animateWith(dummyAnimElem, dummyAnimObj, endLabelTextAttr,
animationDuration, animType).css (config.style);
}
endValElem.data('dataObj', dataObj)
.data('chart', chart)
.data('eventArgs', eventArgs);
}
else {
endValElem && endValElem.hide();
}
}
},
slackElemHandlers: function (ele, chart) {
var dataset = this;
ele && ele.click (function (e) {
var ele = this;
plotEventHandler.call (ele, chart, e);
})
.hover (function (data) {
var ele = this,
dataObj = ele.data ('dataObj');
plotEventHandler.call (ele, chart, data, ROLLOVER);
dataObj.config.showHoverEffect && dataset.taskHoverHandler.call (ele, chart);
}, function (data) {
var ele = this,
dataObj = ele.data ('dataObj');
plotEventHandler.call (ele, chart, data, ROLLOUT);
dataObj.config.showHoverEffect && dataset.taskHoverOutHandler.call (ele, chart);
});
},
taskHoverHandler: function () {
var ele = this,
dataObj = ele.data ('dataObj') || {},
dataset = ele.data('dataset'),
dataStore = dataset.components.data,
config = dataObj.config || {},
index = config.index,
graphics = dataStore[index] && dataStore[index].graphics,
attrib = {
fill: config.hoverFillColor,
stroke: config.hoverBorderColor
};
if (config.percentComplete !== -1 &&
!config.showAsGroup) {
graphics.slackElem.attr ( {
fill: config.slackHoverColor
});
graphics.taskFill.attr ( {
fill: config.hoverFillColor
});
delete attrib.fill;
}
graphics.element.attr (attrib);
},
taskHoverOutHandler: function () {
var ele = this,
dataObj = ele.data ('dataObj') || {},
dataset = ele.data ('dataset') || {},
dataStore = dataset.components.data,
config = dataObj.config || {},
index = config.index,
graphics = dataStore[index] && dataStore[index].graphics,
attrib = {
fill: config.color,
stroke: config.borderColor,
'stroke-width': config.borderThickness,
'stroke-dasharray': config.dashedStyle
};
if (graphics) {
if (config.percentComplete !== -1 &&
!config.showAsGroup) {
graphics.slackElem.attr ( {
fill: config.slackColor
});
graphics.taskFill.attr ( {
fill: config.color
});
delete attrib.fill;
}
graphics.element.attr (attrib);
}
},
slackElemClickHandler: function (e) {
var ele = this,
chart = ele.data('chart');
plotEventHandler.call (ele, chart, e);
},
// Function to remove a data from a dataset during real time update.
_removeDataVisuals : function (dataObj) {
var dataSet = this,
pool = dataSet.components.pool || (dataSet.components.pool = {}),
elementPool,
ele,
graphics,
graphicsObj;
if (!dataObj) {
return;
}
graphics = dataObj.graphics;
for (ele in graphics) {
elementPool = pool[ele] || (pool[ele] = []);
graphicsObj = graphics[ele];
if (graphicsObj.hide && typeof graphicsObj.hide === 'function') {
graphicsObj.attr({
'text-bound': []
});
graphicsObj.hide();
graphicsObj.transform && graphicsObj.transform('');
}
elementPool.push(graphics[ele]);
}
}
}, 'column', {
// configurations with defult values
showpercentlabel: undefined,
showlabels: undefined,
showborder: 1,
borderthickness: 1,
// inherated from parent
font: '',
fontcolor: '',
fontsize: '',
color: '',
alpha: '100',
angle: 270,
slackfillcolor: undefined,
borderalpha: '100',
hoverfillcolor: '',
hoverfillalpha: '100',
slackhoverfillalpha: '100',
showstartdate: UNDEFINED,
showenddate: UNDEFINED
}]);
FusionCharts.register('component', ['dataset', 'Milestone',{
type: 'Milestone',
configure: function(){
var dataSet = this,
config = dataSet.config,
jsonData = dataSet.JSONData,
chart = dataSet.chart,
userConfig = extend2({}, jsonData);
dataSet.__setDefaultConfig();
parseConfiguration(userConfig, config, {milestones: true});
dataSet.yAxis = chart.components.yAxis[0];
dataSet._setConfigure();
},
_setConfigure: function (newDataset) {
var dataset = this,
chart = dataset.chart,
JSONData = dataset.JSONData,
setDataArr = newDataset || JSONData.milestone,
setDataLen = setDataArr && setDataArr.length,
colorM = chart.components.colorManager,
chartConfig = chart.get('config'),
numberFormatter = chart.get('components', 'numberFormatter'),
dataStore = dataset.components.data,
style = chart.config.style,
inCanStyle = style.inCanvasStyle,
tasksMap = chart.components.tasksMap,
dataObj,
taskConfigObj,
dataConfig,
i,
setData,
sides,
color,
shape,
depth,
toolText,
hoverFillColor,
taskId,
labelStyle = chart.config.milestoneLabelStyle,
dateMs,
milestoneDate;
if (!dataStore) {
dataStore = dataset.components.data = [];
}
for (i = 0; i < setDataLen; i += 1) {
setData = setDataArr[i];
dataObj = dataStore[i];
if (!dataObj) {
dataObj = dataStore[i] = {
config: {}
};
}
dataConfig = dataObj.config;
taskId = getFirstValue (setData.taskid, BLANK).toLowerCase ();
shape = pluck (setData.shape, 'polygon').toLowerCase ();
sides = pluckNumber (setData.numsides, 5);
//Restrict
//shape = (shape == 'star') ? shape : mapSymbolName (sides);
depth = 0;
if (shape === 'star') {
depth = 0.4;
} else {
shape = mapSymbolName (sides);
shape = mapSymbolName (sides).split ('-')[0];
}
color = pluck (setData.color, colorM.getColor ('legendBorderColor'));
toolText = getValidValue (parseUnsafeString (pluck (setData.tooltext,
setData.hovertext, chartConfig.milestonetooltext)));
dateMs = numberFormatter.getDateValue(setData.date).ms;
milestoneDate = numberFormatter.getFormattedDate(dateMs);
if (toolText !== undefined && tasksMap[taskId]) {
taskConfigObj = tasksMap[taskId].config;
toolText = lib.parseTooltext (toolText, [28,32,33,34,35,36], {
date: milestoneDate,
taskStartDate: taskConfigObj._startDate,
taskEndDate: taskConfigObj._endDate,
taskLabel: taskConfigObj.label,
taskPercentComplete: taskConfigObj.percentComplete !== -1 ?
numberFormatter.percentValue (taskConfigObj.percentComplete) : BLANK,
// @todo add the process name from data table once created
processName: ''
}, setData);
}
else {
toolText = milestoneDate;
}
// style = {
// fontSize: pluckNumber (setData.fontsize, chartConfig.milestonefontsize,
// inCanStyle.fontSize) + PX,
// fontFamily: pluck (setData.font, chartConfig.milestonefont,
// inCanStyle.fontFamily),
// fontWeight: pluckNumber (setData.fontbold,
// chartConfig.milestonefontbold, 0) && BOLD || NORMAL,
// fontStyle: pluckNumber (setData.fontitalic,
// chartConfig.milestonefontitalic, 0) && ITALIC || NORMAL
// };
style = dataConfig.style = extractLabelStyle({
fontSize: setData.fontsize,
fontFamily: setData.font,
fontWeight: setData.fontbold,
fontStyle: setData.fontitalic
});
dataConfig.textColor = getFirstColor (pluck (setData.fontcolor,
chartConfig.milestonefontcolor, inCanStyle.color));
setLineHeight (style);
dataConfig.lineHeight = pluck(style && style.lineHeight, labelStyle && labelStyle.lineHeight);
dataConfig.numSides = sides,
dataConfig.startAngle = pluckNumber (setData.startangle, 90),
dataConfig.radius = setData.radius,
dataConfig.origDate = setData.date,
dataConfig.date = numberFormatter.getDateValue (setData.date),
dataConfig.fillColor = getFirstColor (color),
dataConfig.fillAlpha = pluckNumber (setData.fillalpha, setData.alpha, 100) * 0.01,
dataConfig.borderColor = getFirstColor (pluck (setData.bordercolor, color)),
dataConfig.borderAlpha = pluckNumber (setData.borderalpha, setData.alpha, 100) * 0.01,
dataConfig.displayValue = parseUnsafeString (setData.label),
dataConfig.style = style;
hoverFillColor = dataConfig.hoverFillColor = getFirstColor (pluck (setData.hoverfillcolor,
chartConfig.milestonehoverfillcolor, getDarkColor (color, 80))),
dataConfig.hoverFillAlpha = pluckNumber (setData.hoverfillalpha,
chartConfig.milestonehoverfillalpha, setData.fillalpha,
setData.alpha, 100) * 0.01,
dataConfig.hoverBorderColor = getFirstColor (pluck (setData.hoverbordercolor,
chartConfig.milestonehoverbordercolor,
getDarkColor (pluck (setData.bordercolor, color), 80))),
dataConfig.hoverBorderAlpha = pluckNumber (setData.hoverborderalpha,
chartConfig.milestonehoverborderalpha, setData.borderalpha,
setData.alpha, 100) * 0.01,
dataConfig.showHoverEffect = pluckNumber (setData.showhovereffect,
chartConfig.showmilestonehovereffect, chartConfig.showhovereffect, 1),
dataConfig.depth = depth,
dataConfig.taskId = taskId,
dataConfig.borderThickness = pluckNumber (setData.borderthickness, 1),
dataConfig.link = setData.link;
dataConfig.toolText = toolText;
}
dataset.visible = pluckNumber(JSONData.visible, 1);
},
draw: function () {
var dataset = this,
chart = dataset.chart,
chartComponents = chart.components,
components = dataset.components,
xAxis = chartComponents.xAxis[0],
dataStore = components.data,
taskMap = chartComponents.tasksMap,
chartConfig = chart.config,
animationObj = chart.get('config', 'animationObj'),
animationDuration = animationObj.duration,
container = dataset.graphics.container,
parentContainer = chart.graphics.parentMilestoneGroup,
dataLabelContainer = dataset.graphics.dataLabelContainer,
visible = dataset.visible,
paper = chartComponents.paper,
removeDataArr = dataset.components.removeDataArr || [],
removeDataArrLen = removeDataArr.length,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animType = animationObj.animType,
dataObj,
taskObj,
graphics,
config,
eventArgs,
taskConfigObj,
setElement,
xPos,
yPos,
polypath,
radius,
milestoneAnimate,
labelElement,
i,
ln,
labelAttrs,
jobList = chart.getJobList(),
showTooltip = chartConfig.showtooltip,
pool = dataset.components.pool || [];
if (!container) {
container = dataset.graphics.container = paper.group('milestone', parentContainer);
if (!visible) {
container.hide();
}
else {
container.show();
}
}
if (!dataLabelContainer) {
dataLabelContainer = dataset.graphics.dataLabelContainer = paper.group('labels', parentContainer);
if (!visible) {
dataLabelContainer.hide();
}
else {
dataLabelContainer.show();
}
}
if (!showTooltip) {
container.trackTooltip(false);
}
else {
container.trackTooltip(true);
}
ln = dataStore && dataStore.length;
for (i = 0; i < ln; i += 1) {
dataObj = dataStore[i];
if (!dataObj) {
continue;
}
config = dataObj.config;
taskObj = taskMap[config.taskId];
!dataObj.graphics && (dataObj.graphics = {});
graphics = dataObj.graphics;
setElement = graphics.element;
labelElement = graphics.label;
if (taskObj) {
taskConfigObj = taskObj.config;
milestoneAnimate = R.animation ({
'fill-opacity': config.fillAlpha,
'stroke-opacity': config.borderAlpha
},
animationDuration, animType);
eventArgs = config.eventArgs = {
sides: config.sides,
date: config.origDate,
radius: config.radius,
taskId: config.taskId,
toolText: config.toolText,
link: config.link,
numSides: config.numSides
};
xPos = xAxis.getPixel (config.date.ms);
yPos = taskConfigObj.yPos + (taskConfigObj.height * 0.5);
radius = pluckNumber (config.radius, taskConfigObj.height * 0.6);
if (checkInvalidValue(xPos, yPos, radius) === false) {
continue;
}
polypath = [config.numSides, xPos, yPos, radius, config.startAngle, config.depth];
if (!setElement) {
if (pool.element && pool.element.length) {
setElement = graphics.element = pool.element.shift();
}
else {
setElement = graphics.element = paper.polypath(container)
.click(dataset.clickHandler(chart))
.hover (dataset.rollOverHandler(chart), dataset.rollOutHandler(chart));
}
}
setElement.show().animateWith(dummyAnimElem, dummyAnimObj, {
polypath: polypath
}, animationDuration, animType).attr({
fill: config.fillColor,
'fill-opacity': animationDuration ? 0 : config.fillAlpha,
stroke: config.borderColor,
'stroke-opacity': animationDuration ? 0 : config.borderAlpha,
groupId: 'gId' + i,
ishot: true,
cursor: config.link ? 'pointer' : BLANK,
'stroke-width': config.borderThickness
})
.tooltip(config.toolText)
.data ('eventArgs', eventArgs)
.data ('dataObj', dataObj);
if (animationDuration && milestoneAnimate && !dataset.drawn) {
graphics.element.animateWith(dummyAnimElem, dummyAnimObj,
milestoneAnimate.delay (animationDuration));
}
labelAttrs = config._labelAttrs || (config._labelAttrs = {});
labelAttrs.x = xPos;
labelAttrs.y = yPos;
labelAttrs.text = config.displayValue;
labelAttrs.groupId = 'gId' + i;
labelAttrs.cursor = config.link ? 'pointer' : BLANK;
labelAttrs.ishot = true;
labelAttrs.direction = chartConfig.textDirection;
labelAttrs['text-anchor'] = 'middle';
labelAttrs.fill = config.textColor;
}
else {
setElement && setElement.hide();
labelElement && labelElement.hide();
}
}
dataset.drawn ? dataset.drawLabel() : jobList.labelDrawID.push(schedular.addJob(dataset.drawLabel,
dataset, [], lib.priorityList.label));
dataset.drawn = true;
for (i = 0; i < removeDataArrLen; i++) {
dataset._removeDataVisuals(removeDataArr.shift());
}
},
drawLabel: function () {
var dataset = this,
chart = dataset.chart,
paper = chart.components.paper,
animationObj = chart.get('config', 'animationObj'),
animationDuration = animationObj.duration,
animType = animationObj.animType,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
tasksMap = chart.components.tasksMap,
config,
dataLabelContainer = dataset.graphics.dataLabelContainer,
eventArgs,
dataObj,
i,
labelElement,
len,
graphics,
labelAttrs,
taskObj,
pool = dataset.components.pool || {},
dataStore = dataset.components.data,
style;
for (i = 0, len = dataStore.length; i < len; i++) {
dataObj = dataStore[i];
config = dataObj.config;
taskObj = tasksMap[config.taskId];
graphics = dataObj.graphics;
labelElement = graphics.label;
eventArgs = config.eventArgs;
labelAttrs = config._labelAttrs;
style = config.style;
if (config.displayValue !== BLANK && config.displayValue !== UNDEFINED && taskObj) {
labelElement = graphics.label || (graphics.label = pool.label && pool.label.shift());
// Drawing of milestone label element
if (!labelElement) {
labelElement = graphics.label = paper.text (labelAttrs, style, dataLabelContainer)
.click (dataset.clickHandler(chart))
.hover (dataset.rollOverHandler(chart), dataset.rollOutHandler(chart));
}
else {
labelElement.removeCSS();
labelElement.show().animateWith(dummyAnimElem, dummyAnimObj, labelAttrs,
animationDuration, animType)
.css (style);
}
labelElement.tooltip(config.toolText)
.data ('eventArgs', eventArgs)
.data ('dataObj', dataObj);
}
else {
labelElement && labelElement.hide();
}
}
},
clickHandler: function (chart) {
return function (event) {
var ele = this;
/**
* In `Gantt` chart, milestones are an important part of the chart as they allow you to visually
* depict any crucial dates on the chart.
* This event is fired when a milestone is clicked
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#milestoneClick
*
* @param {string} date - The date of the milestone.
* @param {string} numSides - The number of sides of the milestone.
* @param {string} radius - The radius of the milestone.
* @param {string} taskId - The id of the task to which this milestone relates to.
* @param {string} toolText - The tooltext that is displayed when hovered over the milestone
* @param {number} chartX - x-coordinate of the pointer relative to the chart.
* @param {number} chartY - y-coordinate of the pointer relative to the chart.
* @param {number} pageX - x-coordinate of the pointer relative to the page.
* @param {number} pageY - y-coordinate of the pointer relative to the page.
* @see FusionCharts#event:milestoneRollOver
* @see FusionCharts#event:milestoneRollOut
*/
plotEventHandler.call(ele, chart, event, 'MilestoneClick');
};
},
rollOverHandler: function (chart) {
return function (event) {
var ele = this,
dataObj = ele.data('dataObj'),
config = dataObj.config;
/**
* In `Gantt` chart, milestones are an important part of the chart as they allow you to visually
* depict any crucial dates on the chart.
* This event is fired when the pointer moves over a milestone
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#milestoneRollOver
*
* @param {string} date - The date of the milestone.
* @param {string} numSides - The number of sides of the milestone.
* @param {string} radius - The radius of the milestone.
* @param {string} taskId - The id of the task to which this milestone relates to.
* @param {string} toolText - The tooltext that is displayed when hovered over the milestone
* @param {number} chartX - x-coordinate of the pointer relative to the chart.
* @param {number} chartY - y-coordinate of the pointer relative to the chart.
* @param {number} pageX - x-coordinate of the pointer relative to the page.
* @param {number} pageY - y-coordinate of the pointer relative to the page.
* @see FusionCharts#event:milestoneClick
* @see FusionCharts#event:milestoneRollOut
*/
plotEventHandler.call(ele, chart, event, 'MilestoneRollOver');
config.showHoverEffect && dataObj.graphics.element.attr({
fill: config.hoverFillColor,
stroke: config.hoverBorderColor,
'fill-opacity': config.hoverFillAlpha,
'stroke-opacity': config.hoverBorderAlpha
});
};
},
rollOutHandler: function (chart) {
return function (event) {
var ele = this,
dataObj = ele.data('dataObj'),
config = dataObj.config;
/**
* In `Gantt` chart, milestones are an important part of the chart as they allow you to visually
* depict any crucial dates on the chart.
* This event is fired when the pointer moves out of a milestone
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#milestoneRollOut
*
* @param {string} date - The date of the milestone.
* @param {string} numSides - The number of sides of the milestone.
* @param {string} radius - The radius of the milestone.
* @param {string} taskId - The id of the task to which this milestone relates to.
* @param {string} toolText - The tooltext that is displayed when hovered over the milestone
* @param {number} chartX - x-coordinate of the pointer relative to the chart.
* @param {number} chartY - y-coordinate of the pointer relative to the chart.
* @param {number} pageX - x-coordinate of the pointer relative to the page.
* @param {number} pageY - y-coordinate of the pointer relative to the page.
* @see FusionCharts#event:milestoneClick
* @see FusionCharts#event:milestoneRollOver
*/
plotEventHandler.call(ele, chart, event, 'MilestoneRollOut');
config.showHoverEffect && dataObj.graphics.element.attr({
fill: config.fillColor,
stroke: config.borderColor,
'fill-opacity': config.fillAlpha,
'stroke-opacity': config.borderAlpha
});
};
}
}, 'Task', {
// configurations with defult values
showpercentlabel: 0,
showstartdate: 0,
showenddate: 0,
showlabels: undefined,
showborder: 1,
borderthickness: 1,
showHoverEffect: 1,
slackFillColor: 'FF5E5E',
// inherated from parent
font: '',
fontcolor: '',
fontsize: '',
color: '',
alpha: '100', // not found
bordercolor: '',// not found
borderalpha: '100', // not found
hoverFillColor: '',// not found
hoverFillAlpha: '100', // not found
slackHoverFillColor: 10, // not found
slackHoverFillAlpha: '100' // notfound
}]);
FusionCharts.register('component', ['dataset', 'Connectors',{
configure: function () {
var dataSet = this,
config = dataSet.config,
jsonData = dataSet.JSONData,
chart = dataSet.chart,
userConfig = extend2({}, jsonData);
dataSet.__setDefaultConfig();
parseConfiguration(userConfig, config, {connector: true});
dataSet.yAxis = chart.components.yAxis[0];
dataSet._setConfigure();
},
_setConfigure: function (newDataset) {
var dataset = this,
datasetConfig = dataset.config,
chart = dataset.chart,
JSONData = dataset.JSONData,
setDataArr = newDataset || JSONData.connector,
setDataLen = (setDataArr && setDataArr.length) || 0,
colorM = chart.components.colorManager,
chartConfig = chart.get('config'),
dataStore = dataset.components.data,
i,
dataObj,
setData,
config,
cnColor,
cnAlpha,
cnThickness,
cnIsDashed;
if (!dataStore) {
dataStore = dataset.components.data = [];
}
// Connectors
for (i = 0; i < setDataLen; i += 1) {
setData = setDataArr[i];
dataObj = dataStore[i];
if (!dataObj) {
dataObj = dataStore[i] = {
config : {}
};
}
!dataObj.config && (dataObj.config = {});
config = dataObj.config;
// Extract the attributes
cnColor = pluck (setData.color, datasetConfig.color, colorM.getColor ('plotBorderColor'));
cnAlpha = pluckNumber (setData.alpha, datasetConfig.alpha, 100);
cnThickness = pluckNumber (setData.thickness, datasetConfig.thickness, 1);
cnIsDashed = pluckNumber (setData.isdashed, datasetConfig.isdashed, 1);
config.fromTaskId = getFirstValue (setData.fromtaskid, BLANK).toLowerCase ();
config.toTaskId = getFirstValue (setData.totaskid, BLANK).toLowerCase (),
config.fromTaskConnectStart = pluckNumber (setData.fromtaskconnectstart, 0),
config.toTaskConnectStart = pluckNumber (setData.totaskconnectstart, 1),
config.color = convertColor (cnColor);
config.alpha = cnAlpha * 0.01;
config.link = setData.link;
config.showHoverEffect = pluckNumber (setData.showhovereffect,
datasetConfig.showhovereffect, chartConfig.showconnectorhovereffect, 1);
config.hoverColor = convertColor (pluck (setData.hovercolor,
datasetConfig.hovercolor, chartConfig.connectorhovercolor,
getDarkColor (cnColor, 80)),
pluckNumber (setData.hoveralpha,
datasetConfig.hoveralpha, chartConfig.connectorhoveralpha, cnAlpha));
config.hoverThickness = pluckNumber (setData.hoverthickness,
datasetConfig.hoverthickness, chartConfig.connectorhoverthickness,
cnThickness);
config.thickness = cnThickness;
config.dashedStyle = cnIsDashed ?
getDashStyle (pluckNumber (setData.dashlen,
datasetConfig.dashlen, 5),
pluckNumber (setData.dashgap, datasetConfig.dashgap,
cnThickness), cnThickness) : DASH_DEF;
}
dataset.visible = pluckNumber(JSONData.visible, 1);
},
draw: function () {
var dataset = this,
chart = dataset.chart,
chartComponents = chart.components,
dataStore = dataset.components.data,
paper = chartComponents.paper,
chartConfig = chart.config,
ln = dataStore.length,
taskMap = chartComponents.tasksMap,
cExt = chartConfig.connectorextension,
parentContainer = chart.graphics.parentConnectorsGroup,
container = dataset.graphics.container,
pool = dataset.components.pool || [],
visible = dataset.visible,
animationObj = chart.get('config', 'animationObj'),
animationDuration = animationObj.duration,
dummyAnimElem = animationObj.dummyObj,
dummyAnimObj = animationObj.animObj,
animType = animationObj.animType,
removeDataArr = dataset.components.removeDataArr || [],
removeDataArrLen = removeDataArr.length,
startTaskId,
endTaskId,
stTObj,
endTObj,
dataObj,
graphics,
isStraightLine,
stY,
etY,
stx1,
stx2,
etx1,
etx2,
diff,
cnCase,
config,
stTConfig,
endTConfig,
opacity,
cPath,
tH,
connector,
initialAnimDuration,
eventArgs,
applyFn,
trackerElement,
dashLength,
dashGap,
connectorAnimation,
i;
if (!container) {
container = dataset.graphics.container = paper.group('connectors', parentContainer);
if (!visible) {
container.hide();
}
else {
container.show();
}
}
//Iterate through each and draw it
for (i = 0; i <= ln; i += 1) {
dataObj = dataStore[i];
if (!dataObj) {
continue;
}
config = dataObj.config;
!dataObj.graphics && (dataObj.graphics = {});
graphics = dataObj.graphics;
startTaskId = config.fromTaskId && config.fromTaskId.toLowerCase();
endTaskId = config.toTaskId && config.toTaskId.toLowerCase();
stTObj = taskMap[startTaskId];
endTObj = taskMap[endTaskId];
connector = graphics.connector;
//If the connector's from and to Id are defined, only then we draw the connector
if (stTObj && endTObj) {
stTConfig = stTObj.config;
endTConfig = endTObj.config;
//Y Positions
stY = stTConfig.yPos + (stTConfig.height * 0.5);
etY = endTConfig.yPos + (endTConfig.height * 0.5);
//Check if the to and from bars are in straight line
isStraightLine = (stY == etY);
//Dash properties
dashLength = 3;
dashGap = config.isDashed ? (config.thickness + 2) : 0;
//X Positions
stx1 = stTConfig.xPos;
stx2 = stTConfig.xPos + stTConfig.width;
etx1 = endTConfig.xPos;
etx2 = endTConfig.xPos + endTConfig.width;
if (checkInvalidValue(stx1, stx2, etx1, etx2) === false) {
continue;
}
diff = 0;
//There can be four cases if the two tasks are not in straight line
cnCase = 0;
//cnCase 1: End of StartTask to Start of EndTask
if (config.fromTaskConnectStart === 0 && config.toTaskConnectStart === 1) {
cnCase = 1;
}
//cnCase 2: End of StartTask to End of EndTask
if (config.fromTaskConnectStart === 0 && config.toTaskConnectStart === 0) {
cnCase = 2;
}
//cnCase 3: Start of StartTask to Start of EndTask
if (config.fromTaskConnectStart === 1 && config.toTaskConnectStart === 1) {
cnCase = 3;
}
//cnCase 4: Start of StartTask to End of EndTask
if (config.fromTaskConnectStart === 1 && config.toTaskConnectStart === 0) {
cnCase = 4;
}
if (isStraightLine) {
tH = stTConfig.height;
switch (cnCase) {
case 1 :
diff = (etx1 - stx2) / 10;
cPath = [M, stx2, stY, stx2 + diff, stY,
L, stx2 + diff, stY, stx2 + diff, stY - tH,
L, stx2 + diff, stY - tH, etx1 - diff, stY - tH,
L, etx1 - diff, stY - tH, etx1 - diff, stY,
L, etx1 - diff, stY, etx1, etY];
break;
case 2 :
cPath = [M, stx2, stY, stx2 + cExt, stY,
L, stx2 + cExt, stY, stx2 + cExt, stY - tH,
L, stx2 + cExt, stY - tH, etx2 + cExt, stY - tH,
L, etx2 + cExt, etY - tH, etx2 + cExt, etY,
etx2, etY];
break;
case 3 :
cPath = [M, stx1, stY, stx1 - cExt, stY,
L, stx1 - cExt, stY, stx1 - cExt, stY - tH,
L, stx1 - cExt, stY - tH, etx1 - cExt, stY - tH,
L, etx1 - cExt, stY - tH, etx1 - cExt, stY,
L, etx1 - cExt, stY, etx1, stY];
break;
case 4 :
cPath = [M, stx1, stY, stx1 - cExt, stY,
L, stx1 - cExt, stY, stx1 - cExt, stY - tH,
L, stx1 - cExt, stY - tH, etx2 + cExt, stY - tH,
L, etx2 + cExt, stY - tH, etx2 + cExt, stY,
L, etx2 + cExt, stY, etx2, stY];
break;
}
} else {
switch (cnCase) {
case 1 :
cPath = [M, stx2, stY, stx2 + (etx1 - stx2) / 2, stY,
L, stx2 + (etx1 - stx2) / 2, stY, stx2 + (etx1 - stx2) / 2, etY,
L, stx2 + (etx1 - stx2) / 2, etY, etx1, etY];
if (stx2 <= etx1) {
cPath = [M, stx2, stY, stx2 + (etx1 - stx2) / 2, stY,
L, stx2 + (etx1 - stx2) / 2, stY, stx2 + (etx1 - stx2) / 2, etY,
L, stx2 + (etx1 - stx2) / 2, etY, etx1, etY];
} else {
cPath = [M, stx2, stY, stx2 + cExt, stY,
L, stx2 + cExt, stY, stx2 + cExt, stY + (etY - stY) / 2,
L, stx2 + cExt, stY + (etY - stY) / 2, etx1 - cExt, stY + (etY - stY) / 2,
L, etx1 - cExt, stY + (etY - stY) / 2, etx1 - cExt, etY,
L, etx1 - cExt, etY, etx1, etY];
}
break;
case 2 :
diff = ((etx2 - stx2) < 0) ? (0) : (etx2 - stx2);
cPath = [M, stx2, stY, stx2 + cExt + diff, stY,
L, stx2 + cExt + diff, stY, stx2 + cExt + diff, etY,
L, stx2 + cExt + diff, etY, etx2, etY];
break;
case 3 :
diff = ((stx1 - etx1) < 0) ? (0) : (stx1 - etx1);
cPath = [M, stx1, stY, stx1 - cExt - diff, stY,
L, stx1 - cExt - diff, stY, stx1 - cExt - diff, etY,
L, stx1 - cExt - diff, etY, etx1, etY];
break;
case 4 :
if (stx1 > etx2) {
cPath = [M, stx1, stY, stx1 - (stx1 - etx2) / 2, stY,
L, stx1 - (stx1 - etx2) / 2, stY, stx1 - (stx1 - etx2) / 2, etY,
L, stx1 - (stx1 - etx2) / 2, etY, etx2, etY];
} else {
cPath = [M, stx1, stY, stx1 - cExt, stY,
L, stx1 - cExt, stY, stx1 - cExt, stY + (etY - stY) / 2,
L, stx1 - cExt, stY + (etY - stY) / 2, etx2 + cExt, stY + (etY - stY) / 2,
L, etx2 + cExt, stY + (etY - stY) / 2, etx2 + cExt, etY,
L, etx2 + cExt, etY, etx2, etY];
}
break;
}
}
if (!connector) {
if (pool.connector && pool.connector.length) {
connector = graphics.connector = pool.connector.shift();
}
else {
connector = graphics.connector = paper.path(container);
}
if (animationDuration) {
// clip-canvas animation to line chart
connectorAnimation = R.animation ( {
'stroke-opacity': config.alpha
},
animationDuration, animType);
applyFn = ATTRFN;
opacity = 0;
initialAnimDuration = animationDuration;
}
else {
applyFn = ATTRFN;
opacity = config.alpha;
}
}
connector.show().animateWith(dummyAnimElem, dummyAnimObj, {
path: cPath
}, animationDuration, animType)
.attr({
stroke: config.color,
'stroke-opacity': opacity,
'stroke-width': config.thickness,
'stroke-dasharray': config.dashedStyle
});
if (connectorAnimation) {
connector.animate(connectorAnimation.delay(initialAnimDuration || 0));
}
eventArgs = {
fromTaskId: config.fromTaskId,
toTaskId: config.toTaskId,
fromTaskConnectStart: config.fromTaskConnectStart,
toTaskConnectStart: config.toTaskConnectStart,
link: config.link,
sourceType: 'connector'
};
trackerElement = graphics.tracker;
if (!trackerElement) {
if (pool.tracker && pool.tracker.length) {
trackerElement = graphics.tracker = pool.tracker.shift();
}
else {
trackerElement = graphics.tracker = paper.path (container)
.click (dataset.connectorClick(chart))
.hover (dataset.rollOverHandler(chart), dataset.rollOutHandler(chart));
}
}
trackerElement.attr ({
path: cPath,
stroke: TRACKER_FILL,
'stroke-width': mathMax (config.thickness, 10),
ishot: true,
cursor: config.link ? 'pointer' : BLANK
})
.data ('dataObj', dataObj)
.data ('eventArgs', eventArgs);
}
else {
if (connector) {
connector.hide();
}
}
}
for (i = 0; i < removeDataArrLen; i++) {
dataset._removeDataVisuals(removeDataArr.shift());
}
},
connectorClick: function (chart) {
return function (e) {
var ele = this;
plotEventHandler.call(ele, chart, e, 'ConnectorClick');
};
},
rollOverHandler: function (chart) {
return function (event) {
var ele = this,
data = ele.data('dataObj'),
config = data.config,
chartComponents = chart.components,
taskMap = chartComponents.tasksMap,
stTObj = taskMap[config.fromTaskId],
endTObj = taskMap[config.toTaskId],
attr = {
stroke: config.hoverColor,
'stroke-dasharray': config.dashedStyle,
'stroke-width': config.hoverThickness
},
connector = data.graphics.connector;
plotEventHandler.call(ele, chart, event, 'ConnectorRollOver');
if (config.showHoverEffect) {
each([stTObj, endTObj], function (obj) {
var attrib = {
fill: obj.config.hoverFillColor,
stroke: obj.config.hoverBorderColor
},
percentComplete = obj.config.percentComplete,
slackGraphic = obj.graphics.slackElem,
element = obj.graphics.element,
// Percent complete graphic is task fill
percentCompleteGraphic = obj.graphics.taskFill;
if (percentComplete &&
!obj.config.showAsGroup) {
slackGraphic && slackGraphic.attr({
fill: obj.config.slackHoverColor
});
percentCompleteGraphic && percentCompleteGraphic.attr({
fill: obj.config.hoverFillColor,
stroke: obj.config.hoverBorderColor
});
delete attrib.fill;
}
element && element.attr(attrib);
});
connector && connector.attr(attr);
}
};
},
rollOutHandler: function (chart) {
return function (event) {
var ele = this,
data = ele.data('dataObj'),
config = data.config,
chartComponents = chart.components,
taskMap = chartComponents.tasksMap,
stTObj = taskMap[config.fromTaskId],
endTObj = taskMap[config.toTaskId],
attr = {
stroke: config.color,
'stroke-width': config.thickness,
'stroke-dasharray': config.dashedStyle
},
connector = data.graphics.connector;
plotEventHandler.call(ele, chart, event, 'ConnectorRollOut');
if (config.showHoverEffect) {
each([stTObj, endTObj], function (obj) {
var attrib = {
fill: obj.config.color,
stroke: obj.config.borderColor,
'stroke-width': obj.config.borderThickness,
'stroke-dasharray': obj.config.dashedStyle
},
percentComplete = obj.config.percentComplete,
slackGraphic = obj.graphics.slackElem,
element = obj.graphics.element,
percentCompleteGraphic = obj.graphics.taskFill;
if (percentComplete &&
!obj.config.showAsGroup) {
slackGraphic && slackGraphic.attr({
fill: obj.config.slackColor
});
percentCompleteGraphic && percentCompleteGraphic.attr({
fill: obj.config.color
});
delete attrib.fill;
}
element && element.attr(attrib);
});
connector && connector.attr(attr);
}
};
}
}, 'Task', {
isdashed: 1,
thickness: 1
}]);
FusionCharts.get ('component', ['axis', 'ganttCommon', {
_drawPlotLine : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartComponents = chart.components,
canvas = axisConfig.canvas,
chartConfig = chart.config,
axisPlotLineContainerBottom = axisConfig.ganttPlotLineContainer,
canvasBottom = canvas.canvasBottom || chartConfig.canvasBottom,
canvasLeft = canvas.canvasLeft || chartConfig.canvasLeft,
canvasRight = canvas.canvasRight || chartConfig.canvasRight,
canvasTop = canvas.canvasTop || chartConfig.canvasTop,
paper = chartComponents.paper,
gridArr = axisConfig.gridArr,
plotLine = axis.graphics.line || [],
animateAxis = axisConfig.animateAxis,
animationDuration,
transposeAnimDuration,
lineStyle,
lineElement,
counter = 0,
i,
ln,
path = [],
animObj,
dummyObj,
animType;
animationDuration = chart.get('config', 'animationObj');
animObj = animationDuration.animObj;
dummyObj = animationDuration.dummyObj;
transposeAnimDuration = animationDuration.transposeAnimDuration;
animType = animationDuration.animType;
lineStyle = {
'stroke-dasharray': axisConfig.plotLineDashStyle,
'stroke-width': axisConfig.plotLineThickness,
stroke: axisConfig.plotLineColor
};
for (i = 0, ln = gridArr.length; i < ln; i += 1) {
if (gridArr[i].x !== undefined) {
path.push('M',gridArr[i].x,canvasTop,'L', gridArr[i].x, canvasBottom);
} else {
path.push('M',canvasLeft,gridArr[i].y,'L', canvasRight, gridArr[i].y);
}
}
if (plotLine[counter]) {
lineElement = plotLine[counter].graphics;
if (transposeAnimDuration && animateAxis) {
lineElement.animateWith(dummyObj, animObj, {path : path}, transposeAnimDuration, animType);
} else {
lineElement.attr({path : path});
}
lineElement.attr(lineStyle);
} else {
lineElement = paper.path(path, axisPlotLineContainerBottom);
lineElement.attr(lineStyle);
plotLine[counter] = {};
plotLine[counter].graphics = lineElement;
}
counter += 1;
for (i = counter, ln = plotLine.length; i < ln; i += 1) {
plotLine[i].graphics.attr({
path : 'M0,0'
});
}
axis.graphics.line = plotLine;
},
_drawPlotBand : function () {
},
translateAxis : function (x, y) {
var axis = this,
axisConfig = axis.config,
isVertical = axisConfig.isVertical,
lastTranslate = axisConfig.lastTranslate || (axisConfig.lastTranslate = {x : 0, y : 0}),
ganttPlotHoverBandContainer = axisConfig.ganttPlotHoverBandContainer,
dx,
dy;
dx = x !== undefined ? x - lastTranslate.x : 0;
dy = y !== undefined ? y - lastTranslate.y : 0;
lastTranslate.x = x !== undefined ? x : lastTranslate.x;
lastTranslate.y = y !== undefined ? y : lastTranslate.y;
axisConfig.labelContainer && axisConfig.labelContainer.translate(dx,dy);
axisConfig.hotContainer && axisConfig.hotContainer.translate(dx,dy);
axisConfig.headerContainer && axisConfig.headerContainer.translate(dx,0);
if (isVertical) {
axisConfig.ganttPlotLineContainer && axisConfig.ganttPlotLineContainer.translate(0,dy);
ganttPlotHoverBandContainer && ganttPlotHoverBandContainer.translate(0,dy);
} else {
axisConfig.ganttPlotLineContainer && axisConfig.ganttPlotLineContainer.translate(dx,0);
ganttPlotHoverBandContainer && ganttPlotHoverBandContainer.translate(dx,0);
axis.setAxisConfig({
animateAxis : false
});
axisConfig.drawTrendLines && axis._drawTrendLine();
axis.setAxisConfig({
animateAxis : true
});
}
},
resetTransletAxis : function () {
var axis = this,
axisConfig = axis.config,
transformAttr;
transformAttr = {
transform : 't0,0'
};
axisConfig.lastTranslate = {x : 0, y : 0};
axisConfig.labelContainer && axisConfig.labelContainer.attr(transformAttr);
axisConfig.headerContainer && axisConfig.headerContainer.attr(transformAttr);
axisConfig.ganttPlotLineContainer && axisConfig.ganttPlotLineContainer.attr(transformAttr);
axisConfig.ganttPlotHoverBandContainer && axisConfig.ganttPlotHoverBandContainer.attr(transformAttr);
axisConfig.hotContainer && axisConfig.hotContainer.attr(transformAttr);
},
_drawProcessAndDataTableStyleParser : function (attrs) {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
smartLabel = chart.linkedItems.smartLabel,
components = chart.components,
colorM = components.colorManager,
labels = axisConfig.labels,
style = labels.style,
elem = attrs.elem || {},
dimension = attrs.dimension,
textStyle = elem._attrib || {},
left = dimension.left,
right = dimension.right,
top = dimension.top,
bottom = dimension.bottom,
processPadding = 2,
fontFamily,
fontSize,
fontWeight,
fontStyle,
bgColor,
xPos,
yPos,
text,
retAttrib,
smartText,
vAlign,
align,
color,
textDecoration,
hoverC,
hoverA,
useHover,
usePlotHover,
rollOverColor,
link,
lHeight;
switch (attrs.type) {
case 'category' :
case 'datatable' :
case 'process' :
fontFamily = pluck(textStyle.font, style.fontFamily);
fontSize = pluck(textStyle.fontsize, style.fontSize).replace(/px/i, '') + PXSTRING;
fontStyle = pluck((Number(textStyle.isitalic) ? 'italic' : undefined), style.fontStyle);
bgColor = convertColor(pluck (textStyle.bgcolor ? getFirstColor(textStyle.bgcolor) : undefined ,
colorM.getColor ('categoryBgColor')), pluckNumber(textStyle.bgalpha, 100));
color = pluck(textStyle.fontcolor ? getFirstColor(textStyle.fontcolor) : undefined, style.color),
textDecoration = pluckNumber (textStyle.isunderline, 0) && UND_LINE || NONE;
vAlign = (pluck(textStyle.valign, 'center')).toLowerCase();
align = (pluck(textStyle.align, 'middle')).toLowerCase();
text = elem.drawLabel || '';
fontWeight = pluck((Number(textStyle.isbold) ? 'bold' : undefined), style.fontWeight);
link = elem.link;
break;
case 'header' :
fontFamily = pluck(textStyle.headerfont, style.fontFamily);
fontSize = pluck(textStyle.headerfontsize, style.fontSize).replace(/px/i, '') + PXSTRING;
fontWeight = pluck((Number(textStyle.headerisbold) === 1 ? 'bold' : textStyle.headerisbold ===
undefined ? 'bold' : undefined), style.fontWeight);
color = pluck (textStyle.headerfontcolor ? getFirstColor(textStyle.headerfontcolor) :
undefined, style.color),
textDecoration = pluckNumber (textStyle.headerisunderline, 0) && UND_LINE || NONE;
fontStyle = pluck((textStyle.headerisitalic ? 'italic' : undefined), style.fontStyle);
bgColor = convertColor(pluck (textStyle.headerbgcolor ? getFirstColor(textStyle.headerbgcolor)
: undefined , colorM.getColor ('categoryBgColor')), pluckNumber(textStyle.headerbgalpha, 100));
vAlign = (pluck(textStyle.headervalign, 'center')).toLowerCase();
align = (pluck(textStyle.headeralign, 'middle')).toLowerCase();
text = elem.drawLabel || '';
link = elem.headerlink;
break;
}
switch (attrs.type) {
case 'category' :
axisConfig.gridLinePath += 'M'+left+','+top+'L'+left+','+bottom+'L'+right+','+bottom;
fontWeight = pluck((Number(textStyle.isbold) === 1 ? 'bold' : textStyle.isbold === undefined ?
'bold' : undefined), style.fontWeight);
break;
case 'datatable' :
case 'process' :
axisConfig.gridLinePath += 'M'+left+','+bottom+'L'+right+','+bottom+'L'+right+','+top;
break;
case 'header' :
axisConfig.gridLineHeaderPath += 'M'+left+','+bottom+'L'+right+','+bottom+'L'+right+','+top;
break;
}
hoverC = pluck (elem._attrib.hoverbandcolor, axisConfig.hoverColor);
hoverA = pluckNumber (elem._attrib.hoverbandalpha, axisConfig.hoverAlpha);
if (align === 'left') {
xPos = left + processPadding;
align = 'start';
} else if (align === 'right') {
xPos = left + (right - left) - processPadding;
align = 'end';
} else {
align = 'middle';
xPos = left + (right - left)/2;
}
if (vAlign === 'top') {
yPos = top - processPadding;
} else if (vAlign === 'bottom') {
yPos = top + (bottom - top) - processPadding;
} else {
vAlign = 'center';
yPos = top + (bottom - top)/2;
}
style = {
fontFamily: fontFamily,
fontSize: fontSize,
fontWeight: fontWeight,
fontStyle: fontStyle,
textDecoration : textDecoration
};
lHeight = setLineHeight(style);
lHeight = Number((lHeight.replace(/px/i, '')));
lHeight = bottom - top > lHeight ? bottom - top : lHeight;
smartLabel.useEllipsesOnOverflow(chart.config.useEllipsesWhenOverflow);
smartLabel.setStyle (style);
smartText = smartLabel.getSmartText (text, right - left, lHeight);
retAttrib = {
textAttr : {
x : xPos,
y : yPos,
text : smartText.text,
fill: color,
'text-anchor' : align,
'vertical-align' : vAlign,
cursor : link ? 'pointer' : 'default'
},
css : style,
rectAttr : {
x : left,
y : top,
width : left < right ? right - left : 0,
height : top < bottom ? bottom - top : 0,
fill: bgColor,
'stroke-width' : 0,
cursor : link ? 'pointer' : 'default'
},
eventArgs : {
isHeader: attrs.type === 'header',
label: text,
vAlign: vAlign,
align: align,
link: link,
id: elem.id
},
tooltext : smartText.oriText
};
if (attrs.type === 'datatable' || attrs.type === 'process' || attrs.type === 'category') {
rollOverColor = convertColor (hoverC, hoverA);
useHover = pluckNumber(elem._attrib.showhoverband, axisConfig.useHover);
usePlotHover = pluckNumber(elem._attrib.showganttpanehoverband, axisConfig.usePlotHover, useHover);
retAttrib.dataArgs = {
rollOverColor: rollOverColor,
useHover: useHover,
usePlotHover: usePlotHover,
dimension: dimension,
hoverEle: elem,
type : attrs.type,
pos : attrs.pos,
axis : axis,
groupId : attrs.elemIndex
};
} else {
retAttrib.dataArgs = {
rollOverColor: undefined,
useHover: 0,
usePlotHover: 0,
dimension: dimension,
hoverEle: elem,
type : attrs.type,
pos : attrs.pos,
axis : axis,
groupId : attrs.elemIndex
};
}
return retAttrib;
},
_drawProcessAndDataTableElement : function(attrs) {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartComponents = chart.components,
categoryElement = axis.components.categoryElement || [],
hoverElemsArr = axisConfig.hoverElemsArr || (axisConfig.hoverElemsArr = []),
paper = chartComponents.paper,
elemIndex = attrs.elemIndex,
labelHoverEventName = axisConfig.labelHoverEventName,
animateAxis = axisConfig.animateAxis,
animationDuration,
transposeAnimDuration,
attribs,
labelBackContainer,
labelLineContainer,
labelTextContainer,
rectElement,
textElement,
animObj,
dummyObj,
showTooltip = chart.config.showtooltip,
animType,
labelClickHandler = function (e) {
var ele = this;
/**
* In `Gantt` chart, category element distributes the time line into visual divisions
* This event is fired when a category is clicked.
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#categoryClick
*
* @param { string } align - The alignment of the category label.
* @param { string } vAlign - The vertical alignment of the category label.
* @param { number } chartX - x-coordinate of the pointer relative to the chart.
* @param { number } chartY - y-coordinate of the pointer relative to the chart.
* @param { number } pageX - x-coordinate of the pointer relative to the page.
* @param { number } pageY - y-coordinate of the pointer relative to the page.
* @param { string } link - URL set for the category on mouse click.
* @param { string } text - The label in the category
* @see FusionCharts#event:categoryRollOver
* @see FusionCharts#event:categoryRollOut
*/
plotEventHandler.call (ele, chart, e, labelHoverEventName.click);
},
labelRollOver = function (e) {
var ele = this;
hoverTimeout = clearTimeout (hoverTimeout);
if (!lastHoverEle || lastHoverEle.removed) {
lastHoverEle = null;
}
lastHoverEle && axis._gridOutHandler.call (lastHoverEle);
axis._gridHoverHandler.call (ele);
/**
* In `Gantt` chart, category element distributes the time line into visual divisions
* This event is fired when the pointer moves over a category.
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#categoryRollOver
*
* @param { string } align - The alignment of the category label.
* @param { string } vAlign - The vertical alignment of the category label.
* @param { number } chartX - x-coordinate of the pointer relative to the chart.
* @param { number } chartY - y-coordinate of the pointer relative to the chart.
* @param { number } pageX - x-coordinate of the pointer relative to the page.
* @param { number } pageY - y-coordinate of the pointer relative to the page.
* @param { string } link - URL set for the category on mouse click.
* @param { string } text - The label in the category
* @see FusionCharts#event:categoryClick
* @see FusionCharts#event:categoryRollOut
*/
plotEventHandler.call (ele, chart, e, labelHoverEventName.rollOver);
},
labelRollOut = function (e) {
lastHoverEle = this;
hoverTimeout = clearTimeout (hoverTimeout);
hoverTimeout = setTimeout (function () {
axis._gridOutHandler.call (lastHoverEle);
}, 500);
/**
* In `Gantt` chart, category element distributes the time line into visual divisions
* This event is fired when the pointer moves out of a category.
*
* This event is only applicable to Gantt chart.
*
* @event FusionCharts#categoryRollOut
*
* @param { string } align - The alignment of the category label.
* @param { string } vAlign - The vertical alignment of the category label.
* @param { number } chartX - x-coordinate of the pointer relative to the chart.
* @param { number } chartY - y-coordinate of the pointer relative to the chart.
* @param { number } pageX - x-coordinate of the pointer relative to the page.
* @param { number } pageY - y-coordinate of the pointer relative to the page.
* @param { string } link - URL set for the category on mouse click.
* @param { string } text - The label in the category
* @see FusionCharts#event:categoryClick
* @see FusionCharts#event:categoryRollOver
*/
plotEventHandler.call (lastHoverEle, chart, e, labelHoverEventName.rollOut);
};
animationDuration = chart.get('config', 'animationObj');
animObj = animationDuration.animObj;
dummyObj = animationDuration.dummyObj;
transposeAnimDuration = animationDuration.transposeAnimDuration;
animType = animationDuration.animType;
if (attrs.type === 'header') {
labelBackContainer = axisConfig.headerBackContainer;
labelLineContainer = axisConfig.headerLineContainer;
labelTextContainer = axisConfig.headerTextContainer;
} else {
labelBackContainer = axisConfig.labelBackContainer;
labelLineContainer = axisConfig.labelLineContainer;
labelTextContainer = axisConfig.labelTextContainer;
}
attribs = axis._drawProcessAndDataTableStyleParser(attrs);
if (categoryElement[elemIndex]) {
textElement = categoryElement[elemIndex].graphics.label;
rectElement = categoryElement[elemIndex].graphics.rect;
labelBackContainer.appendChild(rectElement);
labelTextContainer.appendChild(textElement);
if (transposeAnimDuration && animateAxis) {
rectElement.animateWith(dummyObj, animObj,attribs.rectAttr, transposeAnimDuration, animType);
textElement.animateWith(dummyObj, animObj,attribs.textAttr, transposeAnimDuration, animType);
} else {
rectElement.attr(attribs.rectAttr);
textElement.attr(attribs.textAttr);
}
textElement.css(attribs.css);
} else {
rectElement = paper.rect(attribs.rectAttr, labelBackContainer);
textElement = paper.text(attribs.textAttr, attribs.css, labelTextContainer);
categoryElement[elemIndex] = {};
categoryElement[elemIndex].graphics = {};
categoryElement[elemIndex].config = {};
categoryElement[elemIndex].graphics.label = textElement;
categoryElement[elemIndex].graphics.rect = rectElement;
rectElement.hover (labelRollOver, labelRollOut)
.click (labelClickHandler);
textElement
.hover (labelRollOver, labelRollOut)
.click (labelClickHandler);
}
if (attrs.type !== 'header') {
if (!hoverElemsArr[attrs.pos]) {
hoverElemsArr[attrs.pos] = [];
}
hoverElemsArr[attrs.pos].push({
bgElem : rectElement,
bgColor : attribs.rectAttr.fill
});
}
rectElement
.data ('dataObj', attrs.elem)
.data ('eventArgs', attribs.eventArgs)
.data ('data', attribs.dataArgs);
textElement
.data ('dataObj', attrs.elem)
.data ('eventArgs', attribs.eventArgs)
.data ('data', attribs.dataArgs)
.tooltip(attribs.tooltext)
.trackTooltip(showTooltip ? true : false);
axis.components.categoryElement = categoryElement;
},
_drawGridLine : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartComponents = chart.components,
paper = chartComponents.paper,
gridLine = axis.graphics.gridLine || [],
animateAxis = axisConfig.animateAxis,
animationDuration,
transposeAnimDuration,
lineStyle,
lineElement,
counter = 0,
i = 0,
ln = 2,
path,
animObj,
dummyObj,
container,
animType;
animationDuration = chart.get('config', 'animationObj');
animObj = animationDuration.animObj;
dummyObj = animationDuration.dummyObj;
transposeAnimDuration = animationDuration.transposeAnimDuration;
animType = animationDuration.animType;
lineStyle = {
'stroke-dasharray': axisConfig.lineDashStyle,
'stroke-width': axisConfig.lineThickness,
stroke: axisConfig.lineColor
};
for (; i < ln; i += 1) {
if (i === 0) {
path = axisConfig.gridLinePath;
container = axisConfig.labelLineContainer;
} else {
path = axisConfig.gridLineHeaderPath;
container = axisConfig.headerLineContainer;
if (!path) {
continue;
}
}
if (gridLine[counter]) {
lineElement = gridLine[counter].graphics;
if (transposeAnimDuration && animateAxis) {
lineElement.animateWith(dummyObj, animObj, {path : path}, transposeAnimDuration, animType);
} else {
lineElement.attr({path : path});
}
lineElement.attr(lineStyle);
} else {
lineElement = paper.path(path, container);
lineElement.attr(lineStyle);
gridLine[counter] = {};
gridLine[counter].graphics = lineElement;
}
counter += 1;
}
for (i = counter, ln = gridLine.length; i < ln; i += 1) {
gridLine[i].graphics.attr({
path : 'M0,0'
});
}
axis.graphics.gridLine = gridLine;
},
_gridHoverHandler : function () {
var data = this.data ('data'),
type = data.type,
dimension = data.dimension,
axis = data.axis,
chart = axis.chart,
chartConfig = chart.config,
paper = chart.components.paper,
axisConfig = axis.config,
hoverElemsArr = axisConfig.hoverElemsArr || [],
ganttPlotHoverBandContainer = axisConfig.ganttPlotHoverBandContainer,
plotHoverElement = axis.graphics.plotHoverElement || (axis.graphics.plotHoverElement = []),
plotHoverElementAttr,
i,
ln;
if (type === 'category') {
plotHoverElementAttr = {
x : dimension.left,
y : chartConfig.canvasTop,
width : dimension.left < dimension.right ? (dimension.right - dimension.left) : 0,
height : chartConfig.height,
fill: data.rollOverColor,
'stroke-width' : 0
};
} else {
plotHoverElementAttr = {
y : dimension.top,
x : chartConfig.canvasLeft,
height : dimension.top < dimension.bottom ? (dimension.bottom - dimension.top) : 0,
width : chartConfig.width,
fill: data.rollOverColor,
'stroke-width' : 0
};
}
if (data.usePlotHover) {
if (plotHoverElement[0]) {
plotHoverElement[0].attr(plotHoverElementAttr).show();
} else {
plotHoverElement[0] = paper.rect(plotHoverElementAttr, ganttPlotHoverBandContainer);
}
}
if (data.useHover && hoverElemsArr[data.pos]) {
for (i = 0, ln = hoverElemsArr[data.pos].length; i < ln; i += 1) {
hoverElemsArr[data.pos][i].bgElem.attr({
fill : data.rollOverColor
});
}
}
},
_gridOutHandler : function () {
var data = this.data ('data'),
axis = data.axis,
axisConfig = axis.config,
hoverElemsArr = axisConfig.hoverElemsArr || [],
plotHoverElement = axis.graphics.plotHoverElement || [],
i,
ln,
hoverOutElem;
if (data.usePlotHover) {
if (plotHoverElement[0]) {
plotHoverElement[0].hide();
}
}
if (data.useHover && hoverElemsArr[data.pos]) {
for (i = 0, ln = hoverElemsArr[data.pos].length; i < ln; i += 1) {
hoverOutElem = hoverElemsArr[data.pos][i];
hoverOutElem.bgElem.attr({
fill : hoverOutElem.bgColor
});
}
}
},
_disposeExtraProcessAndDataTableElement : function(index) {
var axis = this,
categoryElement = axis.components.categoryElement || [],
i,
ln;
for (i = index, ln = categoryElement.length; i < ln; i += 1) {
categoryElement[i].graphics.label.attr({
text : ''
});
categoryElement[i].graphics.rect.attr({
x : 0,
y : 0,
width : 0,
heigth : 0
});
}
}
}, 'cartesian']);
FusionCharts.get ('component', ['axis', 'time', {
configure : function () {
var axis = this,
axisConfig = axis.config,
axisAttr = axisConfig.rawAttr,
chart = axis.chart,
jsonData = chart.jsonData,
FCChartObj = jsonData.chart,
chartComponents = chart.components,
colorM = chartComponents.colorManager,
parent = FusionCharts.register('component', ['axis', 'cartesian']);
parent.prototype.configure.call(this);
//Gantt grid line properties
axisConfig.plotLineColor = axisConfig.lineColor = convertColor (pluck (FCChartObj.ganttlinecolor,
colorM.getColor ('gridColor')), pluckNumber (FCChartObj.ganttlinealpha, 100));
axisConfig.plotLineThickness = axisConfig.lineThickness = pluckNumber (FCChartObj.ganttlinethickness, 1);
axisConfig.plotLineDashStyle = axisConfig.lineDashStyle = pluckNumber (FCChartObj.ganttlinedashed, 0) ?
getDashStyle (pluckNumber (FCChartObj.ganttlinedashlen, 1),
FCChartObj.ganttlinedashgap, axisConfig.lineThickness) : DASH_DEF;
axisConfig.hoverColor = pluck (FCChartObj.categoryhoverbandcolor, FCChartObj.hoverbandcolor,
colorM.getColor ('gridColor'));
axisConfig.hoverAlpha = pluckNumber (FCChartObj.categoryhoverbandalpha, FCChartObj.hoverbandalpha, 30);
axisConfig.useHover = pluckNumber (FCChartObj.showcategoryhoverband, FCChartObj.showhoverband,
FCChartObj.showhovereffect, 1);
axisConfig.usePlotHover = pluckNumber (FCChartObj.showganttpaneverticalhoverband);
axisConfig.trendlinesDashLen = pluckNumber(axisAttr.trendlinesDashLen, 3);
axisConfig.trendlinesDashGap = pluckNumber(axisAttr.trendlinesDashGap, 3);
axisConfig.gridLineHeaderPath = '';
axisConfig.gridLinePath = '';
},
setCategory : function (categories) {
var axis = this,
chart = axis.chart,
components = chart.get('components'),
numberFormatter = components.numberFormatter,
axisConfig = axis.config,
axisRange = axisConfig.axisRange,
startPad = axisConfig.startPad || 0,
endPad = axisConfig.endPad || 0,
axisLimits,
catLength,
categoriesFinal,
catObj,
startMS,
endMS,
minTime = Infinity,
maxTime = -Infinity,
i,
j;
// Initialize the category object
axisConfig.categories = {};
// Set the category flag to true
if (categories) {
axisConfig.hasCategory = 1;
} else {
axisConfig.hasCategory = 0;
return;
}
// this will store the category
categoriesFinal = axisConfig.categories.category = extend2({}, categories);
axis._extractAttribToEnd(categoriesFinal, {});
for (i in categoriesFinal) {
if (!categoriesFinal.hasOwnProperty(i) || i === '_attrib') {
continue;
}
for (j = 0, catLength = categoriesFinal[i].category.length; j < catLength; j += 1) {
catObj = categoriesFinal[i].category[j];
startMS = numberFormatter.getDateValue(catObj.start).ms;
endMS = numberFormatter.getDateValue(catObj.end).ms;
if (isNaN(startMS)) { /** @todo nan check without fn call */
startMS = UNDEF;
}
if (startMS > maxTime) { maxTime = startMS; }
if (startMS <= minTime) { minTime = startMS; }
if (isNaN(endMS)) { /** @todo nan check without fn call */
endMS = UNDEF;
}
if (endMS > maxTime) { maxTime = endMS; }
if (endMS <= minTime) { minTime = endMS; }
}
}
axisLimits = {
Max : maxTime + endPad,
Min : minTime - startPad,
divGap : 1
};
axisRange.min = Number(toPrecision(axisLimits.Min,10));
axisRange.max = Number(toPrecision(axisLimits.Max, 10));
axisRange.tickInterval = Number(toPrecision(axisLimits.divGap, 10));
},
_drawComponents : function () {
var axis = this,
axisConfig = axis.config;
axis._drawCategories();
axisConfig.drawPlotlines && axis._drawPlotLine();
axisConfig.drawPlotBand && axis._drawPlotBand();
axisConfig.drawTrendLines && axis._drawTrendLine();
},
_drawCategories : function () {
var axis = this,
axisConfig = axis.config,
axisDimention = axisConfig.axisDimention || {},
axisStartPosition = axisDimention.y,
spaceTaken = axisConfig.totalHeight || 0,
chart = axis.chart,
chartComponents = chart.components,
chartConfig = chart.config,
viewPortConfig = chartConfig.viewPortConfig,
paper = chartComponents.paper,
numberFormatter = chartComponents.numberFormatter,
canvas = axisConfig.canvas,
gridArr = axisConfig.gridArr || (axisConfig.gridArr = []),
canvasLeft = canvas.canvasLeft || chartConfig.canvasLeft,
canvasTop = canvas.canvasTop || chartConfig.canvasTop,
canvasHeight = canvas.canvasHeight || chartConfig.canvasHeight,
canvasWidth = canvas.canvasWidth || chartConfig.canvasWidth,
lastTranslate = axisConfig.lastTranslate || (axisConfig.lastTranslate = {x : 0, y : 0}),
layers = chart.graphics,
axisBottomGroup = layers.axisBottomGroup,
i,
categories,
category,
elemIndex = 0,
j,
args,
lastRightPos,
animationDuration,
animObj,
dummyObj,
transposeAnimDuration,
animType,
labelClipHeight,
startms,
endms;
animationDuration = chart.get('config', 'animationObj');
animObj = animationDuration.animObj;
dummyObj = animationDuration.dummyObj;
transposeAnimDuration = animationDuration.transposeAnimDuration;
animType = animationDuration.animType;
labelClipHeight = mathMin(spaceTaken, canvasTop - (axisConfig.maxTopSpaceAvailable || 0));
labelClipHeight = labelClipHeight > 0 ? labelClipHeight : 0;
layers.ganttPlotHoverBandContainerParent = layers.ganttPlotHoverBandContainerParent ||
paper.group('guntt-plot-band-container-parent', axisBottomGroup);
if (!axisConfig.ganttPlotHoverBandContainer) {
axisConfig.ganttPlotHoverBandContainer = paper.group('guntt-plot-band-container',
layers.ganttPlotHoverBandContainerParent);
axisConfig.ganttPlotHoverBandContainer.attr({
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
});
} else {
axisConfig.ganttPlotHoverBandContainer.animateWith(dummyObj, animObj, {
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.ganttPlotLineContainer) {
axisConfig.ganttPlotLineContainer = paper.group('guntt-plot-line-container', axisBottomGroup);
axisConfig.ganttPlotLineContainer.attr({
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
});
} else {
axisConfig.ganttPlotLineContainer.animateWith(dummyObj, animObj, {
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.labelContainer) {
axisConfig.labelContainer = paper.group('guntt-label-container', axisBottomGroup);
axisConfig.labelContainer.attr({
'clip-rect': canvasLeft +','+ (canvasTop - labelClipHeight) +
','+canvasWidth+ ','+labelClipHeight
});
} else {
axisConfig.labelContainer.animateWith(dummyObj, animObj, {
'clip-rect': canvasLeft +','+ (canvasTop - labelClipHeight) +
','+canvasWidth+ ','+labelClipHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.labelBackContainer) {
axisConfig.labelBackContainer = paper.group('guntt-label-back-container', axisConfig.labelContainer);
}
if (!axisConfig.labelLineContainer) {
axisConfig.labelLineContainer = paper.group('guntt-label-line-container', axisConfig.labelContainer);
}
if (!axisConfig.labelTextContainer) {
axisConfig.labelTextContainer = paper.group('guntt-label-text-container', axisConfig.labelContainer);
}
axisConfig.gridLinePath = '';
axisConfig.gridLineHeaderPath = '';
axisConfig.hoverElemsArr = [];
axisConfig.labelHoverEventName = {
click : 'CategoryClick',
rollOver : 'CategoryRollOver',
rollOut : 'CategoryRollOut'
};
if (axisConfig.hasCategory) {
categories = axisConfig.categories.category;
for (i in categories) {
if (!categories.hasOwnProperty(i) || i === '_attrib') {
continue;
}
category = categories[i].category;
lastRightPos = undefined;
gridArr = axisConfig.gridArr = [];
for (j in category) {
startms = numberFormatter.getDateValue(category[j].start).ms;
endms = numberFormatter.getDateValue(category[j].end).ms;
if (!category.hasOwnProperty(j) || j === '_attrib' || isNaN(startms) || isNaN(endms)) {
continue;
}
args = {
elem : category[j],
elemIndex : elemIndex,
pos : elemIndex,
dimension : {
left : lastRightPos ||
axis.getPixel(startms),
right : axis.getPixel(endms),
top : axisStartPosition - spaceTaken + categories[i]._attrib.topPos,
bottom : axisStartPosition - spaceTaken + categories[i]._attrib.bottomPos
},
type : 'category',
isHeader : false
};
lastRightPos = args.dimension.right;
axis._drawProcessAndDataTableElement(args);
elemIndex += 1;
gridArr.push({x : args.dimension.left});
}
}
if (viewPortConfig.x > 0) {
lastTranslate.x = -(viewPortConfig.x * viewPortConfig.scaleX);
} else {
axisConfig.lastTranslate = {x : 0, y : 0};
}
}
axis._drawGridLine();
axis._disposeExtraProcessAndDataTableElement(elemIndex);
},
placeAxis : function (maxHeight) {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartConfig = chart.config,
components = chart.get('components'),
numberFormatter = components.numberFormatter,
smartLabel = chart.linkedItems.smartLabel,
labelStyle = axisConfig.labels.style,
vPadding = 8,
maxTextSize = 0,
spaceReturn = {
top : 0,
bottom : 0
},
spaceUsed = 0,
categories,
category,
i,
text,
smartLabelText,
j,
textStyle,
singleTextStyle,
jLen,
iLim,
maxTextDimention,
trendStyle = axisConfig.trend.trendStyle,
vtrendlines = axisConfig.vTrendLines,
useEllipsesWhenOverflow = axisConfig.useEllipsesWhenOverflow,
trendMaxHeight = 0,
trendSpaceUsed = 0,
trendObj,
axisSmartTrendValue,
trendHeight,
heightLeft;
smartLabel.useEllipsesOnOverflow(chartConfig.useEllipsesWhenOverflow);
smartLabel.setStyle({
fontSize : labelStyle.fontSize,
fontFamily : labelStyle.fontFamily,
lineHeight : labelStyle.lineHeight,
fontWeight : labelStyle.fontWeight
});
// Used to clip the category when chart height is very small.
axisConfig.maxTopSpaceAvailable = chartConfig.canvasTop;
if (axisConfig.hasCategory) {
categories = axisConfig.categories.category;
for (i in categories) {
if (!categories.hasOwnProperty(i) || i === '_attrib') {
continue;
}
maxTextSize = 0;
category = categories[i].category;
for (j in category) {
if (!category.hasOwnProperty(j) || j === '_attrib') {
continue;
}
text = category[j];
text.drawLabel = parseUnsafeString(text.label || text.name);
textStyle = text._attrib;
singleTextStyle = {
fontFamily: pluck(textStyle.fontfamily, labelStyle.fontFamily).replace(/px/i, '') +
PXSTRING,
fontSize: pluck(textStyle.fontsize, labelStyle.fontSize),
fontWeight: pluck((Number(textStyle.isbold) === 1 ? 'bold' : textStyle.isbold ===
undefined ? 'bold' : undefined), labelStyle.fontWeight),
fontStyle: pluck((textStyle.isitalic ? 'italic' : undefined), labelStyle.fontStyle)
};
setLineHeight(singleTextStyle);
smartLabel.setStyle(singleTextStyle);
smartLabelText = smartLabel.getOriSize(text.drawLabel);
if (smartLabelText.height > maxTextSize) {
maxTextDimention = smartLabelText;
maxTextSize = smartLabelText.height;
}
}
categories[i]._attrib.topPos = spaceUsed;
spaceUsed += maxTextDimention.height + vPadding;
categories[i]._attrib.bottomPos = spaceUsed;
}
}
heightLeft = maxHeight - spaceUsed;
if (axisConfig.drawTrendLines && axisConfig.drawTrendLabels && vtrendlines && axisConfig.isActive){
// for trend line
smartLabel.setStyle({
fontSize : trendStyle.fontSize,
fontFamily : trendStyle.fontFamily,
lineHeight : trendStyle.lineHeight,
fontWeight : trendStyle.fontWeight
});
axisConfig.trendBottomPadding = -1;
for (j = 0, jLen = vtrendlines.length; j < jLen; j += 1) {
for (i = 0, iLim = vtrendlines[j].line.length; i < iLim; i += 1) {
trendObj = vtrendlines[j].line[i];
text = trendObj.origText || trendObj.displayvalue || trendObj.endvalue ||
trendObj.startvalue || '';
text = parseUnsafeString(text);
// if (text === (trendObj.endvalue || trendObj.startvalue)) {
// text = ''+ numberFormatterFn.call(chartComponents.numberFormatter, text);
// }
trendObj.startvalue = trendObj.start && numberFormatter.getDateValue(trendObj.start).ms;
trendObj.endvalue = trendObj.end && numberFormatter.getDateValue(trendObj.end).ms;
trendObj.origText = text;
axisSmartTrendValue = smartLabel.getSmartText(text, chart.canvasWidth,
trendStyle.lineHeight, useEllipsesWhenOverflow);
trendHeight = axisSmartTrendValue.height + 2;
// checking if space available for trend label value to be drawn
// if not make the display value empty
if (heightLeft - trendHeight < 0) {
trendObj.displayvalue = '';
} else {
// set the display value
trendObj.displayvalue = axisSmartTrendValue.text;
trendMaxHeight = trendMaxHeight < axisSmartTrendValue.height ?
axisSmartTrendValue.height : trendMaxHeight;
}
// check tooltext is available which will help to draw tooltext on hover
if (axisSmartTrendValue.tooltext) {
trendObj.valueToolText = axisSmartTrendValue.tooltext;
} else {
delete trendObj.valueToolText;
}
}
}
}
axisConfig.totalHeight = spaceUsed;
if (trendMaxHeight > 0) {
trendSpaceUsed += trendMaxHeight + mathAbs(axisConfig.trendBottomPadding || 0);
}
spaceUsed = spaceUsed > maxHeight ? maxHeight : spaceUsed;
spaceReturn.top += spaceUsed;
spaceReturn.bottom += trendSpaceUsed;
chartConfig.categorySpaceUsed = spaceUsed;
return spaceReturn;
}
}, 'ganttCommon']);
FusionCharts.get ('component', ['axis', 'process', {
configure : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
jsonData = chart.jsonData,
FCChartObj = jsonData.chart,
chartComponents = chart.components,
colorM = chartComponents.colorManager,
parent = FusionCharts.register('component', ['axis', 'cartesian']);
parent.prototype.configure.call(this);
//Grid properties
axisConfig.lineColor = convertColor (pluck (FCChartObj.gridbordercolor,
colorM.getColor ('gridColor')), pluckNumber (FCChartObj.gridborderalpha, 100));
axisConfig.lineThickness = pluckNumber (FCChartObj.gridborderthickness, 1);
axisConfig.lineDashStyle = pluckNumber (FCChartObj.gridborderdashed, 0) ?
getDashStyle (pluckNumber (FCChartObj.gridborderdashlen, 1),
FCChartObj.gridborderdashgap, axisConfig.lineThickness) : DASH_DEF;
axisConfig.plotLineColor = convertColor (pluck (FCChartObj.ganttlinecolor,
colorM.getColor ('gridColor')), pluckNumber (FCChartObj.ganttlinealpha, 100));
axisConfig.plotLineThickness = pluckNumber (FCChartObj.ganttlinethickness, 1);
axisConfig.plotLineDashStyle = pluckNumber (FCChartObj.ganttlinedashed, 0) ?
getDashStyle (pluckNumber (FCChartObj.ganttlinedashlen, 1),
FCChartObj.ganttlinedashgap, axisConfig.lineThickness) : DASH_DEF;
axisConfig.gridResizeBarColor = convertColor (pluck (FCChartObj.gridresizebarcolor,
colorM.getColor ('gridResizeBarColor')), pluckNumber (FCChartObj.gridresizebaralpha, 100));
axisConfig.gridResizeBarThickness = pluckNumber (FCChartObj.gridresizebarthickness, 1);
axisConfig.forceRowHeight = pluckNumber(FCChartObj.forcerowheight, 0);
axisConfig.rowHeight = pluckNumber(FCChartObj.rowheight, 0);
axisConfig.hoverColor = pluck (FCChartObj.processhoverbandcolor, FCChartObj.hoverbandcolor,
colorM.getColor ('gridColor'));
axisConfig.hoverAlpha = pluckNumber (FCChartObj.processhoverbandalpha, FCChartObj.hoverbandalpha, 30);
axisConfig.useHover = pluckNumber (FCChartObj.showprocesshoverband, FCChartObj.showhoverband,
FCChartObj.showhovereffect, 1);
axisConfig.usePlotHover = pluckNumber (FCChartObj.showganttpanehorizontalhoverband);
axisConfig.showFullDataTable = pluckNumber(FCChartObj.showfulldatatable, 1);
axisConfig.useVerticalScrolling = pluckNumber(FCChartObj.useverticalscrolling, 1);
axisConfig.gridLineHeaderPath = '';
axisConfig.gridLinePath = '';
},
setDataTable : function (dataTables) {
var axis = this,
axisConfig = axis.config;
// Initialize the category object
axisConfig.dataTables = {};
axisConfig.dataTables.dataTable = {};
if (dataTables) {
// Set the category flag to true
axisConfig.hasDataTables = 1;
} else {
axisConfig.hasDataTables = 0;
return;
}
// this will store only the category not the vline
extend2(axisConfig.dataTables.dataTable, dataTables);
dataTables = axisConfig.dataTables.dataTable;
// Set the final style property for each text inherating from its parent
axis._extractAttribToEnd(dataTables, {});
},
setProcess : function (processes) {
var axis = this,
axisConfig = axis.config,
axisRange = axisConfig.axisRange,
startPad = axisConfig.startPad || 0,
endPad = axisConfig.endPad || 0,
axisLimits,
processesLen,
processesFinal,
index,
ProcessIndex,
processMap;
// Initialize the category object
axisConfig.processes = {};
if (processes) {
// Set the category flag to true
axisConfig.hasProcess = 1;
} else {
axisConfig.hasProcess = 0;
return;
}
// this will store only the category not the vline
processesFinal = axisConfig.processes.process = extend2({}, processes);
axis._extractAttribToEnd(processesFinal, {});
processesLen = processesFinal.process.length;
processMap = axisConfig.processes.processMap = {};
axisConfig.processes.processHeightMap = {};
// Storing Process mapping
for (index = 0; index < processesLen; index += 1) {
ProcessIndex = processesFinal.process[index];
if (ProcessIndex.id) {
processMap[ProcessIndex.id.toLowerCase()] = {
catObj : ProcessIndex,
index : index
};
}
}
axisLimits = {
Max : processesLen - 1 + endPad,
Min : -startPad,
divGap : 1
};
axisRange.min = Number(toPrecision(axisLimits.Min,10));
axisRange.max = Number(toPrecision(axisLimits.Max, 10));
axisRange.tickInterval = Number(toPrecision(axisLimits.divGap, 10));
},
getProcessPositionById : function (processId) {
var axis = this,
axisConfig = axis.config,
process = axisConfig.processes && axisConfig.processes.processMap[processId],
processHeightMap = axisConfig.processes.processHeightMap;
if (process) {
return processHeightMap[process.index];
} else {
return false;
}
},
getProcessPositionByIndex : function (ind) {
var axis = this,
axisConfig = axis.config,
processHeightMap = axisConfig.processes.processHeightMap;
if (processHeightMap[ind]) {
return processHeightMap[ind];
} else {
return false;
}
},
setProcessHeight : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartConfig = chart.config,
canvasHeight = chartConfig.canvasHeight,
process = axisConfig.processes.process.process,
processHeightMap = axisConfig.processes.processHeightMap,
processHeight = axisConfig.processMaxHeight,
height = 0,
forceRowHeight = axisConfig.forceRowHeight,
rowHeight = axisConfig.rowHeight,
processHeightFinal,
processLength,
i;
if ((processHeight * process.length) < canvasHeight || axisConfig.useVerticalScrolling === 0) {
processHeight = canvasHeight/process.length;
}
if (forceRowHeight === 0) {
if (rowHeight && rowHeight > processHeight) {
processHeight = rowHeight;
}
} else {
processHeight = rowHeight || processHeight;
}
for (i = 0, processLength = process.length; i < processLength ; i++) {
processHeightFinal = pluckNumber(process[i].height,processHeight);
processHeightMap[i] = {
top : height,
bottom : height + processHeightFinal,
height : processHeightFinal
};
height += processHeightFinal;
}
return height;
},
_drawComponents : function () {
var axis = this,
axisConfig = axis.config;
axis._drawProcessAndDataTable();
axisConfig.drawPlotlines && axis._drawPlotLine();
axisConfig.drawPlotBand && axis._drawPlotBand();
axis._drawVerticalLineAndTracker();
axis._drawGridLine();
},
_drawProcessAndDataTable : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
axisDimention = axisConfig.axisDimention || {},
axisStartPosition = axisDimention.x,
spaceTaken = axisConfig.totalWidth || 0,
gridArr = axisConfig.gridArr || (axisConfig.gridArr = []),
canvas = axisConfig.canvas,
chartConfig = chart.config,
chartComponents = chart.components,
paper = chartComponents.paper,
canvasTop = canvas.canvasTop || chartConfig.canvasTop,
canvasLeft = canvas.canvasLeft || chartConfig.canvasLeft,
canvasHeight = canvas.canvasHeight || chartConfig.canvasHeight,
canvasWidth = canvas.canvasWidth || chartConfig.canvasWidth,
layers = chart.graphics,
axisBottomGroup = layers.axisBottomGroup,
totalVisiblelWidth = axisConfig.totalVisiblelWidth,
i,
processLength,
dataTables,
dataColumn,
elemIndex = 0,
j,
args,
topBottom,
translateX,
animationDuration,
animObj,
dummyObj,
transposeAnimDuration,
animType;
animationDuration = chart.get('config', 'animationObj');
animObj = animationDuration.animObj;
dummyObj = animationDuration.dummyObj;
transposeAnimDuration = animationDuration.transposeAnimDuration;
animType = animationDuration.animType;
layers.ganttPlotHoverBandContainerParent = layers.ganttPlotHoverBandContainerParent ||
paper.group('guntt-plot-band-container-parent', axisBottomGroup);
if (!axisConfig.ganttPlotHoverBandContainer) {
axisConfig.ganttPlotHoverBandContainer = paper.group('guntt-plot-band-container',
layers.ganttPlotHoverBandContainerParent);
axisConfig.ganttPlotHoverBandContainer.attr({
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
});
} else {
axisConfig.ganttPlotHoverBandContainer.animateWith(dummyObj, animObj, {
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.ganttPlotLineContainer) {
axisConfig.ganttPlotLineContainer = paper.group('guntt-plot-line-container', axisBottomGroup);
axisConfig.ganttPlotLineContainer.attr({
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
});
} else {
axisConfig.ganttPlotLineContainer.animateWith(dummyObj, animObj, {
'clip-rect': canvasLeft +','+ canvasTop +
','+canvasWidth+ ','+canvasHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.headerContainer) {
axisConfig.headerContainer = paper.group('guntt-header-container', axisBottomGroup);
axisConfig.headerContainer.attr({
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+
(canvasTop - chartConfig.categorySpaceUsed) +
','+axisConfig.totalVisiblelWidth+ ','+chartConfig.categorySpaceUsed
});
} else {
axisConfig.headerContainer.animateWith(dummyObj, animObj, {
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+
(canvasTop - chartConfig.categorySpaceUsed) +
','+axisConfig.totalVisiblelWidth+ ','+chartConfig.categorySpaceUsed
}, transposeAnimDuration, animType);
}
if (!axisConfig.headerBackContainer) {
axisConfig.headerBackContainer = paper.group('guntt-header-back-container', axisConfig.headerContainer);
}
if (!axisConfig.headerLineContainer) {
axisConfig.headerLineContainer = paper.group('guntt-header-line-container', axisConfig.headerContainer);
}
if (!axisConfig.headerTextContainer) {
axisConfig.headerTextContainer = paper.group('guntt-header-text-container', axisConfig.headerContainer);
}
if (!axisConfig.labelContainer) {
axisConfig.labelContainer = paper.group('guntt-label-container', axisBottomGroup);
axisConfig.labelContainer.attr({
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+ canvasTop +
','+axisConfig.totalVisiblelWidth+ ','+canvasHeight
});
} else {
axisConfig.labelContainer.animateWith(dummyObj, animObj, {
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+ canvasTop +
','+axisConfig.totalVisiblelWidth+ ','+canvasHeight
}, transposeAnimDuration, animType);
}
if (!axisConfig.labelBackContainer) {
axisConfig.labelBackContainer = paper.group('guntt-label-back-container', axisConfig.labelContainer);
}
if (!axisConfig.labelLineContainer) {
axisConfig.labelLineContainer = paper.group('guntt-label-line-container', axisConfig.labelContainer);
}
if (!axisConfig.labelTextContainer) {
axisConfig.labelTextContainer = paper.group('guntt-label-text-container', axisConfig.labelContainer);
}
if (!axisConfig.hotContainer) {
axisConfig.hotContainer = paper.group('guntt-hot-container', axisConfig.axisLabelGroup);
axisConfig.hotContainer.attr({
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+
(canvasTop - chartConfig.categorySpaceUsed) +
','+axisConfig.totalVisiblelWidth+ ','+(canvasHeight + chartConfig.categorySpaceUsed)
});
} else {
axisConfig.hotContainer.animateWith(dummyObj, animObj, {
'clip-rect': (canvasLeft - axisConfig.totalVisiblelWidth) +','+
(canvasTop - chartConfig.categorySpaceUsed) +
','+axisConfig.totalVisiblelWidth+ ','+(canvasHeight + chartConfig.categorySpaceUsed)
}, transposeAnimDuration, animType);
}
axisConfig.gridLinePath = '';
axisConfig.gridLineHeaderPath = '';
axisConfig.hoverElemsArr = [];
axisConfig.labelHoverEventName = {
click : 'ProcessClick',
rollOver : 'ProcessRollOver',
rollOut : 'ProcessRollOut'
};
if (axisConfig.hasProcess) {
process = axisConfig.processes.process.process;
args = {
elem : axisConfig.processes.process,
elemIndex : elemIndex,
dimension : {
left : axisStartPosition - spaceTaken + process._attrib.leftPos,
right : axisStartPosition - spaceTaken + process._attrib.rightPos,
top : canvasTop - chartConfig.categorySpaceUsed,
bottom : canvasTop
},
type : 'header'
};
axis._drawProcessAndDataTableElement(args);
elemIndex += 1;
gridArr = axisConfig.gridArr = [];
for (i = 0, processLength = process.length; i < processLength ; i++) {
topBottom = axis.getProcessPositionByIndex(i);
args = {
elem : process[i],
elemIndex : elemIndex,
pos : i,
dimension : {
left : axisStartPosition - spaceTaken + process._attrib.leftPos,
right : axisStartPosition - spaceTaken + process._attrib.rightPos,
top : canvasTop + topBottom.top,
bottom : canvasTop + topBottom.bottom
},
type : 'process'
};
axis._drawProcessAndDataTableElement(args);
elemIndex += 1;
gridArr.push({y : args.dimension.bottom});
}
}
if (axisConfig.hasDataTables) {
dataTables = axisConfig.dataTables.dataTable.datacolumn;
for (i in dataTables) {
if (!dataTables.hasOwnProperty(i) || i === '_attrib') {
continue;
}
args = {
elem : dataTables[i],
elemIndex : elemIndex,
pos : i,
dimension : {
left : axisStartPosition - spaceTaken + dataTables[i]._attrib.leftPos,
right : axisStartPosition - spaceTaken + dataTables[i]._attrib.rightPos,
top : canvasTop - chartConfig.categorySpaceUsed,
bottom : canvasTop
},
type : 'header'
};
axis._drawProcessAndDataTableElement(args);
elemIndex += 1;
dataColumn = dataTables[i].text;
for (j in dataColumn) {
if (dataColumn[j]._attrib && process[j] && process[j]._attrib) {
dataColumn[j]._attrib.hoverbandcolor = process[j]._attrib.hoverbandcolor;
dataColumn[j]._attrib.hoverbandalpha = process[j]._attrib.hoverbandalpha;
dataColumn[j]._attrib.showhoverband = process[j]._attrib.showhoverband;
}
if (!dataColumn.hasOwnProperty(j) || j === '_attrib') {
continue;
}
topBottom = axis.getProcessPositionByIndex(j);
args = {
elem : dataColumn[j],
elemIndex : elemIndex,
pos : j,
dimension : {
left : axisStartPosition - spaceTaken + dataTables[i]._attrib.leftPos,
right : axisStartPosition - spaceTaken + dataTables[i]._attrib.rightPos,
top : canvasTop + topBottom.top,
bottom : canvasTop + topBottom.bottom
},
type : 'datatable'
};
axis._drawProcessAndDataTableElement(args);
elemIndex += 1;
}
}
if (!axisConfig.drawFromProcessVlineDrag) {
if (spaceTaken > totalVisiblelWidth) {
translateX = (spaceTaken - totalVisiblelWidth);
axis.translateAxis(translateX, undefined);
} else {
axis.resetTransletAxis();
axis.resetTransletAxis();
}
} else {
axisConfig.drawFromProcessVlineDrag = false;
}
}
axis._drawGridLine();
axis._disposeExtraProcessAndDataTableElement(elemIndex);
},
_drawVerticalLineAndTracker : function () {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
chartComponents = chart.components,
canvas = axisConfig.canvas,
chartConfig = chart.config,
axisDimention = axisConfig.axisDimention || {},
axisStartPosition = axisDimention.x,
spaceTaken = axisConfig.totalWidth || 0,
canvasTop = canvas.canvasTop || chartConfig.canvasTop,
paper = chartComponents.paper,
plotLine = axis.components.processVline || (axis.components.processVline = []),
processVlineArr = axisConfig.processVlineArr,
trackerGroup = axisConfig.hotContainer,
counter = 0,
TRACKER_W = 30,
i,
ln,
path,
hotElement,
elem,
top,
hoverLineStyle,
lineHotElemStyle,
xPos,
vHoverLine,
dragStart = function () {
var ele = this,
data = ele.data ('drag-options'),
vHoverLine = data.vHoverLine;
data.origX = data.lastX || (data.lastX = 0);
vHoverLine.show ();
chart.trackerClicked = true;
data.draged = false;
},
dragMove = function (dx) {
var ele = this,
data = ele.data ('drag-options'),
vHoverLine = data.vHoverLine,
vLineSetting = data.vLineSetting,
startX = vLineSetting.xPos + dx,
leftSideLimit = vLineSetting.leftLimit,
rightSideLimit = vLineSetting.rightLimit,
transform;
//bound limits
if (startX < leftSideLimit) {
dx = leftSideLimit - vLineSetting.xPos;
}
if (startX > rightSideLimit) {
dx = rightSideLimit - vLineSetting.xPos;
}
transform = {
transform: 't' + (data.origX + dx) + COMMA + 0
};
ele.attr (transform);
vHoverLine.attr (transform);
data.draged = true;
data.lastX = dx;
},
dragUp = function () {
var ele = this,
data = ele.data ('drag-options'),
vLineSetting = data.vLineSetting,
vHoverLine = data.vHoverLine,
vLineIndex = data.vLineIndex,
transform;
chart.trackerClicked = false;
vHoverLine.hide ();
// restoring state with respect to original state
if (data.draged) {
vLineSetting.left.rightPos += data.lastX || 0;
vLineSetting.right.leftPos += data.lastX || 0;
vLineSetting.xPos += data.lastX || 0;
if (processVlineArr[vLineIndex - 1]) {
processVlineArr[vLineIndex - 1].rightLimit += data.lastX || 0;
}
if (processVlineArr[vLineIndex + 1]) {
processVlineArr[vLineIndex + 1].leftLimit += data.lastX || 0;
}
axisConfig.drawFromProcessVlineDrag = true;
axis._drawProcessAndDataTable();
axis._drawVerticalLineAndTracker();
transform = {
transform: 't0,0'
};
ele.attr (transform);
vHoverLine.attr (transform);
}
};
hoverLineStyle = {
stroke: axisConfig.gridResizeBarColor,
'stroke-width': axisConfig.gridResizeBarThickness,
visibility: 'hidden'
};
lineHotElemStyle = {
stroke: TRACKER_FILL,
ishot: true,
'stroke-width': TRACKER_W
};
top = canvasTop - chartConfig.categorySpaceUsed;
for(i = 0, ln = processVlineArr.length; i < ln; i += 1) {
if(processVlineArr[i].type === 'process') {
elem = axisConfig.processes.process.process;
} else {
elem = axisConfig.dataTables.dataTable.datacolumn[processVlineArr[i].ind];
}
xPos = axisStartPosition - spaceTaken + elem._attrib.rightPos;
path = ['M', xPos, top,'L', xPos, canvasTop + axisConfig.processTotalHeight];
if (plotLine[counter]) {
vHoverLine = plotLine[counter].graphics.vHoverLine;
vHoverLine.attr({path : path}).attr(hoverLineStyle);
hotElement = plotLine[counter].graphics.hotElement;
hotElement.attr({path : path}).attr(lineHotElemStyle);
} else {
vHoverLine = paper.path(path, trackerGroup);
vHoverLine.attr(hoverLineStyle);
hotElement = paper.path(path, trackerGroup);
hotElement.attr(lineHotElemStyle);
plotLine[counter] = {};
plotLine[counter].graphics = {};
plotLine[counter].config = {};
plotLine[counter].graphics.vHoverLine = vHoverLine;
plotLine[counter].graphics.hotElement = hotElement;
}
hotElement.css ('cursor', R.svg && 'ew-resize' || 'e-resize')
.drag (dragMove, dragStart, dragUp)
.data ('drag-options', {
vHoverLine: plotLine[counter].graphics.vHoverLine,
vLineSetting: processVlineArr[i],
vLineIndex: i
});
counter += 1;
}
for (i = counter, ln = plotLine.length; i < ln; i += 1) {
plotLine[i].graphics.vHoverLine.attr({
path : ['M',0,0]
});
plotLine[i].graphics.hotElement.attr({
path : ['M',0,0]
});
}
},
manageProcessScroll : function (scroll) {
var axis = this,
axisConfig = axis.config,
spaceTaken = axisConfig.totalWidth || 0,
totalVisiblelWidth = axisConfig.totalVisiblelWidth,
translateX;
if (spaceTaken > totalVisiblelWidth) {
translateX = (spaceTaken - totalVisiblelWidth) * (1 - scroll);
axis.translateAxis(translateX, undefined);
}
},
placeAxis : function (maxWidth) {
var axis = this,
axisConfig = axis.config,
chart = axis.chart,
smartLabel = chart.linkedItems.smartLabel,
labelStyle = axisConfig.labels.style,
hPadding = 4,
processHeightPadding = 8,
maxProcessDimention = 0,
maxTextSize = 0,
spaceReturn = {
left : 0,
right : 0
},
spaceUsed = 0,
processOnRight = false,
processSpaceUsed = 0,
processMaxHeight = 0,
i,
text,
smartLabelText,
processLength,
singleProcess,
processStyle,
processParent,
singleProcessStyle,
dataTables,
dataTable,
dataColumn,
j,
textStyle,
singleTextStyle,
maxTextDimention,
preAlocateSpace = 0;
smartLabel.useEllipsesOnOverflow(chart.config.useEllipsesWhenOverflow);
smartLabel.setStyle({
fontSize : labelStyle.fontSize,
fontFamily : labelStyle.fontFamily,
lineHeight : labelStyle.lineHeight,
fontWeight : labelStyle.fontWeight
});
if (axisConfig.showFullDataTable === 0) {
preAlocateSpace = maxWidth / ((axisConfig.hasDataTables && axisConfig.dataTables &&
axisConfig.dataTables.dataTable && axisConfig.dataTables.dataTable.datacolumn ?
axisConfig.dataTables.dataTable.datacolumn.length :
0) + 1);
}
if (axisConfig.hasProcess) {
process = axisConfig.processes.process.process;
processParent = axisConfig.processes.process;
if (processParent.positioningrid === 'right') {
processOnRight = true;
}
if (processParent.headertext) {
processParent.drawLabel = parseUnsafeString(processParent.headertext);
processStyle = processParent._attrib;
singleProcessStyle = {
fontFamily: pluck(processStyle.headerfontfamily, labelStyle.fontFamily),
fontSize: pluck(processStyle.headerfontsize, labelStyle.fontSize).replace(/px/i, '') + PXSTRING,
fontWeight: pluck((Number(processStyle.headerisbold) === 1 ? 'bold' :
processStyle.headerisbold === undefined ? 'bold' : undefined), labelStyle.fontWeight),
fontStyle: pluck((processStyle.headerisitalic ? 'italic' : undefined), labelStyle.fontStyle)
};
singleProcessStyle.lineHeight = setLineHeight(singleProcessStyle);
smartLabel.setStyle(singleProcessStyle);
smartLabelText = smartLabel.getOriSize(processParent.drawLabel);
if (smartLabelText.width > maxTextSize) {
maxProcessDimention = smartLabelText;
maxTextSize = smartLabelText.width;
}
}
for (i = 0, processLength = process.length; i < processLength ; i++) {
singleProcess = process[i];
processStyle = singleProcess._attrib;
singleProcess.drawLabel = parseUnsafeString(singleProcess.label || singleProcess.name);
singleProcessStyle = {
fontFamily: pluck(processStyle.fontfamily, labelStyle.fontFamily),
fontSize: pluck(processStyle.fontsize, labelStyle.fontSize).replace(/px/i, '') + PXSTRING,
fontWeight: pluck((processStyle.isbold ? 'bold' : undefined), labelStyle.fontWeight),
fontStyle: pluck((processStyle.isitalic ? 'italic' : undefined), labelStyle.fontStyle)
};
singleProcessStyle.lineHeight = setLineHeight(singleProcessStyle);
smartLabel.setStyle(singleProcessStyle);
smartLabelText = smartLabel.getOriSize(singleProcess.drawLabel);
if (smartLabelText.width > maxTextSize) {
maxProcessDimention = smartLabelText;
maxTextSize = smartLabelText.width;
}
if (smartLabelText.height > processMaxHeight) {
processMaxHeight = smartLabelText.height;
}
}
axisConfig.processMaxHeight = processMaxHeight + processHeightPadding;
//axisConfig.processTotalHeight = axis._setProcessHeight(processMaxHeight);
process._attrib.leftPos = spaceUsed;
if(!processOnRight) {
spaceUsed += preAlocateSpace || maxProcessDimention.width + hPadding;
} else {
processSpaceUsed = preAlocateSpace || maxProcessDimention.width + hPadding;
}
process._attrib.rightPos = spaceUsed;
}
if (axisConfig.hasDataTables) {
dataTables = axisConfig.dataTables.dataTable.datacolumn;
for (i in dataTables) {
if (!dataTables.hasOwnProperty(i) || i === '_attrib') {
continue;
}
dataTable = dataTables[i];
maxTextSize = 0;
if (dataTable.headertext) {
processStyle = dataTable._attrib;
dataTable.drawLabel = parseUnsafeString(dataTable.headertext);
singleTextStyle = {
fontFamily: pluck(processStyle.headerfontfamily, labelStyle.fontFamily),
fontSize: pluck(processStyle.headerfontsize, labelStyle.fontSize).replace(/px/i, '') +
PXSTRING,
fontWeight: pluck((Number(processStyle.headerisbold) === 1 ? 'bold' :
processStyle.headerisbold === undefined ? 'bold' : undefined), labelStyle.fontWeight),
fontStyle: pluck((processStyle.headerisitalic ? 'italic' : undefined), labelStyle.fontStyle)
};
singleTextStyle.lineHeight = setLineHeight(singleTextStyle);
smartLabel.setStyle(singleTextStyle);
smartLabelText = smartLabel.getOriSize(dataTable.drawLabel);
if (smartLabelText.width > maxTextSize) {
maxTextDimention = smartLabelText;
maxTextSize = smartLabelText.width;
}
}
dataColumn = dataTable.text;
for (j in dataColumn) {
if (!dataColumn.hasOwnProperty(j) || j === '_attrib') {
continue;
}
text = dataColumn[j];
text.drawLabel = parseUnsafeString(text.label || text.name);
textStyle = text._attrib;
singleTextStyle = {
fontFamily: pluck(textStyle.fontfamily, labelStyle.fontFamily),
fontSize: pluck(textStyle.fontsize, labelStyle.fontSize).replace(/px/i, '') + PXSTRING,
fontWeight: pluck((textStyle.isbold ? 'bold' : undefined), labelStyle.fontWeight),
fontStyle: pluck((textStyle.isitalic ? 'italic' : undefined), labelStyle.fontStyle)
};
singleTextStyle.lineHeight = setLineHeight(singleTextStyle);
smartLabel.setStyle(singleTextStyle);
smartLabelText = smartLabel.getOriSize(text.drawLabel);
if (smartLabelText.width > maxTextSize) {
maxTextDimention = smartLabelText;
maxTextSize = smartLabelText.width;
}
}
dataTables[i]._attrib.leftPos = spaceUsed;
spaceUsed += preAlocateSpace || maxTextDimention.width + hPadding;
dataTables[i]._attrib.rightPos = spaceUsed;
}
}
if (axisConfig.hasProcess) {
if(processOnRight) {
process._attrib.leftPos += spaceUsed;
process._attrib.rightPos += spaceUsed + processSpaceUsed;
spaceUsed += processSpaceUsed;
}
}
axisConfig.totalWidth = spaceUsed;
axis.adjustWidth();
spaceUsed = axisConfig.totalWidth > maxWidth ? maxWidth : axisConfig.totalWidth;
axisConfig.totalVisiblelWidth = spaceUsed;
spaceReturn.left += spaceUsed;
return spaceReturn;
},
adjustWidth : function () {
var axis = this,
axisConfig = axis.config,
totalWidth = axisConfig.totalWidth,
availableWidth = totalWidth,
spaceUsed = 0,
processOnRight = false,
dragPadding = 20,
processVlineArr,
attrib,
getWidth,
processParent,
newLeft,
dataTables,
dataTable,
i,
prevProcessVlineArr;
processVlineArr = axisConfig.processVlineArr = [];
availableWidth -= dragPadding * (axisConfig.hasDataTables && axisConfig.dataTables &&
axisConfig.dataTables.dataTable && axisConfig.dataTables.dataTable.datacolumn ?
axisConfig.dataTables.dataTable.datacolumn.length + 1 : 1);
getWidth = function (width) {
var retW;
availableWidth += dragPadding;
if (width.match(/%/g)) {
retW = pluckNumber(((totalWidth * Number(width.replace(/%/g, '')/100))), 0);
} else {
retW = pluckNumber(width, 0);
}
if (availableWidth < dragPadding) {
retW = dragPadding;
} else if (retW > availableWidth) {
retW = availableWidth;
}
availableWidth -= retW;
return retW;
};
if (axisConfig.hasProcess) {
process = axisConfig.processes.process.process;
processParent = axisConfig.processes.process;
if (processParent.positioningrid === 'right') {
processOnRight = true;
}
attrib = process._attrib;
newLeft = spaceUsed;
spaceUsed += (getWidth(attrib.width || ''+(attrib.rightPos - attrib.leftPos)));
attrib.leftPos = newLeft;
attrib.rightPos = spaceUsed;
if (!processOnRight) {
processVlineArr.push({
type : 'process',
ind : 0,
xPos : attrib.rightPos,
left : attrib,
leftLimit : attrib.leftPos + dragPadding
});
} else {
spaceUsed = 0;
}
}
if (axisConfig.hasDataTables) {
dataTables = axisConfig.dataTables.dataTable.datacolumn;
for (i in dataTables) {
if (!dataTables.hasOwnProperty(i) || i === '_attrib') {
continue;
}
dataTable = dataTables[i];
attrib = dataTable._attrib;
newLeft = spaceUsed;
spaceUsed += (getWidth(attrib.width || ''+(attrib.rightPos - attrib.leftPos)));
attrib.leftPos = newLeft;
attrib.rightPos = spaceUsed;
prevProcessVlineArr = processVlineArr[processVlineArr.length - 1];
if (prevProcessVlineArr) {
prevProcessVlineArr.right = attrib;
prevProcessVlineArr.rightLimit = attrib.rightPos - dragPadding;
}
processVlineArr.push({
type : 'dataTable',
ind : i,
xPos : attrib.rightPos,
left : attrib,
leftLimit : attrib.leftPos + dragPadding
});
}
}
if (axisConfig.hasProcess) {
if(processOnRight) {
attrib = process._attrib;
attrib.rightPos = spaceUsed + (attrib.rightPos - attrib.leftPos);
attrib.leftPos = spaceUsed;
spaceUsed += attrib.rightPos - attrib.leftPos;
prevProcessVlineArr = processVlineArr[processVlineArr.length - 1];
if (prevProcessVlineArr) {
prevProcessVlineArr.right = attrib;
prevProcessVlineArr.rightLimit = attrib.rightPos - dragPadding;
}
} else {
processVlineArr.pop();
}
}
axisConfig.totalWidth = spaceUsed;
}
}, 'ganttCommon']);
}]);
}));