本文介绍了p5.j​​s代码不会抛出错误,但是不会加载鼠标点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对总统候选人的演讲进行分析。我有一个包含以下变量的数据文件:

I'm doing an analysis of the presidential candidates speeches. I have a data file with the following variables:

> names(cl.context)
[1] "id"        "category"  "statement" "nchar"     "polarity"

语句变量由来自三个的每个属于一个类别的句子填充。 polarity 范围从-1到1,反映句子是否有正偏差,中性偏差或负偏差。

我试图做在p5是有语句显示类别,随机x,y放置,当用户单击鼠标内部的画布。语句本身根据其极性着色。

我终于得到了开发者控制台不会抛出任何错误,它绘制画布的点。但是当我在画布中单击时,没有发生任何事。没有语句出现。

我对JavaScript非常新,由于它不会抛出错误消息,我无法解决问题所在。希望在这里提供一些建议。

The statement variable is populated by sentences that each belong to one category from three. The polarity ranges from -1 to 1, reflecting whether the sentence has a positive bias, neutral, or negative bias.
What I'm trying to do in p5 is to have statements displayed by category, with random x,y placement, when the user clicks the mouse INSIDE the canvas. The statements themselves are colored according to their polarity.
I finally got to the point where the developer console doesn't throw any errors and it draws the canvas. But when I click within the canvas, nothing happens. No statements appear.
I'm VERY new to JavaScript, and since it's not throwing an error message, I can't resolve where the issue lies. Hoping for some advice here.

我的p5代码:

var clContext;
var x;
var y;

const STATEMENTS = 118, CATEGORY = 3, QTY = STATEMENTS/CATEGORY | 0,
      POLARITY = 3,
      statements = Array(STATEMENTS), inds = Array(CATEGORY), polarity = Array(POLARITY);

      //load the table of Clinton's words and frequencies
function preload() {
        clContext = loadTable("cl_context.csv", "header");
      }

function setup() {
  createCanvas(647, 400);
  background(51);
  // Calling noStroke once here to avoid unecessary repeated function calls
  noStroke();
  // iterate over the table rows
  for(var i=0; i<clContext.getRowCount(); i++){
      //- Get data out of the relevant columns for each row -//
      var inds = clContext.get(i, "category");
      var statements = clContext.get(i, "statement");
      var polarity = clContext.get(i, "polarity")
    }

  for (let i = 0; i < statements; randomCategoryStates(i++));
  // create your Statement object and add to
  // the statements array for use later
  inds[i] = new Statement();


    console.info(inds);
}

function draw() {
  if(mouseClicked == true){
  for(var i=0; i<inds.length; i++) {
      inds[i].display();
  }
}
}

function mouseClicked() {
  if((mouseX < width) && (mouseY < height)) {
      randomCategoryStates(~~random(CATEGORY));
      redraw();
      return false;
  }

}

// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
  let idx = inds[group], rnd;
  while ((rnd = ~~random(QTY)) == idx);
  inds[group] = rnd;
}

// Function to align statements, categories, and polarity
function Statement() {
  this.x = x;
  this.y = y;
  this.xmax = 10;
  this.ymax = 4;
  this.cat = inds;
  this.statement = statements;
  this.polarity = polarity;
  // set a random x,y position for each statement
  this.dx = (Math.random()*this.xmax) * (Math.random() < .5 ? -1 : 1);
  this.dy = (Math.random()*this.ymax) * (Math.random() < .5 ? -1 : 1);
}
// Attach pseudo-class methods to prototype;
// Maps polarity to color and x,y to random placement on canvas
Statement.prototype.display = function() {
  this.x += this.dx;
  this.y += this.dy;
  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);
  fill(cols);
  textSize(14);
  text(this.statement, this.x, this.y);
};

EDIT:让我困惑的是,这个代码在Processing论坛上没有包括在 draw 函数中调用 mouseClicked()函数,因此我补充说。

One thing that confused me is that the help I got with this code on the Processing forum didn't include a call for the mouseClicked() function in the draw function, so I added that. Not entirely sure that I did it correctly or if it was even necessary.

推荐答案

您的代码有很多功能。

Your code has a lot going on. I'm going to try to go through everything, in no particular order:

为什么需要这些变量?

var x;
var y;

