Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4897 | bpr | 1 | /* |
2 | Copyright 2008 - 2011 |
||
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 | JXG.GeonextReader = { |
||
26 | |||
27 | changeOriginIds: function (board, id) { |
||
28 | if ((id == 'gOOe0') || (id == 'gXOe0') || (id == 'gYOe0') || (id == 'gXLe0') || (id == 'gYLe0')) { |
||
29 | return board.id + id; |
||
30 | } else { |
||
31 | return id; |
||
32 | } |
||
33 | }, |
||
34 | |||
35 | /** |
||
36 | * Retrieves data by TagName from an XML node. |
||
37 | * @param {Node} node The Node that contains the data we want to get. |
||
38 | * @param {String} tag The Name of the tag we are looking for. |
||
39 | * @param {Number} [idx=0] getElementsByTagName returns an array; This parameter decides which element to use. |
||
40 | * @param {Boolean} [fc=true] If True, the result will be the <tt>data</tt> of <tt>firstChild</tt> instead of the result node. |
||
41 | * @returns {String} The gathered data |
||
42 | */ |
||
43 | gEBTN: function (node, tag, idx, fc) { |
||
44 | var tmp; |
||
45 | |||
46 | if (!JXG.exists(node || !node.getElementsByTagName )/* || !JXG.exists(node.getElementsByTagName)*/) { |
||
47 | return ''; |
||
48 | } |
||
49 | // Default values for optional parameters idx and fc |
||
50 | if (!JXG.exists(fc)) { |
||
51 | fc = true; |
||
52 | } |
||
53 | idx = idx || 0; |
||
54 | tmp = node.getElementsByTagName(tag); |
||
55 | if (tmp.length > 0) { |
||
56 | tmp = tmp[idx]; |
||
57 | if (fc && tmp.firstChild) { |
||
58 | tmp = tmp.firstChild.data; |
||
59 | } |
||
60 | } |
||
61 | return tmp; |
||
62 | }, |
||
63 | |||
64 | /** |
||
65 | * Set color properties of a geonext element. |
||
66 | * Set stroke, fill, lighting, label and draft color attributes. |
||
67 | * @param {Object} gxtEl element of which attributes are to set |
||
68 | */ |
||
69 | colorProperties: function (gxtEl, Data) { |
||
70 | var color = this.gEBTN(Data, 'color', 0, false), |
||
71 | rgbo; |
||
72 | |||
73 | //gxtEl.strokewidth = Data.getElementsByTagName('strokewidth')[0].firstChild.data; |
||
74 | // colorStroke = strokeColor etc. is here for downwards compatibility: |
||
75 | // once upon a time we used to create elements in here using the "new JXG.Element" constructor mechanism |
||
76 | // then we changed to board.create + setProperty afterwords |
||
77 | // now i want to use the board.create method with an appropriate attributes object to avoid setProperty calls |
||
78 | // and as gxtEl happens to be somewhat like an attributes object it's just slightly different so we adjust it |
||
79 | // for downwards compatibility during the transformation of this reader we use both properties |
||
80 | |||
81 | rgbo = JXG.rgba2rgbo(this.gEBTN(color, 'stroke')); |
||
82 | gxtEl.strokeColor = rgbo[0]; |
||
83 | gxtEl.strokeOpacity = rgbo[1]; |
||
84 | |||
85 | rgbo = JXG.rgba2rgbo(this.gEBTN(color, 'lighting')); |
||
86 | gxtEl.highlightStrokeColor = rgbo[0]; |
||
87 | gxtEl.highlightStrokeOpacity = rgbo[1]; |
||
88 | |||
89 | rgbo = JXG.rgba2rgbo(this.gEBTN(color, 'fill')); |
||
90 | gxtEl.fillColor = rgbo[0]; |
||
91 | gxtEl.fillOpacity = rgbo[1]; |
||
92 | |||
93 | gxtEl.highlightFillColor = gxtEl.fillColor; |
||
94 | gxtEl.highlightFillOpacity = gxtEl.fillOpacity; |
||
95 | |||
96 | gxtEl.labelColor = JXG.rgba2rgbo(this.gEBTN(color, 'label'))[0]; |
||
97 | gxtEl.colorDraft = JXG.rgba2rgbo(this.gEBTN(color, 'draft'))[0]; |
||
98 | |||
99 | // GEONExT hides labels by setting opacity to 0. |
||
100 | if (JXG.rgba2rgbo(this.gEBTN(color, 'label'))[1]==0) { |
||
101 | gxtEl.withLabel = false; |
||
102 | } |
||
103 | |||
104 | // backwards compatibility |
||
105 | gxtEl.colorStroke = gxtEl.strokeColor; |
||
106 | gxtEl.colorFill = gxtEl.fillColor; |
||
107 | gxtEl.colorLabel = gxtEl.labelColor; |
||
108 | |||
109 | return gxtEl; |
||
110 | }, |
||
111 | |||
112 | firstLevelProperties: function (gxtEl, Data) { |
||
113 | if (!JXG.exists(Data) || !JXG.exists(Data.childNodes)) |
||
114 | return gxtEl; |
||
115 | |||
116 | var arr = Data.childNodes, n, key; |
||
117 | |||
118 | for (n = 0; n < arr.length; n++) { |
||
119 | if (JXG.exists(arr[n].firstChild) && arr[n].nodeName !== 'data' && arr[n].nodeName !== 'straight') { |
||
120 | key = arr[n].nodeName; |
||
121 | gxtEl[key] = arr[n].firstChild.data; |
||
122 | } |
||
123 | } |
||
124 | |||
125 | return gxtEl; |
||
126 | }, |
||
127 | |||
128 | /** |
||
129 | * Set the defining properties of a geonext element. |
||
130 | * Writing the nodeName to ident; setting the name attribute and defining the element id. |
||
131 | * @param {Object} gxtEl element of which attributes are to set |
||
132 | */ |
||
133 | defProperties: function (gxtEl, Data) { |
||
134 | // 3==TEXT_NODE, 8==COMMENT_NODE |
||
135 | if (Data.nodeType==3 || Data.nodeType==8 ) { |
||
136 | return null; |
||
137 | } |
||
138 | |||
139 | gxtEl.ident = Data.nodeName; |
||
140 | |||
141 | if(gxtEl.ident == "text" || gxtEl.ident == "intersection" || gxtEl.ident == "composition") { |
||
142 | gxtEl.name = ''; |
||
143 | } else { |
||
144 | gxtEl.name = this.gEBTN(Data, 'name'); |
||
145 | } |
||
146 | |||
147 | gxtEl.id = this.gEBTN(Data, 'id'); |
||
148 | |||
149 | return gxtEl; |
||
150 | }, |
||
151 | |||
152 | visualProperties: function (gxtEl, Data) { |
||
153 | gxtEl.visible = JXG.str2Bool(this.gEBTN(Data, 'visible')); |
||
154 | gxtEl.trace = JXG.str2Bool(this.gEBTN(Data, 'trace')); |
||
155 | |||
156 | return gxtEl; |
||
157 | }, |
||
158 | |||
159 | transformProperties: function (gxtEl, type) { |
||
160 | var facemap = [ |
||
161 | // 0-2 |
||
162 | 'cross', 'cross', 'cross', |
||
163 | // 3-6 |
||
164 | 'circle', 'circle', 'circle', 'circle', |
||
165 | // 7-9 |
||
166 | 'square', 'square', 'square', |
||
167 | // 10-12 |
||
168 | 'plus', 'plus', 'plus' |
||
169 | ], sizemap = [ |
||
170 | // 0-2 |
||
171 | 2, 3, 4, |
||
172 | // 3-6 |
||
173 | 1, 2, 3, 4, |
||
174 | // 7-9 |
||
175 | 2, 3, 4, |
||
176 | // 10-12 |
||
177 | 2, 3, 4 |
||
178 | ]; |
||
179 | |||
180 | gxtEl.strokeWidth = gxtEl.strokewidth; |
||
181 | gxtEl.face = facemap[parseInt(gxtEl.style, 10)] || 'cross'; |
||
182 | gxtEl.size = sizemap[parseInt(gxtEl.style, 10)] || 3; |
||
183 | |||
184 | gxtEl.straightFirst = JXG.str2Bool(gxtEl.straightFirst); |
||
185 | gxtEl.straightLast = JXG.str2Bool(gxtEl.straightLast); |
||
186 | |||
187 | gxtEl.visible = JXG.str2Bool(gxtEl.visible); |
||
188 | //gxtEl.withLabel = gxtEl.visible; // withLabel is set in colorProperties() |
||
189 | gxtEl.draft = JXG.str2Bool(gxtEl.draft); |
||
190 | gxtEl.trace = JXG.str2Bool(gxtEl.trace); |
||
191 | |||
192 | if (type==='point') { |
||
193 | // Fill properties are ignored by GEONExT |
||
194 | gxtEl.fillColor = gxtEl.strokeColor; |
||
195 | gxtEl.highlightFillColor = gxtEl.highlightStrokeColor; |
||
196 | gxtEl.fillOpacity = gxtEl.strokeOpacity; |
||
197 | gxtEl.highlightFillOpacity = gxtEl.highlightStrokeOpacity; |
||
198 | } |
||
199 | |||
200 | delete gxtEl.color; |
||
201 | return gxtEl; |
||
202 | }, |
||
203 | |||
204 | readNodes: function (gxtEl, Data, nodeType, prefix) { |
||
205 | var arr = this.gEBTN(Data, nodeType, 0, false).childNodes, |
||
206 | key, n; |
||
207 | |||
208 | for (n = 0; n < arr.length; n++) { |
||
209 | if (arr[n].firstChild != null) { |
||
210 | if (prefix != null) { |
||
211 | key = prefix + JXG.capitalize(arr[n].nodeName); |
||
212 | } else { |
||
213 | key = arr[n].nodeName; |
||
214 | } |
||
215 | gxtEl[key] = arr[n].firstChild.data; |
||
216 | } |
||
217 | } |
||
218 | return gxtEl; |
||
219 | }, |
||
220 | |||
221 | subtreeToString: function (root) { |
||
222 | try { |
||
223 | // firefox |
||
224 | return (new XMLSerializer()).serializeToString(root); |
||
225 | } catch (e) { |
||
226 | // IE |
||
227 | return root.xml; |
||
228 | } |
||
229 | }, |
||
230 | |||
231 | readImage: function (node) { |
||
232 | var pic = '', |
||
233 | nod = node; |
||
234 | |||
235 | if (nod != null) { |
||
236 | pic = nod.data; |
||
237 | while (nod.nextSibling != null) { |
||
238 | nod = nod.nextSibling; |
||
239 | pic += nod.data; |
||
240 | } |
||
241 | } |
||
242 | return pic; |
||
243 | }, |
||
244 | |||
245 | parseImage: function (board, fileNode, level, x, y, w, h, el) { |
||
246 | var tag, id, im, picStr, tmpImg; |
||
247 | |||
248 | if (fileNode == null) { |
||
249 | return null; |
||
250 | } |
||
251 | |||
252 | if (fileNode.getElementsByTagName('src')[0] != null) { // Background image |
||
253 | tag = 'src'; |
||
254 | } else if (fileNode.getElementsByTagName('image')[0] != null) { |
||
255 | tag = 'image'; |
||
256 | } else { |
||
257 | return null; |
||
258 | } |
||
259 | |||
260 | picStr = this.readImage(this.gEBTN(fileNode, tag, 0, false).firstChild); |
||
261 | if (picStr!='') { |
||
262 | picStr = 'data:image/png;base64,' + picStr; |
||
263 | if (tag=='src') { // Background image |
||
264 | x = this.gEBTN(fileNode, 'x'); |
||
265 | y = this.gEBTN(fileNode, 'y'); |
||
266 | w = this.gEBTN(fileNode, 'width'); |
||
267 | h = this.gEBTN(fileNode, 'height'); |
||
268 | im = board.create('image', [picStr,[x, y],[w, h]], { |
||
269 | anchor: el, layer: level |
||
270 | }); |
||
271 | return im; |
||
272 | } else { |
||
273 | // Image bound to an element |
||
274 | // Read the original dimensions, i.e. the ratio h/w with the help of a temporary image. |
||
275 | // We have to wait until the image is loaded, therefore |
||
276 | // we need "onload". |
||
277 | tmpImg = new Image(); |
||
278 | tmpImg.src = picStr; |
||
279 | id = el.id + '_image'; |
||
280 | tmpImg.onload = function(){ |
||
281 | // Now, we can read the original dimensions of the image. |
||
282 | var wOrg = this.width, |
||
283 | hOrg = this.height, |
||
284 | xf, yf, wf, hf, im, tRot; |
||
285 | |||
286 | if (el.elementClass == JXG.OBJECT_CLASS_LINE) { |
||
287 | // A line containing an image, runs through the horizontal middle |
||
288 | // of the image. |
||
289 | xf = function(){ return el.point1.X(); }; |
||
290 | wf = function(){ return el.point1.Dist(el.point2); }; |
||
291 | hf = function(){ return wf() * hOrg / wOrg; }; |
||
292 | yf = function(){ return el.point1.Y() - hf() * 0.5; }; |
||
293 | im = board.create('image', [picStr, [xf,yf], [wf,hf]], { |
||
294 | layer: level, |
||
295 | id: id, |
||
296 | anchor: el |
||
297 | }); |
||
298 | tRot = board.create('transform', [ |
||
299 | function () { |
||
300 | return Math.atan2(el.point2.Y()-el.point1.Y(), el.point2.X()-el.point1.X()) |
||
301 | }, |
||
302 | el.point1 |
||
303 | ], { |
||
304 | type:'rotate' |
||
305 | }); |
||
306 | tRot.bindTo(im); |
||
307 | el.image = im; |
||
308 | } else if (el.elementClass == JXG.OBJECT_CLASS_POINT) { |
||
309 | wf = function(){ return wOrg / board.unitX; }; |
||
310 | hf = function(){ return hOrg / board.unitY; }; |
||
311 | xf = function(){ return el.X() - wf() * 0.5; }; |
||
312 | yf = function(){ return el.Y() - hf() * 0.5; }; |
||
313 | |||
314 | im = board.create('image', [picStr, [xf,yf], [wf,hf]], { |
||
315 | layer: level, |
||
316 | id: id, |
||
317 | anchor: el |
||
318 | }); |
||
319 | board.renderer.hide(el.label.content); |
||
320 | el.image = im; |
||
321 | } else if (el.elementClass == JXG.OBJECT_CLASS_CIRCLE) { |
||
322 | // A circle containing an image |
||
323 | wf = function(){ return 2.0 * el.Radius(); }; |
||
324 | hf = function(){ return wf() * hOrg / wOrg; }; |
||
325 | xf = function(){ return el.midpoint.X() - wf() * 0.5; }; |
||
326 | yf = function(){ return el.midpoint.Y() - hf() * 0.5; }; |
||
327 | im = board.create('image', [picStr, [xf,yf], [wf,hf]], { |
||
328 | layer: level, |
||
329 | id: id, |
||
330 | anchor: el |
||
331 | }); |
||
332 | el.image = im; |
||
333 | } else { |
||
334 | im = board.create('image', [picStr, [x, y], [w, h]], { |
||
335 | layer: level, |
||
336 | id: id, |
||
337 | anchor: el |
||
338 | }); |
||
339 | el.image = im; |
||
340 | } |
||
341 | }; |
||
342 | } |
||
343 | return im; |
||
344 | } |
||
345 | }, |
||
346 | |||
347 | readConditions: function(node) { |
||
348 | var i, s, ob, |
||
349 | conditions = ''; |
||
350 | |||
351 | if (JXG.exists(node)) { |
||
352 | for(i = 0; i < node.getElementsByTagName('data').length; i++) { |
||
353 | ob = node.getElementsByTagName('data')[i]; |
||
354 | s = this.subtreeToString(ob); |
||
355 | conditions += s; |
||
356 | } |
||
357 | } |
||
358 | |||
359 | return conditions; |
||
360 | }, |
||
361 | |||
362 | printDebugMessage: function(outputEl,gxtEl,nodetyp,success) { |
||
363 | JXG.debug("* " + success + ": " + nodetyp + " " + gxtEl.name + " " + gxtEl.id + "<br>\n"); |
||
364 | }, |
||
365 | |||
366 | /** |
||
367 | * Reading the elements of a geonext file |
||
368 | * @param {XMLTree} tree expects the content of the parsed geonext file returned by function parseFF/parseIE |
||
369 | * @param {Object} board board object |
||
370 | */ |
||
371 | readGeonext: function(tree, board) { |
||
372 | var xmlNode, elChildNodes, |
||
373 | s, Data, inter, boardData, el, |
||
374 | conditions, tmp, strTrue = 'true', gxtReader = this; |
||
375 | |||
376 | // maybe this is not necessary as we already provide layer options for sectors and circles via JXG.Options but |
||
377 | // maybe these have to be the same for geonext. |
||
378 | board.options.layer.sector = board.options.layer.angle; |
||
379 | board.options.layer.circle = board.options.layer.angle; |
||
380 | |||
381 | boardData = this.gEBTN(tree, 'board', 0, false); |
||
382 | conditions = this.readConditions(boardData.getElementsByTagName('conditions')[0]); |
||
383 | |||
384 | // set the origin |
||
385 | xmlNode = this.gEBTN(boardData, 'coordinates', 0, false); |
||
386 | tmp = this.gEBTN(xmlNode, 'origin', 0, false); |
||
387 | board.origin = { |
||
388 | usrCoords: [1, 0, 0], |
||
389 | scrCoords: [1, parseFloat(this.gEBTN(tmp, 'x')), parseFloat(this.gEBTN(tmp, 'y'))] |
||
390 | }; |
||
391 | |||
392 | // zoom level |
||
393 | tmp = this.gEBTN(xmlNode, 'zoom', 0, false); |
||
394 | board.zoomX = parseFloat(this.gEBTN(tmp, 'x')); |
||
395 | board.zoomY = parseFloat(this.gEBTN(tmp, 'y')); |
||
396 | |||
397 | // screen to user coordinates conversion |
||
398 | tmp = this.gEBTN(xmlNode, 'unit', 0, false); |
||
399 | board.unitX = parseFloat(this.gEBTN(tmp, 'x')); |
||
400 | board.unitY = parseFloat(this.gEBTN(tmp, 'y')); |
||
401 | |||
402 | // resize board |
||
403 | if (board.options.takeSizeFromFile) { |
||
404 | board.resizeContainer(this.gEBTN(boardData, 'width'), this.gEBTN(boardData, 'height')); |
||
405 | } |
||
406 | |||
407 | // check and set fontSize |
||
408 | if (!(parseFloat(board.options.text.fontSize) > 0)) { |
||
409 | board.options.text.fontSize = 12; |
||
410 | } |
||
411 | |||
412 | board.geonextCompatibilityMode = true; |
||
413 | |||
414 | // jsxgraph chooses an id for the board but we don't want to use it, we want to use |
||
415 | // the id stored in the geonext file. if you know why this is required, please note it here. |
||
416 | delete(JXG.JSXGraph.boards[board.id]); |
||
417 | board.id = this.gEBTN(boardData, 'id'); |
||
418 | JXG.JSXGraph.boards[board.id] = board; |
||
419 | |||
420 | // this creates some basic elements present in every geonext construction but not explicitly present in the file |
||
421 | board.initGeonextBoard(); |
||
422 | |||
423 | // Update of properties during update() is not necessary in GEONExT files |
||
424 | // But it maybe necessary if we construct with JavaScript afterwards |
||
425 | board.renderer.enhancedRendering = true; |
||
426 | |||
427 | // Read background image |
||
428 | this.parseImage(board, this.gEBTN(boardData, 'file', 0, false), board.options.layer['image']); |
||
429 | |||
430 | board.options.grid.snapToGrid = (this.gEBTN(this.gEBTN(boardData, 'coordinates', 0, false), 'snap') == strTrue); |
||
431 | // |
||
432 | // TODO: Missing jsxgraph feature snapToPoint |
||
433 | // If snapToGrid and snapToPoint are both true, point snapping is enabled |
||
434 | if (board.options.grid.snapToGrid && this.gEBTN(this.gEBTN(boardData, 'grid', 1, false), 'pointsnap') == strTrue) { |
||
435 | board.options.grid.snapToGrid = false; |
||
436 | } |
||
437 | //board.options.grid.snapToGrid = false; |
||
438 | |||
439 | xmlNode = this.gEBTN(boardData, 'grid', 1, false); |
||
440 | tmp = this.gEBTN(xmlNode, 'x'); |
||
441 | if (tmp) { |
||
442 | board.options.grid.gridX = 1 / parseFloat(tmp); |
||
443 | board.options.grid.snapSizeX = parseFloat(tmp); |
||
444 | } |
||
445 | tmp = this.gEBTN(xmlNode, 'y'); |
||
446 | if (tmp) { |
||
447 | board.options.grid.gridY = 1 / parseFloat(tmp); |
||
448 | board.options.grid.snapSizeY = parseFloat(tmp); |
||
449 | } |
||
450 | //board.calculateSnapSizes(); // Seems not to be correct |
||
451 | board.options.grid.gridDash = JXG.str2Bool(this.gEBTN(xmlNode, 'dash')); |
||
452 | |||
453 | tmp = JXG.rgba2rgbo(this.gEBTN(xmlNode, 'color')); |
||
454 | board.options.grid.gridColor = tmp[0]; |
||
455 | board.options.grid.gridOpacity = tmp[1]; |
||
456 | |||
457 | xmlNode = this.gEBTN(boardData, 'coordinates', 0, false); |
||
458 | if (this.gEBTN(xmlNode, 'grid') == strTrue) { |
||
459 | board.create('grid', []); |
||
460 | } |
||
461 | |||
462 | if (this.gEBTN(xmlNode, 'coord') == strTrue) { |
||
463 | board.options.axis.ticks.majorHeight = 10; // Hard coded default option |
||
464 | board.options.axis.ticks.minorHeight = 4; // Hard coded default option |
||
465 | board.create('axis', [[0, 0], [1, 0]]); |
||
466 | board.create('axis', [[0, 0], [0, 1]]); |
||
467 | } |
||
468 | |||
469 | board.containerObj.style.backgroundColor = JXG.rgba2rgbo(this.gEBTN(this.gEBTN(boardData, 'background', 0, false), 'color'))[0]; |
||
470 | |||
471 | elChildNodes = tree.getElementsByTagName("elements")[0].childNodes; |
||
472 | for (s = 0; s < elChildNodes.length; s++) { |
||
473 | (function (s) { |
||
474 | var i, gxtEl = {}, |
||
475 | l, x, y, w, h, c, numberDefEls, |
||
476 | el, p, inter, rgbo, tmp; |
||
477 | |||
478 | Data = elChildNodes[s]; |
||
479 | gxtEl = gxtReader.defProperties(gxtEl, Data); |
||
480 | |||
481 | // Skip text nodes |
||
482 | if (!JXG.exists(gxtEl)) { |
||
483 | return; |
||
484 | } |
||
485 | |||
486 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName.toLowerCase, 'READ:'); |
||
487 | switch (Data.nodeName.toLowerCase()) { |
||
488 | case "point": |
||
489 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
490 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
491 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
492 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
493 | gxtEl.fixed = JXG.str2Bool(gxtReader.gEBTN(Data, 'fix')); |
||
494 | gxtEl = gxtReader.transformProperties(gxtEl, 'point'); |
||
495 | |||
496 | //try { |
||
497 | p = board.create('point', [parseFloat(gxtEl.x), parseFloat(gxtEl.y)], gxtEl); |
||
498 | |||
499 | var v = function(){ return p.visProp.visible; }; |
||
500 | el = gxtReader.parseImage(board, Data, board.options.layer['image'], 0, 0, 0, 0, p); |
||
501 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
502 | /* |
||
503 | if (JXG.exists(el)) { |
||
504 | el.visProp.visible = function() { return p.visProp.visible; }; |
||
505 | alert(p.visProp.visible); |
||
506 | if (el.visProp.visible()) {el.showElement();} else {el.hideElement();} |
||
507 | } |
||
508 | */ |
||
509 | //} catch(e) { |
||
510 | // JXG.debug(e); |
||
511 | //} |
||
512 | break; |
||
513 | case "line": |
||
514 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
515 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
516 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
517 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
518 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'straight', 'straight'); |
||
519 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
520 | |||
521 | gxtEl.first = gxtReader.changeOriginIds(board, gxtEl.first); |
||
522 | gxtEl.last = gxtReader.changeOriginIds(board, gxtEl.last); |
||
523 | |||
524 | l = board.create('line', [gxtEl.first, gxtEl.last], gxtEl); |
||
525 | |||
526 | gxtReader.parseImage(board, Data, board.options.layer['image'], 0, 0, 0, 0, l); |
||
527 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
528 | break; |
||
529 | case "circle": |
||
530 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
531 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
532 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
533 | |||
534 | tmp = gxtReader.gEBTN(Data, 'data', 0, false); |
||
535 | gxtEl.midpoint = gxtReader.changeOriginIds(board, gxtReader.gEBTN(tmp, 'midpoint')); |
||
536 | |||
537 | if (tmp.getElementsByTagName('radius').length > 0) { |
||
538 | gxtEl.radius = gxtReader.changeOriginIds(board, gxtReader.gEBTN(tmp, 'radius')); |
||
539 | } else if (tmp.getElementsByTagName('radiusvalue').length > 0) { |
||
540 | gxtEl.radius = gxtReader.gEBTN(tmp, 'radiusvalue'); |
||
541 | } |
||
542 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
543 | c = board.create('circle', [gxtEl.midpoint, gxtEl.radius], gxtEl); |
||
544 | |||
545 | gxtReader.parseImage(board, Data, board.options.layer['image'], 0, 0, 0, 0, c); |
||
546 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
547 | break; |
||
548 | case "slider": |
||
549 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
550 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
551 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
552 | |||
553 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
554 | gxtEl.fixed = JXG.str2Bool(gxtReader.gEBTN(Data, 'fix')); |
||
555 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'animate', 'animate'); |
||
556 | gxtEl = gxtReader.transformProperties(gxtEl, 'point'); |
||
557 | try { |
||
558 | gxtEl.parent = gxtReader.changeOriginIds(board, gxtEl.parent); |
||
559 | |||
560 | // if (board.isSuspendedUpdate) { board.unsuspendUpdate().suspendUpdate(); } |
||
561 | p = board.create('glider', [parseFloat(gxtEl.x), parseFloat(gxtEl.y), gxtEl.parent], gxtEl); |
||
562 | p.onPolygon = JXG.exists(gxtEl.onpolygon) && JXG.str2Bool(gxtEl.onpolygon); |
||
563 | |||
564 | gxtReader.parseImage(board, Data, board.options.layer['point'], 0, 0, 0, 0, p); |
||
565 | |||
566 | //if (board.isSuspendedUpdate) { board.unsuspendUpdate().suspendUpdate(); } |
||
567 | |||
568 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
569 | } catch(e) { |
||
570 | JXG.debug("* <b>Err:</b> Slider " + gxtEl.name + " " + gxtEl.id + ': '+ gxtEl.parent +"<br>\n"); |
||
571 | } |
||
572 | break; |
||
573 | case "cas": |
||
574 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
575 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
576 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
577 | gxtEl.fixed = JXG.str2Bool(Data.getElementsByTagName('fix')[0].firstChild.data); |
||
578 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
579 | gxtEl = gxtReader.transformProperties(gxtEl, 'point'); |
||
580 | |||
581 | p = board.create('point', [parseFloat(gxtEl.xval), parseFloat(gxtEl.yval)], gxtEl); |
||
582 | gxtReader.parseImage(board, Data, board.options.layer['point'], 0, 0, 0, 0, p); |
||
583 | p.addConstraint([gxtEl.x, gxtEl.y]); |
||
584 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
585 | break; |
||
586 | case "intersection": |
||
587 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
588 | xmlNode = Data.getElementsByTagName('first')[1]; |
||
589 | |||
590 | gxtEl.outFirst = {}; |
||
591 | gxtEl.outFirst = gxtReader.colorProperties(gxtEl.outFirst, xmlNode); |
||
592 | gxtEl.outFirst = gxtReader.visualProperties(gxtEl.outFirst, xmlNode); |
||
593 | gxtEl.outFirst = gxtReader.firstLevelProperties(gxtEl.outFirst, xmlNode); |
||
594 | gxtEl.outFirst.fixed = JXG.str2Bool(xmlNode.getElementsByTagName('fix')[0].firstChild.data); |
||
595 | gxtEl.outFirst = gxtReader.transformProperties(gxtEl.outFirst, 'point'); |
||
596 | gxtEl.first = gxtReader.changeOriginIds(board, gxtEl.first); |
||
597 | gxtEl.last = gxtReader.changeOriginIds(board, gxtEl.last); |
||
598 | |||
599 | //if ((board.objects[gxtEl.first].type == JXG.OBJECT_TYPE_LINE || board.objects[gxtEl.first].type == JXG.OBJECT_TYPE_ARROW) |
||
600 | // && (board.objects[gxtEl.last].type == JXG.OBJECT_TYPE_LINE || board.objects[gxtEl.last].type == JXG.OBJECT_TYPE_ARROW)) { |
||
601 | if ((JXG.getReference(board, gxtEl.first).elementClass == JXG.OBJECT_CLASS_LINE) |
||
602 | && (JXG.getReference(board, gxtEl.last).elementClass == JXG.OBJECT_CLASS_LINE)) { |
||
603 | /* |
||
604 | inter = new JXG.Intersection(board, gxtEl.id, board.objects[gxtEl.first], |
||
605 | board.objects[gxtEl.last], gxtEl.outFirst.id, '', |
||
606 | gxtEl.outFirst.name, ''); |
||
607 | inter.p.setProperty(gxtEl.outFirst); |
||
608 | */ |
||
609 | inter = board.create('intersection', [board.objects[gxtEl.first], board.objects[gxtEl.last], 0], gxtEl.outFirst); |
||
610 | /* offensichtlich braucht man dieses if doch */ |
||
611 | if (gxtEl.outFirst.visible == "false") { |
||
612 | inter.hideElement(); |
||
613 | } |
||
614 | } else { |
||
615 | xmlNode = Data.getElementsByTagName('last')[1]; |
||
616 | if (JXG.exists(xmlNode)) { |
||
617 | gxtEl.outLast = {}; |
||
618 | gxtEl.outLast = gxtReader.colorProperties(gxtEl.outLast, xmlNode); |
||
619 | gxtEl.outLast = gxtReader.visualProperties(gxtEl.outLast, xmlNode); |
||
620 | gxtEl.outLast = gxtReader.firstLevelProperties(gxtEl.outLast, xmlNode); |
||
621 | gxtEl.outLast.fixed = JXG.str2Bool(xmlNode.getElementsByTagName('fix')[0].firstChild.data); |
||
622 | gxtEl.outLast = gxtReader.transformProperties(gxtEl.outLast, 'point'); |
||
623 | /* |
||
624 | inter = new JXG.Intersection(board, gxtEl.id, board.objects[gxtEl.first], |
||
625 | board.objects[gxtEl.last], gxtEl.outFirst.id, gxtEl.outLast.id, |
||
626 | gxtEl.outFirst.name, gxtEl.outLast.name); |
||
627 | inter.p1.setProperty(gxtEl.outFirst); |
||
628 | inter.p2.setProperty(gxtEl.outLast); |
||
629 | */ |
||
630 | inter = board.create('intersection', [board.objects[gxtEl.first], board.objects[gxtEl.last], 0], gxtEl.outFirst); |
||
631 | inter = board.create('intersection', [board.objects[gxtEl.first], board.objects[gxtEl.last], 1], gxtEl.outLast); |
||
632 | } |
||
633 | } |
||
634 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
635 | break; |
||
636 | case "composition": |
||
637 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
638 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
639 | gxtEl.defEl = []; |
||
640 | numberDefEls = 0; |
||
641 | xmlNode = Data.getElementsByTagName('data')[0].getElementsByTagName('input'); |
||
642 | for (i = 0; i < xmlNode.length; i++) { |
||
643 | gxtEl.defEl[i] = xmlNode[i].firstChild.data; |
||
644 | numberDefEls = i + 1; |
||
645 | } |
||
646 | |||
647 | // every composition produces at least one element and the data for this element is stored |
||
648 | // in gxtEl.out. if additional elements are created their data is read in the according case. |
||
649 | xmlNode = Data.getElementsByTagName('output')[0]; |
||
650 | gxtEl.out = {}; |
||
651 | gxtEl.out = gxtReader.colorProperties(gxtEl.out, xmlNode); |
||
652 | gxtEl.out = gxtReader.visualProperties(gxtEl.out, xmlNode); |
||
653 | gxtEl.out = gxtReader.firstLevelProperties(gxtEl.out, xmlNode); |
||
654 | gxtEl.out = gxtReader.transformProperties(gxtEl.out); |
||
655 | |||
656 | gxtEl.defEl[0] = gxtReader.changeOriginIds(board, gxtEl.defEl[0]); |
||
657 | gxtEl.defEl[1] = gxtReader.changeOriginIds(board, gxtEl.defEl[1]); |
||
658 | gxtEl.defEl[2] = gxtReader.changeOriginIds(board, gxtEl.defEl[2]); |
||
659 | |||
660 | // if (board.isSuspendedUpdate) { board.unsuspendUpdate().suspendUpdate(); } |
||
661 | switch (gxtEl.type) { |
||
662 | // ARROW_PARALLEL |
||
663 | case "210070": |
||
664 | gxtEl.out.fixed = gxtReader.gEBTN(xmlNode, 'fix'); |
||
665 | |||
666 | xmlNode = Data.getElementsByTagName('output')[1]; |
||
667 | gxtEl.outPoint = {}; |
||
668 | gxtEl.outPoint = gxtReader.defProperties(gxtEl.outPoint, xmlNode); |
||
669 | gxtEl.outPoint = gxtReader.colorProperties(gxtEl.outPoint, xmlNode); |
||
670 | gxtEl.outPoint = gxtReader.visualProperties(gxtEl.outPoint, xmlNode); |
||
671 | gxtEl.outPoint = gxtReader.firstLevelProperties(gxtEl.outPoint, xmlNode); |
||
672 | gxtEl.outPoint = gxtReader.transformProperties(gxtEl.outPoint); |
||
673 | gxtEl.out.point = gxtEl.outPoint; |
||
674 | |||
675 | board.create('arrowparallel', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
676 | break; |
||
677 | |||
678 | // BISECTOR |
||
679 | case "210080": |
||
680 | gxtEl.out.straightFirst = false; |
||
681 | board.create('bisector', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], gxtEl.out); |
||
682 | break; |
||
683 | |||
684 | // CIRCUMCIRCLE |
||
685 | case "210090": |
||
686 | xmlNode = Data.getElementsByTagName('output')[1]; |
||
687 | gxtEl.outCircle = {}; |
||
688 | gxtEl.outCircle = gxtReader.defProperties(gxtEl.outCircle, xmlNode); |
||
689 | gxtEl.outCircle = gxtReader.colorProperties(gxtEl.outCircle, xmlNode); |
||
690 | gxtEl.outCircle = gxtReader.visualProperties(gxtEl.outCircle, xmlNode); |
||
691 | gxtEl.outCircle = gxtReader.firstLevelProperties(gxtEl.outCircle, xmlNode); |
||
692 | gxtEl.outCircle = gxtReader.transformProperties(gxtEl.outCircle); |
||
693 | gxtEl.outCircle.point = gxtEl.out; |
||
694 | board.create('circumcircle', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], gxtEl.outCircle); |
||
695 | break; |
||
696 | |||
697 | // CIRCUMCIRCLE_CENTER |
||
698 | case "210100": |
||
699 | board.create('circumcirclemidpoint', [gxtEl.defEl[0], gxtEl.defEl[1], gxtEl.defEl[2]], gxtEl.out); |
||
700 | break; |
||
701 | |||
702 | // MIDPOINT |
||
703 | case "210110": |
||
704 | board.create('midpoint', gxtEl.defEl.slice(0, numberDefEls), gxtEl.out); |
||
705 | break; |
||
706 | |||
707 | // MIRRORLINE |
||
708 | case "210120": |
||
709 | board.create('reflection', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
710 | break; |
||
711 | |||
712 | // MIRROR_POINT |
||
713 | case "210125": |
||
714 | board.create('mirrorpoint', [gxtEl.defEl[0], gxtEl.defEl[1]], gxtEl.out); |
||
715 | break; |
||
716 | |||
717 | // NORMAL |
||
718 | case "210130": |
||
719 | board.create('normal', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
720 | break; |
||
721 | |||
722 | // PARALLEL |
||
723 | case "210140": |
||
724 | board.create('parallel', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
725 | break; |
||
726 | |||
727 | // PARALLELOGRAM_POINT |
||
728 | case "210150": |
||
729 | board.create('parallelpoint', gxtEl.defEl.slice(0, numberDefEls), gxtEl.out); |
||
730 | break; |
||
731 | |||
732 | // PERPENDICULAR |
||
733 | case "210160": |
||
734 | // output[0] was already read and is stored in gxtEl.out |
||
735 | gxtEl.out.fixed = gxtReader.gEBTN(xmlNode, 'fix'); |
||
736 | |||
737 | xmlNode = Data.getElementsByTagName('output')[1]; |
||
738 | gxtEl.outLine = {}; |
||
739 | gxtEl.outLine = gxtReader.defProperties(gxtEl.outLine, xmlNode); |
||
740 | gxtEl.outLine = gxtReader.colorProperties(gxtEl.outLine, xmlNode); |
||
741 | gxtEl.outLine = gxtReader.visualProperties(gxtEl.outLine, xmlNode); |
||
742 | gxtEl.outLine = gxtReader.firstLevelProperties(gxtEl.outLine, xmlNode); |
||
743 | gxtEl.outLine = gxtReader.readNodes(gxtEl.outLine, xmlNode, 'straight', 'straight'); |
||
744 | gxtEl.outLine = gxtReader.transformProperties(gxtEl.outLine); |
||
745 | gxtEl.outLine.point = gxtEl.out; |
||
746 | |||
747 | board.create('perpendicularsegment', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.outLine); |
||
748 | break; |
||
749 | |||
750 | // PERPENDICULAR_POINT |
||
751 | case "210170": |
||
752 | board.create('perpendicularpoint', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
753 | break; |
||
754 | |||
755 | // ROTATION |
||
756 | case "210180": |
||
757 | throw new Error('JSXGraph: Element ROTATION not yet implemented.'); |
||
758 | break; |
||
759 | |||
760 | // SECTOR |
||
761 | case "210190": |
||
762 | // sectors usually provide more than one output element but JSXGraph is not fully compatible |
||
763 | // to GEONExT sector elements. GEONExT sectors consist of two lines, a point, and a sector, |
||
764 | // JSXGraph uses a curve to display the sector incl. the borders, and |
||
765 | // a point and two lines. |
||
766 | // Gliders on sectors also run through the borders. |
||
767 | gxtEl.out = gxtReader.defProperties(gxtEl.out, xmlNode); |
||
768 | gxtEl.out.firstArrow = JXG.str2Bool(gxtReader.gEBTN(xmlNode, 'firstarrow')); |
||
769 | gxtEl.out.lastArrow = JXG.str2Bool(gxtReader.gEBTN(xmlNode, 'lastarrow')); |
||
770 | |||
771 | // el = board.create('sector', gxtEl.defEl, gxtEl.out); |
||
772 | for (i=0; i<4;i++) { |
||
773 | xmlNode = Data.getElementsByTagName('output')[i]; |
||
774 | gxtEl.out = gxtReader.defProperties(gxtEl.out, xmlNode); |
||
775 | gxtEl.out = gxtReader.colorProperties(gxtEl.out, xmlNode); |
||
776 | gxtEl.out = gxtReader.visualProperties(gxtEl.out, xmlNode); |
||
777 | gxtEl.out = gxtReader.firstLevelProperties(gxtEl.out, xmlNode); |
||
778 | gxtEl.out = gxtReader.transformProperties(gxtEl.out); |
||
779 | |||
780 | if (i==0) { |
||
781 | el = board.create('sector', gxtEl.defEl, gxtEl.out); |
||
782 | } else if (i==1) { |
||
783 | p = board.create('point', [ |
||
784 | function(){ |
||
785 | var p1 = JXG.getRef(board,gxtEl.defEl[1]), p2 = JXG.getRef(board,gxtEl.defEl[2]); |
||
786 | return p1.X() + (p2.X()-p1.X())*el.Radius/p1.Dist(p2); |
||
787 | }, |
||
788 | function(){ |
||
789 | var p1 = JXG.getRef(board,gxtEl.defEl[1]), p2 = JXG.getRef(board,gxtEl.defEl[2]); |
||
790 | return p1.Y() + (p2.Y()-p1.Y())*el.Radius/p1.Dist(p2); |
||
791 | }], gxtEl.out); |
||
792 | //p = JXG.getReference(board,gxtEl.defEl[2]); |
||
793 | } else if (i==2) { |
||
794 | el = board.create('segment', [gxtEl.defEl[1], gxtEl.defEl[0]], gxtEl.out); |
||
795 | } else if (i==3) { |
||
796 | el = board.create('segment', [gxtEl.defEl[1], p], gxtEl.out); |
||
797 | } |
||
798 | } |
||
799 | break; |
||
800 | default: |
||
801 | throw new Error("JSXGraph: GEONExT-Element " + gxtEl.type + ' not implemented.'); |
||
802 | break; |
||
803 | } |
||
804 | |||
805 | // if (board.isSuspendedUpdate) { board.unsuspendUpdate().suspendUpdate(); } |
||
806 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
807 | break; |
||
808 | case "polygon": |
||
809 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
810 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
811 | gxtEl.dataVertex = []; |
||
812 | // In Geonext file format the first vertex is equal to the last vertex: |
||
813 | for (i = 0; i < Data.getElementsByTagName('data')[0].getElementsByTagName('vertex').length-1; i++) { |
||
814 | gxtEl.dataVertex[i] = Data.getElementsByTagName('data')[0].getElementsByTagName('vertex')[i].firstChild.data; |
||
815 | gxtEl.dataVertex[i] = gxtReader.changeOriginIds(board, gxtEl.dataVertex[i]); |
||
816 | } |
||
817 | gxtEl.border = []; |
||
818 | gxtEl.lines = { |
||
819 | ids: [] |
||
820 | }; |
||
821 | for (i = 0; i < Data.getElementsByTagName('border').length; i++) { |
||
822 | gxtEl.border[i] = {}; |
||
823 | xmlNode = Data.getElementsByTagName('border')[i]; |
||
824 | gxtEl.border[i].id = xmlNode.getElementsByTagName('id')[0].firstChild.data; |
||
825 | gxtEl.lines.ids.push(gxtEl.border[i].id); |
||
826 | gxtEl.border[i].name = xmlNode.getElementsByTagName('name')[0].firstChild.data; |
||
827 | gxtEl.border[i].straightFirst = JXG.str2Bool(xmlNode.getElementsByTagName('straight')[0].getElementsByTagName('first')[0].firstChild.data); |
||
828 | gxtEl.border[i].straightLast = JXG.str2Bool(xmlNode.getElementsByTagName('straight')[0].getElementsByTagName('last')[0].firstChild.data); |
||
829 | gxtEl.border[i].strokeWidth = xmlNode.getElementsByTagName('strokewidth')[0].firstChild.data; |
||
830 | gxtEl.border[i].dash = JXG.str2Bool(xmlNode.getElementsByTagName('dash')[0].firstChild.data); |
||
831 | gxtEl.border[i].visible = JXG.str2Bool(xmlNode.getElementsByTagName('visible')[0].firstChild.data); |
||
832 | gxtEl.border[i].draft = JXG.str2Bool(xmlNode.getElementsByTagName('draft')[0].firstChild.data); |
||
833 | gxtEl.border[i].trace = JXG.str2Bool(xmlNode.getElementsByTagName('trace')[0].firstChild.data); |
||
834 | |||
835 | xmlNode = Data.getElementsByTagName('border')[i].getElementsByTagName('color')[0]; |
||
836 | rgbo = JXG.rgba2rgbo(xmlNode.getElementsByTagName('stroke')[0].firstChild.data); |
||
837 | gxtEl.border[i].strokeColor = rgbo[0]; |
||
838 | gxtEl.border[i].strokeOpacity = rgbo[1]; |
||
839 | |||
840 | rgbo = JXG.rgba2rgbo(xmlNode.getElementsByTagName('lighting')[0].firstChild.data); |
||
841 | gxtEl.border[i].highlightStrokeColor = rgbo[0]; |
||
842 | gxtEl.border[i].highlightStrokeOpacity = rgbo[1]; |
||
843 | |||
844 | rgbo = JXG.rgba2rgbo(xmlNode.getElementsByTagName('fill')[0].firstChild.data); |
||
845 | gxtEl.border[i].fillColor = rgbo[0]; |
||
846 | gxtEl.border[i].fillOpacity = rgbo[1]; |
||
847 | |||
848 | gxtEl.border[i].highlightFillColor = gxtEl.border[i].fillColor; |
||
849 | gxtEl.border[i].highlightFillOpacity = gxtEl.border[i].fillOpacity; |
||
850 | |||
851 | gxtEl.border[i].labelColor = xmlNode.getElementsByTagName('label')[0].firstChild.data; |
||
852 | gxtEl.border[i].colorDraft = xmlNode.getElementsByTagName('draft')[0].firstChild.data; |
||
853 | } |
||
854 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
855 | p = board.create('polygon', gxtEl.dataVertex, gxtEl); |
||
856 | |||
857 | // to emulate the geonext behaviour on invisible polygons |
||
858 | // A.W.: Why do we need this? |
||
859 | /* |
||
860 | if (!gxtEl.visible) { |
||
861 | p.setProperty({ |
||
862 | fillColor: 'none', |
||
863 | highlightFillColor: 'none' |
||
864 | }); |
||
865 | } |
||
866 | */ |
||
867 | for (i = 0; i < p.borders.length; i++) { |
||
868 | p.borders[i].setProperty(gxtEl.border[i]); |
||
869 | } |
||
870 | |||
871 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
872 | break; |
||
873 | case "graph": |
||
874 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
875 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
876 | gxtEl.funct = Data.getElementsByTagName('data')[0].getElementsByTagName('function')[0].firstChild.data; |
||
877 | |||
878 | c = board.create('curve', ['x',gxtEl.funct], { |
||
879 | id: gxtEl.id, |
||
880 | name: gxtEl.name, |
||
881 | strokeColor: gxtEl.strokeColor, |
||
882 | strokeWidth: gxtEl.strokeWidth, |
||
883 | fillColor: 'none', |
||
884 | highlightFillColor: 'none', |
||
885 | highlightStrokeColor: gxtEl.highlightStrokeColor, |
||
886 | visible: JXG.str2Bool(gxtEl.visible) |
||
887 | }); |
||
888 | |||
889 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
890 | break; |
||
891 | case "arrow": |
||
892 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
893 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
894 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
895 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
896 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'straight', 'straight'); |
||
897 | |||
898 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
899 | gxtEl.first = gxtReader.changeOriginIds(board, gxtEl.first); |
||
900 | gxtEl.last = gxtReader.changeOriginIds(board, gxtEl.last); |
||
901 | |||
902 | l = board.create('arrow', [gxtEl.first, gxtEl.last], gxtEl); |
||
903 | |||
904 | gxtReader.printDebugMessage('debug', l, Data.nodeName, 'OK'); |
||
905 | break; |
||
906 | case "arc": |
||
907 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
908 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
909 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
910 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
911 | |||
912 | gxtEl.firstArrow = JXG.str2Bool(Data.getElementsByTagName('lastarrow')[0].firstChild.data); // It seems that JSXGraph and GEONExT |
||
913 | gxtEl.lastArrow = JXG.str2Bool(Data.getElementsByTagName('firstarrow')[0].firstChild.data); // use opposite directions. |
||
914 | |||
915 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
916 | |||
917 | gxtEl.midpoint = gxtReader.changeOriginIds(board, gxtEl.midpoint); |
||
918 | gxtEl.angle = gxtReader.changeOriginIds(board, gxtEl.angle); |
||
919 | gxtEl.radius = gxtReader.changeOriginIds(board, gxtEl.radius); |
||
920 | |||
921 | c = board.create('arc', [gxtEl.midpoint, gxtEl.radius, gxtEl.angle], gxtEl); |
||
922 | |||
923 | gxtReader.printDebugMessage('debug', c, Data.nodeName, 'OK'); |
||
924 | break; |
||
925 | case "angle": |
||
926 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
927 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
928 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
929 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
930 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
931 | |||
932 | try { |
||
933 | gxtEl.text = Data.getElementsByTagName('text')[0].firstChild.data; |
||
934 | } catch (e) { |
||
935 | gxtEl.text = ''; |
||
936 | } |
||
937 | |||
938 | c = board.create('angle', [gxtEl.first, gxtEl.middle, gxtEl.last], gxtEl); |
||
939 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
940 | break; |
||
941 | case "text": |
||
942 | if (gxtEl.id.match(/oldVersion/)) { |
||
943 | break; |
||
944 | } |
||
945 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
946 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
947 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
948 | |||
949 | gxtEl = gxtReader.readNodes(gxtEl, Data, 'data'); |
||
950 | gxtEl.mpStr = gxtReader.subtreeToString(Data.getElementsByTagName('data')[0].getElementsByTagName('mp')[0]); |
||
951 | gxtEl.mpStr = gxtEl.mpStr.replace(/<\/?mp>/g, ''); |
||
952 | try { |
||
953 | if (Data.getElementsByTagName('data')[0].getElementsByTagName('parent')[0].firstChild) { |
||
954 | gxtEl.parent = Data.getElementsByTagName('data')[0].getElementsByTagName('parent')[0].firstChild.data; |
||
955 | } |
||
956 | } catch (e) { |
||
957 | } |
||
958 | |||
959 | gxtEl.condition = Data.getElementsByTagName('condition')[0].firstChild.data; |
||
960 | gxtEl.content = Data.getElementsByTagName('content')[0].firstChild.data; |
||
961 | gxtEl.fix = Data.getElementsByTagName('fix')[0].firstChild.data; |
||
962 | // not used gxtEl.digits = Data.getElementsByTagName('cs')[0].firstChild.data; |
||
963 | gxtEl.autodigits = Data.getElementsByTagName('digits')[0].firstChild.data; |
||
964 | gxtEl.parent = gxtReader.changeOriginIds(board, gxtEl.parent); |
||
965 | |||
966 | /* |
||
967 | * Not necessary: is handled by getTextAnchor() in parent element |
||
968 | // TODO: Polygons |
||
969 | // Handle parent elements of texts |
||
970 | if (JXG.exists(gxtEl.parent)) { |
||
971 | if (JXG.isPoint(gxtEl.parent)) { |
||
972 | gxtEl.x = (function (x, y, p) { return function() { return x + p.X(); }; }) |
||
973 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
974 | gxtEl.y = (function (x, y, p) { return function() { return y + p.Y(); }; }) |
||
975 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
976 | } else if (JXG.getReference(board, gxtEl.parent).elementClass == JXG.OBJECT_CLASS_CIRCLE) { |
||
977 | gxtEl.x = (function (x, y, p) { return function() { return x + p.midpoint.X(); }; }) |
||
978 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
979 | gxtEl.y = (function (x, y, p) { return function() { return y + p.midpoint.Y(); }; }) |
||
980 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
981 | } else if (JXG.getReference(board, gxtEl.parent).elementClass == JXG.OBJECT_CLASS_LINE) { |
||
982 | gxtEl.x = (function (x, y, p) { return function() { return x + (p.point1.X()+p.point2.X())*0.5; }; }) |
||
983 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
984 | gxtEl.y = (function (x, y, p) { return function() { return y + (p.point1.Y()+p.point2.Y())*0.5; }; }) |
||
985 | (gxtEl.x, gxtEl.y, JXG.getReference(board, gxtEl.parent)); |
||
986 | } |
||
987 | } |
||
988 | */ |
||
989 | c = board.create('text', [gxtEl.x, gxtEl.y, gxtEl.mpStr], { |
||
990 | anchor: gxtEl.parent, |
||
991 | id: gxtEl.id, |
||
992 | name: gxtEl.name, |
||
993 | digits: gxtEl.autodigits, |
||
994 | isLabel: false, |
||
995 | strokeColor: gxtEl.colorLabel, |
||
996 | visible: JXG.str2Bool(gxtEl.visible) |
||
997 | }); |
||
998 | break; |
||
999 | case 'parametercurve': |
||
1000 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
1001 | gxtEl = gxtReader.visualProperties(gxtEl, Data); |
||
1002 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
1003 | gxtEl = gxtReader.transformProperties(gxtEl); |
||
1004 | gxtEl.functionx = Data.getElementsByTagName('functionx')[0].firstChild.data; |
||
1005 | gxtEl.functiony = Data.getElementsByTagName('functiony')[0].firstChild.data; |
||
1006 | gxtEl.min = Data.getElementsByTagName('min')[0].firstChild.data; |
||
1007 | gxtEl.max = Data.getElementsByTagName('max')[0].firstChild.data; |
||
1008 | |||
1009 | gxtEl.fillColor = 'none'; |
||
1010 | gxtEl.highlightFillColor = 'none'; |
||
1011 | |||
1012 | board.create('curve', |
||
1013 | [ new Function('t', 'return ' + JXG.GeonextParser.geonext2JS(gxtEl.functionx, board) + ';' ), |
||
1014 | new Function('t', 'return ' + JXG.GeonextParser.geonext2JS(gxtEl.functiony, board) + ';' ), |
||
1015 | new Function('return ' + JXG.GeonextParser.geonext2JS(gxtEl.min, board) + ';' ), |
||
1016 | new Function('return ' + JXG.GeonextParser.geonext2JS(gxtEl.max, board) + ';' ) |
||
1017 | ], gxtEl); |
||
1018 | /* |
||
1019 | c = new JXG.Curve(board, [ |
||
1020 | 't',gxtEl.functionx,gxtEl.functiony,gxtEl.min,gxtEl.max |
||
1021 | ], gxtEl.id, gxtEl.name); |
||
1022 | c.setProperty('strokeColor:' + gxtEl.colorStroke, 'strokeWidth:' + gxtEl.strokewidth, 'fillColor:none', |
||
1023 | 'highlightStrokeColor:' + gxtEl.highlightStrokeColor); |
||
1024 | */ |
||
1025 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
1026 | break; |
||
1027 | case 'tracecurve': |
||
1028 | //try { |
||
1029 | gxtEl.tracepoint = Data.getElementsByTagName('tracepoint')[0].firstChild.data; |
||
1030 | gxtEl.traceslider = Data.getElementsByTagName('traceslider')[0].firstChild.data; |
||
1031 | JXG.getRef(board, gxtEl.tracepoint).setProperty({trace:true}); |
||
1032 | //} catch(e) {} |
||
1033 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, '<b>ERR</b>'); |
||
1034 | break; |
||
1035 | case 'group': |
||
1036 | gxtEl = gxtReader.colorProperties(gxtEl, Data); |
||
1037 | gxtEl = gxtReader.firstLevelProperties(gxtEl, Data); |
||
1038 | gxtEl.members = [ |
||
1039 | ]; |
||
1040 | for (i = 0; i < Data.getElementsByTagName('data')[0].getElementsByTagName('member').length; i++) { |
||
1041 | gxtEl.members[i] = Data.getElementsByTagName('data')[0].getElementsByTagName('member')[i].firstChild.data; |
||
1042 | gxtEl.members[i] = gxtReader.changeOriginIds(board, gxtEl.members[i]); |
||
1043 | } |
||
1044 | c = new JXG.Group(board, gxtEl.id, gxtEl.name, gxtEl.members); |
||
1045 | gxtReader.printDebugMessage('debug', gxtEl, Data.nodeName, 'OK'); |
||
1046 | break; |
||
1047 | default: |
||
1048 | JXG.debug("* <b>Err:</b> " + Data.nodeName + " not yet implemented <br>\n"); |
||
1049 | } |
||
1050 | delete(gxtEl); |
||
1051 | })(s); |
||
1052 | } |
||
1053 | board.addConditions(conditions); |
||
1054 | }, |
||
1055 | |||
1056 | decodeString: function(str) { |
||
1057 | var unz; |
||
1058 | if (str.indexOf("<GEONEXT>")<0){ |
||
1059 | unz = (new JXG.Util.Unzip(JXG.Util.Base64.decodeAsArray(str))).unzip(); // war Gunzip ME |
||
1060 | if (unz=="") |
||
1061 | return str; |
||
1062 | else |
||
1063 | return unz; |
||
1064 | } else { |
||
1065 | return str; |
||
1066 | } |
||
1067 | }, |
||
1068 | |||
1069 | prepareString: function(fileStr){ |
||
1070 | try { |
||
1071 | if (fileStr.indexOf('GEONEXT')<0) { |
||
1072 | fileStr = (this.decodeString(fileStr))[0][0]; // Base64 decoding |
||
1073 | } |
||
1074 | // Hacks to enable not well formed XML. Will be redone in Algebra.geonext2JS and Board.addConditions |
||
1075 | fileStr = this.fixXML(fileStr); |
||
1076 | } catch(e) { |
||
1077 | fileStr = ''; |
||
1078 | } |
||
1079 | return fileStr; |
||
1080 | }, |
||
1081 | |||
1082 | fixXML: function(str) { |
||
1083 | var arr = ["active", "angle", "animate", "animated", "arc", "area", "arrow", "author", "autodigits", "axis", "back", "background", "board", "border", "bottom", "buttonsize", "cas", "circle", "color", "comment", "composition", "condition", "conditions", "content", "continuous", "control", "coord", "coordinates", "cross", "cs", "dash", "data", "description", "digits", "direction", "draft", "editable", "elements", "event", "file", "fill", "first", "firstarrow", "fix", "fontsize", "free", "full", "function", "functionx", "functiony", "GEONEXT", "graph", "grid", "group", "height", "id", "image", "info", "information", "input", "intersection", "item", "jsf", "label", "last", "lastarrow", "left", "lefttoolbar", "lighting", "line", "loop", "max", "maximized", "member", "middle", "midpoint", "min", "modifier", "modus", "mp", "mpx", "multi", "name", "onpolygon", "order", "origin", "output", "overline", "parametercurve", "parent", "point", "pointsnap", "polygon", "position", "radius", "radiusnum", "radiusvalue", "right", "section", "selectedlefttoolbar", "showconstruction", "showcoord", "showinfo", "showunit", "showx", "showy", "size", "slider", "snap", "speed", "src", "start", "stop", "straight", "stroke", "strokewidth", "style", "term", "text", "top", "trace", "tracecurve", "tracepoint", "traceslider", "type", "unit", "value", "VERSION", "vertex", "viewport", "visible", "width", "wot", "x", "xooy", "xval", "y", "yval", "zoom"], |
||
1084 | list = arr.join('|'), |
||
1085 | regex = '\<(/?('+list+'))\>', |
||
1086 | expr = new RegExp(regex,'g'); |
||
1087 | |||
1088 | // First, we convert all < to < and > to > |
||
1089 | str = JXG.escapeHTML(str); |
||
1090 | // Second, we convert all GEONExT tags of the form <tag> back to <tag> |
||
1091 | str = str.replace(expr,'<$1>'); |
||
1092 | |||
1093 | str = str.replace(/(<content>.*)<arc>(.*<\/content>)/g,'$1<arc>$2'); |
||
1094 | str = str.replace(/(<mp>.*)<arc>(.*<\/mpx>)/g,'$1<arc>$2'); |
||
1095 | str = str.replace(/(<mpx>.*)<arc>(.*<\/mpx>)/g,'$1<arc>$2'); |
||
1096 | return str; |
||
1097 | } |
||
1098 | |||
1099 | }; // end: GeonextReader |