How to invert the legend's on-click--behavior on XY chart in amcharts4? - amcharts4

I have this issue. The default behavior of XY amchart is to load all data, and on legend click - hide the current selection. Is it possible to revert this behavior?
Like, if I select a legend- to hide all the other elements from the chart and leave the current selection.

The grammar may be strange with the help of a translator because of the weak English.
chart.legend.itemContainers.template.togglable = false;
The code above deactivates the basic behavior of the legend.
chart.legend.itemContainers.template.events.on("hit", function(ev) {
let targetName = ev.target.dataItem.dataContext.name;
chart.series.each(function (item) {
if(targetName != item.name){
item.disabled = true;
}
});
});
The code above is an event when you click the legend.
I don't know if it's the answer you want, but I wrote it down...

Related

ChartJS: Update tooltip

I'm having a chart build with ChartJS. I'm including datasets.label in multipleTooltipLabel template and facing an update issue. When changing a datasets.label and running chart.update() the tooltip is not updated. I created a JSFiddle demonstrating the issue.
The code I use to include datasets label in tooltip:
var options = {
multiTooltipTemplate: "<%=datasetLabel%>: <%= value + ' %' %>"
};
Beside that option I followed ChartJS usage example for Line charts.
Change label and update chart:
myNewChart.datasets[0].label = 'updated label';
myNewChart.update();
Label shown in tooltip is not updated...
I had a look in ChartJS source code and figured out that showTooltip function is called with a ChartElements array which was not updated.
Update: I might cached the issue. label of dataset is set on each point element and not updated if it changes. showTooltip used this "cached" dataset label when drawing a tooltip. Perhaps this should not be a question on StackOverflow but a bug report for ChartJS.
I found a solution:
myNewChart.datasets[0].points.forEach(function(point) {
point.datasetLabel = 'updated label';
});
This might also be the way it should be done. Chart.js documentation of update method says you should set myLineChart.datasets[0].points[2].value = 50; to change the value. That's confusing cause on creation dataset expects the values in data property. points is generated by Chart.Line Class on init. Naming may be different for other chart types (eg. it's bars for a bar chart).
I'm not quite sure if myLineChart.datasets[0].label value is used somewhere or if could be unchanged.
I could solve your problem by changing the original data object (data.datasets[0].label='updated label') then running myNewChart.initialize(data).
var option = {
plugins: {
tooltip: {
callbacks: {
label: function (context) {
//console.log(context);
label = 'new string ' + context.label + ', ' + context.dataIndex;
return label;
}
}
}
}
};
myChart.options = option;
ToolTips / Points Events are configurable with chartJS options...
Find more here: https://www.chartjs.org/docs/latest/configuration/tooltip.html

Famo.us - StateModifiers disappearing?

Wondering if someone might help with another pair of eyes - as I am trying to work out why some of my Famo.us 'Views' are being displayed despite having an opacity StateModifier set to '0'.
Here is my code - My apologies for it not being standard - I have "Panels" instead of "Views" and a few other things..but happy to expand on the code if needed.
function _buildSidePanel() {
this._sidePanel = _createPanel.call(this);
this._sidePanel.setOptions(this.constructor.DEFAULT_OPTIONS.sideMenu);
this._sidePanel.position = this.cm(this.constructor.DEFAULT_OPTIONS.sideMenu.position);
this._container.add(this._sidePanel.position).add(this._sidePanel);
this._menuHolder = _createPanel.call(this); //My version of a View
this._menuHolder.setOptions(this.constructor.DEFAULT_OPTIONS.sideMenu.menuHolder);
// Create StateModifiers
this._menuHolder.position = this.cm({ align: [.5,.6], origin: [.5,.6], proportions: [.9,.8] });
this._menuHolder.fadeState = this.cm({ opacity: 0 });
this._menuHolder.sizeState = this.cm();
this._menuHolder.mC = new ModifierChain();
this._menuHolder.mC.addModifier(this._menuHolder.fadeState);
this._menuHolder.mC.addModifier(this._menuHolder.sizeState);
this._menuHolder.mC.addModifier(this._menuHolder.position);
/* Tried splitting it to just modifiers but getting the same thing
this._sidePanel._container.add(this._menuHolder.fadeState)
.add(this._menuHolder.sizeState)
.add(this._menuHolder.position)
.add(this._menuHolder);
*/
this._sidePanel._container.add(this._menuHolder.mC).add(this._menuHolder);
// this._menuHolder.fadeState.setOpacity(1,this.constructor.DEFAULT_OPTIONS.sideMenu.menuHolder.transition.in);
}
I have created a ModifierChain and added among other things an Opacity State of 0. When I add this and then add the modifier and 'View' to the container it displays the View even though the View has a StateModifier of '0' so should not be displayed.
The 'fadeState.setOpacity' command is meant to transition the fadeState to display the View but it is commented out, so the View should not be displayed.
I have this working in other areas so know the approach works. I am also (hopefully) not using the same variable names, so not using a StateModifier more than once. But still stuck as to why this is being displayed.
Any help or thoughts would be gratefully appreciated.
Thanks.

Famo.us how to create a Select Surface or something equivalent

