      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 });