Draw graphics online

    It all started with the fact that about three or four years ago I wrote in Java my own parser and calculator of mathematical expressions - jExpressions.

    And now, relatively recently, in the light of mastering Java EE technology, an idea arose to draw graphing based on this parser online.

    The parser at that time had a rather exotic syntax for calling functions (e.g. exp # 3 instead of exp (3); beta # 1: 2 instead of beta (1,2)).
    Also, bugs from time to time took off.

    After several hours of finishing and deactivating, version jExpressions 1.0 was born .

    After that, it was possible to get down to business.


    Chart drawing is arranged as follows:

    1. The servlet calculates the function values ​​for the N-th number of points (250 for simple and 1000 for parametric) and gives the result in json format.
    2. The web page receives json from the servlet and draws a graph using the Flot plugin.

    Servlet processRequest () function code:

    private void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	response.setContentType("text/plain;charset=UTF-8");
    	PrintWriter out = response.getWriter();
    	String result = "{ \"result\" : ";
    	String func = request.getParameter("func");
    	String var = request.getParameter("variable");
    	String begin = request.getParameter("begin");
    	String end = request.getParameter("end");
    	if (func==null||var==null||begin==null||end==null) {
    		result += "\"error\", \"err\" : \"param\"}";
    		out.println(result);
    		return;
    	}
    	// upd:
    	//Double x0 = Double.parseDouble(begin);
    	//Double x1 = Double.parseDouble(end);
    	Double x0;
    	Double x1;
    	try {
    		x0 = Double.parseDouble(begin);
    		x1 = Double.parseDouble(end);
    	} catch (Exception e) {
    		result += "\"error\", \"err\" : \"param\"}";
    		out.println(result);
    		return;
    	}
    	int num = 0;
            try {        
    		Parser parser = new Parser();
    		num = parser.setAlias(var); // сообщаем парсеру имя переменной
    		long time0 = System.nanoTime();
    		Expr expr = parser.parseExpr(parser.prepareExpr(func)); // на основе выражения строится двоичное дерево
    		String xArr = "[";
    		String yArr = "[";
    		long time1 = System.nanoTime();
    		for (int i=0; i<=points; i++) {
    			if (i>0) {
    				xArr += ", ";
    				yArr += ", ";
    			}
    			Double x = x0 + ((x1-x0)/points)*i;
    			parser.setVar(num, x); // подставляем значение переменной
    			Double y = expr.evaluate(); // вычисляем выражение
    			xArr += x.toString();
    			yArr += y.toString();
    		}
    		long time2 = System.nanoTime();
    		Integer parse_time = (int)((time1-time0)/1e6);
    		Integer calc_time = (int)((time2-time1)/1e6);
    		Integer total_time = (int)((time2-time0)/1e6);
    		System.out.println("Parse time: "+parse_time.toString()
    								+"; Calc time: "+calc_time.toString());
    		xArr += "]";
    		yArr += "]";
    		result += "\"ok\", \"time\" : \""+total_time.toString()
    					+"\", \"x\" : \""+xArr+"\", \"y\" : \""+yArr+"\"}";
    	} catch (BadVarException e) {
    		result += "\"error\", \"err\" : \"badvar\"}";
    	} catch (Exception e) {
    		result += "\"error\", \"err\" : \"wrong\"}";
    	} finally {
    		out.print(result);
    	}
    }
    


    js code for plotting:

    window.getResult = function(func,variable,begin,end){
    	$('#draw').prop('disabled',true);
    	$('#info').text('Идет вычисление...');
    	$.post('/functions/calc',
    				{func: func, variable: variable, begin: begin, end: end},
    																function(data){
    		window.result = $.parseJSON(data);
    		if (result.result == 'error') {
    			if (result.err == 'wrong') $('#info').text('Ошибка в выражении');
    			if (result.err == 'badvar') $('#info').text('Имя переменной зарезервировано');
    			$('#draw').prop('disabled',false);
    			return;
    		}
    		window.xArr = $.parseJSON(result.x);
    		result.y = result.y
    						.split('-Infinity').join('null')
    						.split('Infinity').join('null')
    						.split('NaN').join('null');
    		window.yArr = $.parseJSON(result.y);
    		window.data = [];
    		for (i=0; i


    Результат можно увидеть здесь (простые функции) и здесь (параметрические).

    Примечание: работает довольно медленно, так как сервер крутится на Raspberry Pi.

    Also popular now: