[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 // This file is part of Moodle - http://moodle.org/ 2 // 3 // Moodle is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU General Public License as published by 5 // the Free Software Foundation, either version 3 of the License, or 6 // (at your option) any later version. 7 // 8 // Moodle is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 15 16 /** 17 * Chart output for chart.js. 18 * 19 * @package core 20 * @copyright 2016 Frédéric Massart - FMCorz.net 21 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 22 * @module core/chart_output_chartjs 23 */ 24 define([ 25 'jquery', 26 'core/chartjs', 27 'core/chart_axis', 28 'core/chart_bar', 29 'core/chart_output_base', 30 'core/chart_line', 31 'core/chart_pie', 32 'core/chart_series' 33 ], function($, Chartjs, Axis, Bar, Base, Line, Pie, Series) { 34 35 /** 36 * Makes an axis ID. 37 * 38 * @param {String} xy Accepts 'x' and 'y'. 39 * @param {Number} index The axis index. 40 * @return {String} 41 */ 42 var makeAxisId = function(xy, index) { 43 return 'axis-' + xy + '-' + index; 44 }; 45 46 /** 47 * Chart output for Chart.js. 48 * 49 * @class 50 * @alias module:core/chart_output_chartjs 51 * @extends {module:core/chart_output_base} 52 */ 53 function Output() { 54 Base.prototype.constructor.apply(this, arguments); 55 56 // Make sure that we've got a canvas tag. 57 this._canvas = this._node; 58 if (this._canvas.prop('tagName') != 'CANVAS') { 59 this._canvas = $('<canvas>'); 60 this._node.append(this._canvas); 61 } 62 63 this._build(); 64 } 65 Output.prototype = Object.create(Base.prototype); 66 67 /** 68 * Reference to the chart config object. 69 * 70 * @type {Object} 71 * @protected 72 */ 73 Output.prototype._config = null; 74 75 /** 76 * Reference to the instance of chart.js. 77 * 78 * @type {Object} 79 * @protected 80 */ 81 Output.prototype._chartjs = null; 82 83 /** 84 * Reference to the canvas node. 85 * 86 * @type {Jquery} 87 * @protected 88 */ 89 Output.prototype._canvas = null; 90 91 /** 92 * Builds the config and the chart. 93 * 94 * @protected 95 */ 96 Output.prototype._build = function() { 97 this._config = this._makeConfig(); 98 this._chartjs = new Chartjs(this._canvas[0], this._config); 99 }; 100 101 /** 102 * Get the chart type. 103 * 104 * It also handles the bar charts positioning, deciding if the bars should be displayed horizontally. 105 * Otherwise, get the chart TYPE value. 106 * 107 * @returns {String} the chart type. 108 * @protected 109 */ 110 Output.prototype._getChartType = function() { 111 var type = this._chart.getType(); 112 113 // Bars can be displayed vertically and horizontally, defining horizontalBar type. 114 if (this._chart.getType() === Bar.prototype.TYPE && this._chart.getHorizontal() === true) { 115 type = 'horizontalBar'; 116 } 117 118 return type; 119 }; 120 121 /** 122 * Make the axis config. 123 * 124 * @protected 125 * @param {module:core/chart_axis} axis The axis. 126 * @param {String} xy Accepts 'x' or 'y'. 127 * @param {Number} index The axis index. 128 * @return {Object} The axis config. 129 */ 130 Output.prototype._makeAxisConfig = function(axis, xy, index) { 131 var scaleData = { 132 id: makeAxisId(xy, index) 133 }; 134 135 if (axis.getPosition() !== Axis.prototype.POS_DEFAULT) { 136 scaleData.position = axis.getPosition(); 137 } 138 139 if (axis.getLabel() !== null) { 140 scaleData.scaleLabel = { 141 display: true, 142 labelString: axis.getLabel() 143 }; 144 } 145 146 if (axis.getStepSize() !== null) { 147 scaleData.ticks = scaleData.ticks || {}; 148 scaleData.ticks.stepSize = axis.getStepSize(); 149 } 150 151 if (axis.getMax() !== null) { 152 scaleData.ticks = scaleData.ticks || {}; 153 scaleData.ticks.max = axis.getMax(); 154 } 155 156 if (axis.getMin() !== null) { 157 scaleData.ticks = scaleData.ticks || {}; 158 scaleData.ticks.min = axis.getMin(); 159 } 160 161 return scaleData; 162 }; 163 164 /** 165 * Make the config config. 166 * 167 * @protected 168 * @param {module:core/chart_axis} axis The axis. 169 * @return {Object} The axis config. 170 */ 171 Output.prototype._makeConfig = function() { 172 var config = { 173 type: this._getChartType(), 174 data: { 175 labels: this._chart.getLabels(), 176 datasets: this._makeDatasetsConfig() 177 }, 178 options: { 179 title: { 180 display: this._chart.getTitle() !== null, 181 text: this._chart.getTitle() 182 } 183 } 184 }; 185 186 this._chart.getXAxes().forEach(function(axis, i) { 187 var axisLabels = axis.getLabels(); 188 189 config.options.scales = config.options.scales || {}; 190 config.options.scales.xAxes = config.options.scales.xAxes || []; 191 config.options.scales.xAxes[i] = this._makeAxisConfig(axis, 'x', i); 192 193 if (axisLabels !== null) { 194 config.options.scales.xAxes[i].ticks.callback = function(value, index) { 195 return axisLabels[index] || ''; 196 }; 197 } 198 }.bind(this)); 199 200 this._chart.getYAxes().forEach(function(axis, i) { 201 var axisLabels = axis.getLabels(); 202 203 config.options.scales = config.options.scales || {}; 204 config.options.scales.yAxes = config.options.scales.yAxes || []; 205 config.options.scales.yAxes[i] = this._makeAxisConfig(axis, 'y', i); 206 207 if (axisLabels !== null) { 208 config.options.scales.yAxes[i].ticks.callback = function(value) { 209 return axisLabels[parseInt(value, 10)] || ''; 210 }; 211 } 212 }.bind(this)); 213 214 config.options.tooltips = { 215 callbacks: { 216 label: this._makeTooltip.bind(this) 217 } 218 }; 219 220 return config; 221 }; 222 223 /** 224 * Get the datasets configurations. 225 * 226 * @protected 227 * @return {Object[]} 228 */ 229 Output.prototype._makeDatasetsConfig = function() { 230 var sets = this._chart.getSeries().map(function(series) { 231 var colors = series.hasColoredValues() ? series.getColors() : series.getColor(); 232 var dataset = { 233 label: series.getLabel(), 234 data: series.getValues(), 235 type: series.getType(), 236 fill: false, 237 backgroundColor: colors, 238 // Pie charts look better without borders. 239 borderColor: this._chart.getType() == Pie.prototype.TYPE ? null : colors, 240 lineTension: this._isSmooth(series) ? 0.3 : 0 241 }; 242 243 if (series.getXAxis() !== null) { 244 dataset.xAxisID = makeAxisId('x', series.getXAxis()); 245 } 246 if (series.getYAxis() !== null) { 247 dataset.yAxisID = makeAxisId('y', series.getYAxis()); 248 } 249 250 return dataset; 251 }.bind(this)); 252 return sets; 253 }; 254 255 /** 256 * Get the chart data, add labels and rebuild the tooltip. 257 * 258 * @param {Object[]} tooltipItem The tooltip item data. 259 * @param {Object[]} data The chart data. 260 * @returns {String} 261 * @protected 262 */ 263 Output.prototype._makeTooltip = function(tooltipItem, data) { 264 265 // Get series and chart data to rebuild the tooltip and add labels. 266 var series = this._chart.getSeries()[tooltipItem.datasetIndex]; 267 var serieLabel = series.getLabel(); 268 var serieLabels = series.getLabels(); 269 var chartData = data.datasets[tooltipItem.datasetIndex].data; 270 var tooltipData = chartData[tooltipItem.index]; 271 272 // Build default tooltip. 273 var tooltip = serieLabel + ': ' + tooltipData; 274 275 // Add serie labels to the tooltip if any. 276 if (serieLabels !== null) { 277 tooltip = serieLabels[tooltipItem.index]; 278 } 279 280 return tooltip; 281 }; 282 283 /** 284 * Verify if the chart line is smooth or not. 285 * 286 * @protected 287 * @param {module:core/chart_series} series The series. 288 * @returns {Bool} 289 */ 290 Output.prototype._isSmooth = function(series) { 291 var smooth = false; 292 if (this._chart.getType() === Line.prototype.TYPE) { 293 smooth = series.getSmooth(); 294 if (smooth === null) { 295 smooth = this._chart.getSmooth(); 296 } 297 } else if (series.getType() === Series.prototype.TYPE_LINE) { 298 smooth = series.getSmooth(); 299 } 300 301 return smooth; 302 }; 303 304 /** @override */ 305 Output.prototype.update = function() { 306 $.extend(true, this._config, this._makeConfig()); 307 this._chartjs.update(); 308 }; 309 310 return Output; 311 312 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |