AS3 tracing datagrid content - actionscript-3

I cant seem to work out to trace the content of a data grid i have populated with info;
Once I can work out how to trace it or each row i would push it into a new array for exporting.
so for example: i have a datagrid instanceNamed(info) //populated from a CVS file; text file//
containing 150 rows and 15 columns. I would simply like to trace this in the output window .From then i will work out how to write to disk.
i have been searching around but cant seem to find a solution to this problem.
thank you

Check out this tutorial: Using the Flex Automation API with Fluint
What you need is implemented in the getValuesFromGrid()-method. Check how the DataGridTabularData is used.

I have worked out how to trace a single cell or an entire DataGrid, Below is an example:
function trace_dataGrid(){
for (var k:Number = 0; k < DataGrid.length - 1; k++) {
var info += DataGrid.getItemAt(k).Team_name + "," +
DataGrid.getItemAt(k).Player_name+"\r\n";
trace(info);
}
}
OutPut
Australia Footy,Bob
Sydney Soccer,David
Australia Cricket,Jim
RunThrough:
First creat a loop counter "k" which is checking the Data Grid "length"
"get item AT" will check the first location,matching to the variable in the DataGrid
"TeamName" / " PlayerName is the next reference. After this has done it will repeat this "k++" Same structure until the condition is met(counter == datagrids Length-1) for better understanding the best bet would be how to structure Arrays,tuts ect.

Related

error in reading csv file to plot graph

i am just not able to read a csv file .I want to display a graph for it.
I am getting error:
TypeError: n is undefined
please help me out!!
d3.csv("example.csv", function(dataset){
var svg=d3.select("body").append("svg").attr("width",w).attr("height",h);
var xScale=d3.scale.ordinal().domain(d3.range(dataset.length)).rangeRoundBands([0,w],0.05);
var yScale=d3.scale.linear().domain([0,d3.max(dataset.value)]).range([0,h]);
svg.selectAll("rect").data(dataset).enter().append("rect").attr({x:function(d,i) {return xScale(i);}, y:function(d){
return h-yScale(d);}, width:xScale.rangeBand(),height:function(d){return yScale(d);},fill:function(d){return "rgb(0,0,"+(d.value*10)+")";}});
d3.select("svg").selectAll("text").data(dataset).enter().append("text").text(function(d) {return d.value;}).attr("x",function(d,i){
return xScale(i)+xScale.rangeBand()/2;}).attr("y",function(d){return h-yScale(d)+14;}).attr("font-family","sans-serif").attr("font-size","10px").attr
("fill","white").attr("text-anchor","middle");
d3.select("p").on("click",function(){
var numValues=dataset.length;
dataset=[];
for(var i=0;i<numValues;i++)
{var newNumber=Math.floor(Math.random()*25);
dataset.push(newNumber,newNumber);
}
yScale.domain([0,d3.max(dataset)]);
svg.selectAll("rect").data(dataset).transition().delay(function(d,i){return i/dataset.length*1000;})
.duration(500).attr("y",function(d){return h-yScale(d); }).attr("height",function(d) {return yScale(d);}).attr("fill",function(d){
return "rgb(0,0,"+(d.value*10)+")";});
svg.selectAll("text").data(dataset).transition().delay(function(d,i){return i/dataset.length*1000;}).duration(500).text(function(d){return d.value;})
.attr("x",function(d,i){return xScale(i)+xScale.rangeBand()/2;}).attr("y",function(d) {return h-yScale(d)+14;})
.attr("font-family","sans-serif").attr("font- size","10px").attr("fill","white").attr("text-anchor","middle")
;});
});
here is my csv file
names,value
john,78
brad,105
amber,103
james,2
dean,74
pat,45
matt,6
andrew,18
ashley,15
As mentioned by cuckovic there are quite a few errors in your code, not to mention that you seem to be using different styles to achieve similar things which is confusing. Anyway there are 3 fundamental things that are casuing you trouble, the first is your dataset. The value column of the csv is being read as a string. You need to convert it to a number by:
dataset.forEach(function (d,i) {
d.value = +d.value;
});
The next issue you have is the yScale where you have set the range to .range([0,h]);. This is the wrong way round for an svg viewport in which the y direction starts from top and increases towards the bottom. So you need to swap the 0 and h around in the range.
The next thing to address is the difference between d and d.value. When you bind data through the data() operator you are generally binding an array. In this case it is an array of objects. So after you have bound the data, d refers to each element of that array which in this case is an object containing a name and a value. This can be seen if you console.log your dataset. When d is passed to yScale it doesn't know what to do with it as it is not a number, what you really want to do is to pass d.value to yScale. So replace your d's with d.value.
Finally, the last part of your code starting at d3.select("p") does not seem to add anything.
I'd recommend reading Scott Murray's tutorials, particularly this one if you haven't already.

Can't reference a child with a variable instance name [syntax]

I want to generate villagers for my game and then organize them into a list but I'm having a bit of difficulty, here is what it's supposed to look like and here is what it actually looks like. The code for generating kinsmen is:
var k = new kinsmen ;
menuArea.kinsmenDivider.addChild(k);
totalKinsmen++;
totalKinsmenAlive++;
k.name = "kinsmen" + totalKinsmen;
The code used for sorting them is:
for (var i:int = 1; i < (totalKinsmen+1); i++) {
if (menuArea.kinsmenDivider.getChildByName("kinsmen"+i) !=null) {
menuArea.kinsmenDivider["kinsmen" + i].y = menuItemCount * 107.5;
menuItemCount++;}}
That should look through the ID's of every kinsmen that's ever existed and when it finds the ID of one that's alive it should give it a place in the menu and continue going through the other IDs.
trace ("kinsmen" + totalKinsmen);
trace (menuArea.kinsmenDivider.getChildByName("kinsmen"+i));
Both always have the same values in my tests. The debugger posts the following error during runtime:
TypeError: Error #1010: A term is undefined and has no properties.
When I remove ["kinsmen" + i] it stops giving errors and the entire menu moves down each time a new kinsmen is generated so I know that's the part causing the issue but I don't know why or how to fix it and would appreciate help, all the above code is in my document class. I only started coding AS3 a few days ago so I'm still a bit shaky. Cheers for reading.
You access the clip correctly everywhere except
menuArea.kinsmenDivider["kinsmen" + i].y
shouldn't it be :
menuArea.kinsmenDivider.getChildByName("kinsmen" + i).y

Creating a user generated list in flash

I'm trying to create a flash application that will keep track of user generated values. The app should basically allow the user to input the name of the item and it's cost. The total costs should then be added up to show a total value to the user. I can probably figure out how to add the values together, but I'm not really sure how to allow the user to create a list and then allow the user to save it. Can anyone point me towards a tutorial or point me in the right direction?
I am using variables to add user inputed numbers to come up with a total. The first problem is that actionscript 3.0 does not allow variables for texts. I just converted it to 2.0 to fix this. The second problem, is when I test the app and put in my values and click submit, I get NaN in the total values field. Is there a reason why it wouldn't add the values?
Here is the code I used for the submit button:
on (release) {
total = Number(rent) + Number(food) + Number(travel) + Number(entertainment) + Number(bills);
}
Am I missing anything?
Can I give the input text instance names and then give them variables? How are some ways to go about this?
Thanks for the help!
Have an object array, say for example
var stack:Array = new Array();
Then push the item name and it's cost to that array when user inputs, like
stack.push({item:AAA, cost:xx});
So that you can generate the list whenever you want with that array.
You have to see how this works in code. A list in actionscript could be stored inside an array, vector, dictionary or even an Object.
Var myList:Array = [];
myList.push({name: "item 1", cost: 5 });
myList.push({name: "item 2", cost: 7.5 });
If you want to grab the 'product' of "item 1" from the list, you have to create a function for that, lets call it getProductByName
function getProductByName(name:String):Object
{
for each(var product:Object in myList)
{
if (product.name === name) return product;
}
return null; // no match found
}
You can call that function like this:
var product = getProductByName("item 1");
trace(product.cost); // 5
And you can alter the product, so lets make it more expensive
product.cost += 1;
trace(product.cost); // 6
Have fun! If you are using classes, you would create one for the product, with public name and cost, and in that case you'de better use a vector, to ensure working with the right type.
This is what fixed the issue for me in action script 3.0:
myButton.addEventListener(MouseEvent.CLICK, addThem);
function addThem(e:MouseEvent)
{
totalField.text = String ( Number(field1.text) + Number(field2.text) + ....);
}
I also had to name the instances appropriately.

Can you help me make more OOP abstraction with this code?

