1 /* 2 Copyright 2008-2013 3 Matthias Ehmann, 4 Michael Gerhaeuser, 5 Carsten Miller, 6 Bianca Valentin, 7 Alfred Wassermann, 8 Peter Wilfahrt 9 10 This file is part of JSXGraph. 11 12 JSXGraph is free software dual licensed under the GNU LGPL or MIT License. 13 14 You can redistribute it and/or modify it under the terms of the 15 16 * GNU Lesser General Public License as published by 17 the Free Software Foundation, either version 3 of the License, or 18 (at your option) any later version 19 OR 20 * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT 21 22 JSXGraph is distributed in the hope that it will be useful, 23 but WITHOUT ANY WARRANTY; without even the implied warranty of 24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 GNU Lesser General Public License for more details. 26 27 You should have received a copy of the GNU Lesser General Public License and 28 the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/> 29 and <http://opensource.org/licenses/MIT/>. 30 */ 31 32 33 /*global JXG: true, define: true, document: true*/ 34 /*jslint nomen: true, plusplus: true*/ 35 36 /* depends: 37 jxg 38 utils/type 39 */ 40 41 /** 42 * @fileoverview The JXG.DataSource is a helper class for data organization. Currently supported data sources are 43 * javascript arrays and HTML tables. 44 */ 45 46 define(['jxg', 'utils/type'], function (JXG, Type) { 47 48 "use strict"; 49 50 JXG.DataSource = function () { 51 this.data = []; 52 this.columnHeaders = []; 53 this.rowHeaders = []; 54 55 return this; 56 }; 57 58 JXG.extend(JXG.DataSource.prototype, /** @lends JXG.DataSource.prototype */ { 59 loadFromArray: function (table, columnHeader, rowHeader) { 60 var i, j, cell; 61 62 if (Type.isArray(columnHeader)) { 63 this.columnHeaders = columnHeader; 64 columnHeader = false; 65 } 66 67 if (Type.isArray(rowHeader)) { 68 this.rowHeaders = rowHeader; 69 rowHeader = false; 70 } 71 72 this.data = []; 73 74 if (columnHeader) { 75 this.columnHeaders = []; 76 } 77 78 if (rowHeader) { 79 this.rowHeaders = []; 80 } 81 82 if (Type.exists(table)) { 83 // extract the data 84 this.data = []; 85 86 for (i = 0; i < table.length; i++) { 87 this.data[i] = []; 88 89 for (j = 0; j < table[i].length; j++) { 90 cell = table[i][j]; 91 if (parseFloat(cell).toString() === cell) { 92 this.data[i][j] = parseFloat(cell); 93 } else if (cell !== '-') { 94 this.data[i][j] = cell; 95 } else { 96 this.data[i][j] = NaN; 97 } 98 } 99 } 100 101 if (columnHeader) { 102 this.columnHeaders = this.data[0].slice(1); 103 this.data = this.data.slice(1); 104 } 105 106 if (rowHeader) { 107 this.rowHeaders = []; 108 for (i = 0; i < this.data.length; i++) { 109 this.rowHeaders.push(this.data[i][0]); 110 this.data[i] = this.data[i].slice(1); 111 } 112 } 113 } 114 115 return this; 116 }, 117 118 loadFromTable: function (table, columnHeader, rowHeader) { 119 var row, i, j, col, cell, name; 120 121 if (Type.isArray(columnHeader)) { 122 this.columnHeaders = columnHeader; 123 columnHeader = false; 124 } 125 126 if (Type.isArray(rowHeader)) { 127 this.rowHeaders = rowHeader; 128 rowHeader = false; 129 } 130 131 this.data = []; 132 133 if (columnHeader) { 134 this.columnHeaders = []; 135 } 136 137 if (rowHeader) { 138 this.rowHeaders = []; 139 } 140 141 // to adjust: examples in examples folder & wiki 142 table = document.getElementById(table); 143 144 if (Type.exists(table)) { 145 // extract the data 146 row = table.getElementsByTagName('tr'); 147 this.data = []; 148 149 for (i = 0; i < row.length; i++) { 150 col = row[i].getElementsByTagName('td'); 151 this.data[i] = []; 152 153 for (j = 0; j < col.length; j++) { 154 cell = col[j].innerHTML; 155 156 if (parseFloat(cell).toString() === cell) { 157 this.data[i][j] = parseFloat(cell); 158 } else if (cell !== '-') { 159 this.data[i][j] = cell; 160 } else { 161 this.data[i][j] = NaN; 162 } 163 } 164 } 165 166 if (columnHeader) { 167 this.columnHeaders = this.data[0].slice(1); 168 this.data = this.data.slice(1); 169 } 170 171 if (rowHeader) { 172 this.rowHeaders = []; 173 for (i = 0; i < this.data.length; i++) { 174 this.rowHeaders.push(this.data[i][0]); 175 this.data[i] = this.data[i].slice(1); 176 } 177 } 178 } 179 180 return this; 181 }, 182 183 addColumn: function (name, pos, data) { 184 throw new Error('not implemented'); 185 }, 186 187 addRow: function (name, pos, data) { 188 throw new Error('not implemented'); 189 }, 190 191 getColumn: function (col) { 192 var i, 193 result = []; 194 195 // get column index if column is given as column header title 196 if (typeof col === 'string') { 197 for (i = 0; i < this.columnHeaders.length; i++) { 198 if (col === this.columnHeaders[i]) { 199 col = i; 200 break; 201 } 202 } 203 } 204 205 // build column array 206 for (i = 0; i < this.data.length; i++) { 207 if (this.data[i].length > col) { 208 result[i] = parseFloat(this.data[i][col]); 209 } 210 } 211 212 return result; 213 }, 214 215 getRow: function (row) { 216 var result, i; 217 218 // get column index if column is given as column header title 219 if (typeof row === 'string') { 220 for (i = 0; i < this.rowHeaders.length; i++) { 221 if (row === this.rowHeaders[i]) { 222 row = i; 223 break; 224 } 225 } 226 } 227 228 // allocate memory for result array 229 result = []; 230 231 // build column array. result = this.data[row] is a flat copy and will 232 // destroy our local data copy, that's why we're copying it element wise. 233 for (i = 0; i < this.data[row].length; i++) { 234 result[i] = this.data[row][i]; 235 } 236 237 return result; 238 } 239 }); 240 241 return JXG.DataSource; 242 });