我知道你认为你正在使用它们传递到 Statement ,但是你从来没有设置过这些变量!让我们现在摆脱他们,因为他们不做任何事情。

I know that you think you're using them to pass in a position to a Statement, but you never set these variables! Let's just get rid of them for now, since they aren't doing anything. This will cause an error in your code, but we'll fix that in a second.

看看这个for循环:

for(var i=0; i<clContext.getRowCount(); i++){
      //- Get data out of the relevant columns for each row -//
      var inds = clContext.get(i, "category");
      var statements = clContext.get(i, "statement");
      var polarity = clContext.get(i, "polarity")
    }

这里你正在读取CSV文件,但是你不对这些变量做任何事情。然后你可以这样做:

Here you're reading in the CSV file, but then you aren't doing anything with these variables. You then follow that up with this:

for (let i = 0; i < statements; randomCategoryStates(i++));
  // create your Statement object and add to
  // the statements array for use later
  inds[i] = new Statement();

注意在for循环后的分号! $ c> inds [i] = new Statement()行是循环,这没有任何意义。我也不知道你在使用 randomCategoryStates(i ++)部分做什么。

Notice the semicolon after that for loop! That means the inds[i] = new Statement() line is outside the loop, which doesn't make any sense. I also don't really know what you're doing with the randomCategoryStates(i++) part.

将所有这些结合到一个循环中:

You need to combine all of that into one loop:

  for (var i = 0; i < clContext.getRowCount(); i++) {
    var category = clContext.get(i, "category");
    var statement = clContext.get(i, "statement");
    var polarity = clContext.get(i, "polarity")
    inds[i] = new Statement();
  }

但这还是没有意义,因为你永远不会将这些变量传递到 Statement 类。

But this still doesn't make any sense, because you're never passing those variables into your Statement class. So let's take a look at that.

我只是添加一些注释:

function Statement() {
  this.x = x; //when do you ever set the value of x?
  this.y = y; //when do you ever set the value of y?
  this.cat = inds; //cat is the array that holds all statements? What??
  this.statement = statements; //statement is the statements array, but nothing is ever added to that array?
  this.polarity = polarity; //when do you ever set the value of polarity?

正如你所看到的,你在这里做的事情没有什么意义。您需要更改此构造函数,以便使用参数,然后您需要传入这些参数。类似这样:

As you can see, what you're doing here doesn't make a lot of sense. You need to change this constructor so that it takes arguments, and then you need to pass those arguments in. Something like this:

function Statement(category, polarity, statement) {
  this.category = category;
  this.statement = statement;
  this.polarity = polarity;
}

现在我们有了,我们可以改变for循环中的行this:

Now that we have that, we can change the line in our for loop to this:

inds[i] = new Statement(category, statement, polarity);

但这还是没有意义。语句,类别和极性的数组?你不只是想使用 Statement 类的实例来保存它们的一个数组?所以,让我们摆脱 inds polarity 变量,因为它们不用于任何东西。

But that still doesn't make sense. Why do you have separate arrays for statements, categories, and polarities? Don't you just want one array that holds them all, using instances of the Statement class? So let's get rid of the inds and polarity variables, since they aren't used for anything.

然后我们将该行更改为:

We then change that line to this:

statements[i] = new Statement(category, polarity, statement);

我们还必须改变其他仍然使用

让我们从您的 draw() function:

Let's just start with your draw() function:

function draw() {
  if (mouseClicked == true) {
    for (var i = 0; i < statements.length; i++) {
      statements[i].display();
    }
  }
}

鼠标按下时显示什么,当鼠标未按下时什么也不显示?我不知道这是有道理,但还好。即使这样,这段代码没有意义,因为 mouseClicked 是一个函数,而不是一个变量。要确定是否按下鼠标,要使用变量,您不需要 == true 部分。

So I guess you only want anything to display while the mouse is pressed down, and nothing to display when the mouse is not pressed down? I'm not sure that makes sense, but okay. Even so, this code doesn't make sense because mouseClicked is a function, not a variable. To determine whether the mouse is pressed, you need to use the mouseIsPressed variable, and you don't need the == true part.

if (mouseIsPressed) {

我不知道这两个函数应该做什么: / strong>

I have no idea what these two functions are supposed to do:

function mouseClicked() {
  if ((mouseX < width) && (mouseY < height)) {
    randomCategoryStates(~~random(CATEGORY));
    redraw();
    return false;
  }
}

// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
  let idx = statements[group],
    rnd;
  while ((rnd = ~~random(QTY)) == idx);
  statements[group] = rnd;
}

有更简单的方法来获取随机数据。我现在要删除这些,因为他们比他们的价值更麻烦。

There are much simpler ways to get random data. I'm just going to delete these for now, since they're more trouble than they're worth. We can go back and add the random logic later.

现在,让我们来看看 display()函数在语句内:

For now, let's look at the display() function inside your Statement class:

Statement.prototype.display = function() {
  this.x += this.dx;
  this.y += this.dy;
  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);
  fill(cols);
  textSize(14);
  text(this.statement, this.x, this.y);
};

