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 * Options object. 27 * @class These are the default options of the board and 28 * of all geometry elements. 29 * @constructor 30 */ 31 JXG.Options = { 32 /* Options that are used directly within the board class */ 33 showCopyright : true, 34 showNavigation : true, 35 takeSizeFromFile : false, // If true, the construction - when read from a file or string - the size of the div can be changed. 36 renderer: 'svg', 37 takeFirst : false, // if true the first element with hasPoint==true is taken. 38 39 /* grid options */ 40 grid : { 41 /* grid styles */ 42 hasGrid : false, 43 gridX : 1, 44 gridY : 1, 45 gridColor : '#C0C0C0', 46 gridOpacity : '0.5', 47 gridDash : true, 48 /* snap to grid options */ 49 snapToGrid : false, 50 snapSizeX : 2, 51 snapSizeY : 2 52 }, 53 /* zoom options */ 54 zoom : { 55 factor : 1.25 56 }, 57 58 /* geometry element options */ 59 elements : { 60 /* color options */ 61 strokeColor: '#0000ff', 62 highlightStrokeColor: '#C3D9FF', 63 fillColor: 'none', 64 highlightFillColor: 'none', 65 66 strokeOpacity: 1, 67 highlightStrokeOpacity: 1, 68 fillOpacity: 1, 69 highlightFillOpacity: 1, 70 strokeWidth: '2px', 71 withLabel: false, 72 73 /*draft options */ 74 draft : { 75 draft : false, 76 color : '#565656', 77 opacity : 0.8, 78 strokeWidth : '1px' 79 } 80 }, 81 82 /* special point options */ 83 point : { 84 withLabel: true, 85 style : 5, // deprecated 86 face : 'o', 87 size : 3, 88 fillColor : '#ff0000', 89 highlightFillColor : '#EEEEEE', 90 strokeWidth: '2px', 91 strokeColor : '#ff0000', //'#0000ff', 92 highlightStrokeColor : '#C3D9FF', 93 zoom: false, // Change the point size on zoom 94 showInfobox: true 95 }, 96 97 /* special line options */ 98 line : { 99 firstArrow : false, 100 lastArrow : false, 101 straightFirst : true, 102 straightLast : true, 103 fillColor : '#000000', 104 highlightFillColor : 'none', 105 strokeColor : '#0000ff', 106 highlightStrokeColor : '#888888', 107 /* line ticks options */ 108 ticks : { 109 drawLabels : true, 110 drawZero : false, 111 insertTicks : false, 112 minTicksDistance : 50, 113 maxTicksDistance : 300, 114 minorHeight : 4, 115 majorHeight : 10, 116 minorTicks : 4, 117 defaultDistance : 1 118 }, 119 /* absolute label offset from anchor */ 120 labelOffsets: [10,10] 121 }, 122 123 /* special axis options */ 124 axis : { 125 strokeColor : '#666666', 126 highlightStrokeColor : '#888888' 127 }, 128 129 /*special circle options */ 130 circle : { 131 fillColor : 'none', 132 highlightFillColor : 'none', 133 strokeColor : '#0000ff', 134 highlightStrokeColor : '#C3D9FF' 135 }, 136 137 /* special conic options */ 138 conic : { 139 fillColor : 'none', 140 highlightFillColor : 'none', 141 strokeColor : '#0000ff', 142 highlightStrokeColor : '#C3D9FF' 143 }, 144 145 /* special angle options */ 146 angle : { 147 withLabel:true, 148 radius : 1.0, 149 fillColor : '#FF7F00', 150 highlightFillColor : '#FF7F00', 151 strokeColor : '#FF7F00', 152 textColor : '#0000FF', 153 fillOpacity : 0.3, 154 highlightFillOpacity : 0.3 155 }, 156 157 /* special arc options */ 158 arc : { 159 firstArrow : false, 160 lastArrow : false, 161 fillColor : 'none', 162 highlightFillColor : 'none', 163 strokeColor : '#0000ff', 164 highlightStrokeColor : '#C3D9FF' 165 }, 166 167 /* special polygon options */ 168 polygon : { 169 fillColor : '#00FF00', 170 highlightFillColor : '#00FF00', 171 fillOpacity : 0.3, 172 highlightFillOpacity : 0.3 173 }, 174 175 /* special sector options */ 176 sector : { 177 fillColor: '#00FF00', 178 highlightFillColor: '#00FF00', 179 fillOpacity: 0.3, 180 highlightFillOpacity: 0.3 181 }, 182 183 /* special text options */ 184 text : { 185 fontSize : 12, 186 strokeColor : '#000000', 187 useASCIIMathML : false, 188 useMathJax : false, 189 defaultDisplay : 'html' //'html' or 'internal' 190 }, 191 192 /* special curve options */ 193 curve : { 194 strokeWidth : '1px', 195 strokeColor : '#0000ff', 196 RDPsmoothing : false, // Apply the Ramen-Douglas-Peuker algorithm 197 numberPointsHigh : 1600, // Number of points on curves after mouseUp 198 numberPointsLow : 400, // Number of points on curves after mousemove 199 doAdvancedPlot : true // Use the algorithm by Gillam and Hohenwarter 200 // It is much slower, but the result is better 201 }, 202 203 /* precision options */ 204 precision : { 205 touch : 30, 206 mouse : 4, 207 epsilon : 0.0001, 208 hasPoint : 4 209 }, 210 211 // Default ordering of the layers 212 layer : { 213 numlayers:20, // only important in SVG 214 text : 9, 215 point : 9, 216 arc : 8, 217 line : 7, 218 circle: 6, 219 curve : 5, 220 polygon: 4, 221 sector: 3, 222 angle : 3, 223 grid : 1, 224 image : 0 225 }, 226 227 locus : { 228 translateToOrigin: false, 229 translateTo10: false, 230 stretch: false, 231 toOrigin: null, 232 to10: null 233 } 234 }; 235 236 /** 237 * Apply the options stored in this object to all objects on the given board. 238 * @param {JXG.Board} board The board to which objects the options will be applied. 239 */ 240 JXG.useStandardOptions = function(board) { 241 var o = JXG.Options, 242 boardHadGrid = board.hasGrid, 243 el, t, p; 244 245 board.options.grid.hasGrid = o.grid.hasGrid; 246 board.options.grid.gridX = o.grid.gridX; 247 board.options.grid.gridY = o.grid.gridY; 248 board.options.grid.gridColor = o.grid.gridColor; 249 board.options.grid.gridOpacity = o.grid.gridOpacity; 250 board.options.grid.gridDash = o.grid.gridDash; 251 board.options.grid.snapToGrid = o.grid.snapToGrid; 252 board.options.grid.snapSizeX = o.grid.SnapSizeX; 253 board.options.grid.snapSizeY = o.grid.SnapSizeY; 254 board.takeSizeFromFile = o.takeSizeFromFile; 255 256 for(el in board.objects) { 257 p = board.objects[el]; 258 if(p.elementClass == JXG.OBJECT_CLASS_POINT) { 259 p.visProp['fillColor'] = o.point.fillColor; 260 p.visProp['highlightFillColor'] = o.point.highlightFillColor; 261 p.visProp['strokeColor'] = o.point.strokeColor; 262 p.visProp['highlightStrokeColor'] = o.point.highlightStrokeColor; 263 } 264 else if(p.elementClass == JXG.OBJECT_CLASS_LINE) { 265 p.visProp['fillColor'] = o.line.fillColor; 266 p.visProp['highlightFillColor'] = o.line.highlightFillColor; 267 p.visProp['strokeColor'] = o.line.strokeColor; 268 p.visProp['highlightStrokeColor'] = o.line.highlightStrokeColor; 269 for(t in p.ticks) { 270 t.majorTicks = o.line.ticks.majorTicks; 271 t.minTicksDistance = o.line.ticks.minTicksDistance; 272 t.minorHeight = o.line.ticks.minorHeight; 273 t.majorHeight = o.line.ticks.majorHeight; 274 } 275 } 276 else if(p.elementClass == JXG.OBJECT_CLASS_CIRCLE) { 277 p.visProp['fillColor'] = o.circle.fillColor; 278 p.visProp['highlightFillColor'] = o.circle.highlightFillColor; 279 p.visProp['strokeColor'] = o.circle.strokeColor; 280 p.visProp['highlightStrokeColor'] = o.circle.highlightStrokeColor; 281 } 282 else if(p.type == JXG.OBJECT_TYPE_ANGLE) { 283 p.visProp['fillColor'] = o.angle.fillColor; 284 p.visProp['highlightFillColor'] = o.angle.highlightFillColor; 285 p.visProp['strokeColor'] = o.angle.strokeColor; 286 } 287 else if(p.type == JXG.OBJECT_TYPE_ARC) { 288 p.visProp['fillColor'] = o.arc.fillColor; 289 p.visProp['highlightFillColor'] = o.arc.highlightFillColor; 290 p.visProp['strokeColor'] = o.arc.strokeColor; 291 p.visProp['highlightStrokeColor'] = o.arc.highlightStrokeColor; 292 } 293 else if(p.type == JXG.OBJECT_TYPE_POLYGON) { 294 p.visProp['fillColor'] = o.polygon.fillColor; 295 p.visProp['highlightFillColor'] = o.polygon.highlightFillColor; 296 p.visProp['fillOpacity'] = o.polygon.fillOpacity; 297 p.visProp['highlightFillOpacity'] = o.polygon.highlightFillOpacity; 298 } 299 else if(p.type == JXG.OBJECT_TYPE_CONIC) { 300 p.visProp['fillColor'] = o.conic.fillColor; 301 p.visProp['highlightFillColor'] = o.conic.highlightFillColor; 302 p.visProp['strokeColor'] = o.conic.strokeColor; 303 p.visProp['highlightStrokeColor'] = o.conic.highlightStrokeColor; 304 } 305 else if(p.type == JXG.OBJECT_TYPE_CURVE) { 306 p.visProp['strokeColor'] = o.curve.strokeColor; 307 } 308 } 309 for(el in board.objects) { 310 p = board.objects[el]; 311 if(p.type == JXG.OBJECT_TYPE_SECTOR) { 312 p.arc.visProp['fillColor'] = o.sector.fillColor; 313 p.arc.visProp['highlightFillColor'] = o.sector.highlightFillColor; 314 p.arc.visProp['fillOpacity'] = o.sector.fillOpacity; 315 p.arc.visProp['highlightFillOpacity'] = o.sector.highlightFillOpacity; 316 } 317 } 318 319 board.fullUpdate(); 320 if(boardHadGrid && board.hasGrid) { 321 board.renderer.removeGrid(board); 322 board.renderer.drawGrid(board); 323 } else if(boardHadGrid && !board.hasGrid) { 324 board.renderer.removeGrid(board); 325 } else if(!boardHadGrid && board.hasGrid) { 326 board.renderer.drawGrid(board); 327 } 328 }; 329 330 /** 331 * Converts all color values to greyscale and calls useStandardOption to put them onto the board. 332 * @param {JXG.Board} board The board to which objects the options will be applied. 333 * @see #useStandardOptions 334 */ 335 JXG.useBlackWhiteOptions = function(board) { 336 var o = JXG.Options; 337 o.point.fillColor = JXG.rgb2bw(o.point.fillColor); 338 o.point.highlightFillColor = JXG.rgb2bw(o.point.highlightFillColor); 339 o.point.strokeColor = JXG.rgb2bw(o.point.strokeColor); 340 o.point.highlightStrokeColor = JXG.rgb2bw(o.point.highlightStrokeColor); 341 342 o.line.fillColor = JXG.rgb2bw(o.line.fillColor); 343 o.line.highlightFillColor = JXG.rgb2bw(o.line.highlightFillColor); 344 o.line.strokeColor = JXG.rgb2bw(o.line.strokeColor); 345 o.line.highlightStrokeColor = JXG.rgb2bw(o.line.highlightStrokeColor); 346 347 o.circle.fillColor = JXG.rgb2bw(o.circle.fillColor); 348 o.circle.highlightFillColor = JXG.rgb2bw(o.circle.highlightFillColor); 349 o.circle.strokeColor = JXG.rgb2bw(o.circle.strokeColor); 350 o.circle.highlightStrokeColor = JXG.rgb2bw(o.circle.highlightStrokeColor); 351 352 o.arc.fillColor = JXG.rgb2bw(o.arc.fillColor); 353 o.arc.highlightFillColor = JXG.rgb2bw(o.arc.highlightFillColor); 354 o.arc.strokeColor = JXG.rgb2bw(o.arc.strokeColor); 355 o.arc.highlightStrokeColor = JXG.rgb2bw(o.arc.highlightStrokeColor); 356 357 o.polygon.fillColor = JXG.rgb2bw(o.polygon.fillColor); 358 o.polygon.highlightFillColor = JXG.rgb2bw(o.polygon.highlightFillColor); 359 360 o.sector.fillColor = JXG.rgb2bw(o.sector.fillColor); 361 o.sector.highlightFillColor = JXG.rgb2bw(o.sector.highlightFillColor); 362 363 o.curve.strokeColor = JXG.rgb2bw(o.curve.strokeColor); 364 o.grid.gridColor = JXG.rgb2bw(o.grid.gridColor); 365 366 JXG.useStandardOptions(board); 367 }; 368 369 /** 370 * Decolorizes the given color. 371 * @param {String} color HTML string containing the HTML color code. 372 * @type String 373 * @return Returns a HTML color string 374 */ 375 JXG.rgb2bw = function(color) { 376 if(color == 'none') { 377 return color; 378 } 379 var x, HexChars="0123456789ABCDEF", tmp, arr; 380 arr = JXG.rgbParser(color); 381 x = 0.3*arr[0] + 0.59*arr[1] + 0.11*arr[2]; 382 tmp = HexChars.charAt((x>>4)&0xf)+HexChars.charAt(x&0xf); 383 color = "#" + tmp + "" + tmp + "" + tmp; 384 return color; 385 }; 386 387 /** 388 * Converts the colors of the elements to how a color blind person would approximately see it. Possible 389 * options are <i>protanopia</i>, <i>deuteranopia</i>, and <i>tritanopia</i>. 390 * @param {JXG.Board} board The board to which objects the options will be applied. 391 * @param {string} deficiency The type of deficiency which will be simulated. 392 * @see #useStandardOptions 393 */ 394 JXG.simulateColorBlindness = function(board, deficiency) { 395 o = JXG.Options; 396 o.point.fillColor = JXG.rgb2cb(o.point.fillColor, deficiency); 397 o.point.highlightFillColor = JXG.rgb2cb(o.point.highlightFillColor, deficiency); 398 o.point.strokeColor = JXG.rgb2cb(o.point.strokeColor, deficiency); 399 o.point.highlightStrokeColor = JXG.rgb2cb(o.point.highlightStrokeColor, deficiency); 400 401 o.line.fillColor = JXG.rgb2cb(o.line.fillColor, deficiency); 402 o.line.highlightFillColor = JXG.rgb2cb(o.line.highlightFillColor, deficiency); 403 o.line.strokeColor = JXG.rgb2cb(o.line.strokeColor, deficiency); 404 o.line.highlightStrokeColor = JXG.rgb2cb(o.line.highlightStrokeColor, deficiency); 405 406 o.circle.fillColor = JXG.rgb2cb(o.circle.fillColor, deficiency); 407 o.circle.highlightFillColor = JXG.rgb2cb(o.circle.highlightFillColor, deficiency); 408 o.circle.strokeColor = JXG.rgb2cb(o.circle.strokeColor, deficiency); 409 o.circle.highlightStrokeColor = JXG.rgb2cb(o.circle.highlightStrokeColor, deficiency); 410 411 o.arc.fillColor = JXG.rgb2cb(o.arc.fillColor, deficiency); 412 o.arc.highlightFillColor = JXG.rgb2cb(o.arc.highlightFillColor, deficiency); 413 o.arc.strokeColor = JXG.rgb2cb(o.arc.strokeColor, deficiency); 414 o.arc.highlightStrokeColor = JXG.rgb2cb(o.arc.highlightStrokeColor, deficiency); 415 416 o.polygon.fillColor = JXG.rgb2cb(o.polygon.fillColor, deficiency); 417 o.polygon.highlightFillColor = JXG.rgb2cb(o.polygon.highlightFillColor, deficiency); 418 419 o.sector.fillColor = JXG.rgb2cb(o.sector.fillColor, deficiency); 420 o.sector.highlightFillColor = JXG.rgb2cb(o.sector.highlightFillColor, deficiency); 421 422 o.curve.strokeColor = JXG.rgb2cb(o.curve.strokeColor, deficiency); 423 o.grid.gridColor = JXG.rgb2cb(o.grid.gridColor, deficiency); 424 425 JXG.useStandardOptions(board); 426 }; 427 428 /** 429 * Decolorizes the given color. 430 * @param {String} color HTML string containing the HTML color code. 431 * @param {String} deficiency The type of color blindness. Possible 432 * options are <i>protanopia</i>, <i>deuteranopia</i>, and <i>tritanopia</i>. 433 * @type String 434 * @return Returns a HTML color string 435 */ 436 JXG.rgb2cb = function(color, deficiency) { 437 if(color == 'none') { 438 return color; 439 } 440 441 var rgb, l, m, s, lms, tmp, 442 a1, b1, c1, a2, b2, c2, 443 inflection; 444 // anchor = new Array(12), anchor_e = new Array(3); 445 /* 446 has been required to calculate the constants for a1, ..., c2, and inflection. 447 */ 448 /* old stuff. just here for debugging purposes 449 anchor[0] = 0.08008; anchor[1] = 0.1579; anchor[2] = 0.5897; 450 anchor[3] = 0.1284; anchor[4] = 0.2237; anchor[5] = 0.3636; 451 anchor[6] = 0.9856; anchor[7] = 0.7325; anchor[8] = 0.001079; 452 anchor[9] = 0.0914; anchor[10] = 0.007009; anchor[11] = 0.0; 453 454 anchor_e[0] = 0.14597772; 455 anchor_e[1] = 0.12188395; 456 anchor_e[2] = 0.08413913; 457 458 459 document.getElementById('debug').innerHTML += 'color: ' + color; 460 461 // document.getElementById('debug').innerHTML += 'deuteranopia<br/><br/>'; 462 // find a,b,c for lam=575nm and lam=475 463 a1 = anchor_e[1] * anchor[8] - anchor_e[2] * anchor[7]; 464 b1 = anchor_e[2] * anchor[6] - anchor_e[0] * anchor[8]; 465 c1 = anchor_e[0] * anchor[7] - anchor_e[1] * anchor[6]; 466 a2 = anchor_e[1] * anchor[2] - anchor_e[2] * anchor[1]; 467 b2 = anchor_e[2] * anchor[0] - anchor_e[0] * anchor[2]; 468 c2 = anchor_e[0] * anchor[1] - anchor_e[1] * anchor[0]; 469 inflection = (anchor_e[2] / anchor_e[0]); 470 471 // document.getElementById('debug').innerHTML += 'a1 = ' + a1 + '<br/>' + 'b1 = ' + b1 + '<br/>' + 'c1 = ' + c1 + '<br/>' + 'a2 = ' + a2 + '<br/>' + 'b2 = ' + b2 + '<br/>' + 'c2 = ' + c2 + '<br/>' + 'inflection = ' + inflection + '<br/><br/>protanopia<br/><br/>'; 472 // find a,b,c for lam=575nm and lam=475 473 a1 = anchor_e[1] * anchor[8] - anchor_e[2] * anchor[7]; 474 b1 = anchor_e[2] * anchor[6] - anchor_e[0] * anchor[8]; 475 c1 = anchor_e[0] * anchor[7] - anchor_e[1] * anchor[6]; 476 a2 = anchor_e[1] * anchor[2] - anchor_e[2] * anchor[1]; 477 b2 = anchor_e[2] * anchor[0] - anchor_e[0] * anchor[2]; 478 c2 = anchor_e[0] * anchor[1] - anchor_e[1] * anchor[0]; 479 inflection = (anchor_e[2] / anchor_e[1]); 480 481 // document.getElementById('debug').innerHTML += 'a1 = ' + a1 + '<br/>' + 'b1 = ' + b1 + '<br/>' + 'c1 = ' + c1 + '<br/>' + 'a2 = ' + a2 + '<br/>' + 'b2 = ' + b2 + '<br/>' + 'c2 = ' + c2 + '<br/>' + 'inflection = ' + inflection + '<br/><br/>tritanopia<br/><br/>'; 482 // Set 1: regions where lambda_a=575, set 2: lambda_a=475 483 a1 = anchor_e[1] * anchor[11] - anchor_e[2] * anchor[10]; 484 b1 = anchor_e[2] * anchor[9] - anchor_e[0] * anchor[11]; 485 c1 = anchor_e[0] * anchor[10] - anchor_e[1] * anchor[9]; 486 a2 = anchor_e[1] * anchor[5] - anchor_e[2] * anchor[4]; 487 b2 = anchor_e[2] * anchor[3] - anchor_e[0] * anchor[5]; 488 c2 = anchor_e[0] * anchor[4] - anchor_e[1] * anchor[3]; 489 inflection = (anchor_e[1] / anchor_e[0]); 490 491 492 // document.getElementById('debug').innerHTML += 'a1 = ' + a1 + '<br/>' + 'b1 = ' + b1 + '<br/>' + 'c1 = ' + c1 + '<br/>' + 'a2 = ' + a2 + '<br/>' + 'b2 = ' + b2 + '<br/>' + 'c2 = ' + c2 + '<br/>' + 'inflection = ' + inflection; 493 */ 494 lms = JXG.rgb2LMS(color); 495 l = lms.l; m = lms.m; s = lms.s; 496 497 deficiency = deficiency.toLowerCase(); 498 499 switch(deficiency) { 500 case "protanopia": 501 a1 = -0.06150039994295001; 502 b1 = 0.08277001656812001; 503 c1 = -0.013200141220000003; 504 a2 = 0.05858939668799999; 505 b2 = -0.07934519995360001; 506 c2 = 0.013289415272000003; 507 inflection = 0.6903216543277437; 508 509 tmp = s/m; 510 if (tmp < inflection) 511 l = -(b1 * m + c1 * s) / a1; 512 else 513 l = -(b2 * m + c2 * s) / a2; 514 break; 515 case "tritanopia": 516 a1 = -0.00058973116217; 517 b1 = 0.007690316482; 518 c1 = -0.01011703519052; 519 a2 = 0.025495080838999994; 520 b2 = -0.0422740347; 521 c2 = 0.017005316784; 522 inflection = 0.8349489908460004; 523 524 tmp = m / l; 525 if (tmp < inflection) 526 s = -(a1 * l + b1 * m) / c1; 527 else 528 s = -(a2 * l + b2 * m) / c2; 529 break; 530 default: 531 a1 = -0.06150039994295001; 532 b1 = 0.08277001656812001; 533 c1 = -0.013200141220000003; 534 a2 = 0.05858939668799999; 535 b2 = -0.07934519995360001; 536 c2 = 0.013289415272000003; 537 inflection = 0.5763833686400911; 538 539 tmp = s/l; 540 if(tmp < inflection) 541 m = -(a1 * l + c1 * s) / b1; 542 else 543 m = -(a2 * l + c2 * s) / b2; 544 break; 545 } 546 547 rgb = JXG.LMS2rgb(l, m, s); 548 549 var HexChars="0123456789ABCDEF"; 550 tmp = HexChars.charAt((rgb.r>>4)&0xf)+HexChars.charAt(rgb.r&0xf); 551 color = "#" + tmp; 552 tmp = HexChars.charAt((rgb.g>>4)&0xf)+HexChars.charAt(rgb.g&0xf); 553 color += tmp; 554 tmp = HexChars.charAt((rgb.b>>4)&0xf)+HexChars.charAt(rgb.b&0xf); 555 color += tmp; 556 557 return color; 558 }; 559 560 /** 561 * Load options from a file using FileReader 562 * @param fileurl {String} URL to .json-file containing style information 563 * @param apply {bool} <tt>true</tt> when options in file should be applied to board after being loaded. 564 * @param board {JXG.Board} The board the options should be applied to. 565 */ 566 JXG.loadOptionsFromFile = function(fileurl, applyTo, board) { 567 this.cbp = function(t) { 568 this.parseString(t, applyTo, board); 569 }; 570 this.cb = JXG.bind(this.cbp,this); 571 572 JXG.FileReader.parseFileContent(fileurl, this.cb, 'raw'); 573 }; 574 575 /** 576 * Apply options given as a string to a board. 577 * @param text {String} Options given as a string in .json-Format 578 * @param apply {bool} <tt>true</tt> if the options should be applied to all objects on the board. 579 * @param board {JXG.Board} The board the options should be applied to. 580 */ 581 JXG.parseOptionsString = function(text, applyTo, board) { 582 var newOptions = ''; 583 584 if(text != '') { 585 newOptions = eval("(" + text + ")"); 586 } 587 else 588 return; 589 590 var maxDepth = 10; 591 var applyOption = function (base, option, depth) { 592 if(depth==10) 593 return; 594 depth++; 595 596 for(var key in option) { 597 if((JXG.isNumber(option[key])) || (JXG.isArray(option[key])) || (JXG.isString(option[key])) || (option[key]==true) || (option[key]==false)) { 598 base[key] = option[key]; 599 } 600 else { 601 applyOption(base[key], option[key], depth); 602 } 603 } 604 }; 605 606 applyOption(this, newOptions, 0); 607 608 if(applyTo && typeof board != 'undefined') { 609 JXG.useStandardOptions(board); 610 } 611 }; 612 // vim: et ts=4 613