jsxgraph 1.14.0 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -3
- package/distrib/docs/3d_linspace3d.js.html +16 -10
- package/distrib/docs/3d_point3d.js.html +0 -5
- package/distrib/docs/3d_sphere3d.js.html +92 -69
- package/distrib/docs/3d_view3d.js.html +24 -16
- package/distrib/docs/Angle.html +7 -7
- package/distrib/docs/CircumcircleSector.html +2 -2
- package/distrib/docs/Conic.html +1 -1
- package/distrib/docs/Ellipse.html +23 -1
- package/distrib/docs/Hyperbola.html +24 -1
- package/distrib/docs/JXG.Board.infobox.html +1 -1
- package/distrib/docs/JXG.Board_.html +130 -130
- package/distrib/docs/JXG.CanvasRenderer.html +10 -10
- package/distrib/docs/JXG.Composition.html +3 -3
- package/distrib/docs/JXG.GeometryElement.html +26 -26
- package/distrib/docs/JXG.Math.Numerics.html +45 -47
- package/distrib/docs/JXG.Math.Statistics.html +14 -15
- package/distrib/docs/JXG.Math.Tiling.html +3 -7
- package/distrib/docs/JXG.Math.html +101 -83
- package/distrib/docs/JXG.Point3D.html +2 -2
- package/distrib/docs/JXG.SVGRenderer.html +12 -12
- package/distrib/docs/JXG.Sphere3D.html +1255 -2
- package/distrib/docs/JXG.View3D.html +29 -29
- package/distrib/docs/JXG.html +20 -20
- package/distrib/docs/MajorSector.html +1 -1
- package/distrib/docs/MinorSector.html +1 -1
- package/distrib/docs/NonReflexAngle.html +1 -1
- package/distrib/docs/Parabola.html +1 -1
- package/distrib/docs/Point3D.html +1 -1
- package/distrib/docs/ReflexAngle.html +1 -1
- package/distrib/docs/Sector.html +12 -12
- package/distrib/docs/Sphere3D.html +17 -1
- package/distrib/docs/View3D.html +1 -1
- package/distrib/docs/base_board.js.html +63 -13
- package/distrib/docs/base_composition.js.html +3 -3
- package/distrib/docs/base_constants.js.html +1 -1
- package/distrib/docs/base_element.js.html +2 -1
- package/distrib/docs/base_text.js.html +2 -2
- package/distrib/docs/element_conic.js.html +35 -1
- package/distrib/docs/element_sector.js.html +6 -3
- package/distrib/docs/index.html +1 -1
- package/distrib/docs/math_math.js.html +64 -35
- package/distrib/docs/math_numerics.js.html +13 -12
- package/distrib/docs/math_statistics.js.html +19 -19
- package/distrib/docs/math_tiling.js.html +6 -288
- package/distrib/docs/parser_jessiecode.js.html +1 -1
- package/distrib/docs/renderer_canvas.js.html +7 -6
- package/distrib/docs/renderer_svg.js.html +15 -7
- package/distrib/docs/scripts/jsxgraphcore.js +2 -2
- package/distrib/docs/styles/jsxgraph.css +1 -1
- package/distrib/docs/utils_type.js.html +11 -4
- package/distrib/geogebra.min.js +1 -1
- package/distrib/geonext.min.js +1 -1
- package/distrib/index.d.ts +11 -0
- package/distrib/intergeo.min.js +1 -1
- package/distrib/jsxgraph.css +1 -1
- package/distrib/jsxgraphcore.js +2 -2
- package/distrib/jsxgraphcore.mjs +2 -2
- package/distrib/jsxgraphcore.mjs.map +1 -1
- package/distrib/jsxgraphsrc.js +380 -496
- package/distrib/jsxgraphsrc.mjs +380 -496
- package/distrib/jsxgraphsrc.mjs.map +1 -1
- package/package.json +10 -12
- package/src/3d/linspace3d.js +16 -10
- package/src/3d/point3d.js +0 -5
- package/src/3d/sphere3d.js +92 -69
- package/src/3d/view3d.js +24 -16
- package/src/base/board.js +63 -13
- package/src/base/composition.js +3 -3
- package/src/base/constants.js +1 -1
- package/src/base/element.js +2 -1
- package/src/base/text.js +2 -2
- package/src/element/conic.js +35 -1
- package/src/element/sector.js +6 -3
- package/src/index.d.ts +11 -0
- package/src/math/math.js +64 -35
- package/src/math/numerics.js +13 -12
- package/src/math/statistics.js +19 -19
- package/src/math/tiling.js +6 -288
- package/src/parser/jessiecode.js +1 -1
- package/src/renderer/canvas.js +7 -6
- package/src/renderer/svg.js +15 -7
- package/src/utils/type.js +11 -4
- package/src/unused/bst.js +0 -475
- package/src/unused/heap.js +0 -135
- package/src/unused/locus.js +0 -162
- package/src/unused/server/JXG.py +0 -74
- package/src/unused/server/JXGServer.py +0 -94
- package/src/unused/server/JXGServerModule.py +0 -9
- package/src/unused/server/README.md +0 -63
- package/src/unused/server/RStats.py +0 -45
- package/src/unused/server/YahooFinance.py +0 -81
- package/src/unused/server/fft.py +0 -136
- package/src/unused/server/geoloci.py +0 -210
- package/src/unused/server/jxggroebner.py +0 -219
- package/src/unused/server/jxgtestplugin.py +0 -19
- package/src/unused/server/server.js +0 -280
- package/src/unused/sketch.js +0 -2895
- package/src/unused/symbolic.js +0 -416
package/src/unused/locus.js
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2008-2026
|
|
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 <https://www.gnu.org/licenses/>
|
|
29
|
-
and <https://opensource.org/licenses/MIT/>.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/*global JXG: true, define: true*/
|
|
33
|
-
/*jslint nomen: true, plusplus: true*/
|
|
34
|
-
|
|
35
|
-
import JXG from "../jxg.js";
|
|
36
|
-
import Symbolic from "../math/symbolic.js";
|
|
37
|
-
import Type from "../utils/type.js";
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @class The locus element is used to visualize the curve a given constraint point describes.
|
|
41
|
-
* @pseudo
|
|
42
|
-
* @constructor
|
|
43
|
-
* @name Locus
|
|
44
|
-
* @type JXG.Curve
|
|
45
|
-
* @augments JXG.Curve
|
|
46
|
-
* @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
|
|
47
|
-
* @param {Point} p The constructed curve is the geometric locus of the given point.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* // This examples needs JXG.Server up and running, otherwise it won't work.
|
|
51
|
-
* p1 = board.create('point', [0, 0]);
|
|
52
|
-
* p2 = board.create('point', [6, -1]);
|
|
53
|
-
* c1 = board.create('circle', [p1, 2]);
|
|
54
|
-
* c2 = board.create('circle', [p2, 1.5]);
|
|
55
|
-
* g1 = board.create('glider', [6, 3, c1]);
|
|
56
|
-
* c3 = board.create('circle', [g1, 4]);
|
|
57
|
-
* g2 = board.create('intersection', [c2,c3,0]);
|
|
58
|
-
* m1 = board.create('midpoint', [g1,g2]);
|
|
59
|
-
* loc = board.create('locus', [m1], {strokeColor: 'red'});
|
|
60
|
-
* </pre><div class="jxgbox" id="JXGd45d7188-6624-4d6e-bebb-1efa2a305c8a" style="width: 400px; height: 400px;"></div>
|
|
61
|
-
* <script type="text/javascript">
|
|
62
|
-
* (function() {
|
|
63
|
-
* board = JXG.JSXGraph.initBoard('JXGd45d7188-6624-4d6e-bebb-1efa2a305c8a', {boundingbox:[-4, 6, 10, -6], axis: true, grid: false, keepaspectratio: true});
|
|
64
|
-
* p1 = board.create('point', [0, 0]);
|
|
65
|
-
* p2 = board.create('point', [6, -1]);
|
|
66
|
-
* c1 = board.create('circle', [p1, 2]);
|
|
67
|
-
* c2 = board.create('circle', [p2, 1.5]);
|
|
68
|
-
* g1 = board.create('glider', [6, 3, c1]);
|
|
69
|
-
* c3 = board.create('circle', [g1, 4]);
|
|
70
|
-
* g2 = board.create('intersection', [c2,c3,0]);
|
|
71
|
-
* m1 = board.create('midpoint', [g1,g2]);
|
|
72
|
-
* loc = board.create('locus', [m1], {strokeColor: 'red'});
|
|
73
|
-
* })();
|
|
74
|
-
* </script><pre>
|
|
75
|
-
*/
|
|
76
|
-
JXG.createLocus = function (board, parents, attributes) {
|
|
77
|
-
var c, p;
|
|
78
|
-
|
|
79
|
-
if (Type.isArray(parents) && parents.length === 1 && Type.isPoint(parents[0])) {
|
|
80
|
-
p = parents[0];
|
|
81
|
-
} else {
|
|
82
|
-
throw new Error(
|
|
83
|
-
"JSXGraph: Can't create locus with parent of type other than point." +
|
|
84
|
-
"\nPossible parent types: [point]"
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
c = board.create("curve", [[null], [null]], attributes);
|
|
89
|
-
c.dontCallServer = false;
|
|
90
|
-
|
|
91
|
-
c.elType = 'locus'
|
|
92
|
-
c.setParents([p.id]);
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Should be documented in JXG.Curve
|
|
96
|
-
* @ignore
|
|
97
|
-
*/
|
|
98
|
-
c.updateDataArray = function () {
|
|
99
|
-
var spe, cb, data;
|
|
100
|
-
|
|
101
|
-
if (c.board.mode > 0) {
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
spe = Symbolic.generatePolynomials(board, p, true).join("|");
|
|
106
|
-
if (spe === c.spe) {
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
c.spe = spe;
|
|
111
|
-
|
|
112
|
-
cb = function (x, y, eq, t) {
|
|
113
|
-
c.dataX = x;
|
|
114
|
-
c.dataY = y;
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* The implicit definition of the locus.
|
|
118
|
-
* @memberOf Locus.prototype
|
|
119
|
-
* @name eq
|
|
120
|
-
* @type String
|
|
121
|
-
*/
|
|
122
|
-
c.eq = eq;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* The time it took to calculate the locus
|
|
126
|
-
* @memberOf Locus.prototype
|
|
127
|
-
* @name ctime
|
|
128
|
-
* @type Number
|
|
129
|
-
*/
|
|
130
|
-
c.ctime = t;
|
|
131
|
-
|
|
132
|
-
// convert equation and use it to build a generatePolynomial-method
|
|
133
|
-
c.generatePolynomial = (function (equations) {
|
|
134
|
-
return function (point) {
|
|
135
|
-
var i,
|
|
136
|
-
x = "(" + point.symbolic.x + ")",
|
|
137
|
-
y = "(" + point.symbolic.y + ")",
|
|
138
|
-
res = [];
|
|
139
|
-
|
|
140
|
-
for (i = 0; i < equations.length; i++) {
|
|
141
|
-
res[i] = equations[i]
|
|
142
|
-
.replace(/\*\*/g, "^")
|
|
143
|
-
.replace(/x/g, x)
|
|
144
|
-
.replace(/y/g, y);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return res;
|
|
148
|
-
};
|
|
149
|
-
})(eq);
|
|
150
|
-
};
|
|
151
|
-
data = Symbolic.geometricLocusByGroebnerBase(board, p, cb);
|
|
152
|
-
|
|
153
|
-
cb(data.datax, data.datay, data.polynomial, data.exectime);
|
|
154
|
-
};
|
|
155
|
-
return c;
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
JXG.registerElement("locus", JXG.createLocus);
|
|
159
|
-
|
|
160
|
-
// export default {
|
|
161
|
-
// createLocus: JXG.createLocus
|
|
162
|
-
// };
|
package/src/unused/server/JXG.py
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
import inspect
|
|
3
|
-
|
|
4
|
-
class Request(object):
|
|
5
|
-
|
|
6
|
-
def __init__(self, action, id, data):
|
|
7
|
-
self._action = action
|
|
8
|
-
self._id = id
|
|
9
|
-
self._data = data
|
|
10
|
-
|
|
11
|
-
def getValue(self, item, default = 'empty'):
|
|
12
|
-
if item == 'action':
|
|
13
|
-
return self._action
|
|
14
|
-
elif item == 'id':
|
|
15
|
-
return self._id
|
|
16
|
-
else:
|
|
17
|
-
return json.loads(self._data)[item]
|
|
18
|
-
|
|
19
|
-
def getList(self, item):
|
|
20
|
-
return self._data.getlist(item)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Response(object):
|
|
24
|
-
|
|
25
|
-
def __init__(self, _id):
|
|
26
|
-
self._id = _id
|
|
27
|
-
self._type = 'response'
|
|
28
|
-
self._data = {}
|
|
29
|
-
self._fields = []
|
|
30
|
-
self._handler = []
|
|
31
|
-
|
|
32
|
-
def error(self, msg):
|
|
33
|
-
self._type = 'error'
|
|
34
|
-
self._message = msg
|
|
35
|
-
|
|
36
|
-
def dump(self):
|
|
37
|
-
if self._type == 'error':
|
|
38
|
-
# drop all the data and methods, just output the error
|
|
39
|
-
return json.dumps({ \
|
|
40
|
-
'type' : 'error', \
|
|
41
|
-
'id' : self._id, \
|
|
42
|
-
'message' : self._message \
|
|
43
|
-
})
|
|
44
|
-
else:
|
|
45
|
-
return json.dumps({ \
|
|
46
|
-
'type' : 'response', \
|
|
47
|
-
'id' : self._id, \
|
|
48
|
-
'fields' : self._fields, \
|
|
49
|
-
'handler' : self._handler, \
|
|
50
|
-
'data' : self._data \
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
def addField(self, namespace, name, value):
|
|
54
|
-
self._fields.append({ \
|
|
55
|
-
'namespace' : namespace, \
|
|
56
|
-
'name' : name, \
|
|
57
|
-
'value' : value \
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
def addData(self, name, value):
|
|
61
|
-
self._data[name] = value
|
|
62
|
-
|
|
63
|
-
def addHandler(self, function, callback):
|
|
64
|
-
params = [];
|
|
65
|
-
args = inspect.getargspec(function);
|
|
66
|
-
for i in range(0, len(args.args)):
|
|
67
|
-
if (args.args[i] != 'resp') and (args.args[i] != 'self'):
|
|
68
|
-
params.append(args.args[i])
|
|
69
|
-
|
|
70
|
-
self._handler.append({ \
|
|
71
|
-
'name' : function.__name__,\
|
|
72
|
-
'callback' : callback, \
|
|
73
|
-
'parameters' : params \
|
|
74
|
-
})
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python
|
|
2
|
-
|
|
3
|
-
# ZIP compression
|
|
4
|
-
import zlib
|
|
5
|
-
# Base64 en-/decoding
|
|
6
|
-
import base64
|
|
7
|
-
# CGI variables handling
|
|
8
|
-
import cgi
|
|
9
|
-
|
|
10
|
-
import JXG
|
|
11
|
-
import inspect
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# Base plugin
|
|
15
|
-
from JXGServerModule import JXGServerModule
|
|
16
|
-
|
|
17
|
-
def print_httpheader():
|
|
18
|
-
print("""\
|
|
19
|
-
Content-Type: text/plain\n
|
|
20
|
-
""")
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
def default_action(req, resp):
|
|
24
|
-
action = req.getvalue('action', 'empty')
|
|
25
|
-
resp.error("action \"" + action + "\" is undefined")
|
|
26
|
-
return resp.dump()
|
|
27
|
-
|
|
28
|
-
def import_module(plugin, resp):
|
|
29
|
-
try:
|
|
30
|
-
__import__(plugin, None, None, [''])
|
|
31
|
-
|
|
32
|
-
tp = JXGServerModule.__subclasses__()
|
|
33
|
-
if len(tp) == 0:
|
|
34
|
-
resp.error("error loading module \"" + plugin + "\"")
|
|
35
|
-
return tp
|
|
36
|
-
tp = tp[0]()
|
|
37
|
-
|
|
38
|
-
if not tp.isJXGServerModule:
|
|
39
|
-
resp.error("not a jxg server module: \"" + plugin + "\"")
|
|
40
|
-
return tp
|
|
41
|
-
except Exception as e:
|
|
42
|
-
resp.error("error loading jxg server module: \"" + plugin + "\": " + e.__str__())
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
return tp
|
|
46
|
-
|
|
47
|
-
def load_module(req, resp):
|
|
48
|
-
plugin = req.getValue("module", 'none')
|
|
49
|
-
tp = import_module(plugin, resp)
|
|
50
|
-
|
|
51
|
-
if resp._type != 'error':
|
|
52
|
-
tp.init(resp)
|
|
53
|
-
return resp.dump()
|
|
54
|
-
|
|
55
|
-
def exec_module(req, resp):
|
|
56
|
-
handler = req.getValue('handler', 'none')
|
|
57
|
-
module = req.getValue('module', 'none')
|
|
58
|
-
|
|
59
|
-
m = import_module(module, resp)
|
|
60
|
-
if resp._type == 'error':
|
|
61
|
-
return resp.dump()
|
|
62
|
-
|
|
63
|
-
method = getattr(m, handler)
|
|
64
|
-
params = ()
|
|
65
|
-
args = inspect.getargspec(method)
|
|
66
|
-
for i in range(0, len(args.args)):
|
|
67
|
-
if args.args[i] == 'self':
|
|
68
|
-
pass
|
|
69
|
-
elif args.args[i] == 'resp':
|
|
70
|
-
params += (resp, )
|
|
71
|
-
else:
|
|
72
|
-
params += (req.getValue(args.args[i]), )
|
|
73
|
-
|
|
74
|
-
method(*params)
|
|
75
|
-
|
|
76
|
-
return resp.dump()
|
|
77
|
-
|
|
78
|
-
# Get Data from post/get parameters
|
|
79
|
-
form = cgi.FieldStorage();
|
|
80
|
-
|
|
81
|
-
action = form.getfirst('action', 'empty')
|
|
82
|
-
id = form.getfirst('id', 'none')
|
|
83
|
-
data = base64.b64decode(form.getfirst('dataJSON', ''))
|
|
84
|
-
|
|
85
|
-
actions_map = { \
|
|
86
|
-
'load': load_module, \
|
|
87
|
-
'exec': exec_module \
|
|
88
|
-
}
|
|
89
|
-
ret = actions_map.get(action, default_action)(JXG.Request(action, id, data), JXG.Response(id))
|
|
90
|
-
|
|
91
|
-
print_httpheader()
|
|
92
|
-
|
|
93
|
-
print(base64.b64encode(zlib.compress(ret, 9)))
|
|
94
|
-
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# JSXGraph server scripts
|
|
2
|
-
|
|
3
|
-
__Update 18.10.2024__
|
|
4
|
-
|
|
5
|
-
Since v1.10.1 this module is retired !
|
|
6
|
-
|
|
7
|
-
The server module needs a complete rewrite. The installation is error prone,
|
|
8
|
-
since python 3.13 the module `cgi` is not longer supported.
|
|
9
|
-
A modern implementation would use a different approach with nodejs or
|
|
10
|
-
a comparable system for python.
|
|
11
|
-
|
|
12
|
-
## Description
|
|
13
|
-
|
|
14
|
-
JSXGraph is a cross-browser library for interactive geometry, function plotting,
|
|
15
|
-
graphs, and data visualization in a web browser. It is implemented completely in
|
|
16
|
-
JavaScript and uses SVG and VML.
|
|
17
|
-
Using the JSXGraph server scripts it is possible to do computations with software
|
|
18
|
-
not running in a browser and use the results in JSXGraph, e.g. it is possible to
|
|
19
|
-
compute the polynomial equation of the geometric locus of a point in a construction,
|
|
20
|
-
use matplotlib to extract the points of the graph and return a list of points and
|
|
21
|
-
plot that points in JSXGraph.
|
|
22
|
-
|
|
23
|
-
Scripts available:
|
|
24
|
-
|
|
25
|
-
- `jxggroebner.py`
|
|
26
|
-
|
|
27
|
-
## General configuration
|
|
28
|
-
|
|
29
|
-
By default server scripts are stored in the subdirectory `server` of the JavaScript
|
|
30
|
-
files. If you want the scripts in another place you'll have to adjust
|
|
31
|
-
`JXG.serverBase`
|
|
32
|
-
either directly in JSX source (loadjsxgraph[InOneFile].js) or by setting it with
|
|
33
|
-
javascript in your page after loading JSXGraph.
|
|
34
|
-
|
|
35
|
-
## jxggroebner.py
|
|
36
|
-
|
|
37
|
-
- __Required software__
|
|
38
|
-
|
|
39
|
-
- CoCoA (https://cocoa.dima.unige.it/)
|
|
40
|
-
- Python (https://python.org/)
|
|
41
|
-
- numpy (https://numpy.scipy.org/)
|
|
42
|
-
- matplotlib (https://matplotlib.sourceforge.net/)
|
|
43
|
-
|
|
44
|
-
- __Setup__
|
|
45
|
-
|
|
46
|
-
Install CoCoA so it can be started by just typing cocoa in a terminal or adjust
|
|
47
|
-
the configuration in `jsxgroebner.py`. Install all of the python packages.
|
|
48
|
-
|
|
49
|
-
Your webserver has to be configured to execute python .py scripts as cgi, e.g.
|
|
50
|
-
for Apache you have to configure
|
|
51
|
-
|
|
52
|
-
Options +ExecCGI
|
|
53
|
-
AddHandler cgi-script .py
|
|
54
|
-
|
|
55
|
-
for the directory JSXGraph server scripts are in.
|
|
56
|
-
|
|
57
|
-
It is highly recommended to adjust the `os.environ['MPLCONFIGDIR']` variable in
|
|
58
|
-
the script or setting the variable `$MPLCONFIGDIR` for the webserver environment
|
|
59
|
-
to somewhere more persistent than '/tmp' and writable by the webserver. If you
|
|
60
|
-
don't do this, the matplotlib configuration will be erased at times (e.g. the
|
|
61
|
-
server gets rebooted) and every first plot after matplotlib config erasure
|
|
62
|
-
takes much more time because of matplotlib generating a new default config in
|
|
63
|
-
that place.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
from JXGServerModule import JXGServerModule
|
|
2
|
-
from rpy import r
|
|
3
|
-
import JXG
|
|
4
|
-
import io, gzip
|
|
5
|
-
import datetime, math, random
|
|
6
|
-
|
|
7
|
-
class RStats(JXGServerModule):
|
|
8
|
-
|
|
9
|
-
def __init__(self):
|
|
10
|
-
JXGServerModule.__init__(self)
|
|
11
|
-
|
|
12
|
-
def init(self, resp):
|
|
13
|
-
resp.addHandler(self.mean, 'function(data) { }')
|
|
14
|
-
resp.addHandler(self.sd, 'function(data) { }')
|
|
15
|
-
resp.addHandler(self.median, 'function(data) { }')
|
|
16
|
-
resp.addHandler(self.mad, 'function(data) { }')
|
|
17
|
-
resp.addHandler(self.all, 'function(data) { }')
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
def mean(self, resp, x):
|
|
21
|
-
y = r.mean(x);
|
|
22
|
-
resp.addData('mean', y)
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
def sd(self, resp, x):
|
|
26
|
-
y = r.sd(x);
|
|
27
|
-
resp.addData('sd', y)
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
def median(self, resp, x):
|
|
31
|
-
y = r.median(x);
|
|
32
|
-
resp.addData('median', y)
|
|
33
|
-
return
|
|
34
|
-
|
|
35
|
-
def mad(self, resp, x):
|
|
36
|
-
y = r.mad(x);
|
|
37
|
-
resp.addData('mad', y)
|
|
38
|
-
return
|
|
39
|
-
|
|
40
|
-
def all(self, resp, x):
|
|
41
|
-
self.mean(resp, x)
|
|
42
|
-
self.sd(resp, x)
|
|
43
|
-
self.median(resp, x)
|
|
44
|
-
self.mad(resp, x)
|
|
45
|
-
return
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
from JXGServerModule import JXGServerModule
|
|
2
|
-
import JXG
|
|
3
|
-
import urllib.request, urllib.error, urllib.parse, http.client, io, gzip
|
|
4
|
-
import datetime, math, random
|
|
5
|
-
|
|
6
|
-
class YahooFinance(JXGServerModule):
|
|
7
|
-
|
|
8
|
-
def __init__(self):
|
|
9
|
-
self.djmin = 9641.01
|
|
10
|
-
self.djmax = 9735.93
|
|
11
|
-
self.daxmin = 5559.47
|
|
12
|
-
self.daxmax = 5620.13
|
|
13
|
-
JXGServerModule.__init__(self)
|
|
14
|
-
|
|
15
|
-
def init(self, resp):
|
|
16
|
-
resp.addHandler(self.getCurrentSharePrice, 'function(data) { alert(data.price); }')
|
|
17
|
-
resp.addHandler(self.getMinMax, 'function(data) { }')
|
|
18
|
-
resp.addHandler(self.getFakeCurrentSharePrice, 'function(data) { alert(data.price); }')
|
|
19
|
-
resp.addHandler(self.getFakeMinMax, 'function(data) { }')
|
|
20
|
-
return
|
|
21
|
-
|
|
22
|
-
def _getData(self, share):
|
|
23
|
-
#httplib.HTTPConnection.debuglevel = 1
|
|
24
|
-
# todo: adjust the s parameter to input the share given with parameter share
|
|
25
|
-
request = urllib.request.Request('http://finance.yahoo.com/d/quotes.csv?s=' + share.lower() + '&f=sl1d1t1c1ohgv&e=.csv')
|
|
26
|
-
# accept compressed data
|
|
27
|
-
request.add_header('Accept-encoding', 'gzip')
|
|
28
|
-
opener = urllib.request.build_opener()
|
|
29
|
-
f = opener.open(request)
|
|
30
|
-
|
|
31
|
-
compresseddata = f.read()
|
|
32
|
-
compressedstream = io.StringIO(compresseddata)
|
|
33
|
-
gzipper = gzip.GzipFile(fileobj=compressedstream)
|
|
34
|
-
try:
|
|
35
|
-
data = gzipper.read()
|
|
36
|
-
# if data is gzip compressed no exception is thrown
|
|
37
|
-
except:
|
|
38
|
-
# data is not compressed, read original response from server
|
|
39
|
-
data = compresseddata
|
|
40
|
-
return data
|
|
41
|
-
|
|
42
|
-
def getCurrentSharePrice(self, resp, share):
|
|
43
|
-
data = self._getData(share)
|
|
44
|
-
datalist = data.split(',')
|
|
45
|
-
|
|
46
|
-
resp.addData('price', datalist[1])
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
def getMinMax(self, resp, share):
|
|
50
|
-
data = self._getData(share)
|
|
51
|
-
datalist = data.split(',')
|
|
52
|
-
|
|
53
|
-
resp.addData('max', datalist[6])
|
|
54
|
-
resp.addData('min', datalist[7])
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
def getFakeCurrentSharePrice(self, resp, share):
|
|
58
|
-
if share=='^DJI':
|
|
59
|
-
smax = self.djmax
|
|
60
|
-
smin = self.djmin
|
|
61
|
-
else:
|
|
62
|
-
smax = self.daxmax
|
|
63
|
-
smin = self.daxmin
|
|
64
|
-
|
|
65
|
-
diff = smax - smin
|
|
66
|
-
base = smin + diff/2. * (1. + math.sin(datetime.datetime.now().second * 2*math.pi))
|
|
67
|
-
price = base + random.uniform(-diff/60., diff/60.)
|
|
68
|
-
resp.addData('price', price)
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
def getFakeMinMax(self, resp, share):
|
|
72
|
-
if share=='^DJI':
|
|
73
|
-
smax = self.djmax
|
|
74
|
-
smin = self.djmin
|
|
75
|
-
else:
|
|
76
|
-
smax = self.daxmax
|
|
77
|
-
smin = self.daxmin
|
|
78
|
-
|
|
79
|
-
resp.addData('max', smax)
|
|
80
|
-
resp.addData('min', smin)
|
|
81
|
-
return
|
package/src/unused/server/fft.py
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
from JXGServerModule import JXGServerModule
|
|
2
|
-
import numpy
|
|
3
|
-
import numpy.fft
|
|
4
|
-
import wave, struct, uuid
|
|
5
|
-
import os, subprocess
|
|
6
|
-
import io, gzip, base64
|
|
7
|
-
import datetime, math, random
|
|
8
|
-
|
|
9
|
-
# Should be changed to something more persistent but must be writable by
|
|
10
|
-
# the webserver (usually user www-data)
|
|
11
|
-
#if not 'MPLCONFIGDIR' in os.environ:
|
|
12
|
-
# os.environ['MPLCONFIGDIR'] = '/tmp/'
|
|
13
|
-
# os.environ['MPLCONFIGDIR'] = 'C:/xampp/tmp'
|
|
14
|
-
|
|
15
|
-
#import matplotlib
|
|
16
|
-
#import matplotlib.pyplot as plt
|
|
17
|
-
|
|
18
|
-
class FFT(JXGServerModule):
|
|
19
|
-
|
|
20
|
-
def __init__(self):
|
|
21
|
-
JXGServerModule.__init__(self)
|
|
22
|
-
|
|
23
|
-
def init(self, resp):
|
|
24
|
-
resp.addHandler(self.fft, 'function(data) { }')
|
|
25
|
-
resp.addHandler(self.ifft, 'function(data) { }')
|
|
26
|
-
resp.addHandler(self.cutoutrange, 'function(data) { }')
|
|
27
|
-
resp.addHandler(self.makeAudio, 'function(data) { }')
|
|
28
|
-
resp.addHandler(self.loadAudio, 'function(data) { }')
|
|
29
|
-
resp.addHandler(self.sampleifft, 'function(data) { }')
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
def fft(self, resp, x):
|
|
33
|
-
y = numpy.fft.rfft(x)
|
|
34
|
-
y = list(map(abs, y));
|
|
35
|
-
resp.addData('y', y)
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
def _real(self, val):
|
|
39
|
-
return val.real
|
|
40
|
-
|
|
41
|
-
def ifft(self, resp, x):
|
|
42
|
-
y = numpy.fft.irfft(x)
|
|
43
|
-
y = list(map(self._real, y));
|
|
44
|
-
resp.addData('y', y)
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
def _set0(val):
|
|
48
|
-
return 0
|
|
49
|
-
|
|
50
|
-
def sampleifft(self, resp, name, s, e, factor):
|
|
51
|
-
# read wav
|
|
52
|
-
pathtowavefiles = '/share8/home/michael/www-store/audio/'
|
|
53
|
-
fname = pathtowavefiles + os.path.basename(name) + '.wav'
|
|
54
|
-
w = wave.open(fname, 'r')
|
|
55
|
-
(nchannels, sampwidth, framerate, nframes, comptype, compname) = w.getparams()
|
|
56
|
-
frames = w.readframes(nframes*nchannels)
|
|
57
|
-
out = [value/8192. for value in struct.unpack_from("%dh" % nframes * nchannels, frames)]
|
|
58
|
-
w.close()
|
|
59
|
-
# apply fft
|
|
60
|
-
x = numpy.fft.rfft(out)
|
|
61
|
-
# filters
|
|
62
|
-
l = len(x)
|
|
63
|
-
for i in range(0, s):
|
|
64
|
-
x[i] = x[i] * factor
|
|
65
|
-
for i in range(e, l):
|
|
66
|
-
x[i] = x[i] * factor
|
|
67
|
-
#ifft
|
|
68
|
-
y = numpy.fft.irfft(x)
|
|
69
|
-
y = list(map(self._real, y));
|
|
70
|
-
resp.addData('y', y)
|
|
71
|
-
self.makeAudio(resp, 'ogg', framerate, y)
|
|
72
|
-
return
|
|
73
|
-
|
|
74
|
-
# s: 0 < Start < len(x)/2
|
|
75
|
-
# e: 0 < End < len(x)/2
|
|
76
|
-
def cutoutrange(self, resp, x, s, e, factor):
|
|
77
|
-
l = len(x)
|
|
78
|
-
for i in range(0, s):
|
|
79
|
-
x[i] = x[i] * factor
|
|
80
|
-
for i in range(e, l):
|
|
81
|
-
x[i] = x[i] * factor
|
|
82
|
-
resp.addData('y', x)
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
def loadAudio(self, resp, type, name):
|
|
86
|
-
pathtowavefiles = '/share8/home/michael/www-store/audio/'
|
|
87
|
-
fname = pathtowavefiles + os.path.basename(name) + '.wav'
|
|
88
|
-
fogg = pathtowavefiles + os.path.basename(name) + '.ogg'
|
|
89
|
-
# read ogg
|
|
90
|
-
f = open(fogg, 'r')
|
|
91
|
-
audio = f.read()
|
|
92
|
-
audio = "data:audio/ogg;base64," + base64.b64encode(audio)
|
|
93
|
-
resp.addData('audioB64', audio)
|
|
94
|
-
# read wav
|
|
95
|
-
w = wave.open(fname, 'r')
|
|
96
|
-
(nchannels, sampwidth, framerate, nframes, comptype, compname) = w.getparams()
|
|
97
|
-
frames = w.readframes(nframes*nchannels)
|
|
98
|
-
out = [value/8192. for value in struct.unpack_from("%dh" % nframes * nchannels, frames)]
|
|
99
|
-
w.close()
|
|
100
|
-
step = math.floor(len(out)/7500);
|
|
101
|
-
#resp.addData('audioData', [out[i] for i in range(len(out)) if i % step == 0]);
|
|
102
|
-
resp.addData('audioData', out);
|
|
103
|
-
resp.addData('seconds', (nframes*1.0)/framerate)
|
|
104
|
-
resp.addData('samplerate', framerate)
|
|
105
|
-
return
|
|
106
|
-
|
|
107
|
-
def makeAudio(self, resp, type, samplerate, data):
|
|
108
|
-
fname = '/tmp/'+str(uuid.uuid4())
|
|
109
|
-
fogg = fname + '.ogg'
|
|
110
|
-
# Validate that the generated paths are confined to the expected
|
|
111
|
-
# temp directory before they are passed to the external oggenc
|
|
112
|
-
# binary, guarding against path/argument manipulation.
|
|
113
|
-
tmp_dir = os.path.abspath('/tmp') + os.sep
|
|
114
|
-
if not os.path.abspath(fname).startswith(tmp_dir) or not os.path.abspath(fogg).startswith(tmp_dir):
|
|
115
|
-
raise ValueError('Invalid audio file path')
|
|
116
|
-
w = wave.open(fname, 'w')
|
|
117
|
-
w.setnchannels(1)
|
|
118
|
-
w.setsampwidth(2)
|
|
119
|
-
w.setframerate(samplerate)
|
|
120
|
-
w.setnframes(len(data))
|
|
121
|
-
for s in data:
|
|
122
|
-
if s < -4:
|
|
123
|
-
s = -4
|
|
124
|
-
if s > 4:
|
|
125
|
-
s = 4
|
|
126
|
-
w.writeframes(struct.pack('h', int(s*4000)))
|
|
127
|
-
w.close()
|
|
128
|
-
ogg_process = subprocess.Popen(["oggenc", fname, "-Q", "-o", fogg], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
|
|
129
|
-
output = ogg_process.communicate('')[0]
|
|
130
|
-
f = open(fogg, 'r')
|
|
131
|
-
audio = f.read()
|
|
132
|
-
audio = "data:audio/ogg;base64," + base64.b64encode(audio)
|
|
133
|
-
resp.addData('audioB64', audio)
|
|
134
|
-
os.remove(fname)
|
|
135
|
-
os.remove(fogg)
|
|
136
|
-
return
|