Dicas para exibição de conteúdo matemático com MathJax e JQuery Mobile.
jQuery Mobile, segundo seus autores, é um “Framework UI baseado em HTML5 projetado para desenvolver sites e aplicativos que sejam acessíveis em todos os dispositivos (smartphone, tablet e desktop) de forma responsiva”.
MathJax, novamente segundo seus autores, é um “Mecanismo JavaScript para exibição de textos matemáticos que executa em todos os navegadores”.
Juntando essas tecnologias podemos construir aplicações multi-plataforma que mostram conteúdo matemático dinâmico de uma forma simples e versátil.
O aplicativo
Nesta dica vamos ilustrar uma aplicação muito simples que mostra o poder dessas bibliotecas: O Cálculo de equações quadráticas, como mostrado na figura abaixo:
Veja como as fórmulas matemáticas são exibidos de uma forma muito profissional. Você pode executar este aplicativo on-line aqui.
O funcionamento do aplicativo é muito simples:
- O sistema exibe a tela e espera que o usuário digite os coeficientes da equação
- O sistema valida os dados inseridos e, se tudo estiver ok, os resultados são apresentados
Para a edição de código-fonte, eu usei as seguintes ferramentas:
- NetBeans IDE – Excelente suporte para HTML5, CSS3 e JavaScript
- RIB – é uma ferramenta de design baseada em navegador para criar a interface do usuário para o jQuery Mobile
O código-fonte
Vamos olhar para o código HTML desta aplicação:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Yet Another Quadratic Equation Solver</title> <meta name="keywords" content="mathematics,math,html5,javascript,mathjs,mathjax,quadratic,equation,solve" /> <meta name="description" content="Calculating the roots of quadratic equation with mathjax and jquery mobile" /> <meta name="author" content="José Augusto Cintra"> <meta name="robots" content="index, follow"> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <meta name="HandheldFriendly" content="true"/> <meta name="MobileOptimized" content="320"/> <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" /> <script type="text/javascript" src="https://code.jquery.com/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=AM_HTMLorMML-full"></script> </head> <body> <div data-role="page" id="main_page" data-theme="a"> <div data-role="header" data-position="fixed"> <h3 style="text-align:left; margin-left:10px;color: green;">Yet Another Quadratic Equation Solver</h3> </div> <div data-role="content" id="main_content"> <div class="ui-corner-all ui-overlay-shadow" style="padding: 1em;"> <strong>Coefficients for `ax^2 + bx + c` `(a ne 0)` :</strong> <div class="ui-grid-b"> <div class="ui-block-a"> <div data-controltype="textinput" > <input class="coef" name="a_coef" id="a_coef" placeholder="a" value="" type="text" > </div> </div> <div class="ui-block-b"> <div data-controltype="textinput" > <input class="coef" name="b_coef" id="b_coef" placeholder="b" value="" type="text"> </div> </div> <div class="ui-block-c"> <div data-controltype="textinput" > <input class="coef" name="c_coef" id="c_coef" placeholder="c" value="" type="text"> </div> </div> </div> <div id="results"> <p> <br/> <strong style="text-decoration: underline;color: green;">Equation</strong> <br/> <div id="dv_equation"></div> </p> <p> <br/> <strong style="text-decoration: underline;color: green;">Solution</strong> <br/> </p> `Delta = b^2 - 4ac = `<span id="dv_delta"></span> <br/> <br/> <span id="dv_delta_msg"></span> <br/> <span class="x" id="dv_x1"></span> <br/> <span class="x" id="dv_x2"></span> </div> </div> </div> <div data-role="footer" id="main_footer" data-position="fixed" > <a href="http://html-apps.info" target="_BLANK" style="text-align:left; margin-left:10px;color: green;">HTML Apps</a> </div> </div> <script src="js/yaques.js"></script> </body> </html>
Pontos de interesse:
- A biblioteca MathJax pode ser configurada logo no carregamento. Neste caso, usamos o parâmetro AM_HTMLorMML-full. Este arquivo de configuração é para sites que utilizam apenas o formato AsciiMath para exibir suas fórmulas matemáticas. Ele vai usar a saída MathML nos navegadores que a suportam e saída de HTML/CSS3 caso não haja suporte;
- AsciiMath é uma biblioteca que converte expressões matemáticas (computacionais) em código MathML on-the-fly. Para isso, a expressão deve ser delimitada com `…` ;
- A chamada à biblioteca local foi colocada no corpo do documento para garantir o carregamento correto de todas as bibliotecas;
Em seguida, olhar para o código javascript:
/* Quadratic Equation Solver * 2015, by José Cintra * e-Mail: jose.cintra@html-apps.info * HomePage: html-apps.info */ var a_coef = b_coef = c_coef = 0; //Event handling $('#main_page').on('pageinit', function() { $('#results').hide(); $('.coef').bind('keyup', function(event) { $('#results').hide(); a_coef = Number(eval($('#a_coef').val())); b_coef = Number(eval($('#b_coef').val())); c_coef = Number(eval($('#c_coef').val())); if ($.isNumeric(a_coef) && $.isNumeric(b_coef) && $.isNumeric(c_coef)) { if (a_coef != 0) { Refresh(); } } }); }); //Calculating and updating the screen function Refresh(){ //Display equation a_coef_text = b_coef_text = c_coef_text = ""; a_coef_text = (a_coef < 0 ? "-" : "") + (Math.abs(a_coef) === 1 ? "" : String(Math.abs(a_coef))) + "x^2 "; if(b_coef !== 0){ b_coef_text = (b_coef < 0 ? " - " : " + ") + (Math.abs(b_coef) === 1 ? "" : String(Math.abs(b_coef))) + "x "; } if(c_coef !== 0){ c_coef_text = (c_coef < 0 ? " - " : " + ") + String(Math.abs(c_coef)); } equation_text = a_coef_text + b_coef_text + c_coef_text + " = 0"; $('#dv_equation').text("`" + equation_text + "`"); MathJax.Hub.Queue(["Typeset", MathJax.Hub, "dv_equation"]); //Get the solution x1 = x2 = 0; delta = (Math.pow(b_coef,2)) - (4 * a_coef * c_coef); $('.x').text(""); //clear roots $('#dv_delta').text('`' + delta + '`'); MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'dv_delta']); delta_msg = "How `Delta` is negative, the equation has NO real roots"; if (delta === 0) { delta_msg = "How `Delta` is ZERO, the equation has ONE real root:"; x1 = (-b_coef + Math.sqrt(delta))/(2*a_coef) x1_text = "x = (-b + sqrt(Delta))/(2a) = ".concat(x1); $('#dv_x1').text('`' + x1_text + '`'); MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'dv_x1']); } else if (delta > 0) { delta_msg = "How `Delta` is positive, the equation has TWO real roots:"; x1 = (-b_coef + Math.sqrt(delta))/(2*a_coef) x1_text = "x1 = (-b + sqrt(Delta))/(2a) = ".concat(x1); $('#dv_x1').text('`' + x1_text + '`'); MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'dv_x1']); x2 = (-b_coef - Math.sqrt(delta))/(2*a_coef) x2_text = "x2 = (-b - sqrt(Delta))/(2a) = ".concat(x2); $('#dv_x2').text('`' + x2_text + '`'); MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'dv_x2']); } //Print solution $('#dv_delta_msg').text(delta_msg); MathJax.Hub.Queue(['Typeset', MathJax.Hub, 'dv_delta_msg']); $('#results').show(); }
Pontos de interesse:
- Em JQuery Mobile, o equivalente ao evento onload do elemento BODY é o evento pageinit;
- O resultado será atualizado cada vez que o usuário pressiona uma tecla, através da captura do evento KeyUP;
- O uso da função eval permite que o usuário insira expressões matemáticas (uma fração, por exemplo) para os coeficientes.
- Observe que cada vez que a expressão é alterada pelo usuário, nós chamamos o método MathJax.Hub.Queue que irá atualizar a fórmula que está sendo exibida.
Recursos
Conclusão
Há ainda alguns problemas de compatibilidade entre navegadores que não renderizam o MathJax adequadamente, mas o uso combinado dessas bibliotecas viabiliza a construção de aplicações matemáticas muito interessantes.
Isso é tudo! Espere ter ajudado.
Até a próxima…