Advertisement
Guest User

Untitled

a guest
Aug 28th, 2014
372
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. "use strict"
  2. /**!
  3.  * @licence
  4.  *
  5.  * Copyright Notice:
  6.  *
  7.  * The material in this file is protected by copyright.
  8.  *
  9.  * Copyright of this file is owned by C.W.A.M. van Overveld, Eindhoven, the Netherlands
  10.  *
  11.  * It is permitted to use, copy or modify this file under the following conditions:
  12.  *
  13.  * * Commercial use is forbidden without prior written permission by the copyright owner;
  14.  * * This copyright message is to be left in the top of the file (also in case of minification);
  15.  * * If this file is included in, or can be downloaded from a website, the website should contain
  16.  *   a link to www.keesvanoverveld.com and a message that states the copyright of this file;
  17.  * * The author takes no responsabilities for any consequences that should follow from using
  18.  *   the contents of this file.
  19.  *
  20.  */
  21.  
  22. var userGraph = function() {
  23.         var graphContour = "graph"
  24.         var autoScale = true;
  25.         var exactClamp = false;
  26.         // autoscale governs the vertical scaling of the graph.
  27.         // it is always true, except if the user overrules the range from- and true values.
  28.         // Normally, the values computed by autoscaling are made nice, that is: not too many decimals.
  29.         // and a little room on both sides of the graph.
  30.         // It can be convenient, however, to have the graph range adjusted exactly to the min and max values
  31.         // attained. In that case, exactClamp should be true.
  32.         var argVar = '';
  33.         var coArgVar = '';
  34.         var rangeVar = '';
  35.         var argFrom = 0.0;
  36.         var coArgFrom = 0.0;
  37.         var argTo = 0.0;
  38.         var coArgTo = 0.0;
  39.         var rangeFrom = 0.0;
  40.         var rangeTo = 0.0;
  41.         var that = this;
  42.         var rememberState = true;
  43.         // this ensures that on a re-visit of the analysis tab, if the script has not been updated,
  44.         // we update the graph with the recent cat.-I values.
  45.         var msgHasBeenGiven = false
  46.             // to limit the numeber of stack-overflow warnings
  47.         var wrongGraph = {
  48.             'background': {
  49.                 'fcol_a': 1,
  50.                 'fcol_r': 153,
  51.                 'fcol_g': 51,
  52.                 'fcol_b': 204
  53.             },
  54.             'locations': {
  55.                 'x': 50,
  56.                 'y': 50,
  57.                 'tag': 'no graph',
  58.                 'pointSize': 4,
  59.                 'tcol_r': 255,
  60.                 'tcol_g': 255,
  61.                 'tcol_b': 255
  62.             }
  63.         }
  64.         var lastFunctionReport = ''
  65.             // to print on top of the user graph if coordinates are not to be printed
  66.         var plotOK = true
  67.             // to flag if there is a valid graph
  68.         var argValues = [];
  69.         // the array of argument values to be passed to the evaluation function
  70.         var coArgValues = [];
  71.         // the array of co-argument values, used in case of contours
  72.         var rangeValues = [];
  73.         // the array of range values received back from the evaluation function. Notice: in case of
  74.         // contours, this is a 2-D array
  75.         var isSlider = false;
  76.         var intSlider = false;
  77.         var rangeValues = [];
  78.         var isSliderArg = false;
  79.         var intSliderArg = false;
  80.         var isSliderCoArg = false;
  81.         var intSliderCoArg = false;
  82.         // it is important to know if (co-) arguments are slides, and if so, if these are all-integer sliders
  83.         //--------------------------------------------------------------------------
  84.         this.moveCallBack = function(x, y, m) {
  85.                 if (plotOK) {
  86.                     if (m) {
  87.                         if (graphContour == 'graph') {
  88.                             var h = (x * (argTo - argFrom) + 1 * argFrom) + ' '
  89.                             var v = (y * (rangeTo - rangeFrom) + 1 * rangeFrom) + ' '
  90.                             h = (h.length > 10) ? h.substr(0, 8) + '...' : h
  91.                             v = (v.length > 10) ? v.substr(0, 8) + '...' : v
  92.                             $('#userResultPlotLabel').html(argVar + "=" + h + "; " + rangeVar + "=" + v);
  93.                         } else {
  94.                             // we don't want to re-evaluate the function. Instead, we approximate the
  95.                             // function value by bi-linear interpolation from the values in the (2D) range-array
  96.                             var h = (x * (argTo - argFrom) + 1 * argFrom)
  97.                             var v = (y * (coArgTo - coArgFrom) + 1 * coArgFrom)
  98.                             var hhi = Math.max(0.01, Math.min(x * (rangeValues.length - 1), rangeValues.length - 1.01))
  99.                             var vvi = Math.max(0.01, Math.min(y * (rangeValues[0].length - 1), rangeValues[0].length - 1.01))
  100.                             var hi = Math.floor(hhi)
  101.                             var vi = Math.floor(vvi)
  102.                             var ll = rangeValues[hi][vi]
  103.                             var lh = rangeValues[hi][vi + 1]
  104.                             var hl = rangeValues[hi + 1][vi]
  105.                             var hh = rangeValues[hi + 1][vi + 1]
  106.                             var app = (hhi - hi) * (vvi - vi) * hh + (hi + 1 - hhi) * (vi + 1 - vvi) * ll + (hhi - hi) * (vi + 1 - vvi) * hl + (hi + 1 - hhi) * (vvi - vi) * lh
  107.                             h += ' '
  108.                             v += ' '
  109.                             app += ' '
  110.                             h = (h.length > 10) ? h.substr(0, 8) + '...' : h
  111.                             v = (v.length > 10) ? v.substr(0, 8) + '...' : v
  112.                             app = (app.length > 10) ? app.substr(0, 8) + '...' : app
  113.                             $('#userResultPlotLabel').html(argVar + "=" + h + "; " + coArgVar + "=" + v + "; " + rangeVar + "=" + app);
  114.                         }
  115.                     } else {
  116.                         $('#userResultPlotLabel').html(lastFunctionReport);
  117.                     }
  118.                 }
  119.             }
  120.             //--------------------------------------------------------------------
  121.         this.setRenderMode = function(val) {
  122.                 argVar = ''
  123.                 coArgVar = ''
  124.                 if (val) {
  125.                     graphContour = "contour"
  126.                     $('#clampControl').hide()
  127.                     $('#argVFrom').show()
  128.                     $('#argVTo').show()
  129.                     $("label[for='graphOrContour']").text("contour");
  130.                     $('#userResultPlotLabel').html("Select quantities for contour plot");
  131.                     plotOK = false
  132.                     userResultGraph.draw([
  133.                         wrongGraph
  134.                     ]);
  135.                 } else {
  136.                     graphContour = "graph"
  137.                     $('#clampControl').show()
  138.                     $('#argVFrom').hide()
  139.                     $('#argVTo').hide()
  140.                     $("label[for='graphOrContour']").text("graph");
  141.                     $('#userResultPlotLabel').html("Select quantities for contour plot");
  142.                     plotOK = false
  143.                     userResultGraph.draw([
  144.                         wrongGraph
  145.                     ]);
  146.                 }
  147.                 this.setUpQuantityLists()
  148.             }
  149.             //--------------------------------------------------------------------
  150.         this.setAutoScale = function(val) {
  151.                 autoScale = val;
  152.             }
  153.             //---------------------------------------------------------------------
  154.         this.setExactClamp = function(val) {
  155.                 exactClamp = val;
  156.             }
  157.             //-----------------------------------------------------
  158.         this.plotUserGraphOrContour = function() {
  159.                 if (graphContour == 'graph') {
  160.                     that.plotUserGraph()
  161.                 } else {
  162.                     that.plotUserContour()
  163.                 }
  164.             }
  165.             //--------------------------------------------------
  166.         this.plotUserGraph = function() {
  167.                 var NRSAMPLES = 50;
  168.                 var nrValues;
  169.                 argFrom = $('#argFrom').val();
  170.                 argTo = $('#argTo').val();
  171.                 rangeFrom = $('#rangeFrom').val();
  172.                 rangeTo = $('#rangeTo').val();
  173.                 var evalOK = true;
  174.                 if (!usesHistory() || NITER_SET >= 1) {
  175.                     if (myIsNumber(argFrom)) {
  176.                         if (myIsNumber(argTo)) {
  177.                             if (myIsNumber(rangeFrom)) {
  178.                                 if (myIsNumber(rangeTo)) {
  179.                                     if (rangeFrom != rangeTo) {
  180.                                         if (argFrom != argTo) {
  181.                                             var argIndex = -1;
  182.                                             var rangeIndex = -1;
  183.                                             for (var j = 0; j < symbolTable.length; j++) {
  184.                                                 if (symbolTable[j].name == argVar) {
  185.                                                     argIndex = j;
  186.                                                     var myC1I = symbolTable[j].myCat1Index;
  187.                                                     if (myC1I >= 0) {
  188.                                                         if (cat1Vars[myC1I].type == "slider") {
  189.                                                             isSlider = true;
  190.                                                             if (cat1Vars[myC1I].round) {
  191.                                                                 intSlider = true;
  192.                                                             } else {
  193.                                                                 intSlider = false
  194.                                                             }
  195.                                                         } else {
  196.                                                             isSlider = false
  197.                                                         }
  198.                                                     } else {
  199.                                                         isSlider = false;
  200.                                                         intSlider = false;
  201.                                                     }
  202.                                                 }
  203.                                                 if (symbolTable[j].name == rangeVar) {
  204.                                                     rangeIndex = j;
  205.                                                 }
  206.                                             }
  207.                                             // post condition: argIndex >=0
  208.                                             msgHasBeenGiven = false;
  209.                                             if (testReachable(argVar, rangeVar, 0)) {
  210.                                                 if (argIndex >= 0 && rangeIndex >= 0) {
  211.                                                     if (argIndex != rangeIndex) {
  212.                                                         var saveValue = symbolTable[argIndex].valOb;
  213.                                                         // we must not destroy the state prior to drawing the graph
  214.                                                         // it is possible that we have to draw a discrete graph: if the argument is a cat.-I quantity, namely an integer slider
  215.                                                         if (intSlider) {
  216.                                                             var stepSize = 1
  217.                                                             nrValues = argTo - argFrom + 1;
  218.                                                             if (nrValues > 100) {
  219.                                                                 stepSize = nrValues / 100
  220.                                                             }
  221.                                                             nrValues = nrValues / stepSize
  222.                                                             var saveSymbol = symbolTable[argIndex].valOb
  223.                                                             for (var i = 0; i < nrValues; i++) {
  224.                                                                 symbolTable[argIndex].valOb = 1 * argFrom + 1 * i * stepSize
  225.                                                                     // if I don't put the 1*, javascript will concatenate strings !!! GR%$#@#%$@^%$^%@$
  226.                                                                 executeOnBehalfOfGraph(argIndex, argIndex)
  227.                                                                 argValues[i] = 2.0 + 96.0 * i / (nrValues - 1)
  228.                                                                 if (isNumeric(symbolTable[rangeIndex].valOb)) {
  229.                                                                     rangeValues[i] = symbolTable[rangeIndex].valOb
  230.                                                                 } else {
  231.                                                                     rangeValues[i] = -1;
  232.                                                                     evalOK = false;
  233.                                                                 }
  234.                                                             }
  235.                                                             rangeValues.length = nrValues
  236.                                                             symbolTable[argIndex].valOb = saveSymbol
  237.                                                         } else {
  238.                                                             nrValues = NRSAMPLES
  239.                                                             var saveSymbol = symbolTable[argIndex].valOb
  240.                                                             for (var i = 0; i < NRSAMPLES; i++) {
  241.                                                                 var argVal = parseFloat(argFrom) + parseFloat(i * (argTo - argFrom) / (NRSAMPLES - 1));
  242.                                                                 symbolTable[argIndex].valOb = argVal;
  243.                                                                 executeOnBehalfOfGraph(argIndex, argIndex);
  244.                                                                 argValues[i] = 100 * (argVal - argFrom) / (argTo - argFrom);
  245.                                                                 if (isNumeric(symbolTable[rangeIndex].valOb)) {
  246.                                                                     rangeValues[i] = symbolTable[rangeIndex].valOb
  247.                                                                 } else {
  248.                                                                     rangeValues[i] = -1;
  249.                                                                     evalOK = false;
  250.                                                                 }
  251.                                                             }
  252.                                                             rangeValues.length = nrValues
  253.                                                             symbolTable[argIndex].valOb = saveSymbol
  254.                                                         }
  255.                                                         // restore the symbol table
  256.                                                         symbolTable[argIndex].valOb = saveValue;
  257.                                                         // distinguish autoscaling from non autoscaling
  258.                                                         if (autoScale) {
  259.                                                             var minR = rangeValues[0];
  260.                                                             var maxR = rangeValues[0];
  261.                                                             for (i = 0; i < nrValues; i++) {
  262.                                                                 if (minR > rangeValues[i])
  263.                                                                     minR = rangeValues[i];
  264.                                                                 if (maxR < rangeValues[i])
  265.                                                                     maxR = rangeValues[i];
  266.                                                             }
  267.                                                             if (exactClamp) {
  268.                                                                 var deltaR = (maxR - minR);
  269.                                                             } else {
  270.                                                                 var deltaR = 1.1 * (maxR - minR);
  271.                                                             }
  272.                                                             var avg = (maxR + minR) / 2;
  273.                                                             if (exactClamp) {
  274.                                                                 if (deltaR == 0) {
  275.                                                                     $('#userResultPlotLabel').html("Scaling fails; all computed values = " + avg);
  276.                                                                     plotOK = false
  277.                                                                 }
  278.                                                                 minR = avg - 0.5 * deltaR,
  279.                                                                     false;
  280.                                                                 maxR = avg + 0.5 * deltaR,
  281.                                                                     true;
  282.                                                             } else {
  283.                                                                 if (deltaR == 0)
  284.                                                                     deltaR = avg;
  285.                                                                 minR = niceNumber(avg - 0.5 * deltaR, false);
  286.                                                                 maxR = niceNumber(avg + 0.5 * deltaR, true);
  287.                                                             }
  288.                                                             rangeFrom = minR;
  289.                                                             rangeTo = maxR;
  290.                                                             $('#rangeFrom').val(rangeFrom);
  291.                                                             $('#rangeTo').val(rangeTo);
  292.                                                         } else {
  293.                                                             deltaR = rangeTo - rangeFrom;
  294.                                                         }
  295.                                                         if (deltaR > 0) {
  296.                                                             for (i = 0; i < nrValues; i++) {
  297.                                                                 rangeValues[i] = 100 * (rangeValues[i] - rangeFrom) / deltaR;
  298.                                                             }
  299.                                                         } else {
  300.                                                             for (i = 0; i < nrValues; i++) {
  301.                                                                 rangeValues[i] = 50;
  302.                                                             }
  303.                                                         }
  304.                                                         var plotGraphData = []
  305.                                                         for (i = 0; i < nrValues; i++) {
  306.                                                             plotGraphData.push({
  307.                                                                 'x': argValues[i],
  308.                                                                 'y': rangeValues[i]
  309.                                                             })
  310.                                                         }
  311.                                                         var grid = {
  312.                                                             'majX': 5,
  313.                                                             'minX': 21,
  314.                                                             'grMajX': 'line',
  315.                                                             'grMinX': 'line',
  316.                                                             'majY': 5,
  317.                                                             'minY': 21,
  318.                                                             'grMajY': 'line',
  319.                                                             'grMinY': 'line'
  320.                                                         }
  321.                                                         if (!intSlider) {
  322.                                                             var plotGraph = {
  323.                                                                 'grid': grid,
  324.                                                                 'locations': {
  325.                                                                     'data': plotGraphData
  326.                                                                 },
  327.                                                                 'edges': {
  328.                                                                     'thickness': 2
  329.                                                                 }
  330.                                                             }
  331.  
  332.                                                         } else {
  333.                                                             var diam = 2;
  334.                                                             if (nrValues < 25)
  335.                                                                 diam = 4
  336.                                                             var plotGraph = {
  337.                                                                 'grid': grid,
  338.                                                                 'locations': {
  339.                                                                     'fill': 'interior',
  340.                                                                     'rad': diam / 2,
  341.                                                                     'data': plotGraphData
  342.                                                                 }
  343.                                                             }
  344.                                                         }
  345.                                                         if (evalOK) {
  346.                                                             userResultGraph.enforceRedraw()
  347.                                                             userResultGraph.draw([
  348.                                                                 plotGraph
  349.                                                             ]);
  350.                                                             lastFunctionReport = rangeVar + ' = function( ' + argVar + ' )'
  351.                                                             $('#userResultPlotLabel').html(lastFunctionReport);
  352.                                                             plotOK = true
  353.                                                         } else {
  354.                                                             alert("one or more of the evaluations failed; we can't plot a graph")
  355.                                                         }
  356.                                                     } else {
  357.                                                         $('#userResultPlotLabel').html("We don't plot identical functions " + rangeVar + " = function( " + argVar + " )");
  358.                                                         plotOK = false
  359.                                                         userResultGraph.draw([
  360.                                                             wrongGraph
  361.                                                         ]);
  362.                                                     }
  363.                                                 } else {
  364.                                                     $('#userResultPlotLabel').html("could not find argument and/or range " + argVar + ", " + rangeVar);
  365.                                                     plotOK = false
  366.                                                     userResultGraph.draw([
  367.                                                         wrongGraph
  368.                                                     ]);
  369.                                                 }
  370.                                             } else {
  371.                                                 $('#userResultPlotLabel').html(rangeVar + " does not depend on " + argVar);
  372.                                                 plotOK = false
  373.                                                 userResultGraph.draw([
  374.                                                     wrongGraph
  375.                                                 ]);
  376.                                             }
  377.                                         } else {
  378.                                             $('#userResultPlotLabel').html("argument from and to values must be different, scanning " + argFrom + " and " + argTo);
  379.                                             plotOK = false
  380.                                             userResultGraph.draw([
  381.                                                 wrongGraph
  382.                                             ]);
  383.                                         }
  384.                                     } else {
  385.                                         $('#userResultPlotLabel').html("range from and to values must be different, scanning " + rangeFrom + " and " + rangeTo);
  386.                                         plotOK = false
  387.                                         userResultGraph.draw([
  388.                                             wrongGraph
  389.                                         ]);
  390.                                     }
  391.                                 } else {
  392.                                     $('#userResultPlotLabel').html("range to-value must be a number, scanning " + rangeTo);
  393.                                     plotOK = false
  394.                                     userResultGraph.draw([
  395.                                         wrongGraph
  396.                                     ]);
  397.                                 }
  398.                             } else {
  399.                                 $('#userResultPlotLabel').html("range from-value must be a number, scanning " + rangeFrom);
  400.                                 plotOK = false
  401.                                 userResultGraph.draw([
  402.                                     wrongGraph
  403.                                 ]);
  404.                             }
  405.                         } else {
  406.                             $('#userResultPlotLabel').html("argument to-value must be a number, scanning " + argTo);
  407.                             plotOK = false
  408.                             userResultGraph.draw([
  409.                                 wrongGraph
  410.                             ]);
  411.                         }
  412.                     } else {
  413.                         $('#userResultPlotLabel').html("argument from-value must be a number, scanning " + argFrom);
  414.                         plotOK = false
  415.                         userResultGraph.draw([
  416.                             wrongGraph
  417.                         ]);
  418.                     }
  419.                 } else {
  420.                     $('#userResultPlotLabel').html("cannot draw a graph because model uses time-shift operators ({...}), and iteration counter is set to 0. This means that the model will take infinitely many time steps. Please set the iteration counter to a value >0");
  421.                     plotOK = false
  422.                     userResultGraph.draw([
  423.                         wrongGraph
  424.                     ]);
  425.                 }
  426.             }
  427.             //-------------------------------------------------------------------------
  428.         this.plotUserContour = function() {
  429.                 var NRSAMPLES = $('#nrContourSamples').val()
  430.                 if (NRSAMPLES < 5) {
  431.                     NRSAMPLES = 5
  432.                     $('#nrContourSamples').val(NRSAMPLES)
  433.                 }
  434.                 if (NRSAMPLES > 50) {
  435.                     NRSAMPLES = 50
  436.                     $('#nrContourSamples').val(NRSAMPLES)
  437.                 }
  438.                 var NRCONTOURS = $('#nrContours').val()
  439.                 if (NRCONTOURS < 5) {
  440.                     NRCONTOURS = 5
  441.                     $('#nrContours').val(NRCONTOURS)
  442.                 }
  443.                 if (NRCONTOURS > 50) {
  444.                     NRCONTOURS = 50
  445.                     $('#nrContours').val(NRCONTOURS)
  446.                 }
  447.                 argFrom = $('#argFrom').val();
  448.                 argTo = $('#argTo').val();
  449.                 coArgFrom = $('#coArgFrom').val();
  450.                 coArgTo = $('#coArgTo').val();
  451.                 rangeFrom = $('#rangeFrom').val();
  452.                 rangeTo = $('#rangeTo').val();
  453.                 var evalOK = true;
  454.                 if (!usesHistory() || NITER_SET >= 1) {
  455.                     if (myIsNumber(argFrom)) {
  456.                         if (myIsNumber(argTo)) {
  457.                             if (myIsNumber(coArgFrom)) {
  458.                                 if (myIsNumber(coArgTo)) {
  459.                                     if (myIsNumber(rangeFrom)) {
  460.                                         if (myIsNumber(rangeTo)) {
  461.                                             if (rangeFrom != rangeTo) {
  462.                                                 if (argFrom != argTo) {
  463.                                                     if (coArgFrom != coArgTo) {
  464.                                                         var argIndex = -1;
  465.                                                         var coArgIndex = -1;
  466.                                                         var rangeIndex = -1;
  467.                                                         for (var j = 0; j < symbolTable.length; j++) {
  468.                                                             if (symbolTable[j].name == argVar) {
  469.                                                                 argIndex = j;
  470.                                                                 var myC1I = symbolTable[j].myCat1Index;
  471.                                                                 if (myC1I >= 0) {
  472.                                                                     if (cat1Vars[myC1I].type == "slider") {
  473.                                                                         isSliderArg = true;
  474.                                                                         if (cat1Vars[myC1I].round) {
  475.                                                                             intSliderArg = true;
  476.                                                                         } else {
  477.                                                                             intSliderArg = false
  478.                                                                         }
  479.                                                                     } else {
  480.                                                                         isSliderArg = false
  481.                                                                     }
  482.                                                                 } else {
  483.                                                                     isSliderArg = false;
  484.                                                                     intSliderArg = false;
  485.                                                                 }
  486.                                                             }
  487.                                                             if (symbolTable[j].name == coArgVar) {
  488.                                                                 coArgIndex = j;
  489.                                                                 var myC1I = symbolTable[j].myCat1Index;
  490.                                                                 if (myC1I >= 0) {
  491.                                                                     if (cat1Vars[myC1I].type == "slider") {
  492.                                                                         isSliderCoArg = true;
  493.                                                                         if (cat1Vars[myC1I].round) {
  494.                                                                             intSliderCoArg = true;
  495.                                                                         } else {
  496.                                                                             intSliderCoArg = false
  497.                                                                         }
  498.                                                                     } else {
  499.                                                                         isSliderCoArg = false
  500.                                                                     }
  501.                                                                 } else {
  502.                                                                     isSliderCoArg = false;
  503.                                                                     intSliderCoArg = false;
  504.                                                                 }
  505.                                                             }
  506.                                                             if (symbolTable[j].name == rangeVar) {
  507.                                                                 rangeIndex = j;
  508.                                                             }
  509.                                                         }
  510.                                                         // post condition: argIndex >=0 and coArgIndex >=0
  511.                                                         msgHasBeenGiven = false;
  512.                                                         if (testReachable(argVar, rangeVar, 0)) {
  513.                                                             if (testReachable(coArgVar, rangeVar, 0)) {
  514.                                                                 if (argIndex >= 0 && rangeIndex >= 0 && coArgIndex >= 0) {
  515.                                                                     if ((argIndex != rangeIndex) && (coArgIndex != rangeIndex)) {
  516.                                                                         var saveValue = symbolTable[argIndex].valOb;
  517.                                                                         var coSaveValue = symbolTable[coArgIndex].valOb
  518.                                                                         for (var i = 0; i < NRSAMPLES; i++) {
  519.                                                                             if (intSliderArg) {
  520.                                                                                 argValues[i] = 1 * argFrom + i * (argTo - argFrom) / (NRSAMPLES - 1)
  521.                                                                                 argValues[i] = Math.round(argValues[i])
  522.                                                                             } else {
  523.                                                                                 argValues[i] = 1 * argFrom + i * (argTo - argFrom) / (NRSAMPLES - 1)
  524.                                                                             }
  525.                                                                         }
  526.                                                                         for (i = 0; i < NRSAMPLES; i++) {
  527.                                                                             if (intSliderCoArg) {
  528.                                                                                 coArgValues[i] = 1 * coArgFrom + i * (coArgTo - coArgFrom) / (NRSAMPLES - 1)
  529.                                                                                 coArgValues[i] = Math.round(coArgValues[i])
  530.                                                                             } else {
  531.                                                                                 coArgValues[i] = 1 * coArgFrom + i * (coArgTo - coArgFrom) / (NRSAMPLES - 1)
  532.                                                                             }
  533.                                                                         }
  534.                                                                         if (autoScale) {
  535.                                                                             var minR = 9.9e+100
  536.                                                                             var maxR = -9.9e+100
  537.                                                                         } else {
  538.                                                                             var minR = $('#rangeFrom').val()
  539.                                                                             var maxR = $('#rangeTo').val()
  540.                                                                         }
  541.                                                                         for (i = 0; i < NRSAMPLES; i++) {
  542.                                                                             rangeValues[i] = []
  543.                                                                             for (j = 0; j < NRSAMPLES; j++) {
  544.                                                                                 symbolTable[argIndex].valOb = argValues[i]
  545.                                                                                 symbolTable[coArgIndex].valOb = coArgValues[j]
  546.                                                                                 executeOnBehalfOfGraph(argIndex, coArgIndex)
  547.                                                                                 if (isNumeric(symbolTable[rangeIndex].valOb)) {
  548.                                                                                     rangeValues[i].push(symbolTable[rangeIndex].valOb)
  549.                                                                                 } else {
  550.                                                                                     rangeValues[i].push(-1)
  551.                                                                                     evalOK = false
  552.                                                                                 }
  553.                                                                                 if (rangeValues[i][j] < minR && autoScale) {
  554.                                                                                     minR = rangeValues[i][j]
  555.                                                                                 }
  556.                                                                                 if (rangeValues[i][j] > maxR && autoScale) {
  557.                                                                                     maxR = rangeValues[i][j]
  558.                                                                                 }
  559.                                                                             }
  560.                                                                         }
  561.                                                                         rangeValues.length = NRSAMPLES
  562.                                                                             // this is necessary, because the same array is used in the draw graph-case,
  563.                                                                             // and then rangeValues could have received more than NRSAMPLES values.
  564.                                                                         if (autoScale) {
  565.                                                                             $('#rangeFrom').val(minR);
  566.                                                                             $('#rangeTo').val(maxR);
  567.                                                                         }
  568.                                                                         symbolTable[argIndex].valOb = saveValue
  569.                                                                         symbolTable[coArgIndex].valOb = coSaveValue
  570.                                                                         executeOnBehalfOfGraph(argIndex, coArgIndex)
  571.                                                                         var grid = {
  572.                                                                             'majX': 5,
  573.                                                                             'minX': 21,
  574.                                                                             'grMajX': 'line',
  575.                                                                             'grMinX': 'line',
  576.                                                                             'majY': 5,
  577.                                                                             'minY': 21,
  578.                                                                             'grMajY': 'line',
  579.                                                                             'grMinY': 'line'
  580.                                                                         }
  581.                                                                         var plotContour = {
  582.                                                                             'grid': grid,
  583.                                                                             'contour': {
  584.                                                                                 'nrContours': NRCONTOURS,
  585.                                                                                 'map': rangeValues,
  586.                                                                                 'iso': {
  587.                                                                                     'mode': 'intp',
  588.                                                                                     'low': minR,
  589.                                                                                     'high': maxR
  590.                                                                                 },
  591.                                                                                 'col_r': {
  592.                                                                                     'mode': 'intp',
  593.                                                                                     'low': 0,
  594.                                                                                     'high': 255
  595.                                                                                 }
  596.                                                                             }
  597.                                                                         }
  598.                                                                         if (evalOK) {
  599.                                                                             userResultGraph.enforceRedraw()
  600.                                                                             userResultGraph.draw([plotContour]);
  601.                                                                             lastFunctionReport = rangeVar + ' = function( ' + argVar + ',' + coArgVar + ' )'
  602.                                                                             $('#userResultPlotLabel').html(lastFunctionReport);
  603.                                                                             plotOK = true
  604.                                                                         } else {
  605.                                                                             alert("one or more of the evaluations failed; we can't plot a graph")
  606.                                                                             plotOK = false
  607.                                                                         }
  608.                                                                     } else {
  609.                                                                         $('#userResultPlotLabel').html("We don't plot identical functions " + rangeVar + " = function( " +
  610.                                                                             argVar + " ) and/or " + rangeVar + " = function( " + coArgVar + ")");
  611.                                                                         plotOK = false
  612.                                                                         userResultGraph.draw([
  613.                                                                             wrongGraph
  614.                                                                         ]);
  615.                                                                     }
  616.                                                                 } else {
  617.                                                                     $('#userResultPlotLabel').html("could not find hor. argument and/or vert. argument and/or range " + argVar + ", " + coArgVar + "," + rangeVar);
  618.                                                                     plotOK = false
  619.                                                                     userResultGraph.draw([
  620.                                                                         wrongGraph
  621.                                                                     ]);
  622.                                                                 }
  623.                                                             } else {
  624.                                                                 $('#userResultPlotLabel').html(rangeVar + " does not depend on " + coArgVar);
  625.                                                                 plotOK = false
  626.                                                                 userResultGraph.draw([
  627.                                                                     wrongGraph
  628.                                                                 ]);
  629.                                                             }
  630.                                                         } else {
  631.                                                             $('#userResultPlotLabel').html(rangeVar + " does not depend on " + argVar);
  632.                                                             plotOK = false
  633.                                                             userResultGraph.draw([
  634.                                                                 wrongGraph
  635.                                                             ]);
  636.                                                         }
  637.                                                     } else {
  638.                                                         $('#userResultPlotLabel').html("vertical argument from and to values must be different, scanning " + coArgFrom + " and " + coAgTo);
  639.                                                         plotOK = false
  640.                                                         userResultGraph.draw([
  641.                                                             wrongGraph
  642.                                                         ]);
  643.                                                     }
  644.                                                 } else {
  645.                                                     $('#userResultPlotLabel').html("horizontal argument from and to values must be different, scanning " + argFrom + " and " + argTo);
  646.                                                     plotOK = false
  647.                                                     userResultGraph.draw([
  648.                                                         wrongGraph
  649.                                                     ]);
  650.                                                 }
  651.                                             } else {
  652.                                                 $('#userResultPlotLabel').html("range from and to values must be different, scanning " + rangeFrom + " and " + rangeTo);
  653.                                                 plotOK = false
  654.                                                 userResultGraph.draw([
  655.                                                     wrongGraph
  656.                                                 ]);
  657.                                             }
  658.                                         } else {
  659.                                             $('#userResultPlotLabel').html("range to-value must be a number, scanning " + rangeTo);
  660.                                             plotOK = false
  661.                                             userResultGraph.draw([
  662.                                                 wrongGraph
  663.                                             ]);
  664.                                         }
  665.                                     } else {
  666.                                         $('#userResultPlotLabel').html("range from-value must be a number, scanning " + rangeFrom);
  667.                                         plotOK = false
  668.                                         userResultGraph.draw([
  669.                                             wrongGraph
  670.                                         ]);
  671.                                     }
  672.                                 } else {
  673.                                     $('#userResultPlotLabel').html("vertical argument to-value must be a number, scanning " + coArgTo);
  674.                                     plotOK = false
  675.                                     userResultGraph.draw([
  676.                                         wrongGraph
  677.                                     ]);
  678.                                 }
  679.                             } else {
  680.                                 $('#userResultPlotLabel').html("vertical argument from-value must be a number, scanning " + coArgFrom);
  681.                                 plotOK = false
  682.                                 userResultGraph.draw([
  683.                                     wrongGraph
  684.                                 ]);
  685.                             }
  686.                         } else {
  687.                             $('#userResultPlotLabel').html("horizontal argument to-value must be a number, scanning " + argTo);
  688.                             plotOK = false
  689.                             userResultGraph.draw([
  690.                                 wrongGraph
  691.                             ]);
  692.                         }
  693.                     } else {
  694.                         $('#userResultPlotLabel').html("horizontal argument from-value must be a number, scanning " + argFrom);
  695.                         plotOK = false
  696.                         userResultGraph.draw([
  697.                             wrongGraph
  698.                         ]);
  699.                     }
  700.                 } else {
  701.                     $('#userResultPlotLabel').html("cannot draw a graph because model uses time-shift operators ({...}), and iteration counter is set to 0. This means that the model will take infinitely many time steps. Please set the iteration counter to a value >0");
  702.                     plotOK = false
  703.                     userResultGraph.draw([
  704.                         wrongGraph
  705.                     ]);
  706.                 }
  707.             }
  708.             //--------------------------------------------------------------------------
  709.         this.eraseState = function() {
  710.                 // this is called when the script is (re) compiled, so any quantitiy selections made earlier
  711.                 // loose their meaning
  712.                 rememberState = false;
  713.                 $('#userResultPlotLabel').html("");
  714.                 plotOK = false
  715.                 $('#argFrom').html("");
  716.                 $('#argTo').html("");
  717.                 $('#coArgFrom').html("");
  718.                 $('#coArgTo').html("");
  719.                 $('#rangeFrom').html("");
  720.                 $('#rangeTo').html("");
  721.             }
  722.             //-------------------------------------------------------------------------
  723.         this.optionalRefresh = function() {
  724.                 // in case there were quantities selected the previous time this tab
  725.                 // was visible, and the script has not changed, it is possible that
  726.                 // cat.-I quantities have changed. In that case we must update the graph
  727.                 if (rememberState) {
  728.                     if (graphContour == 'graph') {
  729.                         that.plotUserGraph()
  730.                     } else {
  731.                         that.plotUserContour()
  732.                     }
  733.                 }
  734.             }
  735.             //-------------------------------------------------------------------------
  736.         this.setUpQuantityLists = function() {
  737.                 userPlotArg = [];
  738.                 userPlotRange = [];
  739.                 for (var i = 0; i < symbolTable.length; i++) {
  740.                     if (!symbolTable[i].isDummy) {
  741.                         if (!isUserFunction(symbolTable[i].name)) {
  742.                             if (!(symbolTable[i].valOb instanceof Array)) {
  743.                                 if (myIsNumber(symbolTable[i].valOb)) {
  744.                                     userPlotArg.push({
  745.                                         'name': symbolTable[i].name,
  746.                                         'value': symbolTable[i].valOb.toPrecision ? symbolTable[i].valOb.toPrecision(2) : symbolTable[i].valOb,
  747.                                         // in case valOb is a string, it doesn't make sense to ask for the first two digits
  748.                                         'horPlot': (symbolTable[i].name == argVar) ? 'H' : '_',
  749.                                         'verPlot': (symbolTable[i].name == coArgVar) ? 'V' : '_'
  750.                                     });
  751.                                     userPlotRange.push({
  752.                                         'name': symbolTable[i].name,
  753.                                         'value': symbolTable[i].valOb.toPrecision ? symbolTable[i].valOb.toPrecision(2) : symbolTable[i].valOb
  754.                                     });
  755.                                 }
  756.                             }
  757.                         }
  758.                     }
  759.                 }
  760.                 userPlotArg.sort(varSorter);
  761.                 userPlotRange.sort(varSorter);
  762.                 var plotArgFormat = []
  763.                 if (graphContour == 'graph') {
  764.                     plotArgFormat.push({
  765.                         bd: 'name',
  766.                         bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#cccccc"',
  767.                         hd: 'name',
  768.                         tt: 'name of the quantity',
  769.                         hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  770.                         bc: function(data, row) {
  771.                             if (data[row]['value'] != 0) {
  772.                                 $('#argFrom').val(0.5 * data[row]['value']);
  773.                                 $('#argTo').val(2.0 * data[row]['value']);
  774.                             } else {
  775.                                 $('#argFrom').val(-1);
  776.                                 $('#argTo').val(1);
  777.                             }
  778.                             argVar = data[row]['name'];
  779.                             // if the clicked arg-quantity happens to be in cat.-I, and if it happens to be a slider,
  780.                             // we take the lower and upper bounds of the slider as from- and to values.
  781.                             for (var j = 0; j < symbolTable.length; j++) {
  782.                                 if (symbolTable[j].name == argVar) {
  783.                                     var myC1I = symbolTable[j].myCat1Index;
  784.                                     if (myC1I >= 0) {
  785.                                         if (cat1Vars[myC1I].type == "slider") {
  786.                                             $('#argFrom').val(cat1Vars[myC1I].low);
  787.                                             $('#argTo').val(cat1Vars[myC1I].high);
  788.                                         }
  789.                                     }
  790.                                 }
  791.                             }
  792.                             autoScale = true;
  793.                             rememberState = true;
  794.                             that.plotUserGraphOrContour();
  795.                         }
  796.                     })
  797.                 } else {
  798.                     plotArgFormat.push({
  799.                         bd: 'name',
  800.                         bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#cccccc"',
  801.                         hd: 'name',
  802.                         tt: 'name of the quantity',
  803.                         hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  804.                         bc: function(data, row) {
  805.                             alert("You must click on the 'H' or the 'V' column to assign quantity <" + data[row]['name'] + "> to the horizontal or vertical axis of the contour plot, respectively")
  806.                         }
  807.                     })
  808.                 }
  809.                 plotArgFormat.push({
  810.                     bd: function() {
  811.                         return '?'
  812.                     },
  813.                     bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00cc00;text-decoration:underline;"',
  814.                     hd: '?',
  815.                     tt: 'the comment (explanation) of this quantity',
  816.                     hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  817.                     bc: function(data, row) {
  818.                         var k = 0;
  819.                         var fnd = false;
  820.                         while (!fnd && k < script.length) {
  821.                             if (script[k].varName == data[row]['name']) {
  822.                                 fnd = true;
  823.                                 if (script[k].comment) {
  824.                                     alert(script[k].comment);
  825.                                 } else {
  826.                                     alert("could not find comment text for quantity " + data[row]['name']);
  827.                                 }
  828.                             } else {
  829.                                 k++;
  830.                             }
  831.                         }
  832.                         if (!fnd)
  833.                             alert("could not find quantity " + data[row]['name']);
  834.                     }
  835.                 })
  836.                 plotArgFormat.push({
  837.                     bd: 'value',
  838.                     bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00ffff"',
  839.                     hd: 'value',
  840.                     tt: 'the value for this quantity',
  841.                     hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"'
  842.                 })
  843.                 if (graphContour == 'contour') {
  844.                     plotArgFormat.push({
  845.                         bd: 'horPlot',
  846.                         bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00cc00;text-decoration:underline;"',
  847.                         hd: 'H',
  848.                         tt: 'select this quantity for plotting horizontally in the contour plot',
  849.                         hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  850.                         bc: function(data, row) {
  851.                             argVar = data[row]['name']
  852.                             that.setUpQuantityLists()
  853.                             if (data[row]['value'] != 0) {
  854.                                 $('#argFrom').val(0.5 * data[row]['value']);
  855.                                 $('#argTo').val(2.0 * data[row]['value']);
  856.                             } else {
  857.                                 $('#argFrom').val(-1);
  858.                                 $('#argTo').val(1);
  859.                             }
  860.                             // if the clicked arg-quantity happens to be in cat.-I, and if it happens to be a slider,
  861.                             // we take the lower and upper bounds of the slider as from- and to values.
  862.                             for (var j = 0; j < symbolTable.length; j++) {
  863.                                 if (symbolTable[j].name == argVar) {
  864.                                     var myC1I = symbolTable[j].myCat1Index;
  865.                                     if (myC1I >= 0) {
  866.                                         if (cat1Vars[myC1I].type == "slider") {
  867.                                             $('#argFrom').val(cat1Vars[myC1I].low);
  868.                                             $('#argTo').val(cat1Vars[myC1I].high);
  869.                                         }
  870.                                     }
  871.                                 }
  872.                             }
  873.                             autoScale = true;
  874.                             rememberState = true;
  875.                             that.plotUserGraphOrContour();
  876.                         }
  877.                     })
  878.                     plotArgFormat.push({
  879.                         bd: 'verPlot',
  880.                         bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00cc00;text-decoration:underline;"',
  881.                         hd: 'V',
  882.                         tt: 'select this quantity for plotting vertically in the contour plot',
  883.                         hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  884.                         bc: function(data, row) {
  885.                             coArgVar = data[row]['name']
  886.                             that.setUpQuantityLists()
  887.                             if (data[row]['value'] != 0) {
  888.                                 $('#coArgFrom').val(0.5 * data[row]['value']);
  889.                                 $('#coArgTo').val(2.0 * data[row]['value']);
  890.                             } else {
  891.                                 $('#coArgFrom').val(-1);
  892.                                 $('#coArgTo').val(1);
  893.                             }
  894.                             // if the clicked arg-quantity happens to be in cat.-I, and if it happens to be a slider,
  895.                             // we take the lower and upper bounds of the slider as from- and to values.
  896.                             for (var j = 0; j < symbolTable.length; j++) {
  897.                                 if (symbolTable[j].name == coArgVar) {
  898.                                     var myC1I = symbolTable[j].myCat1Index;
  899.                                     if (myC1I >= 0) {
  900.                                         if (cat1Vars[myC1I].type == "slider") {
  901.                                             $('#coArgFrom').val(cat1Vars[myC1I].low);
  902.                                             $('#coArgTo').val(cat1Vars[myC1I].high);
  903.                                         }
  904.                                     }
  905.                                 }
  906.                             }
  907.                             autoScale = true;
  908.                             rememberState = true;
  909.                             that.plotUserGraphOrContour();
  910.                         }
  911.                     })
  912.                 }
  913.                 userPlotArgsList.drawTable(userPlotArg, plotArgFormat);
  914.                 userPlotRangesList.drawTable(userPlotRange, [{
  915.                     bd: 'name',
  916.                     bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#cccccc"',
  917.                     hd: 'name',
  918.                     tt: 'the name of this quantity',
  919.                     hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  920.                     bc: function(data, row) {
  921.                         if (data[row]['value'] != 0) {
  922.                             $('#rangeFrom').val(0.5 * data[row]['value']);
  923.                             $('#rangeTo').val(2.0 * data[row]['value']);
  924.                         } else {
  925.                             $('#rangeFrom').val(-1);
  926.                             $('#rangeTo').val(1);
  927.                         }
  928.                         rangeVar = data[row]['name'];
  929.                         this.autoScale = true;
  930.                         that.plotUserGraphOrContour();
  931.                     }
  932.                 }, {
  933.                     bd: function() {
  934.                         return '?'
  935.                     },
  936.                     bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00cc00;text-decoration:underline;"',
  937.                     hd: '?',
  938.                     tt: 'the comment (explanation) of this quantity',
  939.                     hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"',
  940.                     bc: function(data, row) {
  941.                         var k = 0;
  942.                         var fnd = false;
  943.                         while (!fnd && k < script.length) {
  944.                             if (script[k].varName == data[row]['name']) {
  945.                                 fnd = true;
  946.                                 if (script[k].comment) {
  947.                                     alert(script[k].comment);
  948.                                 } else {
  949.                                     alert("could not find comment text for quantity " + data[row]['name']);
  950.                                 }
  951.                             } else {
  952.                                 k++;
  953.                             }
  954.                         }
  955.                         if (!fnd)
  956.                             alert("could not find quantity " + data[row]['name']);
  957.                     }
  958.                 }, {
  959.                     bd: 'value',
  960.                     bf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#00ffff"',
  961.                     hd: 'value',
  962.                     tt: 'the value for this quantity',
  963.                     hf: 'style=" text-align: left;font-family:Verdana;font-size:60%;color:#ffffff"'
  964.                 }]);
  965.             }
  966.             //-------------------------------------------------
  967.         var varSorter = function(a, b) {
  968.                 return (a.name > b.name ? 1 : (a.name < b.name ? -1 : 0));
  969.             }
  970.             //------------------------------------------------------------------------------------------------------------------
  971.         var testReachable = function(argVar, rangeVar, cnter) {
  972.                 for (var i = 0; i < symbolTable.length; i++) {
  973.                     symbolTable[i].touched = false;
  974.                 }
  975.                 var result = reachable(argVar, rangeVar, cnter)
  976.                 for (i = 0; i < symbolTable.length; i++) {
  977.                     symbolTable[i].touched = false;
  978.                 }
  979.                 return result
  980.             }
  981.             //-------------------------------------------------------------------------------------------------------------------
  982.         var reachable = function(argVar, rangeVar, cnter) {
  983.                 // return true if the rangeVar depends on the argVar. Do a  recursive connectivity search in the depOn-arrays in the symboltable entries, starting
  984.                 // in rangeVar.
  985.                 if (cnter > script.length) {
  986.                     if (!msgHasBeenGiven) {
  987.                         alert("Cannot assess if quantity " + rangeVar + " depends on quantity " + argVar + ". Perhaps there is a cyclic dependency in the model.")
  988.                         msgHasBeenGiven = true
  989.                     }
  990.                     return false
  991.                 }
  992.                 var iRangeIndex = findSymbolTableEntryPoint(rangeVar);
  993.                 if (!symbolTable[iRangeIndex].touched) {
  994.                     var isReachable = false;
  995.                     var i = 0;
  996.                     if (argVar == rangeVar)
  997.                         return true;
  998.                     while (i < symbolTable[iRangeIndex].depOn.length && !isReachable) {
  999.                         symbolTable[iRangeIndex].touched = true
  1000.                         if (reachable(argVar, symbolTable[iRangeIndex].depOn[i].name, cnter + 1)) {
  1001.                             isReachable = true;
  1002.                         } else {
  1003.                             i++;
  1004.                         }
  1005.                     }
  1006.                 } else {
  1007.                     return false
  1008.                 }
  1009.                 return isReachable;
  1010.             }
  1011.             //------------------------------------------------------------------------------------------------------------------
  1012.         var executeOnBehalfOfGraph = function(p1, p2) {
  1013.                 shouldCheckUnits = false
  1014.                 if (NITER_SET == 0) {
  1015.                     for (var k = 0; k < symbolTable.length; k++) {
  1016.                         if (k == p1 || k == p2) {
  1017.                             symbolTable[k].eval = true;
  1018.                         } else {
  1019.                             symbolTable[k].eval = false;
  1020.                         }
  1021.                     }
  1022.                     rt.execute(false, false);
  1023.                 } else {
  1024.                     // now we cannot use rt.execute, since we need to keep the symboltable value with index p the same.
  1025.                     // So we have to do the main part of preruninitialization and iterating over NITER_SET loops ourselves.
  1026.                     var nIter = 0;
  1027.                     rt.clearHistories();
  1028.                     while (nIter < NITER_SET) {
  1029.                         var i = 0;
  1030.                         while (i < symbolTable.length) {
  1031.                             if (i != p1 && i != p2) {
  1032.                                 if (symbolTable[i].valOb instanceof Array) {
  1033.                                     symbolTable[i].valOb = [];
  1034.                                 } else {
  1035.                                     symbolTable[i].valOb = 0;
  1036.                                 }
  1037.                                 symbolTable[i].eval = false;
  1038.                             } else {
  1039.                                 symbolTable[i].eval = true;
  1040.                             }
  1041.                             symbolTable[i].touched = false;
  1042.                             i++;
  1043.                         }
  1044.                         rt.executeOnceBare();
  1045.                         nIter++;
  1046.                     }
  1047.                 }
  1048.             }
  1049.             //--------------------------------------------------
  1050.         var myIsNumber = function(n) {
  1051.             return !isNaN(parseFloat(n)) && isFinite(n);
  1052.         }
  1053.  
  1054.     }
  1055.     //--------------------------------------------------------------
  1056. var usesHistory = function() {
  1057.         var useHis = false
  1058.         for (var i = 0; i < symbolTable.length; i++) {
  1059.             if (symbolTable[i].dValOb.length > 0) {
  1060.                 useHis = true;
  1061.             }
  1062.         }
  1063.         return useHis
  1064.     }
  1065.     //-------------------------------------------------------------
  1066. var niceNumber = function(p, dir) {
  1067.     // clips p to a nearest number with no more than 2 non-zero decimals.
  1068.     // If dir==false round down, otherwise round up.
  1069.     var q = Math.abs(p);
  1070.     var nDec = Math.round(Math.log(q) / 2.302585092994046);
  1071.     var refN = Math.pow(10, nDec);
  1072.     if (dir) {
  1073.         var reduced = refN * Math.ceil(10 * q / refN) / 10;
  1074.     } else {
  1075.         var reduced = refN * Math.floor(10 * q / refN) / 10;
  1076.     }
  1077.     if (p < 0) {
  1078.         return -reduced;
  1079.     } else {
  1080.         return reduced;
  1081.     }
  1082.  
  1083. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement