Listen for click / hover on individual axis labels - anychart

I'm looking for a way to change the value (or format) for an individual series label when hovering it in anycharts.
Currently I'm only able to access the entire axis and I can find no getter method for individual labels so as to attach a listener.
xAxis.labels().listen('mouseOver', function(e) {
console.log(this, e.target);
});
This jsfiddle is as far as I got (see console log), this as well as the event.target reference the entire axis but not the label:
https://jsfiddle.net/robstarbuck/pbhd4b7L/9/

Indeed, there was a little bug with cache and format() function, our dev team made the fix, so please check the working sample:
var labelIndex = e.labelIndex;
var label = this.getLabel(labelIndex);
var value = xAxis.scale().ticks().get()[labelIndex];
label.format(value * 2);
https://jsfiddle.net/pbhd4b7L/13/ – it also shows how to work with tick values:
Currently it takes the js from branch, but this fix will be included in the upcoming release – 7.14.0 version (ETA: May 2017)

Our API is a little bit complicated here, but we're working hard to improve it. Does this what you're looking for?
var labelIndex = e.labelIndex;
var label = this.getLabel(labelIndex);
label.fontColor('red');
label.draw();
https://jsfiddle.net/pbhd4b7L/10/

This issue was fixed in the 7.14.0 release, use this code:
xAxis.labels().listen('mouseOver', function(e) {
var labelIndex = e.labelIndex;
var label = this.getLabel(labelIndex);
var value = xAxis.scale().ticks().get()[labelIndex];
label.format(value * 2);
label.fontColor('red');
label.draw();
});
with the latest version: https://jsfiddle.net/2t08ahkg/3/

Related

ui-scroll: Disable update/fetch while scrolling

I am trying to use ui-scroll to provide dynamic scrolling through a large dataset.
The get method calls a back end function which queries a database. The query is "slow" so I'd like to disable queries while the scroll thumb is moving.
For example, suppose the viewport shows 10 rows and there are 100,000 rows in the database and we fetch 100 rows at a time.
If you quickly drag the thumb from the top to the bottom, ui-scroll currently makes lots and lots of requests for data. I'd like to skip all of the intermediate requests and only fetch data when the thumb stops moving.
I've fiddled with isLoading on the adapter but couldn't find a way to make this work.
Suggestions? Angular 1.4.1.
$scope.datasource = { };
$scope.datasource.get = fetchData
$scope.datasource.minIndex = 0;
$scope.datasource.maxIndex = 10553;
$scope.scrollAdaptor = {};
var loadCount = 0;
function fetchData(desc, successCb)
{
var start = desc.index;
var end = desc.index + desc.count - 1;
var url = "scrollTest.php?start=" + start + "&end=" + end;
$http.get(url)
.then(function(goodResp)
{
console.log("got data, loadCount", loadCount);
successCb(goodResp.data);
},
function(badResp)
{
});
};
There is a discussion on GitHub related to the question. In short, angular-ui-scroll can't skip intermediate requests out-of-box, but following workaround might help.
Set min/max indexes on start to make the viewport relevant to
100,000 rows
$scope.datasource.minIndex = 1
$scope.datasource.maxIndex = 10000
Bind additional scroll event to intercept user scrolling over the viewport
Check scroll position delta between two events, and if it is more than some fixed value (say, 500px), rebuild the viewport
Rebuild means adapter.reload(indexToReload) method call and setting min/max indexes
The last thing is indexToReload, it should be calculated by current scroll position and item height:
indexToReload = Math.floor(scrollTop/itemHeight)

Receiving no data when testing bound text