I need a select box with options and an on select / on change so i can populate a second select box.
My first instinct was to just create one using a surface with a click event and a renderController / scrollview to make my drop down appear. This works wonderfully except that if I leave and come back to the page the zindex of the scrollview breaks and it scrolls over the container size.
Its a bug I need to deal with but my other problem is that with the small Iphone screen size conventional drop downs just eat to much screen real-estate.
This stackoverflow famo.us: how to handle textbox.onchange events had some great hints on how to edit an InputSurface. I thought using that and looking at the code for a Surface I could do it but no luck.
Any Ideas on how to deal with the lack of a select surface?
You can access the value property from inside the callback function:
function SelectSurface(options) {
Surface.apply(this, arguments);
this.onchange = options.onchange;
this._superDeploy = Surface.prototype.deploy;
SelectSurface.prototype.elementType = 'select';
}
SelectSurface.prototype = Object.create(Surface.prototype);
SelectSurface.prototype.constructor = SelectSurface;
SelectSurface.prototype.deploy = function deploy(target) {
target.onchange = this.onchange;
this._superDeploy(target);
};
var regionSelector = new SelectSurface({
size:[140,40],
onchange: regionSelect(),
content: '<option disabled selected style="display:none;">REGION</option><option value="central">CENTRAL</option><option value="northern">NORTHERN</option><option value="pacific">PACIFIC</option><option value="southern">SOUTHERN</option><option value="western">WESTERN</option>',
});
var regionSelect = function(){
return function() {
alert(this.value);
}
};

How change the event in [XTK]

Hello,
I wonder how do I change my mouse event
because I would like to X.Caption activates only when I right-clicked on it.
thank you very much
If I'm correct ( other contributors, don't be afraid to correct me ), you might have to edit the internals of XTK for your needs. XTK has the "controls" defined in X.event.js for it's event such as HoverEvent and PanEvent which are acquired from the Google Closure Library. You can look into the Google Closure Library more as I haven't completely reviewed it, but X.caption is mostly derived from Goog.ui.Tooltip which can be used with the events from Goog.ui.Popup, Goog.ui.PopupBase, and Goog.events. You can try to include Goog.events into your Javascript and define your own click event or something related to that and look through the Google Closure Library some more.
If what I just wrote in the small paragraph above is not completely correct or anything like that, there are of course basic Javascript DOM Events for clicking. I'm not quite sure how those would work with XTK because XTK uses WebGL for rendering. You can review the basic events at http://www.w3schools.com/jsref/dom_obj_event.asp. If you find any solution for yourself, you are more than welcome to contribute it to XTK.
I think there are too ways no ? Change the xtk source code and compile your own version or something like this :
window.onload = function() {
myrenderer.config.HOVERING_ENABLED = false; // disabling show caption on mousehover
var mouse_x, mouse_y;
myrenderer.interactor.onMouseMove = function(event) {
mouse_x = event.offsetX;
mouse_y = event.offsetY;
}
myrenderer.interactor.onMouseDown = function(left,middle, right) {
if (right) {
var picked_id = myrenderer.pick(mouse_x, mouse_y);
if (picked_id==-1) throw new Error("No object");
var picked_object = myrenderer.get(picked_id);
var mycontainer = myrenderer.container;
var caption = new X.caption(mycontainer,mycontainer.offsetLeft + mouse_x + 10, mycontainer.offsetTop + mouse_y + 10,myrenderer.interactor);
caption.setHtml(picked_object.caption);
// use settimeout or something else to destroy the caption
}
}
}
The following JSFiddle shows how to do that. To actually display a tooltip etc. you can use any JS Library like jQuery UI.
http://jsfiddle.net/haehn/ZpX34/

Flexigrid + IE9 height:auto

The problem is very elemental.
If you go to http://flexigrid.info/ with IE9, and explore the 'example 2' section, and the columns resize over the visible place, that it will activate the horizontal scrollbar. And you hover the rows, you experience growing up the Flexigrid size. I don't experience IE7 and IE8, only IE9. This problem has by height: auto configurate. I didn't find solution yet. Please help me!
Actually, the solution that #Szenti posted will only work for 1 flexigrid on the page, if there are multiple, it will only takes the height value of the 1st bDiv it founds and apply the fix to all.
My revised version I think will apply to situations where there are many flexigrids on the page at one time.
ie9Fix: function() {
var bDivH = $(this.bDiv).height();
var bDivTH = $('table', this.bDiv).height();
if(bDivH != bDivTH && p.height=='auto') {
$(".bDiv").css({height: bDivTH + 18});
}
},
I had this same issue. Thanks #Szenti for the Answer, however, once this was in place I then had flexigrid resize issue when the results in the table where regenerated via AJAX. This occured in latest Chrome, Firefox and IE7/8.
So I added a (some would say dirty) browser sniff into the mix.
Global var:
var ie9 = false;
if ($.browser.msie && parseInt($.browser.version, 10) == 9) {
ie9 = true;
}
Then where #Szanti's method is called I just wrap it in:
if (ie9) {
this.ie9Fix();
}
Now works a treat in all browsers.
The solution:
You have to edit the flexigrid js. Append the g object with this:
ie9Fix: function() {
if($(".bDiv").height() != $(".bDiv table").height() && p.height=='auto') {
$(".bDiv").css({height: $(".bDiv table").height() + 18});
}
},
You have to call ie9Fix function in 2 places
In the g.dragEnd() function last row (this.ie9Fix();)
In the g.addRowProp() you have to write a new event:
.mouseleave(function(){
g.ie9Fix();
})
That's it!