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.DataSource.prototype.loadFromArray = function(table, columnHeader, rowHeader) {
 43     var i, j,cell;
 44 
 45     if(typeof columnHeader == 'undefined')
 46         columnHeader = false;
 47     if(typeof rowHeader == 'undefined')
 48         rowHeader = false;
 49 
 50     if(JXG.isArray(columnHeader)) {
 51         this.columnHeader = columnHeader;
 52         columnHeader = false;
 53     }
 54 
 55     if(JXG.isArray(rowHeader)) {
 56         this.rowHeader = rowHeader;
 57         rowHeader = false;
 58     }
 59 
 60     this.data = [];
 61     if(columnHeader)
 62         this.columnHeader = [];
 63     if(rowHeader)
 64         this.rowHeader = [];
 65 
 66     if(typeof table != 'undefined') {
 67         // extract the data
 68         this.data = new Array(table.length);
 69 
 70         for(i=0; i<table.length; i++) {
 71             this.data[i] = new Array(table[i].length);
 72             for(j=0; j<table[i].length; j++) {
 73                 cell = table[i][j];
 74                 if('' + parseFloat(cell) == cell)
 75                     this.data[i][j] = parseFloat(cell);
 76                 else if (cell != '-')
 77                     this.data[i][j] = cell;
 78                 else
 79                     this.data[i][j] = NaN;
 80             }
 81         }
 82             
 83         if(columnHeader) {
 84             this.columnHeader = this.data[0].slice(1);
 85             this.data = this.data.slice(1);
 86         }
 87 
 88         if(rowHeader) {
 89             this.rowHeader = new Array();
 90             for(i=0; i<this.data.length; i++) {
 91                 this.rowHeader.push(this.data[i][0]);
 92                 this.data[i] = this.data[i].slice(1);
 93             }
 94         }
 95     }
 96 
 97     return this;
 98 };
 99 
100 JXG.DataSource.prototype.loadFromTable = function(table, columnHeader, rowHeader) {
101     var row, i, j, col, cell, name;
102 
103     if(typeof columnHeader == 'undefined')
104         columnHeader = false;
105     if(typeof rowHeader == 'undefined')
106         rowHeader = false;
107 
108     if(JXG.isArray(columnHeader)) {
109         this.columnHeader = columnHeader;
110         columnHeader = false;
111     }
112 
113     if(JXG.isArray(rowHeader)) {
114         this.rowHeader = rowHeader;
115         rowHeader = false;
116     }
117 
118     this.data = [];
119     if(columnHeader)
120         this.columnHeader = [];
121     if(rowHeader)
122         this.rowHeader = [];
123 
124     table = document.getElementById(table);

125     if(typeof table != 'undefined') {
126         // extract the data
127         row = table.getElementsByTagName('tr');
128         this.data = new Array(row.length);
129 
130         for(i=0; i<row.length; i++) {
131             col = row[i].getElementsByTagName('td');
132             this.data[i] = new Array(col.length);
133             for(j=0; j<col.length; j++) {
134                 cell = col[j].innerHTML;
135                 if('' + parseFloat(cell) == cell)
136                     this.data[i][j] = parseFloat(cell);
137                 else if (cell != '-')
138                     this.data[i][j] = cell;
139                 else
140                     this.data[i][j] = NaN;
141             }
142         }
143             
144         if(columnHeader) {
145             this.columnHeader = this.data[0].slice(1);
146             this.data = this.data.slice(1);
147         }
148 
149         if(rowHeader) {
150             this.rowHeader = new Array();
151             for(i=0; i<this.data.length; i++) {
152                 this.rowHeader.push(this.data[i][0]);
153                 this.data[i] = this.data[i].slice(1);
154             }
155         }
156     }
157 
158     return this;
159 };
160 
161 JXG.DataSource.prototype.addColumn = function(name, pos, data) {
162     // todo
163 };
164 
165 JXG.DataSource.prototype.addRow = function(name, pos, data) {
166     // todo
167 };
168 
169 JXG.DataSource.prototype.getColumn = function(col) {
170     var result = new Array(this.data.length), i;
171 
172     // get column index if column is given as column header title
173     if(typeof col == 'string') {
174         for(i=0; i<this.columnHeader.length; i++) {
175             if(col == this.columnHeader[i]) {
176                 col = i;
177                 break;
178             }
179         }
180     }
181 
182     // build column array
183     for(i=0; i<this.data.length; i++) {
184         if(this.data[i].length > col)
185             result[i] = this.data[i][col];
186     }
187 
188     return result;
189 };
190 
191 JXG.DataSource.prototype.getRow = function(row) {
192     var result, i;
193 
194     // get column index if column is given as column header title
195     if(typeof row == 'string') {
196         for(i=0; i<this.rowHeader.length; i++) {
197             if(row == this.rowHeader[i]) {
198                 row = i;
199                 break;
200             }
201         }
202     }
203 
204     // allocate memory for result array
205     result = new Array(this.data[row].length);
206 
207     // build column array. result = this.data[row] is a flat copy and will
208     // destroy our local data copy, that's why we're copying it element wise.
209     for(i=0; i<this.data[row].length; i++) {
210         result[i] = this.data[row][i];
211     }
212 
213     return result;
214 };
215