How to measure the length of a D3.JS node's attribute - javascript

I have several paths I've made in D3.JS and on mouseover I call this mouseover function to get the attributes of that path and store them in variables. Then I try to measure the length of the level attribute and console.log it, however Im getting an error:
I'd also like to use the .slice(-1,1) method to get the last figure in that value attribute but this doesn't work either.
I think the attribute needs to be read as a string in order to do these things. but when I call .toString() on circleLevel I'm still getting this error.
here is the mouseover function:
function mouseover(){
var circleName = d3.select(this).attr("name");
var circleSize = d3.select(this).attr("size");
var circleLevel = d3.select(this).attr("level");
var levelLength = circleLevel.length();
console.log(circleLevel.length());
}
here it is on JS fiddle: http://jsfiddle.net/RL_NewtoJS/ryyt6ruj/3/

In JavaScript, string length is a prop, not a method. So
circleLevel.length()
should be
circleLevel.length
The error is because it's trying to call the length, the Number, as a function: 5() // invalid
Regarding obtaining the last character, either use
circleLevel.charAt(circleLevel.length - 1)
or
circleLevel.substr(circleLevel.length - n) // to get last n characters

Related

Why am I not getting the content of this element when I call it by its ID?

I want to limit how long a string is when updated by JS. To do so, I want to use a loop that checks the length of the current string and only accepts new inputs if the string is shorter than the maximum length.
For some reason when I ask for the length of the html element, it returns the... nature of the element?
This specifically: [object HTMLParagraphElement]
This is how I'm getting the html element:
const digits = document.getElementById("digits");
This is how I'm trying to limit the size, I marked which line I'm currently using to add numbers (it works on its own, I just want to limit how long the string can be):
addEventListenerList(numeral, "click", () => {
if (digits.toString().length > 10){ //(*)
return null;
} else {
digits.innerText += event.target.value; //This is the line that adds numbers.
}
});
So yeah, it's not working because line (*) is finding the current length to be 29 (the length of [object HTMLParagraphElement]). I have no idea how to get the length of the content, and not this... what is this exactly?
I don't know if it's useful, but just in case, numeral is a node list that I iterate through using this:
function addEventListenerList(list, event, fn){
for (let i = 0, len = list.length; i < len; i++) {
list[i].addEventListener(event, fn);
}
}
The most direct way to solve this is to use digits.textContent.length > 10 instead of digits.toString(). However, as others have noted, digits.value.length and/or digits.innerHTML.length may be relevant in some cases.
innerHTML is less desirable here because nested html objects or formatting tags like or will count as part of the calculated length. It also uses more memory than .textContent. See innerText vs innerHtml vs label vs text vs textContent vs outerText for a longer discussion on the differences.
You assigned the element to variable not its contents, to get the length of the contents depends on what element type it is.
If it is a input then you can get the value:
digits.value.length
If it is another type you can use the innerHTML property:
digits.innerHTML.length

Animate CC - Call instance with var Strings

I'm trying to make a function that make play a symbol animation (hijo) when i click other one (padre). I want a function to use them many times so I'm trying to automatized.
Im getting the instance name of click button "padre" and try to add some sting after that in this case "hijo". I created some vars but when i use string value it doesn't work.
this.padre.addEventListener("click", nose.bind(this));
function nose(evt) {
var root = this
//In this case on evt.currentTarget.name i get 'padre'
var loprimero = evt.currentTarget.name;
var loquesigue = "hijo";
var todito = loprimero + loquesigue;
//This console fine the name of instance i want gotoAndPlay
console.log(todito);
//This is i want to make work
//This give me cannot read property 'gotoAndPlay' of undefined
root.todito.gotoAndPlay(1);
//And this work fine
this.padrehijo.gotoAndPlay(1);
}
When I define var loquesigue = this.padrehijo; without quotation marks it works fine. But remember I need to use this on some other parents symbols.
This is simply logging a string:
console.log(todito);
If you have an instance with that name, you can access it using brackets:
var inst = root[todito];
console.log(inst); // Does this work?
One other note, you don't need to use bind in EaselJS, you can just use on() and its a little cleaner (docs) :)
this.padre.on("click", nose, this);
Cheers,

how to get the length of the given web element in protractor tests

