Hover event in graph Chart.js - chart.js

Goodnight
Possible to implement something like that? in chartjs http://grab.by/C1T6
canvas.mouseover = function(e){
var activePoints = MyCharts.getBarsAtEvent(e);
console.log(activePoints);
};
so it is impossible to catch event(

The chart is wrapped in a div, why dont you just put a move over on that element
$(function() {
$("#element").mouseover(function(e) { /* implementation */ });
});

So a little trick I found is you can use the customTooltip option to call your own function. It takes one object as a parameter, and is either false, or the segment that is being hovered over.

Related

How can I build a good abstraction for a nested tree view ui component using ImGui?

I would like to create a nested tree view ui component using ImGui. The result would look like this:
This is the code needed in order to create the nesting of Selectable() elements like so:
void imgui_nested_tree() {
bool is_expanded = ImGui::TreeNodeExV( (void*)nullptr, ImGuiTreeNodeFlags_FramePadding, "", nullptr);
ImGui::SameLine();
ImGui::Selectable("outer selectable", false);
if (is_expanded) {
bool is_expanded = ImGui::TreeNodeExV( (void*)nullptr, ImGuiTreeNodeFlags_FramePadding, "", nullptr);
ImGui::SameLine();
ImGui::Selectable("inner1 selectable", false);
if (is_expanded) {
// and so on...
}
}
}
This code also makes the little arrow and the Selectable independently clickable which is great. It means I can fire events when clicking on the Selectable next to the arrow:
Since it's easy to make a mistake when manually coding it this way, I figured I would use recursion to deal with creating those nesting elements. How would you do this?

Subscribe to a DS.Model event in controller

I have the following controller :
export default Controller.extend({
/* model is an array of Posts */
didDeletePost(post) {
/* PROBLEM HERE : post is an InternalModel */
this.get('model').removeObject(post);
/* do other stuff with post */
},
actions: {
markPostForDelete(post) {
post.markForDelete(); /* starts a timer */
post.one('didDelete', this, this.didDeletePost);
},
clearMarkPostForDelete(post) {
post.clearMarkForDelete(); /* cancel a timer which will destroyRecord */
post.off('didDelete', this, this.didDeletePost);
}
}
});
But remove the post from the model in didDeletePost does not work because the post argument is the InternalModel, not the DS.Model.
How can I achieve this ?
As it does not seem to be easy to do it like this, I guess there should be a better way to implement this kind of timer ?
Actually you don't need to remove the post from model.
Please check out the twiddle I provided : https://ember-twiddle.com/25de9c8d217eafe03aea874f8eefb0fd
In my experience and from what others have told me, listening for events rather than calling actions/functions can leave you with very confusing chains of events (and this seems to exemplify that, at least to me).
I'd do it slightly more manually with a flag (here's an example all in the model for simplicity, tho you might need to move to the controller depending on other interactions):
export default DS.Model.extend({
markPostForDelete() {
this.set('marked', true).then( () => /*function in model to start timer and then call this.deleteMarked() */);
},
clearMarkPostForDelete() {
this.set('marked', false)
},
deleteMarked() {
if(this.get('marked')) {
this.destroyRecord();
}
}
}); /* end of model */

QML not registering property change from C++ property

I'm displaying data in a GridView from a custom QAbstractListItem subclass (implementation here). Adding and removing items works fine, QML is notified of the changes and transitions work fine.
Now I'm trying to set a property of an Item inside the model and have QML react on it. The problem is, the onPropertyChanged inside QML is not called.
Here is the property in C++:
// item.h
Q_PROPERTY(bool pToBeDeleted READ toBeDeleted NOTIFY toBeDeletedChanged)
// item.cpp
void Item::requestDelete()
{
toBeDeleted_m = true;
qDebug() << "emitting";
emit toBeDeletedChanged();
}
This is what the GridView looks like:
// main.qml
GridView {
id: grid
// ...
model: empty
delegate: customComponent {
toBeDeleted: pToBeDeleted
}
ListModel {
id: empty
}
}
When the program starts, grid's model is set to my itemmodel.
And this is the QML type that does not see the changes:
// customComponentForm.ui.qml
Item {
property bool toBeDeleted: false
}
// customComponent.qml
CustomComponentForm {
onToBeDeletedChanged: {
console.debug("change")
}
}
Now when I call the method from inside the model like this:
this->items.at(i++)->requestDelete();
The output shows emitting but not change.
I have tried to include
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
which did result in onToBeDeletedChanged to be called sometimes, but that also resulted in some wonky behaviour with the error
DelegateModel::item: index out range 3 3
Two things went wrong here. First, because of the ++ at
this->items.at(i++)->requestDelete();
the dataChanged emit had the wrong index which resulted in wrong items being updated. Second of all,
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
was missing the third argument, and since in another attempt I had tried inline defining of a Vector the wrong way, I didn't find this to be the problem right away. The right call here would have been
QVector<int> v;
v.append(Qt::UserRole + 7 + 1);
// pToBeDeleted being the 7th property, always check this with
// roleNames()[Qt::UserRole + i + 1]. It should say your property.
emit dataChanged(createIndex(i, 0), createIndex(i, 0), v);
My mistake.
But on another note, since the rolename index seems to be platform dependent and signaling the change from the model is somewhat of a dirty approach, a better solution (as suggested by Kevin Krammer) would be to rewrite the itemmodel to only contain a single property, which is the QObject item. That way QML is notified of the changes item's properties have.

