自定义JavaScript和Flot的交互

时间:2014-07-10 18:39:19

标签: javascript html flot

我在网站上遇到了各种各样的问题,我正在努力教自己JavaScript。在阅读本文时请记住,我是一位老Fortraner。我将尝试使这些问题中的每一个都格外清楚,以防其他人也希望向他们学习。所有愚蠢的错误都是我自己的。

问题#1:<input type="number" ...>内容未传递给JavaScript

HTML:

<div class="form">
  <form id="pendulum">
    <table class="form">
      <tr>
        <td>
          <label><span class="rollover">Initial angle<span>0.0 &le; <i>&theta;</i> &le; 1.6</span></span>, $\theta_0$, of the mass:</label>
          <input type="number" name="theta0" id="theta0" value="0.1" min="0.0" max="1.6" step="0.1"> rad
        </td>
      </tr>
      <tr>
        <td>
          <label><span class="rollover">Ratio<span>1.0 &le; <i>g</i>/<i>L</i> &le; 10.0</span></span> of $\frac{g}{L}$:</label>
          <input type="number" name="read_ratio" id="read_ratio" value="9.0" min="1.0" max="10.0" step="0.1">
        </td>
      </tr>
      <tr>
        <td>
          <label><span class="rollover">Initial angular velocity<span>0.0 &le; <i>&omega;</i> &le; 6.0</span></span>, $\omega_0$, of the mass:</label>
          <input type="number" name="omega_read" id="omega_read" value="0.0" min="0.0" max="6.0" step="0.1"> rad/sec
        </td>
      </tr>
      <tr>
        <td>
          <label><span class="rollover">Time-step<span>0.001 &le; <i>dt</i> &le; 0.1</span></span>, $dt$, of the system:</label>
          <input type="number" name="dt_read" id="dt_read" value="0.01" min="0.001" max="0.1" step="0.001"> sec
        </td>
      </tr>
      <tr>
        <td>
          Period of the pendulum: <span id="output"></span> sec
        </td>
      </tr>
    </table>
    <input type="button" value="Evaluate" onclick="amp()">
    <a class="js" href="amp.js">Download the JavaScript</a><br>
  </form>
</div>

JavaScript的:

function amp() {
  "use strict";
  var i_max,
    m,
    g,
    pendulum,
    f_osc,
    theta,
    omega,
    a,
    e,
    de,
    time,
    pi,
    theta0,
    read_ratio,
    const0,
    T,
    result,
    message,
    omega_read,
    dt_read,
    dt,
    i;
  i_max = 500;
  m = 1.0;
  g = 9.8;
  f_osc = 0.0;
  pendulum = document.forms.pendulum;
  theta = [];
  omega = [];
  a = [];
  e = [];
  de = [];
  time = [];
  pi = Math.acos(-1.0);
  theta0 = pendulum.elements.theta0;
  theta[0] = theta0;
  read_ratio = pendulum.elements.read_ratio;
  const0 = read_ratio;
  T = 2 * pi * Math.sqrt(Math.pow(const0, -1));
  result = T.toFixed(2);
  document.getElementById('output').innerHTML = result;
  omega_read = pendulum.elements.omega_read;
  omega[0] = omega_read;
  dt_read = pendulum.elements.dt_read;
  dt = dt_read;
  e[0] = 0.5 * (Math.pow(omega[0], 2) + const0 * Math.pow(theta[0], 2));
  time[0] = 0.0;
  i = 0;
  do {
    f_osc = -const0 * Math.sin(theta[i]);
    a[i] = f_osc / m;
    e[i] = 0.5 * (Math.pow(omega[i], 2) + const0 * Math.pow(theta[i], 2));
    de[i] = e[i] - e[0];
    theta[i + 1] = theta[i] + omega[i] * dt + 0.5 * a[i] * dt * dt;
    f_osc = -const0 * Math.sin(theta[i + 1]);
    a[i + 1] = f_osc / m;
    omega[i + 1] = omega[i] + 0.5 * (a[i + 1] + a[i]) * dt;
    e[i] = 0.5 * (Math.pow(omega[i + 1], 2) + const0 * Math.pow(theta[i + 1], 2));
    de[i] = e[i] - e[0];
    time[i + 1] = time[i] + dt;
    i = i + 1;
  } while (i < i_max);
  return time;
  return theta;
  return omega;
  return e;
}

我之前使用线性函数进行了一个简单的测试。 (好奇的是,这个当前的脚本模拟了一个简单的钟摆。)我的简单测试似乎有效;这不是。我不知道为什么不。我想返回timethetaomegae的数组。但是当我做所有这些return陈述时,JSLint尖叫着血腥谋杀。

问题#2:不知道传递的数组?

我希望执行的下一个任务是获取timethetaomegae的有趣数据,并使用Flot绘制它。但是,我不确定此信息是否正确传递给Flot脚本。例如,Chrome的错误控制台似乎没有抱怨,但对JavaScript来说是新手,我不确定做出这种&#34;健全检查的最佳做法&#34;。

JavaScript的:

function doPlot(position,time,theta,omega,e) {
  $.plot("#placeholder", [
    {
      data: [time, theta],
      label: "Angle (rad)",
      yaxis: 1,
      color: "red"
    },
    {
      data: [time, omega],
      label: "Angular Velocity (rad/sec)",
      yaxis: 2,
      color: "green"
    },
    {
      data: [time, e],
      label: "Energy (J)",
      yaxis: 3,
      color: "blue"
    }
  ],
    {
      yaxes: [ { alignTicksWithAxis: position == "left" ? 1 : null } ],
      legend: { position: "ne" }
    }
  );
};

