2 * Chart type enumerations
16 * Abstract chart factory which defines the contract for chart factories
18 var ChartFactory = function () {
20 ChartFactory.prototype = {
21 createChart : function (type, options) {
22 throw new Error("createChart must be implemented by a subclass");
27 * Abstract chart which defines the contract for charts
30 * id of the div element the chart is drawn in
32 var Chart = function (elementId) {
33 this.elementId = elementId;
36 draw : function (data, options) {
37 throw new Error("draw must be implemented by a subclass");
39 redraw : function (options) {
40 throw new Error("redraw must be implemented by a subclass");
42 destroy : function () {
43 throw new Error("destroy must be implemented by a subclass");
48 * Abstract representation of charts that operates on DataTable where,<br />
50 * <li>First column provides index to the data.</li>
51 * <li>Each subsequent columns are of type
52 * <code>ColumnType.NUMBER<code> and represents a data series.</li>
54 * Line chart, area chart, bar chart, column chart are typical examples.
57 * id of the div element the chart is drawn in
59 var BaseChart = function (elementId) {
60 Chart.call(this, elementId);
62 BaseChart.prototype = new Chart();
63 BaseChart.prototype.constructor = BaseChart;
64 BaseChart.prototype.validateColumns = function (dataTable) {
65 var columns = dataTable.getColumns();
66 if (columns.length < 2) {
67 throw new Error("Minimum of two columns are required for this chart");
69 for (var i = 1; i < columns.length; i++) {
70 if (columns[i].type != ColumnType.NUMBER) {
71 throw new Error("Column " + (i + 1) + " should be of type 'Number'");
81 * id of the div element the chart is drawn in
83 var PieChart = function (elementId) {
84 BaseChart.call(this, elementId);
86 PieChart.prototype = new BaseChart();
87 PieChart.prototype.constructor = PieChart;
88 PieChart.prototype.validateColumns = function (dataTable) {
89 var columns = dataTable.getColumns();
90 if (columns.length > 2) {
91 throw new Error("Pie charts can draw only one series");
93 return BaseChart.prototype.validateColumns.call(this, dataTable);
97 * Abstract timeline chart
100 * id of the div element the chart is drawn in
102 var TimelineChart = function (elementId) {
103 BaseChart.call(this, elementId);
105 TimelineChart.prototype = new BaseChart();
106 TimelineChart.prototype.constructor = TimelineChart;
107 TimelineChart.prototype.validateColumns = function (dataTable) {
108 var result = BaseChart.prototype.validateColumns.call(this, dataTable);
110 var columns = dataTable.getColumns();
111 if (columns[0].type != ColumnType.DATE) {
112 throw new Error("First column of timeline chart need to be a date column");
119 * Abstract scatter chart
122 * id of the div element the chart is drawn in
124 var ScatterChart = function(elementId) {
125 BaseChart.call(this, elementId);
127 ScatterChart.prototype = new BaseChart();
128 ScatterChart.prototype.constructor = ScatterChart;
129 ScatterChart.prototype.validateColumns = function (dataTable) {
130 var result = BaseChart.prototype.validateColumns.call(this, dataTable);
132 var columns = dataTable.getColumns();
133 if (columns[0].type != ColumnType.NUMBER) {
134 throw new Error("First column of scatter chart need to be a numeric column");
141 * The data table contains column information and data for the chart.
143 var DataTable = function () {
147 this.addColumn = function (type, name) {
154 this.getColumns = function () {
158 this.setData = function (rows) {
163 this.getData = function () {
167 var fillMissingValues = function () {
168 if (columns.length === 0) {
169 throw new Error("Set columns first");
172 for (var i = 0; i < data.length; i++) {
174 if (row.length > columns.length) {
175 row.splice(columns.length - 1, row.length - columns.length);
176 } else if (row.length < columns.length) {
177 for (var j = row.length; j < columns.length; j++) {
186 * Column type enumeration
195 /*******************************************************************************
196 * JQPlot specific code
197 ******************************************************************************/
200 * Chart factory that returns JQPlotCharts
202 var JQPlotChartFactory = function () {
204 JQPlotChartFactory.prototype = new ChartFactory();
205 JQPlotChartFactory.prototype.createChart = function (type, elementId) {
209 chart = new JQPlotLineChart(elementId);
211 case ChartType.SPLINE:
212 chart = new JQPlotSplineChart(elementId);
214 case ChartType.TIMELINE:
215 chart = new JQPlotTimelineChart(elementId);
218 chart = new JQPlotAreaChart(elementId);
221 chart = new JQPlotBarChart(elementId);
223 case ChartType.COLUMN:
224 chart = new JQPlotColumnChart(elementId);
227 chart = new JQPlotPieChart(elementId);
229 case ChartType.SCATTER:
230 chart = new JQPlotScatterChart(elementId);
238 * Abstract JQplot chart
241 * id of the div element the chart is drawn in
243 var JQPlotChart = function (elementId) {
244 Chart.call(this, elementId);
248 JQPlotChart.prototype = new Chart();
249 JQPlotChart.prototype.constructor = JQPlotChart;
250 JQPlotChart.prototype.draw = function (data, options) {
251 if (this.validator.validateColumns(data)) {
252 this.plot = $.jqplot(this.elementId, this.prepareData(data), this
253 .populateOptions(data, options));
256 JQPlotChart.prototype.destroy = function () {
257 if (this.plot !== null) {
261 JQPlotChart.prototype.redraw = function (options) {
262 if (this.plot !== null) {
263 this.plot.replot(options);
266 JQPlotChart.prototype.populateOptions = function (dataTable, options) {
267 throw new Error("populateOptions must be implemented by a subclass");
269 JQPlotChart.prototype.prepareData = function (dataTable) {
270 throw new Error("prepareData must be implemented by a subclass");
277 * id of the div element the chart is drawn in
279 var JQPlotLineChart = function (elementId) {
280 JQPlotChart.call(this, elementId);
281 this.validator = BaseChart.prototype;
283 JQPlotLineChart.prototype = new JQPlotChart();
284 JQPlotLineChart.prototype.constructor = JQPlotLineChart;
286 JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
287 var columns = dataTable.getColumns();
291 label : columns[0].name,
292 renderer : $.jqplot.CategoryAxisRenderer,
296 label : (columns.length == 2 ? columns[1].name : 'Values'),
297 labelRenderer : $.jqplot.CanvasAxisLabelRenderer
307 $.extend(true, optional, options);
309 if (optional.series.length === 0) {
310 for (var i = 1; i < columns.length; i++) {
311 optional.series.push({
312 label : columns[i].name.toString()
316 if (optional.axes.xaxis.ticks.length === 0) {
317 var data = dataTable.getData();
318 for (var i = 0; i < data.length; i++) {
319 optional.axes.xaxis.ticks.push(data[i][0].toString());
325 JQPlotLineChart.prototype.prepareData = function (dataTable) {
326 var data = dataTable.getData(), row;
327 var retData = [], retRow;
328 for (var i = 0; i < data.length; i++) {
330 for (var j = 1; j < row.length; j++) {
331 retRow = retData[j - 1];
332 if (retRow === undefined) {
334 retData[j - 1] = retRow;
343 * JQPlot spline chart
346 * id of the div element the chart is drawn in
348 var JQPlotSplineChart = function (elementId) {
349 JQPlotLineChart.call(this, elementId);
351 JQPlotSplineChart.prototype = new JQPlotLineChart();
352 JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
354 JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
356 var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
365 $.extend(true, optional, opt, compulsory);
370 * JQPlot scatter chart
373 * id of the div element the chart is drawn in
375 var JQPlotScatterChart = function (elementId) {
376 JQPlotChart.call(this, elementId);
377 this.validator = ScatterChart.prototype;
379 JQPlotScatterChart.prototype = new JQPlotChart();
380 JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
382 JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
383 var columns = dataTable.getColumns();
387 label : columns[0].name
390 label : (columns.length == 2 ? columns[1].name : 'Values'),
391 labelRenderer : $.jqplot.CanvasAxisLabelRenderer
397 formatString:'%d, %d'
401 for (var i = 1; i < columns.length; i++) {
402 optional.series.push({
403 label : columns[i].name.toString()
417 $.extend(true, optional, options, compulsory);
421 JQPlotScatterChart.prototype.prepareData = function (dataTable) {
422 var data = dataTable.getData(), row;
423 var retData = [], retRow;
424 for (var i = 0; i < data.length; i++) {
427 for (var j = 1; j < row.length; j++) {
428 retRow = retData[j - 1];
429 if (retRow === undefined) {
431 retData[j - 1] = retRow;
433 retRow.push([row[0], row[j]]);
441 * JQPlot timeline chart
444 * id of the div element the chart is drawn in
446 var JQPlotTimelineChart = function (elementId) {
447 JQPlotLineChart.call(this, elementId);
448 this.validator = TimelineChart.prototype;
450 JQPlotTimelineChart.prototype = new JQPlotLineChart();
451 JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
453 JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
458 formatString: '%b %#d, %y'
463 var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
467 renderer : $.jqplot.DateAxisRenderer
471 $.extend(true, optional, opt, compulsory);
475 JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
476 var data = dataTable.getData(), row, d;
477 var retData = [], retRow;
478 for (var i = 0; i < data.length; i++) {
481 for (var j = 1; j < row.length; j++) {
482 retRow = retData[j - 1];
483 if (retRow === undefined) {
485 retData[j - 1] = retRow;
488 retRow.push([d.getTime(), row[j]]);
499 * id of the div element the chart is drawn in
501 var JQPlotAreaChart = function (elementId) {
502 JQPlotLineChart.call(this, elementId);
504 JQPlotAreaChart.prototype = new JQPlotLineChart();
505 JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
507 JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
513 var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
520 $.extend(true, optional, opt, compulsory);
525 * JQPlot column chart
528 * id of the div element the chart is drawn in
530 var JQPlotColumnChart = function (elementId) {
531 JQPlotLineChart.call(this, elementId);
533 JQPlotColumnChart.prototype = new JQPlotLineChart();
534 JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
536 JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
542 var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
546 renderer : $.jqplot.BarRenderer
549 $.extend(true, optional, opt, compulsory);
557 * id of the div element the chart is drawn in
559 var JQPlotBarChart = function (elementId) {
560 JQPlotLineChart.call(this, elementId);
562 JQPlotBarChart.prototype = new JQPlotLineChart();
563 JQPlotBarChart.prototype.constructor = JQPlotBarChart;
565 JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
566 var columns = dataTable.getColumns();
570 label : columns[0].name,
571 labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
572 renderer : $.jqplot.CategoryAxisRenderer,
576 label : (columns.length == 2 ? columns[1].name : 'Values'),
577 labelRenderer : $.jqplot.CanvasAxisLabelRenderer
592 renderer : $.jqplot.BarRenderer,
594 barDirection : 'horizontal'
598 $.extend(true, optional, options, compulsory);
600 if (optional.axes.yaxis.ticks.length === 0) {
601 var data = dataTable.getData();
602 for (var i = 0; i < data.length; i++) {
603 optional.axes.yaxis.ticks.push(data[i][0].toString());
606 if (optional.series.length === 0) {
607 for (var i = 1; i < columns.length; i++) {
608 optional.series.push({
609 label : columns[i].name.toString()
620 * id of the div element the chart is drawn in
622 var JQPlotPieChart = function (elementId) {
623 JQPlotChart.call(this, elementId);
624 this.validator = PieChart.prototype;
626 JQPlotPieChart.prototype = new JQPlotChart();
627 JQPlotPieChart.prototype.constructor = JQPlotPieChart;
629 JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
634 formatString:'%s, %d',
635 useAxesFormatters: false
640 renderer : $.jqplot.PieRenderer
643 $.extend(true, optional, options, compulsory);
647 JQPlotPieChart.prototype.prepareData = function (dataTable) {
648 var data = dataTable.getData(), row;
650 for (var i = 0; i < data.length; i++) {
652 retData.push([ row[0], row[1] ]);