Unit test jqgrid action

I need to verify that the jqxgrid's 'rowClicked' action gets called using mocha unit tests in EmberJS. I have a grid initialized and can verify that it gets rendered, rows and headers are rendered, but I'm stuck on the rowclick event. I use jQuery to simulate a click on a row like this:
this.$('#row0grid_testgrid').trigger('click');
My grid code listens for the rowClick event like this:
this.grid().on('rowclick', function(evt) {
// My code here
});
How can I verify that this gets called?
Thanks
Can you do something like this - mocking functions?
/*** in your unit test ***/
//... get your grid object ...
const gridComponent = ....
// save the original function to assign it later back
const originalOn = gridComponent.on;
// now mock the on function
gridComponent.on = function(actionName, handler){
assert.ok(true, "on() function has been called");
assert.equal(actionName, "rowclick", "the action on which on() function has been triggered is correct");
}
// execute tested context
this.$('#row0grid_testgrid').trigger('click');
// tidy up
gridComponent.on = originalOn;
There are few things to mention here: if this works, you will test that on() has been called and that it was triggered on correct action 'rowclick'. However, you are still not able to test the part of your code "// My code here", within evented function.
If you want to test your evented function, what you can do is to call anonymous function from it. Let me show you what I mean:
/*** your component code ***/
// this will be called on "rowclick"
myComponentFunction: function(whatArgument){
// My code here
}
....
const self = this;
this.grid().on('rowclick', function(evt) {
// instead of pure code call a function
const someParameters = "foo";
self.myComponentFunction(someParameters);
});
...
In your unit test you are then able to mock also myComponentFunction:
// same unit test
....
const originalMyComponentFunction = gridComponent.myComponentFunction;
gridComponent.myComponentFunction = function(arg){
assert.ok(true, "myComponentFunction() has been called!");
// test argument, whatever
assert.equal(arg, "foo", "argument passed to myComponentFunction() from an event triggered on 'rowclick' is correct");
}
// tidy up myComponentFunction mock, too.
gridComponent.myComponentFunction = originalMyComponentFunction;
Btw, prefered way to set up mocks and tidy them up are to put it into beforeEach() and afterEach(), look at the ember-cli testing guides.
If you have any better idea how to test this, I would like to learn from you, too :)

ngAnimate unit test not adding class

I'm new to unit testing as well as the ng-animate module. I made a simple directive to test out ng-animate.
.directive('slideShow', function ($animate, $compile) {
return {
template: '<div class="slide-show-container"></div>',
restrict: 'EA',
replace: true,
link: function (scope, element, attrs) {
var newElement = $compile('<div class="slide-show-slide"></div>')(scope);
element.bind('mouseenter',function() {
element.append(newElement);
$animate.addClass(newElement, 'slide-enter');
});
element.bind('mouseleave',function() {
$animate.removeClass(newElement, 'slide-enter');
});
}
};
});
Then I made the following unit test to confirm that the .slide-enter class was being added.
it('should add slide-enter class', function () {
element.triggerHandler( "mouseenter" );
expect(element.children().hasClass("slide-enter")).toEqual(true)
});
The directive correctly added the class when I moused over it in a manual test. However the unit test failed and showed that the slide-enter class wasn't being added.
Finally I figured out the only way I could fix it was wrapping the unit test in a $timeout:
it('should add slide-enter class', inject(function ($timeout) {
element.triggerHandler( "mouseenter" );
$timeout(function() {
expect(element.children().hasClass("slide-enter")).toEqual(true);
});
$timeout.flush();
}));
Can anyone help me understand why this $timeout is required for the test to work? Is there another way to get this unit test to work that I'm messing?
NOTE I am using angular-animate 1.2.0-rc.2 and have documented my findings with this version. The need for the $timeout.flush() call seems to be fixed when looking at the 1.2.0-rc.3 code but I have not tested it yet. https://github.com/angular/angular.js/blob/v1.2.0-rc.3/src/ngAnimate/animate.js
I had the same problem with one of my tests. I was able to get my test to work by just calling $timeout.flush() after I had called the code that was supposed to trigger the adding of the class and before I called the expect. Your test should work if you rewrite it like:
it('should add slide-enter class', inject(function ($timeout) {
element.triggerHandler( "mouseenter" );
$timeout.flush();
expect(element.children().hasClass("slide-enter")).toEqual(true);
}));
I had to dig into the ngAnimate code to figure it out and this is what I found.
If you take a look at the angular-animate.js file at the addClass function. You will see the following:
addClass : function(element, className, done) {
performAnimation('addClass', className, element, null, null, function() {
$delegate.addClass(element, className, done);
});
}
The closure that is the last parameter to performAnimation is what will finally add the class.
In performAnimation, that last parameter is named 'onComplete`. There is a section of code that deals with calling this closure when animations should be skipped:
//skip the animation if animations are disabled, a parent is already being animated
//or the element is not currently attached to the document body.
if ((parent.inheritedData(NG_ANIMATE_STATE) || disabledAnimation).running) {
//avoid calling done() since there is no need to remove any
//data or className values since this happens earlier than that
//and also use a timeout so that it won't be asynchronous
$timeout(onComplete || noop, 0, false);
return;
}
And there is the call to $timeout that is causing the problem. When running this code in an angular test, the call to $timeout simply queues up the closure. The test code then has to call $timeout.flush() in order to get that function to run.