第二个问题是绘制 x y 数据数组的正确语法。在这一点上,Flot文档似乎并不是很清楚。上面代码中显示的内容是我目前最好的猜测,但看到它根本不起作用,显然是错误的。

问题#3:Flot中的彩色轴?

如问题#2所示,我有一个包含多个 y -axes的图。为了便于阅读,我想使用用于绘制数据的相应颜色对轴2和3进行着色。我在这个问题上找到的最多的是here。但我不明白在那里做了什么。

我知道这很多,但我为了提高效率而试图涵盖很多方面,并且希望这会帮助那些尝试同样事情的人。


更新

jrouillard,谢谢你的帮助。您对return陈述的建议最具信息性。我也重新格式化了我的数据(JavaScript):

theta_plot[i + 1] = [time[i + 1], theta[i + 1]];
omega_plot[i + 1] = [time[i + 1], omega[i + 1]];
e_plot[i + 1] = [time[i + 1], e[i + 1]];

...

return [theta_plot, omega_plot, e_plot];

关于问题#3,经过一些更好的搜索后,我遇到了this。 (那里有Flot文档的多个版本;也许我看错了。)这是我最初计划的更好的替代方案。经过一些更正(JavaScript):

function doPlot(position,theta_plot,omega_plot,e_plot) {
  $.plot("#placeholder", [
    {
      data: theta_plot,
      /*label: "Angle (rad)",*/
      yaxis: 1,
      color: "red"
    },
    {
      data: omega_plot,
      /*label: "Angular Velocity (rad/sec)",*/
      yaxis: 2,
      color: "green"
    },
    {
      data: e_plot,
      /*label: "Energy (J)",*/
      yaxis: 3,
      color: "blue"
    }
  ],
    {
      yaxes: [
        {
          position: "left",
          axisLabel: "Angle (rad)",
          axisLabelPadding: 10
        },
        {
          position: "left",
          axisLabel: "Angular Velocity (rad/sec)",
          axisLabelPadding: 10
        },
        {
          position: "left",
          axisLabel: "Energy (J)",
          axisLabelPadding: 10
        },
        { alignTicksWithAxis: position == "left" ? 1 : null }
      ]
    }
  );
  $(".yaxisLabel").css("color","red");
  $(".y2axisLabel").css("color","green");
  $(".y3axisLabel").css("color","blue");
};
doPlot("left");

我还不知道这是否能达到我想要的效果,因为当我加载页面时它仍然没有绘制。现在这部分返回NaN(JavaScript):

read_ratio = pendulum.elements.read_ratio;
//read_ratio = 9.0;
const0 = read_ratio;
T = 2 * pi * Math.sqrt(Math.pow(const0, -1));
result = T.toFixed(2);
document.getElementById('output').innerHTML = result;

但是,当测试值是硬编码时,它会起作用并将预期值返回到Period of the pendulum: <span id="output"></span> sec

为什么剧本的其余部分不起作用仍然是个谜。错误控制台没有提供任何线索。和想法?

2 个答案:

答案 0 :(得分:3)

问题1:

如果您想要多次返回,则应将它们收集到一个数组中。

return [time, theta, omega, e];

您还可以根据变量返回具有已定义属性的对象:

{time: time, theta: theta, omega: omega, e: e}
但是,我没有测试你的代码,所以可能还有其他问题。


问题2:

数据格式不正确。您需要提取数组以创建正确的数据数组。

这是你当前的数组(有假数据):

[[0,1,2,3,4,5,6],[0,1,2,3,4,5,6]]

您想要做的是这种格式:

[[0,0], [1,1], [2,2], [3,3], [4,4], [5,5], [6,6]]

(第一个点是x轴,第二个点是y轴)


<强> Issue3:

我没有阅读很多关于flot代码内部细节的博文。这对初学者来说无济于事。 它确实说明您可以使用轴选项中的颜色选项访问轴的颜色。

来自doc:

Customizing the axes:
    xaxis, yaxis: {
           ...
          color: null or color spec

          ...
     } 
  

&#34;颜色&#34;选项确定行的颜色和刻度   轴,和        默认为具有透明度的网格颜色。要获得更细粒度的控制,您可以        还可以使用&#34; tickColor&#34;分别设置刻度线的颜色。        您可以使用CSS或
来自定义用于绘制轴刻度标签的字体和颜色        直接通过&#34; font&#34;选项。当&#34; font&#34;为null - 默认值 - 每个tick标签        鉴于&#39; flot-tick-label&#39;类。为了兼容Flot 0.7及更早版本        标签也被给予了'tickLabel&#39; class,但这已被弃用和计划        将在1.0.0版本发布时删除。

所以行的颜色选项和标签的css

修改

&#34;对&#34;文档可以在http://www.flotcharts.org/上找到,还有多个相关的示例和官员(以及维护过的)插件。

你提供的jsfiddle很老(flot版本是0.7,我们是0.8.3)但似乎axislabel插件仍然适用于最新的flot。

这是您使用模型数据的示例:

http://jsfiddle.net/P2yDJ/

我没有更改除假数据之外的东西,因此您的数据可能存在问题。你确定你有合适的阵列吗? 在你返回数组之前,你可以使用console.log吗? (console.log(某个变量)会在控制台中写一些变量)

EDIT2:对于你的NaN问题,你的readratio可能实际上是一个字符串。你应该确保parseInt(),然后是console.log。

答案 1 :(得分:0)

答案:read_ratio = pendulum.elements.read_ratio;后跟const0 = read_ratio.value;从表单中读取value