I would like to find out the length of the variable which I get from the screen. If I use
var driverID = element(by.id('driverID')).getAttribute('value')
driverID.length
it is throwing and error as Property 'length' does not exist on type'Promise <string>. Can some one help me in finding the length of the string.
I would also like to know how to use string operations in protractor tests. In this case I want to know, if the string first index is 'character or a number' and the second index is 'character or a number'. I want to do this by using the length of the string.
use the count() method for the number of elements inside a Promise.
Now for your specific problem, you should do something like:
element(by.id('driverID')).getAttribute('value').then(function(attr) {
var length = attr.length; // I don't really need why you need this length
if (!isNaN(attr[0]) && !isNaN(attr[1])) {
// 1st and 2nd characters of the string are numbers.
}
})
try that:
var driverID = element(by.id('driverID')).getAttribute('value');
driverID.then((attribute) => {
console.log(attribute.length)
});
the second issue you can resolve using regex

Accessing values in javascript

I am using a JS library for facetracking/emotion detection called CLMtracker.
http://auduno.github.io/clmtrackr/examples/clm_emotiondetection.html
Note: Seems to work best in chrome for those trying to use it.
Is the example I am using, I am wondering how I can access the values for each emotion. For instance, I want check every 10 seconds what the values are and print to console. From this I would also like to compare the values to find the highest and find the emotion that is attached to that. I think I am right in saying that the max() function will give me the highest out of an array?
What I have tried:
I have tried to get emotionData[0].emotion and emotionData[0].value which should print Angry and the value, but it only prints 0. I have also tried the same method with data which does not seem to return anything.
EDIT
emotionData gets me:
however it does not seem to show any update/change as I make my expression change
ec.meanPredict(ctrack.getCurrentParameters()) returns an object containing all the current scores for all emotions.
To get the current score of "Angry", for example, you would do :
ec.meanPredict(ctrack.getCurrentParameters())[0].value
So, in order to get the current most probable emotion, you could do this :
function getCurrentEmotion()
{
if(!ec.meanPredict(ctrack.getCurrentParameters())){setTimeout(getCurrentEmotion,1000);return;}
var currentData = ec.meanPredict(ctrack.getCurrentParameters());
var currentScores = [];
//Gather all scores in an array
for(var i=0;i<currentData.length;i++)
{
currentScores.push(currentData[i].value);
}
//Get the biggest score
var max = Math.max.apply(null,currentScores);
//Calculate its index
var indexOfScore = currentScores.indexOf(max);
//Get the associated emotion
var emotion = currentData[indexOfScore].emotion;
console.log(emotion);
//Set up a loop (did not add 'var', to allow stopping it from outside)
currentEmotionLoop = setTimeout(getCurrentEmotion,3000);
}
To stop the loop at any time, do this :
clearTimeout(currentEmotionLoop);
By the way, the ec variable is declared privately, so in order for this to work, either remove var where it is declared :
var ec = new emotionClassifier();
or write this code in the same file, under the same scope.

Trying to reduce repetition of javascript using a variable

I am trying to reduce the repetition in my code but not having any luck. I reduced the code down to its simplest functionality to try and get it to work.
The idea is to take the last two letters of an id name, as those letters are the same as a previously declared variable and use it to refer to the old variable.
I used the alert to test whether I was getting the right output and the alert window pops up saying "E1". So I am not really sure why it wont work when I try and use it.
E1 = new Audio('audio/E1.ogg');
$('#noteE1').click(function() {
var fileName = this.id.slice(4);
//alert(fileName); used to test output
fileName.play();
$('#note' + fileName).addClass('active');
});
The code block works when I use the original variable E1 instead of fileName. I want to use fileName because I am hoping to have this function work for multiple elements on click, instead of having it repeated for each element.
How can I make this work? What am I missing?
Thanks.
fileName is still a string. JavaScript does not know that you want to use the variable with the same name. You are calling the play() method on a string, which of course does not exist (hence you get an error).
Suggestion:
Store your objects in a table:
var files = {
E1: new Audio('audio/E1.ogg')
};
$('#noteE1').click(function() {
var fileName = this.id.slice(4);
//alert(fileName); used to test output
files[fileName].play();
$('#note' + fileName).addClass('active');
});
Another suggestion:
Instead of using the ID to hold information about the file, consider using HTML5 data attributes:
<div id="#note" data-filename="E1">Something</div>
Then you can get the name with:
var filename = $('#note').data('filename');
This makes your code more flexible. You are not dependent on giving the elements an ID in a specific format.

Categories