summaryrefslogtreecommitdiff
path: root/www/lib/chart.horizontalbar/Chart.HorizontalBar.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/lib/chart.horizontalbar/Chart.HorizontalBar.js')
-rw-r--r--www/lib/chart.horizontalbar/Chart.HorizontalBar.js495
1 files changed, 0 insertions, 495 deletions
diff --git a/www/lib/chart.horizontalbar/Chart.HorizontalBar.js b/www/lib/chart.horizontalbar/Chart.HorizontalBar.js
deleted file mode 100644
index d66331f6..00000000
--- a/www/lib/chart.horizontalbar/Chart.HorizontalBar.js
+++ /dev/null
@@ -1,495 +0,0 @@
-(function(){
- "use strict";
-
- var root = this,
- Chart = root.Chart,
- helpers = Chart.helpers;
-
-
- var defaultConfig = {
- //Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value
- scaleBeginAtZero : true,
-
- //Boolean - Whether grid lines are shown across the chart
- scaleShowGridLines : true,
-
- //String - Colour of the grid lines
- scaleGridLineColor : "rgba(0,0,0,.05)",
-
- //Number - Width of the grid lines
- scaleGridLineWidth : 1,
-
- //Boolean - Whether to show horizontal lines (except X axis)
- scaleShowHorizontalLines: true,
-
- //Boolean - Whether to show vertical lines (except Y axis)
- scaleShowVerticalLines: true,
-
- //Boolean - If there is a stroke on each bar
- barShowStroke : true,
-
- //Number - Pixel width of the bar stroke
- barStrokeWidth : 2,
-
- //Number - Spacing between each of the X value sets
- barValueSpacing : 5,
-
- //Number - Spacing between data sets within X values
- barDatasetSpacing : 1,
-
- //String - A legend template
- legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
-
- };
-
- Chart.HorizontalRectangle = Chart.Element.extend({
- draw : function(){
- var ctx = this.ctx,
- halfHeight = this.height/2,
- top = this.y - halfHeight,
- bottom = this.y + halfHeight,
- right = this.left - (this.left - this.x),
- halfStroke = this.strokeWidth / 2;
-
- // Canvas doesn't allow us to stroke inside the width so we can
- // adjust the sizes to fit if we're setting a stroke on the line
- if (this.showStroke){
- top += halfStroke;
- bottom -= halfStroke;
- right += halfStroke;
- }
-
- ctx.beginPath();
-
- ctx.fillStyle = this.fillColor;
- ctx.strokeStyle = this.strokeColor;
- ctx.lineWidth = this.strokeWidth;
-
- // It'd be nice to keep this class totally generic to any rectangle
- // and simply specify which border to miss out.
- ctx.moveTo(this.left, bottom);
- ctx.lineTo(this.left, top);
- ctx.lineTo(right, top);
- ctx.lineTo(right, bottom);
- ctx.fill();
- if (this.showStroke){
- ctx.stroke();
- }
- },
- inRange : function(chartX,chartY){
- return (chartY >= this.y - this.height/2 && chartY <= this.y + this.height/2) && (chartX >= this.left && chartX <= this.right);
- }
- });
-
- Chart.Type.extend({
- name: "HorizontalBar",
- defaults : defaultConfig,
- initialize: function(data){
-
- //Expose options as a scope variable here so we can access it in the ScaleClass
- var options = this.options;
-
- this.ScaleClass = Chart.Scale.extend({
- offsetGridLines : true,
- calculateBarX : function(datasetCount, datasetIndex, barIndex){
- //Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar
- var xWidth = this.calculateBaseWidth(),
- xAbsolute = this.calculateX(barIndex) - (xWidth/2),
- barWidth = this.calculateBarWidth(datasetCount);
-
- return xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;
- },
- calculateBaseWidth : function(){
- return (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);
- },
- calculateBarWidth : function(datasetCount){
- //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
- var baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);
-
- return (baseWidth / datasetCount);
- },
-
- calculateBaseHeight : function(){
- return ((this.endPoint - this.startPoint) / this.yLabels.length) - (2*options.barValueSpacing);
- },
- calculateBarHeight : function(datasetCount){
- //The padding between datasets is to the right of each bar, providing that there are more than 1 dataset
- var baseHeight = this.calculateBaseHeight() - ((datasetCount) * options.barDatasetSpacing);
-
- return (baseHeight / datasetCount);
- },
-
- calculateXInvertXY : function(value) {
- var scalingFactor = (this.width - Math.round(this.xScalePaddingLeft) - this.xScalePaddingRight) / (this.max - this.min);
- return Math.round(this.xScalePaddingLeft) + (scalingFactor * (value - this.min));
- },
-
- calculateYInvertXY : function(index){
- return index * ((this.startPoint - this.endPoint) / (this.yLabels.length));
- },
-
- calculateBarY : function(datasetCount, datasetIndex, barIndex){
- //Reusable method for calculating the yPosition of a given bar based on datasetIndex & height of the bar
- var yHeight = this.calculateBaseHeight(),
- yAbsolute = (this.endPoint + this.calculateYInvertXY(barIndex) - (yHeight / 2)) - 5,
- barHeight = this.calculateBarHeight(datasetCount);
- if (datasetCount > 1) yAbsolute = yAbsolute + (barHeight * (datasetIndex - 1)) - (datasetIndex * options.barDatasetSpacing) + barHeight/2;
- return yAbsolute;
- },
-
- buildCalculatedLabels : function() {
- this.calculatedLabels = [];
-
- var stepDecimalPlaces = helpers.getDecimalPlaces(this.stepValue);
-
- for (var i=0; i<=this.steps; i++){
- this.calculatedLabels.push(helpers.template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));
- }
- },
-
- buildYLabels : function(){
- this.buildYLabelCounter = (typeof this.buildYLabelCounter === 'undefined') ? 0 : this.buildYLabelCounter + 1;
- this.buildCalculatedLabels();
- if(this.buildYLabelCounter === 0) this.yLabels = this.xLabels;
- this.xLabels = this.calculatedLabels;
- this.yLabelWidth = (this.display && this.showLabels) ? helpers.longestText(this.ctx,this.font,this.yLabels) : 0;
- },
-
- calculateX : function(index){
- var isRotated = (this.xLabelRotation > 0),
- innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
- valueWidth = innerWidth/(this.steps - ((this.offsetGridLines) ? 0 : 1)),
- valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
-
- if (this.offsetGridLines){
- valueOffset += (valueWidth/2);
- }
-
- return Math.round(valueOffset);
- },
-
- draw : function(){
- var ctx = this.ctx,
- yLabelGap = (this.endPoint - this.startPoint) / this.yLabels.length,
- xStart = Math.round(this.xScalePaddingLeft);
- if (this.display){
- ctx.fillStyle = this.textColor;
- ctx.font = this.font;
- helpers.each(this.yLabels,function(labelString,index){
- var yLabelCenter = this.endPoint - (yLabelGap * index),
- linePositionY = Math.round(yLabelCenter);
-
- yLabelCenter -= yLabelGap / 2;
-
- ctx.textAlign = "right";
- ctx.textBaseline = "middle";
- if (this.showLabels){
- ctx.fillText(labelString,xStart - 10,yLabelCenter);
- }
- ctx.beginPath();
- if (index > 0){
- // This is a grid line in the centre, so drop that
- ctx.lineWidth = this.gridLineWidth;
- ctx.strokeStyle = this.gridLineColor;
- } else {
- // This is the first line on the scale
- ctx.lineWidth = this.lineWidth;
- ctx.strokeStyle = this.lineColor;
- }
-
- linePositionY += helpers.aliasPixel(ctx.lineWidth);
-
- ctx.moveTo(xStart, linePositionY);
- ctx.lineTo(this.width, linePositionY);
- ctx.stroke();
- ctx.closePath();
-
- ctx.lineWidth = this.lineWidth;
- ctx.strokeStyle = this.lineColor;
- ctx.beginPath();
- ctx.moveTo(xStart - 5, linePositionY);
- ctx.lineTo(xStart, linePositionY);
- ctx.stroke();
- ctx.closePath();
-
- },this);
-
- helpers.each(this.xLabels,function(label,index){
- var width = this.calculateX(1) - this.calculateX(0);
- var xPos = this.calculateX(index) + helpers.aliasPixel(this.lineWidth) - (width / 2),
- // Check to see if line/bar here and decide where to place the line
- linePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + helpers.aliasPixel(this.lineWidth),
- isRotated = (this.xLabelRotation > 0);
-
- ctx.beginPath();
-
- if (index > 0){
- // This is a grid line in the centre, so drop that
- ctx.lineWidth = this.gridLineWidth;
- ctx.strokeStyle = this.gridLineColor;
- } else {
- // This is the first line on the scale
- ctx.lineWidth = this.lineWidth;
- ctx.strokeStyle = this.lineColor;
- }
- ctx.moveTo(linePos,this.endPoint);
- ctx.lineTo(linePos,this.startPoint - 3);
- ctx.stroke();
- ctx.closePath();
-
-
- ctx.lineWidth = this.lineWidth;
- ctx.strokeStyle = this.lineColor;
-
-
- // Small lines at the bottom of the base grid line
- ctx.beginPath();
- ctx.moveTo(linePos,this.endPoint);
- ctx.lineTo(linePos,this.endPoint + 5);
- ctx.stroke();
- ctx.closePath();
-
- ctx.save();
- ctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);
- ctx.rotate(helpers.radians(this.xLabelRotation)*-1);
- ctx.font = this.font;
- ctx.textAlign = (isRotated) ? "right" : "center";
- ctx.textBaseline = (isRotated) ? "middle" : "top";
- ctx.fillText(label, 0, 0);
- ctx.restore();
- },this);
-
- }
- }
-
- });
-
- this.datasets = [];
-
- //Set up tooltip events on the chart
- if (this.options.showTooltips){
- helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
- var activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];
-
- this.eachBars(function(bar){
- bar.restore(['fillColor', 'strokeColor']);
- });
- helpers.each(activeBars, function(activeBar){
- activeBar.fillColor = activeBar.highlightFill;
- activeBar.strokeColor = activeBar.highlightStroke;
- });
- this.showTooltip(activeBars);
- });
- }
-
- //Declare the extension of the default point, to cater for the options passed in to the constructor
- this.BarClass = Chart.HorizontalRectangle.extend({
- strokeWidth : this.options.barStrokeWidth,
- showStroke : this.options.barShowStroke,
- ctx : this.chart.ctx
- });
-
- //Iterate through each of the datasets, and build this into a property of the chart
- helpers.each(data.datasets,function(dataset,datasetIndex){
-
- var datasetObject = {
- label : dataset.label || null,
- fillColor : dataset.fillColor,
- strokeColor : dataset.strokeColor,
- bars : []
- };
-
- this.datasets.push(datasetObject);
-
- helpers.each(dataset.data,function(dataPoint,index){
- //Add a new point for each piece of data, passing any required data to draw.
- datasetObject.bars.push(new this.BarClass({
- value : dataPoint,
- label : data.labels[index],
- datasetLabel: dataset.label,
- strokeColor : dataset.strokeColor,
- fillColor : dataset.fillColor,
- highlightFill : dataset.highlightFill || dataset.fillColor,
- highlightStroke : dataset.highlightStroke || dataset.strokeColor
- }));
- },this);
-
- },this);
-
- this.buildScale(data.labels);
-
- this.BarClass.prototype.left = Math.round(this.scale.xScalePaddingLeft);
-
- this.eachBars(function(bar, index, datasetIndex){
- helpers.extend(bar, {
- x: Math.round(this.scale.xScalePaddingLeft),
- y : this.scale.calculateBarY(this.datasets.length, datasetIndex, index),
- height : this.scale.calculateBarHeight(this.datasets.length)
- });
- bar.save();
- }, this);
-
- this.render();
- },
- update : function(){
- this.scale.update();
- // Reset any highlight colours before updating.
- helpers.each(this.activeElements, function(activeElement){
- activeElement.restore(['fillColor', 'strokeColor']);
- });
-
- this.eachBars(function(bar){
- bar.save();
- });
- this.render();
- },
- eachBars : function(callback){
- helpers.each(this.datasets,function(dataset, datasetIndex){
- helpers.each(dataset.bars, callback, this, datasetIndex);
- },this);
- },
- getBarsAtEvent : function(e){
- var barsArray = [],
- eventPosition = helpers.getRelativePosition(e),
- datasetIterator = function(dataset){
- barsArray.push(dataset.bars[barIndex]);
- },
- barIndex;
-
- for (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {
- for (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {
- if (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){
- helpers.each(this.datasets, datasetIterator);
- return barsArray;
- }
- }
- }
-
- return barsArray;
- },
- buildScale : function(labels){
- var self = this;
-
- var dataTotal = function(){
- var values = [];
- self.eachBars(function(bar){
- values.push(bar.value);
- });
- return values;
- };
-
- var scaleOptions = {
- templateString : this.options.scaleLabel,
- height : this.chart.height,
- width : this.chart.width,
- ctx : this.chart.ctx,
- textColor : this.options.scaleFontColor,
- fontSize : this.options.scaleFontSize,
- fontStyle : this.options.scaleFontStyle,
- fontFamily : this.options.scaleFontFamily,
- valuesCount : labels.length,
- beginAtZero : this.options.scaleBeginAtZero,
- integersOnly : this.options.scaleIntegersOnly,
- calculateYRange: function(currentHeight){
- var updatedRanges = helpers.calculateScaleRange(
- dataTotal(),
- currentHeight,
- this.fontSize,
- this.beginAtZero,
- this.integersOnly
- );
- helpers.extend(this, updatedRanges);
- },
- xLabels : labels,
- font : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),
- lineWidth : this.options.scaleLineWidth,
- lineColor : this.options.scaleLineColor,
- showHorizontalLines : this.options.scaleShowHorizontalLines,
- showVerticalLines : this.options.scaleShowVerticalLines,
- gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
- gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
- padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
- showLabels : this.options.scaleShowLabels,
- display : this.options.showScale
- };
-
- if (this.options.scaleOverride){
- helpers.extend(scaleOptions, {
- calculateYRange: helpers.noop,
- steps: this.options.scaleSteps,
- stepValue: this.options.scaleStepWidth,
- min: this.options.scaleStartValue,
- max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
- });
- }
-
- this.scale = new this.ScaleClass(scaleOptions);
- },
- addData : function(valuesArray,label){
- //Map the values array for each of the datasets
- helpers.each(valuesArray,function(value,datasetIndex){
- //Add a new point for each piece of data, passing any required data to draw.
- this.datasets[datasetIndex].bars.push(new this.BarClass({
- value : value,
- label : label,
- x: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),
- y: this.scale.endPoint,
- width : this.scale.calculateBarWidth(this.datasets.length),
- base : this.scale.endPoint,
- strokeColor : this.datasets[datasetIndex].strokeColor,
- fillColor : this.datasets[datasetIndex].fillColor
- }));
- },this);
-
- this.scale.addXLabel(label);
- //Then re-render the chart.
- this.update();
- },
- removeData : function(){
- this.scale.removeXLabel();
- //Then re-render the chart.
- helpers.each(this.datasets,function(dataset){
- dataset.bars.shift();
- },this);
- this.update();
- },
- reflow : function(){
- helpers.extend(this.BarClass.prototype,{
- y: this.scale.endPoint,
- base : this.scale.endPoint
- });
- var newScaleProps = helpers.extend({
- height : this.chart.height,
- width : this.chart.width
- });
-
- this.scale.update(newScaleProps);
- },
- draw : function(ease){
- var easingDecimal = ease || 1;
- this.clear();
-
- var ctx = this.chart.ctx;
-
- this.scale.draw(easingDecimal);
-
- //Draw all the bars for each dataset
- helpers.each(this.datasets,function(dataset,datasetIndex){
- helpers.each(dataset.bars,function(bar,index){
- if (bar.hasValue()){
- bar.left = Math.round(this.scale.xScalePaddingLeft);
- //Transition then draw
- bar.transition({
- x : this.scale.calculateXInvertXY(bar.value),
- y : this.scale.calculateBarY(this.datasets.length, datasetIndex, index),
- height : this.scale.calculateBarHeight(this.datasets.length)
- }, easingDecimal).draw();
- }
- },this);
-
- },this);
- }
- });
-
-
-}).call(this);