I have a chart where one of the series provided is a 'total' sum value of the other values.
What I'm trying to is to have this column initially behind the others (or hidden) then bring it to the front when that series' legendItem is hovered.
So far I've been able to increase the zIndex on the series to bring the 'total' column to the front on 'mouseover' no problem, but triggering the inverse on 'mouseout' isn't working for me and the 'total' column stays in front.
I've also tried a simlar solution using .toFront(), this worked but was left with the same problem of moving the column back BEHIND on mouseout.
How might I correctly move this column to front/back on legendItem hover?
https://codesandbox.io/s/cold-night-9p0gk?file=/src/components/BarChart.vue:1272-1325
On 'mouseout' you can call toFront method on the stacked series only:
chart.series.forEach(s => {
if (s.name === 'Total') {
s.legendItem.on('mouseover', () => {
s.group.toFront();
});
s.legendItem.on('mouseout', () => {
s.chart.series.forEach(item => {
if (s !== item) {
item.group.toFront();
}
});
});
}
});
Live demo: http://jsfiddle.net/BlackLabel/mpduxwkh/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGElement#toFront
Related
Good day
I have 2 tables side by side and I want them to act like one table with borders and scroll independently and, when my cursor goes over the 1 row in the first table I want to highlight 1 row in the second table
However this is done internally by react-table.
Any solutions how can I implement highlighting same row from both tables?
And I wonder about simultaneous vertical scroll, are there also any solutions in react way?
Don't want to add event listeners to tables like this
firstTableBody.addEventListener('scroll', e => {
const tablePosition = e.target.scrollTop;
firstTableBody.scrollTop = tablePosition;
});
https://stackblitz.com/edit/react-edgooj?file=src/App.js
ok, I did a highlight for all tables at once
For every table I add
getTrProps={rowProps}
and in rowProps I implement
const rowProps = useCallback((state, rowInfo) => {
if (rowInfo && rowInfo.row) {
const isRowHovered = rowInfo.index === hoveredRow;
return {
style: {
background: isRowHovered ? '#D1DDE1' : ''
},
onMouseEnter: () => {
setHoveredRow(rowInfo.index)
},
onMouseLeave: () => {
setHoveredRow(null)
}
}
}
}, [hoveredRow]);
I really dunno why there is always such a poor documentation in all those libs
I have a Chart.js doughnut chart (v2.7.1) and I am looking to set the class of an external element when the user hovers over the relevant chart element
I can use the onHover event within the options.hover of the chart
hover: {
onHover: function (evt, item) {
if (item.length) {
var index = item[0]._index;
var legendElement = $(#get element based on index#);
legendElement.addClass('active');
}
}
}
and this sets the class on the element (legendElement) perfectly but I need to be able to remove the class I set from the element when the user is no longer hovering over the element
Am I using the correct approach? Is there a way to detect that the onHover is complete or that the segment is no longer in focus?
Are you defining an "events" property apart from the "onHover" property? If you add "mouseout" to the list, the "onHover" function will be called in both cases. Check out the documentation for this https://www.chartjs.org/docs/latest/general/interactions/events.html
An example code that might work:
options: {
events: ["mousemove", "mouseout"],
onHover: function (evt, item) {
if (item.length) {
var index = item[0]._index;
var legendElement = $(#get element based on index#);
if(evt.type == "mousemove"){
legendElement.addClass('active');
}else{
legendElement.removeClass('active');
}
}
}
}
here is a stackblitz link of my Angular app with amchart.
Amchart Angular app
For UX reasons I am keeping the chart stack colors same. Now in code if am using amcharts default legend (line 225 of code) everything works fine. On clicking on legends it filter the stack chart accordingly, but again for UX reasons am using custom item for legends (line 227 to 235 in code) and here when I click on legend the stack columns are not getting filtered accordingly.
How to achieve amchart's default legend behaviour in this scenario?
I figured it out, added following changes in my code and I achieved the desired result:
legend.itemContainers.template.clickable = true;
legend.itemContainers.template.togglable = false;
legend.itemContainers.template.events.on('hit', (ev) => {
// console.log(ev);
if (ev.target.dataItem.dataContext['name'] === 'Success') {
series2.hide();
series3.hide();
}
if (ev.target.dataItem.dataContext['name'] === 'Failed') {
series1.hide();
series3.hide();
}
if (ev.target.dataItem.dataContext['name'] === 'Progress') {
series1.hide();
series2.hide();
}
if (ev.target.dataItem.dataContext['name'] === 'All') {
if (series1.isHidden) {
series1.show();
}
if (series2.isHidden) {
series2.show();
}
if (series3.isHidden) {
series3.show();
}
}
});
Is there any way to let users to adjust column width of Ant Design Table by drag and drop?
I found some examples that about is for column sorting, but not for column resizing.
Please help, thanks!
UPDATED # 2018-11-13
There is an official example of resizing table column now:
https://ant.design/components/table/#components-table-demo-resizable-column
I have made a working sample - its far from perfect and needs a lot of optimization. Basically you need to use the onHeaderCell and capture onMouseDown, onMouseUp and onMouseMove.
onMouseMove we call setState and basically trigger a re-render with the new column width.
https://codesandbox.io/s/j2zw9nn5w9
onHeaderCell: column => {
let colw = this.state.columnWidth;
return {
onMouseDown: e => {
this.mouseDownX = e.clientX;
this.beginDrag = true;
},
onMouseUp: () => {
this.beginDrag = false;
},
onMouseMove: e => {
if(this.beginDrag === true) {
this.updateColumnWidth(colw +
Math.round((e.clientX - this.mouseDownX)*.05));
}
}
};
}
I want to make a function which send dynamically all visible series name in a Highchart instance to a PHP function.
For example, in this chart, I want to get this array : [Salle, PR].
If I click on Internet, the serie become visible and I want to get [Salle, Internet, PR].
To do this, I tried to use legendItemClick event and make a function that check if each serie is visible to add it to an array but I can't figure out how to use the visible option to do this.
Do you have an idea ?
As of now, I don't have much code to share :
plotOptions: {
series: {
events: {
legendItemClick: function(){
}
}
}
}
If you retain the pointer to your chart like this:
var ch = Highcharts.chart(_chart_data_);
Then later you can access the whole chart structure. What you will be interested in is the series array.
ch.series[]
It contains array of all your series. Series with visible attribute set to true are the ones that currently displayed. So,it might be something like this:
var ch = Highcharts.chart(...
plotOptions: {
series: {
events: {
legendItemClick: function(){
ch.series.forEach(function(sr){
if(sr.visible){
console.log(sr.name, "visible!");
}
});
}
}
}
}
...);
However, there is a catch with your approach, that on actual legend click your current action for the legend is not yet processed.so the output you will see is the output for the previous state, before current click.
So for that reason you may try to use setTimeout to get your listing after the event is applied:
events: {
legendItemClick: function(){
setTimeout(
function(){
ch.series.forEach(
function(sr){
if(sr.visible){
console.log(sr.name, "visible!");
}
}
)
},20);
}
}
Try this and check the console log: http://jsfiddle.net/op8142z0/