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