MathML or Latex - how we implemented a changing salary in calculating salaries using MathJax

    The article will be useful for web developers who are thinking about displaying mathematical formulas in a browser, and, probably, for other ITs for general development.

    Our company has long implemented a system of employee incentives (KPI) based on "Redmine", combining the functions of calculating the salary ratio. I’ll tell you a little about her.

    Each post has some kind of salary, the employee holding the position can nicely work and multiply his salary by a performance coefficient, which is calculated on the basis of a handful of indicators configured for his position. The coefficient of performance can be either more or less than one. Thus, modeling indicators, it is possible to stimulate employees of certain positions to work in a certain direction.

    All this may look something like this:

    image



    Over time, we came to the conclusion that the salary of some posts should also vary depending on various indicators. For example, with pharmacy managers, the base salary should depend on the pharmacy’s cash flow. Moreover, this dependence can be different!

    An important feature that should always be considered when implementing KPI is transparency! An employee should always know why he received just such a salary, where he did not work, why the indicator was calculated that way.

    Therefore, in addition to calculating the base salary, it became necessary to demonstrate how the salary was calculated.

    Latex and MathML


    At the moment, there are two main standards for displaying formulas in a browser: Latex and MathML.

    I painfully chose which technology to use. As a result, I made several conclusions. I hope they will be useful to the community.

    The main advantage of Latex in brevity of record. Otherwise, in my opinion , this format is inferior to MathML.

    For example, writing a formula imagein Latex looks like this:

    \frac{(a+b )}{4} 
    

    In MathML, the same would be written much more cumbersome:

    a+b4

    MathML is pure XML, from here simpler parsing for your own needs, if necessary.

    MathML seemed to be a more understandable and quickly mastered format. Although this opinion is individual and controversial.

    MathML is supported by most modern browsers, except Chrome, which has refused to support this format, citing the MathJax library . This means that in Firefox, for example, you do not need to connect additional libraries, the browser parses and displays the formula indicated above without the help of third-party libraries.

    "MathML" allows you to complement the formula with a bunch of useful additions. For example, it was vital for us to get a tooltip for certain values ​​of the formula so that the employee would see where this value came from. There is a maction tag in MathML for this:

    17 745 400Товарооборот

    As a result, when hovering over the value, the user will see a tooltip:



    Funny, but the most understandable format documentation seemed to be the Mozilla documentation. I recommend it to those who will be picking in this format: developer.mozilla.org/en-US/docs/Web/MathML/Element

    Mathjax


    MathML is good, but unfortunately it is not supported by all browsers. There is a MathJax library that allows you to parse MathML in HTML, SVG, etc. She, by the way, parses rejected by me Latex.

    The library does a good job of parsing formulas, but it has flaws.

    The largest, in my opinion, its volume is 32.9 Mb in compressed form. Of course, not everything will be given to the client when rendering the formula, but this volume of the js library itself is annoying. For example, we needed to distribute it to external clients.

    Having initially connected the entire library and realized the task, I randomly threw a bunch of folders out of it. Using the “poke” method, checking that nothing has broken. Size reduced to 16 Mb. Basically threw folders with fonts and extra output formats (for example, SVG).

    I did not find competent documentation for reducing the volume of the library.

    The library is quite difficult to master. I poked around for a long time, turning off unnecessary chips in it. I’ll list some useful configuration settings that turned out to be useful:

    First, each formula opens in a separate window that loads asynchronously (via AJAX). Therefore, there is no need to load the library when the user does not click on the link. It looks something like this: The



    library supports dynamic loading (here docs.mathjax.org/en/latest/dynamic.html is written in detail about this ). Relatively speaking, you need to dynamically add the library declaration to the “head” tag and only do this if the library has not been connected before:

    if(typeof $('body').data('mathjax_loaded') == 'undefined' )
              {
              //подключение библиотеки в тег head
              $('body').data('mathjax_loaded', 'true')
              }
    else
              {
              MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
              }
    

    When connecting the library dynamically, there were problems with rendering the formula. The formula was rendered only in the case when the libraries were loaded in the first, with a second click and opening the window, the formula was not rendered. The construct that forced the rendering of formulas on the page helped:

    MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
    

    The formula does not render instantly, so it’s better for the user to show the preloader, for this there is a construction:

    mml2jax: {preview: [["img", {src: '/plugin_assets/kpi/images/loader.gif'}]]}
    

    Sometimes it’s useful to zoom in:

    HTML-CSS: { scale: 140 }
    

    If after rendering the formula you need to run some additional javascript, then you can use the construction:

    MathJax.Hub.Queue(function () {
                    alert('Test');
                    });
    

    To disable the additional menu, which can be called with the right mouse click, and disable the zoom formula:

    showMathMenu: false,
    menuSettings: { zoom: false }
    

    Two formulas, not one


    Until recently, the idea of ​​parsing a mathematical formula did not leave me, by which the calculation in MathML format would actually be performed. That is, in the database I wanted to save one formula of the form:

    31000.00 + (0.015*{"pattern": "imported_value", "id": "51"}/{"pattern": "imported_value", "id": "40"})
    

    And get the mathml construct from the original formula:

    
         {"pattern": "result"}
       =31 000Базовый оклад+0.015×{"pattern": "imported_value", "id": "51"}Товарооборот{"pattern": "imported_value", "id": "40"}Количество сотрудников

    As a result, he concluded that it was impossibly difficult and not always justified. A mathml formula can have a bunch of elements that cannot be stored in a regular formula, for example, tooltips, font highlighting, etc. Currently, we save two formulas in the database, one for directly calculating the value, and the other for displaying the calculation system to the user.

    I try to write articles after having encountered difficulties I did not find a clear and quick solution to my problems. I think my specific article will be useful to someone.

    Also popular now: