Trying to toggle the visibility of MarkerClusterer (V3):
var hydrantsShowing = true;
function ToggleHydrants() {
var markers = hydrantsClusterer.getMarkers();
for (var i = 0; i < markers.length; i++) {
markers[i].setVisible(!hydrantsShowing);
}
hydrantsShowing = !hydrantsShowing;
}
The markers do toggle but with two problems:
1. The map must be panned a bit to the change can take place.
2. The MarkerClusterer icons (with the numbers) are always there, even after the markers are not visible.
I've also tried using the setMap approach, but with similar behavior:
var hydrantsShowing = true;
function ToggleHydrants() {
var markers = hydrantsClusterer.getMarkers();
if (hydrantsShowing) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(null);
}
}
else {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(gmap);
}
}
hydrantsShowing = !hydrantsShowing;
}
Solved it by using MarkerClustererPlus instead.
var hydrantsShowing = true;
function ToggleHydrants() {
var markers = hydrantsClusterer.getMarkers();
for (var i = 0; i < markers.length; i++) {
markers[i].setVisible(!hydrantsShowing);
}
hydrantsClusterer.repaint();
hydrantsShowing = !hydrantsShowing;
}
Calling repaint() after setting visibility sorted all issues.
The original MarkerClusterer don't have such a function.
Related
I have a dc.js example going where I'd like to calculate moving averages over two different windows of the dataset and group them. Ultimately, I'd like to also group the ratio between the two moving averages with them so I can access them using a key.
I've got a handle on how to do single moving avg using reductio, but I'm not sure how to do two of them concurrently, make a ratio, and show all three (MA1,MA2,Ratio) in the graph.
Here is how I'm doing each independent MA:
var date_array = [];
var mapped_date_array = [];
var activities_infinity = activityDistanceByDayGroup.top(Infinity);
var i = 0;
for (i=0; i < activities_infinity.length; i++) {
date_array.push(activities_infinity[i].key);
}
date_array.sort(function (date1, date2) {
if (date1 > date2) return 1;
if (date1 < date2) return -1;
})
mapped_date_array = date_array.map(function(e) { return e.toDateString();
});
// For Chronic Load
var cLoadMovingAvg = activityByDay.groupAll();
cReducer = reductio().groupAll(function(record) {
var idx = mapped_date_array.indexOf(record.dtg.toDateString());
if (record.dtg < date_array[9]) {
return [date_array[idx]];
} else {
var i = 0;
var return_array = [];
for (i = 9; i >= 0; i--) {
return_array.push(date_array[idx - i]);
}
return return_array;
}
}).count(true).sum(dc.pluck('Distance')).avg(true)(cLoadMovingAvg);
// For Acute Load
var aLoadMovingAvg = activityByDay.groupAll();
aReducer = reductio().groupAll(function(record) {
var idx = mapped_date_array.indexOf(record.dtg.toDateString());
if (record.dtg < date_array[3]) {
return [date_array[idx]];
} else {
var i = 0;
var return_array = [];
for (i = 3; i >= 0; i--) {
return_array.push(date_array[idx - i]);
}
return return_array;
}
}).count(true).sum(dc.pluck('Distance')).avg(true)(aLoadMovingAvg);
jsFiddle is here: http://jsfiddle.net/gasteps/hLh5frc8/2/
Thanks so much for any help on this!
When I looping through a nodelist obtained by querySelectorAll and add a new class for each one,it takes much less time(3ms) than which obtained by getElementsByClassName(100ms).Why?
var container = document.getElementById('box-container');
var button = document.getElementById('button');
for (var i = 0; i < 3000; i++) {
var div = document.createElement('div');
div.classList.add('box');
div.index = i;
container.appendChild(div);
}
button.addEventListener('click', function() {
var box1 = container.getElementsByClassName('box');
for (var i = 1;i < box1.length; i+=2){
box1[i].classList.toggle('gray');
};
var box2 = container.querySelectorAll('.box');
for (var i = 1;i < box2.length; i+=2){
box2[i-1].classList.toggle('gray');
};
});
The difference is the type of list you are running on.
box1 is a NodeList (a.k.a a live node list) which is updated when the DOM changes. box2 is an array, which is a non-live list - so changing the DOM doesn't affect it.
What happens when you iterate on box1 is that on every class toggle, the box1 list is updated, which causes the overhead.
Here's a test you can easily run:
var container = document.getElementById('box-container');
var button = document.getElementById('button');
for (var i = 0; i < 6000; i++) { // added 3000 more to challenge modern browsers...
var div = document.createElement('div');
div.classList.add('box');
div.index = i;
container.appendChild(div);
}
button.addEventListener('click', function () {
var box1 = container.getElementsByClassName('box');
for (var i = 1; i < box1.length; i += 2) {
box1[i].classList.toggle('gray');
}
var deadBox1 = [];
for (i = 0; i < box1.length; i++) {
deadBox1[i] = box1[i];
}
for (var i = 1; i < deadBox1.length; i += 2) {
deadBox1[i].classList.toggle('gray');
}
var box2 = container.querySelectorAll('.box');
for (i = 1; i < box2.length; i += 2) {
box2[i - 1].classList.toggle('gray');
}
});
Now run the chrome performance (or timeline) tool. You can see the diff here:
I've made the following program to simulate the classic card game "War". But when I try to run it, it experiences stack overflow. Why? I thought my algorithm was as effective as it could be. Another weird thing that happens is that 1 out of 10 times the program will finish, returning a VERY low vale for the round count (around 26). The code is as follows:
Firstly, I have a class named Card.
package {
public class Card {
public var cardName:String;
public var suit:String;
public var number:int;
public function Card() {
}
}
}
Then I have the following code:
import flash.utils.getDefinitionByName;
var cardDeck:Array = new Array();
var suits:Array = new Array();
suits = ["Hearts", "Clubs", "Spades", "Diamonds"];
for each (var suit in suits)
{
for (var a = 1; a <= 13; a++)
{
var card:Card = new Card();
card.cardName = suit + a;
card.number = a;
card.suit = suit;
cardDeck.push(card);
}
}
var shuffledCardDeck:Array = new Array();
var randomPos:int = 0;
for (var b = 0; b < 52; b++) {
randomPos = Math.random()*cardDeck.length;
shuffledCardDeck[b] = cardDeck[randomPos];
cardDeck.splice(randomPos, 1);
}
var handOne:Array = new Array();
var handTwo:Array = new Array();
for (var c = 0; c < 26; c++) {
handOne.push(shuffledCardDeck[c]);
}
for (var d = 26; d < 52; d++) {
handTwo.push(shuffledCardDeck[d]);
}
var roundCount:int;
round();
function round() {
roundCount+=1;
var cardOne:Card = handOne[0];
var cardTwo:Card = handTwo[0];
if (cardOne.number < cardTwo.number) {
// Player two wins
handTwo.push(cardOne);
handOne.splice(0, 1);
} else if (cardOne.number > cardTwo.number) {
// Player one wins
handOne.push(cardTwo);
handTwo.splice(0, 1);
} else {
// Draw
handOne.splice(0,1)
handOne.push(cardOne);
handTwo.splice(0,1)
handTwo.push(cardTwo);
}
if (handOne.length == 0 || handTwo.length == 0) {
trace("Good game")
} else {
round();
}
}
trace(roundCount);
Flash runtime’s maximum recursion limit is default 1000, but can be set via the compiler argument default-script-limits. Instead of just recursion, call the function in an interval to prevent such stack overflow. It will be helpful even when you decide to show visually the process to the gamers.
setTimeout(round,50); //in place of round();
Source: http://www.designswan.com/archives/as3-recursive-functions-vs-loop-functions.html
I need help and quick since this project is for this wednesday and i dont know what its wrong with my code and its screwing everything.
This is supposed to be a battleships game
the click handler keeps screwing me over and i hope you can help me`
this.Handler = function (getRow, getColumn) {
var myId = "#grid_" + getRow + "_" + getColumn;
if (this.GridArray[getRow][getColumn] == 0) {
$(myId).removeClass('grid');
$(myId).addClass('gridMiss');
this.bullets--;
}
else if (this.GridArray[getRow][getColumn] == 1) {
$(myId).removeClass('grid');
$(myId).addClass('gridHit');
explosion.pause();
explosion.play();
Ships.isHit(getRow, getColumn);
this.ShipStatus();
this.bullets--;
this.bulletStatus();
//call the function that keep track of the hits of the ships
}
}
this.ClickHandler = function () {
refOutside = this
$('.grid').click(function (eventData) {
var getRow = $(this).attr('data-Row');
var getColumn = $(this).attr('data-Column');
refOutside.Handler(getRow, getColumn);
});
}
}
And in here i have the creation of the array
this.CreateEmptyGrid = function () {
for (i = 0; i < ROWS; i++) {
this.GridArray[i] = [];
for (j = 0; j < COLUMNS; j++) {
this.GridArray[i][j] = 0;
}
}
}
I am trying to load a world(kind of..) into webglfrom an external file which has information of vertex position and face positions but the problem is the file containing the data is very large..(about 100mb). In my approach I am using the file as buffer and have a single buffer in the init buffer which is over-written again and again. What I am doing is, I am reading the values for an object from the file and drawing it on the canvas, then over-writing the buffer with the data of other object in my scene and adding it to the scene. In short I am not saving the vertex and face information. While animating I am reading the entire file again and re-drawing. Its working fine with a file size of 20mb. but for file of large size I am not able to use high frame rate while animating. Which is not looking good.
My question is should I put all the vertex information into buffer and then draw the graphics and forget about the file…or my approach can be optimized…? Also if you can suggest any other method then it would be really helpful
try {
var fileInput = document.getElementById('fileInput');
var file = fileInput.files[0];
// read from filename
var reader = new FileReader();
reader.onload = function (e) {
var count=0;
var lastline=0;
var i;
var j;
var text = reader.result;
var lines = text.split("\r\n");
while(lastline<lines.length)
{
var vertices = [];
var VertexIndices = [];
var vertexNormals=[];
/////Position of the objects
for (i = lastline; i < lines.length; i++) {
if (lines[i] == "MESH_FACE_POSITION_LIST {") {
break;
}
}
for (j = i + 1; j < lines.length; j++) {
if (lines[j] == "}") {
break;
}
else {
var currentvertices = lines[j].split(" ");
for (var k = 0; k < currentvertices.length; k++) {
VertexIndices.push(parseInt(currentvertices[k]));//Check for ","
}
}
}
noOfVerticesForTriangles = VertexIndices.length;
for (i = j; i < lines.length; i++) {
if (lines[i] == "MODEL_POSITION_LIST {") {
break;
}
}
for (j = i + 1; j < lines.length; j++) {
if (lines[j] == "}") {
break;
}
else {
var currentvertices = lines[j].split(" ");
for (var k = 0; k < currentvertices.length; k++) {
vertices.push(parseFloat(currentvertices[k]));//Check for ","
}
}
}
noOfVertices = vertices.length / 3;
lastline=j;
//this is where i am calling the function to draw the graphics after reading the data for an object
initBuffers(vertices,VertexIndices);
drawScene();
}
}
reader.readAsText(file);
}
catch (e) {
}
}
Code for init buffer
function initBuffers(vertices,VertexIndices) {
vertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
vertexPositionBuffer.itemSize = 3;
vertexPositionBuffer.numItems = noOfVertices;
vertexIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(VertexIndices), gl.STATIC_DRAW);
vertexIndexBuffer.itemSize = 1;
vertexIndexBuffer.numItems = noOfVerticesForTriangles;
}
My question is should I put all the vertex information into buffer and
then draw the graphics and forget about the file…
Yes, this is pretty much how 3d works :)