I have searched high and low for an answer to this question, but I could not find one that works in my instance. I am currently trying to test that some text is bound correctly (I can see it), but I cannot get the actual text when testing. Below is some code.
<h3>Borrowing Potential: {{$ctrl.borrowingPotential.value | currency}} as of
{{$ctrl.borrowingPotential.timeStamp | date:'MM/dd/yyyy hh:mm:ss a':EST}} EST</h3>
__
fit("should have a borrowing potential calculated", function () {
var tab = element(by.css('[ng-click="$ctrl.setSelectedTab($ctrl.tabs.summary)"]'));
tab.click();
var parent = element(by.tagName("member-summary"));
var borrowingPotential = parent.element(by.tagName("h3"));
expect(borrowingPotential.getAttribute("value")).toContain("Some Text");
});
Essentially, I click a tab which displays a custom component called "member-summary", then I attempt to access that element via web driver. It is the only instance of member-summary on this page. However, when I access either parent or borrowingPotential, getText() returns an empty string, and getAttribute returns a null type.
Note: I have also attempted to access the binding directly, again with no results. This does not work because the binding is not considered a child of the parent element (https://github.com/angular/protractor/issues/3147).
How can I get that text and then test that it displayed is correct?
As requested, below is the html from the Chrome debugger. As you can see, the bindings have been replaced with text.
<h3 class="ng-binding">Borrowing Potential: -$48,939,539.14 as of 01/01/0001 12:00:00 AM EST</h3>
Based on your provided info you should only retrieve the text of the h3-element because it isn't an input-field. You can use getText() for it. Your code would be like this
fit("should have a borrowing potential calculated", function() {
var tab = element(by.css('[ng-click="$ctrl.setSelectedTab($ctrl.tabs.summary)"]'));
tab.click();
var parent = element(by.tagName("member-summary"));
var borrowingPotential = parent.element(by.tagName("h3"));
// Replace the `getValue()` with `getText()`
expect(borrowingPotential.getText()).toContain("Some Text");
});

AngularJS Microsoft Edge Screen doesn't reflect the DOM

I'm using AngularJS 1.5.0 and Microsoft Edge browser screen doesn't reflect the DOM.
I would like some suggestion how this can be fixed.
I can't really apply a fix for each element as the application is somewhat big with dynamic user content including Angular equations.
Also the app include a lot of dynamic bindings linked to input boxes.
Selecting the text with the mouse turn the 0 into a 2 which is the right value in the example below.
Also changing the position style back and forth seem to force Edge to redraw the element but it's somewhat an ugly fix that I don't like very much and it need to be trigger at so many places (Ajax request, input changes and so on...)
The page start with a value of 0. Then an Ajax call is made and it go fetch the real data. After some experimentation the bug only appears if the new data is 1 character (ex: 2 or 9). And it happens every time. If it's a 2 digit number (ex: 26) then the good number appears.
Any help on this matter would be gladly appreciated.
We were facing the same problem and it stopped occurring after removing the text-transform: uppercase style from the elements that are not updating.
#Sampson, it looks like this is a bug in Edge.
I was able to make a temporary fix with the use of Mutation Observer.
Little script that I made that works for AngularJS elements created server side.
Currently those are the only one causing trouble in my app.
<script>
$(document).ready(function(){
var ua = navigator.userAgent;
var re = new RegExp("Edge/");
if (re.exec(ua) != null){
console.log('edgeMutationObserver ON!!')
var edgeMutationConfig = { characterData: true, subtree: true };
var edgeMutationObserver = new MutationObserver(function(mutations) {
var rgb_p = /rgb\((\d+), (\d+), (\d+)\)/g;
var rgba_p = /rgba\((\d+), (\d+), (\d+), (\d.?\d*)\)/g;
mutations.forEach(function(mutation){
if(mutation.target.nodeType == 3){
var that = mutation.target.parentNode;
// Save the background color
var bgc = that.style.backgroundColor;
// Get applied style from style or css
var bgc_css = bgc || $(that).css('backgroundColor');
var bgc_temp,match;
if(match = rgb_p.exec(bgc_css)){
// rgb transformed in rgba triggers update
bgc_temp = 'rgba('+match[1]+','+match[2]+','+match[3]+',1)';
}else if(match = rgba_p.exec(bgc_css)){
// Slightly modify transparency
var alpha = match[4] == 0 ? 0.01 : match[4] - 0.01 ;
bgc_temp = 'rgba('+match[1]+','+match[2]+','+match[3]+','+alpha+')';
}else{
// If either inline style or css is already equal to transparent the redraw is not made so i choose an alternate color with 0 opacity
bgc_temp = bgc_css != 'transparent' ? 'transparent' : 'rgba(0,0,0,0)';
}
// Change background color to force redraw
that.style.backgroundColor = bgc_temp;
setTimeout(function(){
// Apply back previous style
// Doesn't redraw without a timeout in Edge
that.style.backgroundColor = bgc;
},0);
}
});
});
$('.ng-binding').each(function(){
edgeMutationObserver.observe(this, edgeMutationConfig);
});
}
});
</script>

Getting scroll position with sencha architect extjs

I have been trying to get the scroll position of a tree grid in and ext.js application using sencha architect. Originally I wanted to keep the scroll position after a reload so when a user deletes a post it will scroll back to that same spot after reload. I have attempted to use various methods I have searched for but nothing is working. I'm currently testing by having a java script timeout function give me the scroll position after a few seconds, long enough for me to scroll down and console.log the position but it gives me nothing and I'm not showing anything but zero when I go into the dom and look at the tree view object. I have already tried the following
1st: var newcompheight = comboboxeample.getHeight();
2nd: getScroll: function() {
var me = this,
dom = me.dom,
doc = document,
body = doc.body,
docElement = doc.documentElement,
left, top;
if (dom === doc || dom === body) {
// the scrollLeft/scrollTop may be either on the body or documentElement,
// depending on browser. It is possible to use window.pageXOffset/pageYOffset
// in most modern browsers but this complicates things when in rtl mode because
// pageXOffset does not always behave the same as scrollLeft when direction is
// rtl. (e.g. pageXOffset can be an offset from the right, while scrollLeft
// is offset from the left, one can be positive and the other negative, etc.)
// To avoid adding an extra layer of feature detection in rtl mode to deal with
// these differences, it's best just to always use scrollLeft/scrollTop
left = docElement.scrollLeft || (body ? body.scrollLeft : 0);
top = docElement.scrollTop || (body ? body.scrollTop : 0);
} else {
left = dom.scrollLeft;
top = dom.scrollTop;
}
return {
left: left,
top: top
};
3rd: var test = window.pageYOffset;
I have also attempted to setting the keepscroll position property in Sencha architect to true and other things I have googled but nothing is working. Any help would be appreciated.
Use this:
treeGrid.getEl().getScrollTop()

Extjs 4.0.7 How do I re render my treepanel to see changes

I am creating an item selector with two boxes that move things back and forth within an extjs application. On the right box, I am creating buttons that serve to move items up and down. Essentially I am swapping the item with one above or below it. So, my code is straight forward in that regard
MoveUp: function(button, event, eOpts){
var theChosen = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
var chosenPanel = Ext.ComponenetQuery.query('#chosenTreePanel')[0];
var selected = chosenPanel.getSelectionModel().getSelection();
for( var i = 1; i < theChosen.childNodes.length; i++){
if(Ext.Array.contains(selected, theChosen.childNodes[i]) && (!Ext.Array.contains(selected, theChosen.childNodes[i-1]){
var temp = theChosen.childNodes[i];
theChosen.childNodes[i] = theChosen.childNodes[i-1];
theChosen.childNodes[i-1] = temp;
}
}
}
All of this code seems to work fine, because after clicking my button, and checking the DOM in firebug, I can see that the selected nodes have moved in the array correctly, however, this effect is never shown within my treepanel. ???How do I make the treepanel update when it's elements change. ???
TreePanel heirarchy looks like this just to clarify
Root Node
'Chosen Folder Node'
Array of items I am moving up and down within the 'folder'
I am USING VERSION 4.0.7
Attempting to use replaceChild() to fire an event to rerender does not behave as I expected
Changing:
var temp = theChosen.childNodes[i];
theChosen.childNodes[i] = theChosen.childNodes[i-1];
theChosen.childNodes[i-1] = temp;
To:
var temp = theChosen.childNodes[i];
theChosen.replaceChild(theChosen.childNodes[i-1], theChosen.childNodes[i]);
theChosen.replaceChild(temp, theChosen.childNodes[i-1]);
Results in odd behavior in which some nodes go missing. Certaintly not what I was looking for. Where am I going wrong here?
Tried the following code using the datachanged and (undocumented)refresh event:
Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );
Ext.getStore('storeId').fireEvent('datachanged', Ext.getStore('chosen') );
This does not reload anything...
SOLUTION:
Use the insertChild method of nodeInterface....
I have noticed something strange in how insertChild works in that I need to change my index more based on moving up or down will explain with code below.
To move Up:
theChosen.insertChild( (i-1), theChosen.childNodes[i]);
To move down:
theChosen.insertChild( (i+2), theChosen.childNodes[i]);
Although the -1 vs +2 they both effectively move the item by one in the appropriate direction.
If you want to update the view of the nodes, I recommend using yourTree.getView().refresh();
But you can avoid that by using parentNode.insertChild(index, childNode); where index is where you want the node to show up and parentNode is the parent to the nodes you are reordering. ChildNode can be a config for a new node or any other nodeinterface that already exists. If the node does already exist and you use the insertChild method to insert it, it will automatically remove that node from whereever else it is.
So as you provided in your question in response to my answer, your code will work with something like (this is probably how I'd do it, but this is untested):
MoveUp: function(button, event, eOpts){
var chosenPanel = Ext.ComponenetQuery.query('#chosenTreePanel')[0];
var selectedNodes = chosenPanel.getSelectionModel().getSelection();
for( var i = 0; i < selectedNodes.length; i++){
var currentNode = selectedNodes[i];
if(!currentNode.isFirst())
{
var parentNode = currentNode.parentNode;
var newIndex = parentNode.indexOf(currentNode) - 1;
parentNode.insertChild(newIndex, currentNode);
}
}
}
Edit:
Back to the the responsible event question...
You need to fire the
'datachanged'
'refresh'
Events on the store with the store as only param. That should cause a UI update. But please note that I just had a glimpse into the sourcecode and I am sure this can all be done much smarter. At least a DD solution for this exists already.
If I find some time I my look into this again, but I guess you should be fine with these events for the first.
You never see anything cause you just do it without the appropriate methods that then fire the responsible events that cause rerender. Take a look at
appendChild()
removeChild()
replaceChild()
There may also be more methods that can help on the Ext.data.NodeInterface. I recommend you to use these instead of doing it under hood without any responsible event fired.
In addition to my second comment (just a wild guess without knowing if that is exactly what you want):
MoveUp: function(button, event, eOpts){
var target = Ext.getStore('storeId').getRootNode().findChild('text', 'Chosen folder');
var selected = chosenPanel.getSelectionModel().getSelection();
target.appendChild(selected);
}

Resources