add sppd to git repo
This commit is contained in:
517
plugins/highcharts/jquery.highchartTable.js
Normal file
517
plugins/highcharts/jquery.highchartTable.js
Normal file
@@ -0,0 +1,517 @@
|
||||
;
|
||||
|
||||
(function($) {
|
||||
$.fn.highchartTable = function() {
|
||||
|
||||
var allowedGraphTypes = ['column', 'line', 'area', 'spline', 'pie'];
|
||||
|
||||
var getCallable = function (table, attribute) {
|
||||
var callback = $(table).data(attribute);
|
||||
if (typeof callback != 'undefined') {
|
||||
var infosCallback = callback.split('.');
|
||||
var callable = window[infosCallback[0]];
|
||||
for(var i = 1, infosCallbackLength = infosCallback.length; i < infosCallbackLength; i++) {
|
||||
callable = callable[infosCallback[i]];
|
||||
}
|
||||
return callable;
|
||||
}
|
||||
};
|
||||
|
||||
this.each(function() {
|
||||
var table = $(this);
|
||||
var $table = $(table);
|
||||
var nbYaxis = 1;
|
||||
|
||||
// Retrieve graph title from the table caption
|
||||
var captions = $('caption', table);
|
||||
var graphTitle = captions.length ? $(captions[0]).text() : '';
|
||||
|
||||
var graphContainer;
|
||||
if ($table.data('graph-container-before') != 1) {
|
||||
// Retrieve where the graph must be displayed from the graph-container attribute
|
||||
var graphContainerSelector = $table.data('graph-container');
|
||||
if (!graphContainerSelector) {
|
||||
throw "graph-container data attribute is mandatory";
|
||||
}
|
||||
|
||||
if (graphContainerSelector[0] === '#' || graphContainerSelector.indexOf('..')===-1) {
|
||||
// Absolute selector path
|
||||
graphContainer = $(graphContainerSelector);
|
||||
} else {
|
||||
var referenceNode = table;
|
||||
var currentGraphContainerSelector = graphContainerSelector;
|
||||
|
||||
while (currentGraphContainerSelector.indexOf('..')!==-1) {
|
||||
currentGraphContainerSelector = currentGraphContainerSelector.replace(/^.. /, '');
|
||||
referenceNode = referenceNode.parent();
|
||||
}
|
||||
|
||||
graphContainer = $(currentGraphContainerSelector, referenceNode);
|
||||
}
|
||||
if (graphContainer.length !== 1) {
|
||||
throw "graph-container is not available in this DOM or available multiple times";
|
||||
}
|
||||
graphContainer = graphContainer[0];
|
||||
} else {
|
||||
$table.before('<div></div>');
|
||||
graphContainer = $table.prev();
|
||||
graphContainer = graphContainer[0];
|
||||
}
|
||||
|
||||
// Retrieve graph type from graph-type attribute
|
||||
var globalGraphType = $table.data('graph-type');
|
||||
if (!globalGraphType) {
|
||||
throw "graph-type data attribute is mandatory";
|
||||
}
|
||||
if ($.inArray(globalGraphType, allowedGraphTypes) == -1) {
|
||||
throw "graph-container data attribute must be one of " + allowedGraphTypes.join(', ');
|
||||
}
|
||||
|
||||
var stackingType = $table.data('graph-stacking');
|
||||
if (!stackingType) {
|
||||
stackingType = 'normal';
|
||||
}
|
||||
|
||||
var dataLabelsEnabled = $table.data('graph-datalabels-enabled');
|
||||
var isGraphInverted = $table.data('graph-inverted') == 1;
|
||||
|
||||
// Retrieve series titles
|
||||
var ths = $('thead th', table);
|
||||
var columns = [];
|
||||
var vlines = [];
|
||||
var skippedColumns = 0;
|
||||
var graphIsStacked = false;
|
||||
ths.each(function(indexTh, th) {
|
||||
var $th = $(th);
|
||||
var columnScale = $th.data('graph-value-scale');
|
||||
|
||||
var serieGraphType = $th.data('graph-type');
|
||||
if($.inArray(serieGraphType, allowedGraphTypes) == -1) {
|
||||
serieGraphType = globalGraphType;
|
||||
}
|
||||
|
||||
var serieStackGroup = $th.data('graph-stack-group');
|
||||
if(serieStackGroup) {
|
||||
graphIsStacked = true;
|
||||
}
|
||||
|
||||
var serieDataLabelsEnabled = $th.data('graph-datalabels-enabled');
|
||||
if (typeof serieDataLabelsEnabled == 'undefined') {
|
||||
serieDataLabelsEnabled = dataLabelsEnabled;
|
||||
}
|
||||
|
||||
var yaxis = $th.data('graph-yaxis');
|
||||
|
||||
if (typeof yaxis != 'undefined' && yaxis == '1') {
|
||||
nbYaxis = 2;
|
||||
}
|
||||
|
||||
var isColumnSkipped = $th.data('graph-skip') == 1;
|
||||
if (isColumnSkipped)
|
||||
{
|
||||
skippedColumns = skippedColumns + 1;
|
||||
}
|
||||
|
||||
var thGraphConfig = {
|
||||
libelle: $th.text(),
|
||||
skip: isColumnSkipped,
|
||||
indexTd: indexTh - skippedColumns - 1,
|
||||
color: $th.data('graph-color'),
|
||||
visible: !$th.data('graph-hidden'),
|
||||
yAxis: typeof yaxis != 'undefined' ? yaxis : 0,
|
||||
dashStyle: $th.data('graph-dash-style') || 'solid',
|
||||
dataLabelsEnabled: serieDataLabelsEnabled == 1,
|
||||
dataLabelsColor: $th.data('graph-datalabels-color') || $table.data('graph-datalabels-color')
|
||||
|
||||
};
|
||||
|
||||
var vlinex = $th.data('graph-vline-x');
|
||||
if (typeof vlinex == 'undefined') {
|
||||
thGraphConfig.scale = typeof columnScale != 'undefined' ? parseFloat(columnScale) : 1;
|
||||
thGraphConfig.graphType = serieGraphType == 'column' && isGraphInverted ? 'bar' : serieGraphType;
|
||||
thGraphConfig.stack = serieStackGroup;
|
||||
thGraphConfig.unit = $th.data('graph-unit');
|
||||
columns[indexTh] = thGraphConfig;
|
||||
} else {
|
||||
thGraphConfig.x = vlinex;
|
||||
thGraphConfig.height = $th.data('graph-vline-height');
|
||||
thGraphConfig.name = $th.data('graph-vline-name');
|
||||
vlines[indexTh] = thGraphConfig;
|
||||
}
|
||||
});
|
||||
|
||||
var series = [];
|
||||
$(columns).each(function(indexColumn, column) {
|
||||
if(indexColumn!=0 && !column.skip) {
|
||||
|
||||
var serieConfig = {
|
||||
name: column.libelle + (column.unit ? ' (' + column.unit + ')' : ''),
|
||||
data: [],
|
||||
type: column.graphType,
|
||||
stack: column.stack,
|
||||
color: column.color,
|
||||
visible: column.visible,
|
||||
yAxis: column.yAxis,
|
||||
dashStyle: column.dashStyle,
|
||||
marker: {
|
||||
enabled: false
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: column.dataLabelsEnabled,
|
||||
color: column.dataLabelsColor,
|
||||
align: $table.data('graph-datalabels-align') || (globalGraphType == 'column' && isGraphInverted == 1 ? undefined : 'center')
|
||||
}
|
||||
};
|
||||
|
||||
if(column.dataLabelsEnabled) {
|
||||
var callableSerieDataLabelsFormatter = getCallable(table, 'graph-datalabels-formatter');
|
||||
if (callableSerieDataLabelsFormatter) {
|
||||
serieConfig.dataLabels.formatter = function () {
|
||||
return callableSerieDataLabelsFormatter(this.y);
|
||||
};
|
||||
}
|
||||
}
|
||||
series.push(serieConfig);
|
||||
}
|
||||
});
|
||||
|
||||
$(vlines).each(function(indexColumn, vline) {
|
||||
if (typeof vline != 'undefined' && !vline.skip) {
|
||||
series.push({
|
||||
name: vline.libelle,
|
||||
data: [{x: vline.x, y:0, name: vline.name}, {x:vline.x, y:vline.height, name: vline.name}],
|
||||
type: 'spline',
|
||||
color: vline.color,
|
||||
visible: vline.visible,
|
||||
marker: {
|
||||
enabled: false
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var xValues = [];
|
||||
var callablePoint = getCallable(table, 'graph-point-callback');
|
||||
var isGraphDatetime = $table.data('graph-xaxis-type') == 'datetime';
|
||||
|
||||
var rows = $('tbody:first tr', table);
|
||||
rows.each(function(indexRow, row) {
|
||||
if (!!$(row).data('graph-skip')) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tds = $('td', row);
|
||||
tds.each(function(indexTd, td) {
|
||||
var cellValue;
|
||||
var column = columns[indexTd];
|
||||
|
||||
if (column.skip) {
|
||||
return;
|
||||
}
|
||||
var $td = $(td);
|
||||
if (indexTd==0) {
|
||||
cellValue = $td.text();
|
||||
xValues.push(cellValue);
|
||||
} else {
|
||||
var rawCellValue = $td.text();
|
||||
var serie = series[column.indexTd];
|
||||
|
||||
if (rawCellValue.length==0) {
|
||||
if (!isGraphDatetime) {
|
||||
serie.data.push(null);
|
||||
}
|
||||
} else {
|
||||
var cleanedCellValue = rawCellValue.replace(/\s/g, '').replace(/,/, '.');
|
||||
var eventOptions = {
|
||||
value: cleanedCellValue,
|
||||
rawValue: rawCellValue,
|
||||
td: $td,
|
||||
tr: $(row),
|
||||
indexTd: indexTd,
|
||||
indexTr: indexRow
|
||||
}
|
||||
$table.trigger('highchartTable.cleanValue', eventOptions);
|
||||
cellValue = Math.round(parseFloat(eventOptions.value) * column.scale * 100) / 100;
|
||||
|
||||
var dataGraphX = $td.data('graph-x');
|
||||
|
||||
if (isGraphDatetime) {
|
||||
dataGraphX = $('td', $(row)).first().text();
|
||||
var date = parseDate(dataGraphX);
|
||||
dataGraphX = date.getTime() - date.getTimezoneOffset()*60*1000;
|
||||
}
|
||||
|
||||
var tdGraphName = $td.data('graph-name');
|
||||
var serieDataItem = {
|
||||
name: typeof tdGraphName != 'undefined' ? tdGraphName : rawCellValue,
|
||||
y: cellValue,
|
||||
x: dataGraphX //undefined if no x defined in table
|
||||
};
|
||||
|
||||
if (callablePoint) {
|
||||
serieDataItem.events = {
|
||||
click: function () {
|
||||
return callablePoint(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (column.graphType === 'pie') {
|
||||
if ($td.data('graph-item-highlight')) {
|
||||
serieDataItem.sliced = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var tdGraphItemColor = $td.data('graph-item-color');
|
||||
if (typeof tdGraphItemColor != 'undefined') {
|
||||
serieDataItem.color = tdGraphItemColor;
|
||||
}
|
||||
|
||||
serie.data.push(serieDataItem);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var getYaxisAttr = function($table, yAxisNum, name) {
|
||||
var oldConvention = $table.data('graph-yaxis-' + yAxisNum + '-' + name);
|
||||
if (typeof oldConvention != 'undefined') {
|
||||
return oldConvention;
|
||||
}
|
||||
|
||||
return $table.data('graph-yaxis' + yAxisNum + '-' + name);
|
||||
};
|
||||
|
||||
var yAxisConfig = [];
|
||||
var yAxisNum;
|
||||
for (yAxisNum=1 ; yAxisNum <= nbYaxis ; yAxisNum++) {
|
||||
var yAxisConfigCurrentAxis = {
|
||||
title: {
|
||||
text: typeof getYaxisAttr($table, yAxisNum, 'title-text') != 'undefined' ? getYaxisAttr($table, yAxisNum, 'title-text') : null
|
||||
},
|
||||
max: typeof getYaxisAttr($table, yAxisNum, 'max') != 'undefined' ? getYaxisAttr($table, yAxisNum, 'max') : null,
|
||||
min: typeof getYaxisAttr($table, yAxisNum, 'min') != 'undefined' ? getYaxisAttr($table, yAxisNum, 'min') : null,
|
||||
reversed: getYaxisAttr($table, yAxisNum, 'reversed') == '1',
|
||||
opposite: getYaxisAttr($table, yAxisNum, 'opposite') == '1',
|
||||
tickInterval: getYaxisAttr($table, yAxisNum, 'tick-interval') || null,
|
||||
labels: {
|
||||
rotation: getYaxisAttr($table, yAxisNum, 'rotation') || 0
|
||||
},
|
||||
startOnTick: getYaxisAttr($table, yAxisNum, 'start-on-tick') != "0",
|
||||
endOnTick: getYaxisAttr($table, yAxisNum, 'end-on-tick') != "0",
|
||||
stackLabels : {
|
||||
enabled: getYaxisAttr($table, yAxisNum, 'stacklabels-enabled') == '1'
|
||||
},
|
||||
gridLineInterpolation: getYaxisAttr($table, yAxisNum, 'grid-line-interpolation') || null
|
||||
};
|
||||
|
||||
var callableYAxisFormatter = getCallable(table, 'graph-yaxis-'+yAxisNum+'-formatter-callback');
|
||||
|
||||
if (!callableYAxisFormatter) {
|
||||
callableYAxisFormatter = getCallable(table, 'graph-yaxis'+yAxisNum+'-formatter-callback');
|
||||
}
|
||||
|
||||
if (callableYAxisFormatter) {
|
||||
yAxisConfigCurrentAxis.labels.formatter = function () {
|
||||
return callableYAxisFormatter(this.value);
|
||||
};
|
||||
}
|
||||
|
||||
yAxisConfig.push(yAxisConfigCurrentAxis);
|
||||
}
|
||||
|
||||
var defaultColors = [
|
||||
'#4572A7',
|
||||
'#AA4643',
|
||||
'#89A54E',
|
||||
'#80699B',
|
||||
'#3D96AE',
|
||||
'#DB843D',
|
||||
'#92A8CD',
|
||||
'#A47D7C',
|
||||
'#B5CA92'
|
||||
];
|
||||
var colors = [];
|
||||
|
||||
var themeColors = typeof Highcharts.theme != 'undefined' && typeof Highcharts.theme.colors != 'undefined' ? Highcharts.theme.colors : [];
|
||||
var lineShadow = $table.data('graph-line-shadow');
|
||||
var lineWidth = $table.data('graph-line-width') || 2;
|
||||
|
||||
var nbOfColors = Math.max(defaultColors.length, themeColors.length);
|
||||
for(var i=0; i < nbOfColors; i++) {
|
||||
var dataname = 'graph-color-' + (i+1);
|
||||
colors.push(typeof $table.data(dataname) != 'undefined' ? $table.data(dataname) : typeof themeColors[i] != 'undefined' ? themeColors[i] : defaultColors[i]);
|
||||
}
|
||||
|
||||
var marginTop = $table.data('graph-margin-top');
|
||||
var marginRight = $table.data('graph-margin-right');
|
||||
var marginBottom = $table.data('graph-margin-bottom');
|
||||
var marginLeft = $table.data('graph-margin-left');
|
||||
|
||||
var xAxisLabelsEnabled = $table.data('graph-xaxis-labels-enabled');
|
||||
|
||||
var xAxisLabelStyle = {};
|
||||
var xAxisLabelFontSize = $table.data('graph-xaxis-labels-font-size');
|
||||
|
||||
if (typeof xAxisLabelFontSize != 'undefined')
|
||||
{
|
||||
xAxisLabelStyle.fontSize = xAxisLabelFontSize;
|
||||
}
|
||||
|
||||
var highChartConfig = {
|
||||
colors: colors,
|
||||
chart: {
|
||||
renderTo: graphContainer,
|
||||
inverted: isGraphInverted,
|
||||
marginTop: typeof marginTop != 'undefined' ? marginTop : null,
|
||||
marginRight: typeof marginRight != 'undefined' ? marginRight : null,
|
||||
marginBottom: typeof marginBottom != 'undefined' ? marginBottom : null,
|
||||
marginLeft: typeof marginLeft != 'undefined' ? marginLeft : null,
|
||||
spacingTop: $table.data('graph-spacing-top') || 10,
|
||||
height: $table.data('graph-height') || null,
|
||||
zoomType: $table.data('graph-zoom-type') || null,
|
||||
polar: $table.data('graph-polar') || null
|
||||
},
|
||||
title: {
|
||||
text: graphTitle
|
||||
},
|
||||
subtitle: {
|
||||
text: $table.data('graph-subtitle-text') || ''
|
||||
},
|
||||
legend: {
|
||||
enabled: $table.data('graph-legend-disabled') != '1',
|
||||
layout: $table.data('graph-legend-layout') || 'horizontal',
|
||||
symbolWidth: $table.data('graph-legend-width') || 30,
|
||||
x: $table.data('graph-legend-x') || 15,
|
||||
y: $table.data('graph-legend-y') || 0
|
||||
},
|
||||
xAxis: {
|
||||
categories: ($table.data('graph-xaxis-type') != 'datetime') ? xValues : undefined,
|
||||
type: ($table.data('graph-xaxis-type') == 'datetime') ? 'datetime' : undefined,
|
||||
reversed: $table.data('graph-xaxis-reversed') == '1',
|
||||
opposite: $table.data('graph-xaxis-opposite') == '1',
|
||||
showLastLabel: typeof $table.data('graph-xaxis-show-last-label') != 'undefined' ? $table.data('graph-xaxis-show-last-label') : true,
|
||||
tickInterval: $table.data('graph-xaxis-tick-interval') || null,
|
||||
dateTimeLabelFormats: { //by default, we display the day and month on the datetime graphs
|
||||
second: '%e. %b',
|
||||
minute: '%e. %b',
|
||||
hour: '%e. %b',
|
||||
day: '%e. %b',
|
||||
week: '%e. %b',
|
||||
month: '%e. %b',
|
||||
year: '%e. %b'
|
||||
},
|
||||
labels:
|
||||
{
|
||||
rotation: $table.data('graph-xaxis-rotation') || undefined,
|
||||
align: $table.data('graph-xaxis-align') || undefined,
|
||||
enabled: typeof xAxisLabelsEnabled != 'undefined' ? xAxisLabelsEnabled : true,
|
||||
style: xAxisLabelStyle
|
||||
},
|
||||
startOnTick: $table.data('graph-xaxis-start-on-tick'),
|
||||
endOnTick: $table.data('graph-xaxis-end-on-tick'),
|
||||
min: getXAxisMinMax(table, 'min'),
|
||||
max: getXAxisMinMax(table, 'max'),
|
||||
alternateGridColor: $table.data('graph-xaxis-alternateGridColor') || null,
|
||||
title: {
|
||||
text: $table.data('graph-xaxis-title-text') || null
|
||||
},
|
||||
gridLineWidth: $table.data('graph-xaxis-gridLine-width') || 0,
|
||||
gridLineDashStyle: $table.data('graph-xaxis-gridLine-style') || 'ShortDot',
|
||||
tickmarkPlacement: $table.data('graph-xaxis-tickmark-placement') || 'between',
|
||||
lineWidth: $table.data('graph-xaxis-line-width') || 0
|
||||
},
|
||||
yAxis: yAxisConfig,
|
||||
tooltip: {
|
||||
formatter: function() {
|
||||
if ($table.data('graph-xaxis-type') == 'datetime') {
|
||||
return '<b>'+ this.series.name +'</b><br/>'+ Highcharts.dateFormat('%e. %b', this.x) +' : '+ this.y;
|
||||
} else {
|
||||
var xValue = typeof xValues[this.point.x] != 'undefined' ? xValues[this.point.x] : this.point.x;
|
||||
if (globalGraphType === 'pie') {
|
||||
return '<strong>' + this.series.name + '</strong><br />' + xValue + ' : ' + this.point.y;
|
||||
}
|
||||
return '<strong>' + this.series.name + '</strong><br />' + xValue + ' : ' + this.point.name;
|
||||
}
|
||||
}
|
||||
},
|
||||
credits: {
|
||||
enabled: false
|
||||
},
|
||||
plotOptions: {
|
||||
line: {
|
||||
dataLabels: {
|
||||
enabled: true
|
||||
},
|
||||
lineWidth: lineWidth
|
||||
},
|
||||
area: {
|
||||
lineWidth: lineWidth,
|
||||
shadow: typeof lineShadow != 'undefined' ? lineShadow : true,
|
||||
fillOpacity: $table.data('graph-area-fillOpacity') || 0.75
|
||||
},
|
||||
pie: {
|
||||
allowPointSelect: true,
|
||||
dataLabels: {
|
||||
enabled: true
|
||||
},
|
||||
showInLegend: $table.data('graph-pie-show-in-legend') == '1',
|
||||
size: '80%'
|
||||
},
|
||||
series: {
|
||||
animation: false,
|
||||
stickyTracking : false,
|
||||
stacking: graphIsStacked ? stackingType : null,
|
||||
groupPadding: $table.data('graph-group-padding') || 0
|
||||
}
|
||||
},
|
||||
series: series,
|
||||
exporting: {
|
||||
filename: graphTitle.replace(/ /g, '_'),
|
||||
buttons: {
|
||||
exportButton: {
|
||||
menuItems: null,
|
||||
onclick: function() {
|
||||
this.exportChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$table.trigger('highchartTable.beforeRender', highChartConfig);
|
||||
new Highcharts.Chart(highChartConfig);
|
||||
|
||||
});
|
||||
//for fluent api
|
||||
return this;
|
||||
};
|
||||
|
||||
var getXAxisMinMax = function(table, minOrMax) {
|
||||
var value = $(table).data('graph-xaxis-'+minOrMax);
|
||||
if (typeof value != 'undefined') {
|
||||
if ($(table).data('graph-xaxis-type') == 'datetime') {
|
||||
var date = parseDate(value);
|
||||
return date.getTime() - date.getTimezoneOffset()*60*1000;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
var parseDate = function(datetime) {
|
||||
var calculatedateInfos = datetime.split(' ');
|
||||
var dateDayInfos = calculatedateInfos[0].split('-');
|
||||
var min = null;
|
||||
var hour = null;
|
||||
// If hour and minute are available in the datetime string
|
||||
if(calculatedateInfos[1]) {
|
||||
var dateHourInfos = calculatedateInfos[1].split(':');
|
||||
min = parseInt(dateHourInfos[0], 10);
|
||||
hour = parseInt(dateHourInfos[1], 10);
|
||||
}
|
||||
return new Date(parseInt(dateDayInfos[0], 10), parseInt(dateDayInfos[1], 10)-1, parseInt(dateDayInfos[2], 10), min, hour);
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user