I found this function to remove a gui element but i think it is outdated. So far I haven't been able to find anyone else who knows how to remove any part of a gui, whether its an entire dat.GUI() or just an added element to a dat.GUI(). The first would probably be enough for what i need (just removing the dat.GUI() all together) but either one would be super helpful!
supposed to remove a dat.GUI()
gui = new dat.GUI();
...
removeGui(gui);
function removeGui(gui, parent)
{
if(!parent)
{
parent = dat.GUI.autoPlaceContainer;
}
parent.removeChild(gui.domElement);
}
But gives back the error: cannot call method 'removeChild' of undefined, so i am guessing that autoPlaceContainer is wrong.
The original author of this function left these notes:
where the parameters gui represents the DAT.GUI you want to remove and parent is the parent container where if you didn't specify a domElement when instantiating DAT.GUI then you don't need to pass a parent.
var gui = new dat.GUI();
item = gui.add(text, 'message');
To delete:
gui.remove(item);
If your item is inside a folder, you have to do:
folder.remove(item);
If you want to remove the entire dat.GUI element along with all of its listeners, you can use gui.destroy()
If you want to reset the dat.GUI's values, you can use datGUI.__controllers.forEach(controller => controller.setValue(controller.initialValue));
You can delete dat.GUI element like this:
gui.remove()
You can try hiding it using:
gui.hide()
Change the remove function in the dat.gui.js file: "slice" wants to be "splice".
The answer can be found here: https://github.com/ulyssesp/dat.gui/commit/86f43c0be5db08c9a6d7339aa8287620306fb0b5
Related
I would like to be able to use the dc.js select menu (dc.selectMenu) in such a way that when I click on an element it gets the value of said element and that becomes the value of the select, once selected it should refresh the data as it normally would if you had just selected in the first place.
The problem I'm having is that I can set the value, but dc.redrawAll() seems to do nothing for me so I think I must be filtering wrongly, but I can't find much information online regarding how to do it other than simply using the filter method (not onclick).
I have tried to set the destination to whatever data-destination is which appears to be working, the value of the select does update when I check with console.log to check the value of the select menu, I then use the dc.redrawAll() function expecting it would filter based on the select option but it does nothing (not even an error in the console)
My function so far is looking like:
function select_destination(ndx) {
var destination_dim = ndx.dimension(dc.pluck('destination'));
var destination_group = destination_dim.group();
var destination = null;
document.addEventListener('click', function(e) {
if (!e.target.matches('.open-popup-link')) return;
e.preventDefault();
var destination = e.target.getAttribute('data-destination').toString();
document.getElementById('select-destination').value = destination;
dc.redrawAll();
});
dc.selectMenu('#select-destination')
.dimension(destination_dim)
.group(destination_group)
.filter(destination);
}
I would expect the graphs to update based on the select option but nothing happens, and I get no error message to go off either.
I suspect I'm using dc.redrawAll() wrongly as if I go to the console and type dc.redrawAll(); I get undefined but I'm really at a loss now and the documentation isn't really helping me at this point so I don't know what else to do.
they are bits of your code that I don't quite understand, for instance why do you have have filter(destination /*=null */)
anyway, So you want to filter the select menu? you can call directly the replaceFilter function with the value, as done in the source code:
menu.replaceFilter(destination);
dc.events.trigger(function () {
menu.redrawGroup();
});
See the source code for the full example of how it's done
https://dc-js.github.io/dc.js/docs/html/select-menu.js.html#sunlight-1-line-129
as for why it doesn't work, I have had some surprising results mixing d3 with pure dom js. Try to rewrite your even handler in d3, eg
d3.select('#select-destination').property('value', destination);
it's possibly that changing the value on the dom directly isn't triggering the change event.
My experience with d3 is that it works better to change the underlying data (call directly filter functions or whatever you want to do) and let dc redraw the needed rather than manipulating the dom directly
I have a group of objects (actually 3D text on an arc) that I want to remove from the scene on a specific click. Does .remove not work on groups? Here's basically what I have:
$(".inscript").on("mousedown", function(event){
var x = scene.getObjectByName("inscriptArc");
scene.remove(x);
});
This answer seems to suggest you can (remove a group from a scene using .remove), but it isn't working for me.
THREE.Scene.getObjectByName returns the first instance of a child with that name. If you have multiples you won't catch them by calling it once.
To remove all instances I would use the THREE.Object.traverse(fn(child){}) function ie:
var children_to_remove = [];
scene.traverse(function(child){
if(child.name == "inscriptArc"){
children_to_remove.push(child);
}
});
children_to_remove.forEach(function(child){
scene.remove(child);
});
you might be able to just do
scene.traverse(function(child){
if(child.name == "inscriptArc"){
scene.remove(child);
}
});
but I think there are some cases where this could cause an error if you are loading/removing anything from the scene asyncronously - because removing a child might throw an error when that child's children get traversed. Not sure, so I would try the simple one and swap with the more complicated one if it causes issues.
Yes, you definitely can remove a group of objects. You might have named children of the object instead of the actual group. Function getObjectByName did not always work as promised in older three.js releases so maybe try this.
scene.children.forEach(child => child.name == "inscriptArc" ? scene.remove(child) : null)
I want to track a variable as I navigate around my site. How can I use jQuery to output this value without having to worry about tracking down wherever it might be affected and having it update.
var num = 1;
$(#trackvariable).text(num)
I want the above to execute constantly as it were.. I don't necessarily want to do it on a timer. Is there any way to do that?
If you want to listen to changes on a textnode, you can do something like this:
function InitListener () {
var container = document.getElementById ("textContainer");
var textNode = container.firstChild;
if (textNode.addEventListener) {
textNode.addEventListener ('DOMCharacterDataModified', OnCharacterModified, false);
}
}
This will only work in Firefox (and probably Chrome in Safari also):
https://developer.mozilla.org/en/JavaScript/Guide/Working_with_Objects#Defining_Getters_and_Setters
Off the top of my head I would say that the functions changing the variable should just call some sort of update function at the end of them? just an idea. I think even if you set up some kind of custom event it would still have to manually triggered in each function.
I'm writing a Blackberry app. I have a custom list field where I can select an item in the list which pushes the edit screen onto the stack. I edit the item and save, and when I pop that screen off so I am back on my list screen, I want to view the update I just made reflected in the list. I have done this on other screens which just had LabelFields and it worked fine. However, with the list screen, calling invalidate() seems to do nothing. I know the value has saved correctly through print lines, and I see the paint() method in the listfield is getting called. But the only way I can get the list field to update is to delete it from the screen and re-add it. That seems wrong. What am I doing wrong?
public class ListTasksScreen extends MainScreen{
private TaskList tasks;
private CustomListField taskListField;
public ListTasksScreen (TaskList tasks){
super();
this.tasks = tasks;
Vector incompleteTasks = tasks.getIncompleteTasks();
taskListField = new CustomListField(incompleteTasks, tasks);
add(taskListField);
}
public void updateTaskList(TaskList t)
{
Vector incompleteTasks = t.getIncompleteTasks();
taskListField= new TaskListField(incompletetTasks, t);
//I just want to call taskListField.invalidate() here.
//the only thing that seems to work is deleting taskListField
//and re-adding
this.delete(taskListField);
add(taskListField);
}
}
Is there a typo in your code above? in the updateTaskList method you do:
taskListField= new TaskListField(incompletetTasks, t);
should it be:
taskListField= new CustomListField(incompletetTasks, t);
Anyway, I think the reason you are having problems is because when you update your task list you are actually creating a new CustomListField object. When you first do add(taskListField) you are passing a reference to the field to the screen, so it has its own reference. When you call taskListField= new CustomListField(incompletetTasks, t); you are only updating your own reference, not the one in the screen. So if you call invalidate the screen will repaint using the original reference, which must be using references to the original versions of incompleteTasks and tasks too.
The reason it works the other way is because you are actually removing the old reference and adding the new one, so the screen now knows of the updated data.
What you should do is add a method to your CustomListField that allows you to update the task list object. Then when you call that method on the existing reference to taskListField and then call invalidate, your paint method should now use the new values when it calls drawListRow in the callback.
to add item and update list:
add item to array/vector of list items
perform insert new row (listField.insert(listField.getSize());)
I was wondering if anyone has found a solution or example to actually populating the input box of a slider and having it slide to the appropriate position onBlur() .. Currently, as we all know, it just updates this value with the position you are at. So in some regards, I am trying to reverse the functionality of this amazing slider.
One link I found: http://www.webdeveloper.com/forum/archive/index.php/t-177578.html is a bit outdated, but looks like they made an attempt. However, the links to the results do not exist. I am hoping that there may be a solution out there.
I know Filament has re-engineered the slider to handle select (drop down) values, and it works flawlessly.. So the goal would be to do the same, but with an input text box.
Will this do what you want?
$("#slider-text-box").blur(function() {
$("#slider").slider('option', 'value', parseInt($(this).val()));
});
Each option on the slider has a setter as well as a getter, so you can set the value with that, as in the example above. From the documentation:
//getter
var value = $('.selector').slider('option', 'value');
//setter
$('.selector').slider('option', 'value', 37);
UPDATE:
For dual sliders you'll need to use:
$("#amount").blur(function () {
$("#slider-range").slider("values", 0, parseInt($(this).val()));
});
$("#amount2").blur(function () {
$("#slider-range").slider("values", 1, parseInt($(this).val()));
});
You'll need to use Math.min/max to make sure that one value doesn't pass the other, as the setter doesn't seem to prevent this.
You were almost there when you were using the $("#slider-range").slider("values", 0) to get each value. A lot of jQuery has that kind of get/set convention in which the extra parameter is used to set the value.
I've done some work around the jQuery UI slider to make it accept values from a textbox, it may not be exactly what you were after but could help:
http://chowamigo.blogspot.com/2009/10/jquery-ui-slider-that-uses-text-box-for.html
$slider = $("#slider");
$("#amountMin").blur(function () {
$slider.slider("values", 0,Math.min($slider.slider("values", 1),parseInt($(this).val()) ) );
$(this).val(Math.min($slider.slider("values", 1),parseInt($(this).val())));
});
$("#amountMax").blur(function () {
$slider.slider("values",1,Math.max($slider.slider("values", 0),parseInt($(this).val()) ) );
$(this).val(Math.max($slider.slider("values", 0),parseInt($(this).val())));
});
I just used martin's code and updated the id to #slider also added the math.max as he suggested so the sliders won't overlap.