This code is not java code, and I'm not getting any answer from ActionScript developers. So I tagged it with java, but Action Script is similar to java and this an OOP question.
I'm using Grid Data and I want to accomplish this following task:
Method 1: I want to multiply each row Row1num1 * Row1num2 and so on,
var Row1num1:String;
var Row2num2:String;
var Row2num1:String;
var Row2num2:String;
var Row3num1:String;
var Row3num2:String;
var event1:Object={num1:Row1num1,num2:Row1num2};
var event2:Object={num1:Row2num1,num2:Row2num2};
var event3:Object={num1:Row3num1,num2:Row3num2};
then add them to a dataGrid
dataGrid.columns =["num1","num2"];
dataGrid.addItem(event1);
dataGrid.addItem(event2);
dataGrid.addItem(event3);
but by using this method, if I have 20 rows, I will have a lot of variables, obviously it's bad.
method 2: In this method creating Grid Data rows at runtime and multiply them.
//button to add rowGrid
dd.addEventListener(MouseEvent.CLICK,ddd);
var numm:String="34";
function ddd(evt:MouseEvent):void
{
var event4:Object={num1:Rownum1,num2:Rownum2};
dataGrid.addItem(event4);
}
but when I use this method, I have a hard time accessing each row data and multiply them.
This example because I'm creating GPA calculator and I want to take each row credit Hours and multiply them with the scale value at the same row, first method is bad because there's not abstraction .
The second method what I'm hoping to work ,because I want user to add row depend on their number of courses.
I hope my English is not bad.
I hope my question don't get vote down, and by reading this question can you determine what I'm missing so I can learn it .
And is there any tutorial I can use to solve my problem?
I'm just addressing your first method for now, but it almost seems at though you want an array of some sort.
Here's a link on how to use Actionscript arrays.
If you need more dimensions, you can make an array of arrays. This will help you cut down on the number of variables.
I hope I correctly understood your question. I'll give it a go either way...
So, one of the best things about actionscript in comparison to most other strongly-typed Object-Oriented languages is how easy reflection is (probably thanks to its javascript origins).
That being said, what you can do is simply create an array using a "for" loop. What I am assuming is that the variables row1Num1 row2Num2 and so on already exist in your class. Otherwise, obviously it would be much more efficient to store them in an array and simply read from it into a new array. Anyhow, the code should look something like this:
method 1:
var eventsArr:Array = [];
for(var i:int = 1; this["row" + i + "Num1"] != undefined /*or i<=length*/; i++){
eventsArr.push({num1:this["row" + i + "Num1"], num2:this["row" + i + "Num2"]});
}
for(var j:int = 0; j < eventsArr.length; j++){
dataGrid.addItem(eventsArr[j]);
}
method 2:
dd.addEventListener(MouseEvent.CLICK,ddd);
var numm:String="34"; //I am assuming this refers to the row number you wanted to add.
function ddd(evt:MouseEvent):void
{
var event4:Object={num1:this["row" + numm + "Num1"],num2:this["row" + numm + "Num2"]};
eventsArr.push(event4);
dataGrid.addItem(event4);
}
Hope that helps.

Re-stacking MovieClips in an Array

I was trying to make a similar thing with the game SameGame (ie. the block above the removed blocks fall downward). Before trying this with an Array that contains MovieClips, this code worked (tried it with int values). With MovieClips on the array, it seems not working the same way.
With int values, example:
popUp(0, 4): Before: 1,2,3,4,5,6,7,8,9,10; After: 1,2,3,4,6,7,8,9,10
But with MovieClips:
popUp(0, 4): Before: 1,2,3,4,5,6,7,8,9,10; After; 1,2,3,4
// Assume the numbers are movieclips XD
Basically, it strips everything else, rather than just the said block >_<
Here's the whole method. Basically, two extra arrays juggle the values above the soon-to-be removed value, remove the value, then re-stack it to the original array.
What could be wrong with this? And am I doing the right thing for what I really wanted to emulate?
function popUp(col:uint, row:uint)
{
var tempStack:Array = new Array();
var extraStack:Array = new Array();
tempStack = IndexArray[col];
removeChild(tempStack[0]);
for(var ctr:uint = tempStack.length-(row+1); ctr > 0; ctr--)
{
removeChild(tempStack[ctr]);
extraStack.push(tempStack.pop());
trace(extraStack);
}
tempStack.pop();
for(ctr = extraStack.length; ctr > 0; ctr--)
{
tempStack.push(extraStack.pop());
//addChild(tempStack[ctr]);
}
IndexArray[col] = tempStack;
}
PS: If it's not too much to ask, are there free step-by-step guides on making a SameGame in AS3 (I fear I might not be doing things right)? Thanks in advance =)
I think you just want to remove an element and have everything after that index shift down a place to fill what you removed. There's an inbuilt function for this called splice(start:uint, length:uint);
Parameters:
start - the index to start removing elements from
length - the amount of elements to remove
var ar:Array = ["hello","there","sir"];
ar.splice(1, 1);
ar is now -> ["hello", "sir"];
As per question:
Here's an example with different types of elements:
var ar:Array = [new MovieClip(), "some string", new Sprite(), 8];
ar.splice(2, 1);
trace(ar); // [object MovieClip], some string, 8
And further example to display the indexes being changed:
trace(ar[2]); // was [object Sprite], is now 8