我们从未真正声明 x code> y , dx dy 他们到构造函数:

We never actually declared the x, y, dx, or dy, variables, so let's add them to the constructor:

  this.x = random(width);
  this.y = random(height);
  this.dx = random(-5, 5);
  this.dy = random(-5, 5);

返回 display() 这些行没有任何意义:

  var cols = map(this.polarity == -1, 205, 38, 38);
  var cols = map(this.polarity == 0, 148, 0, 211);
  var cols = map(this.polarity == 1, 0, 145, 205);

为什么要声明同一变量3次?为什么要将布尔值映射到数值?这没有任何意义。现在,让我们摆脱这些行并简化你的逻辑:

Why are you declaring the same variable 3 times? Why are you trying to map a boolean value to a number value? This doesn't make any sense. For now, let's just get rid of these lines and simplify your logic:

  if(this.polarity == -1){
    fill(255, 0, 0);
  }
  else if(this.polarity == 1){
    fill(0, 255, 0);
  }
  else{
    fill(0, 0, 255);
  }

这将使负极性为红色,正极性为绿色,中性极性为蓝色。

This will make negative polarity red, positive polarity green, and neutral polarity blue.

现在我们有了这个,我们可以运行代码。当您按住鼠标时,您将看到您的语句随机显示和移动。但是,他们会很快填满你的屏幕,因为你不会清除旧的框架。 每当您想要清除旧框架时,您需要调用 background()函数。我们可以在 draw()函数,或者直接在 if(mouseIsPressed)语句之前。

Now that we have this, we can actually run the code. When you hold the mouse down, you'll see your statements display and move around randomly. However, they'll quickly fill up your screen because you aren't ever clearing out old frames. You need to call the background() function whenever you want to clear out old frames. We might do that at the beggining of the draw() function, or right inside the if(mouseIsPressed) statement, before the for loop.

  if (mouseIsPressed) {
    background(51);
    for (var i = 0; i < statements.length; i++) {

如果您进行所有这些更改,您将有一个有效的计划。我愿意打赌,它仍然不能完全按照您的要求。 你必须更简单。你的代码有点麻烦,这是一次尝试写整个程序,而不是一次测试一个小块的结果。 这就是为什么我们要求 ,因为调试这样的整个操作是非常痛苦的。

If you make all those changes, you will have a working program. I'd be willing to bet that it still doesn't do exactly what you want. You're going to have to start much simpler. Your code is a bit of a mess, and that's a result of trying to write the whole program all at once instead of testing small pieces one at a time. This is why we ask for an MCVE, because debugging the whole thing like this is very painful. You need to start narrowing your goals down into smaller pieces.

例如,如果您现在想让每次只显示一个语句,则开始用一个更简单的示例草图,只显示一个硬编码语句。在尝试将其集成到主程序之前,请让它正常工作。如果您希望按类别排列语句,则使用更简单的示例草图重新开始,只显示基于类别的语句,而不需要任何额外的逻辑。

For example, if you now want to make it so only one statement appears at a time, start over with a simpler example sketch that only shows one hardcoded statement. Get that working perfectly before you try to integrate it into your main program. If you want the statements to be ordered by category, then start over with a simpler example sketch that only shows statements based on category, without any of the extra logic. That way if you have a question about something specific, you can post that small code and it will be much easier to help you.

祝你好运。

这篇关于p5.j​​s代码不会抛出错误,但是不会加载鼠标点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 20:17