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();
}
}
});
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 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
I'm a newbie using d3.js to create a multi-level filter plot based on user selections. All filters are working exceptenter link description here the categorical color selection. Colors are defaulting to fluid type (default should be material type) and using the radio button to switch doesn't work. Can anyone help?
https://plnkr.co/edit/yoFCbe?p=preview
function filter_color(){
colored = document.getElementById("color_Filter");
svg.append("circle")
.style("fill", function(d) {
if (colored == 0) {
return color(d["Material group"]);
} else {
return color(d["Fluid type"]);
}
})
}
You're not checking for the actual value of the radio box.
Get the checked/unchecked state and that if statement will run as it should:
colored = document.getElementById("color_Filter")[0].checked; // <= mind here
if (colored == 0) {
return color(d["Material group"]);
} else {
return color(d["Fluid type"]);
}
See https://plnkr.co/edit/gZOIbDgYj6OCs5aM1CV2?p=preview
I am building a small UI where the user has to select a point on each of the two SVGs shown.
These points coordinates are then shown under the SVGs. I would like to achieve this using D3's data-binding with the enter() and exit() methods. However it seems that D3 doesn't always update the part where I display the points coordinates, even if I call the enter() method on the bound elements. When removing data, the exit() methods works however.
Here is the main code :
function showPoints() {
var coordinatesElements = d3.select('#coordinates').selectAll('.point').data(points);
coordinatesElements.enter().append('div').classed('point', true)
.text(function (d) {
var textParts = [];
if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
return textParts.join(' - ');
})
.append("span")
.classed('removeCalibrationPoint', true)
.html(" X")
.on('click', function(d, i) {
points.splice(i, 1);
showPoints();
});
coordinatesElements.exit().remove();
}
I have created a JSBin fiddle that demonstrates the problem.
The first problem is that you have an empty div of class point in your HTML. This will be selected by the .selectAll('.point') and cause the first element in your data not to show up.
The second problem is that you're not handling the update selection -- in some cases, you're not adding new data, but modifying existing data. The following code updates the text for the data in the update selection.
coordinatesElements.text(function (d) {
var textParts = [];
if (d.firstSvg) { textParts.push('first : '+JSON.stringify(d.firstSvg)); }
if (d.secondSvg) { textParts.push('second : '+JSON.stringify(d.secondSvg)); }
return textParts.join(' - ');
});
Complete demo here. Notice I've simplified the code slightly by setting the text only on the update selection -- elements added from the enter selection merge into the update selection, so there's no need to do it twice.
I'm teaching myself EXTjs 4 by building a very simple application.
In EXTjs 4 I've got 4 grids that each have the Grid to Grid drag/drop plugin. (Example functionality here: http://dev.sencha.com/deploy/ext-4.0.2a/examples/dd/dnd_grid_to_grid.html )
In my view I have the plugin defined as such:
viewConfig: {
plugins: {
ptype: 'gridviewdragdrop',
dragGroup: 'ddzone',
dropGroup: 'ddzone'
}
},
Now in the example, they have different dragGroups and dropGroups, but because I want the items to drag/dropped between each other fluidly, I gave the groups the same name.
The way the information gets originally populated into the 4 different lists is by looking at an the state_id in the db. All state_ids 1 go into the backlog store, 2 In Progress store, etc, etc.
So what I need to do when the item is drag/dropped, is remove it from its old store and put it into the new store (updating the state_id at the same time, so I can sync it with the db afterwards).
My only problem is figuring out the origin grid and destination grid of the row that was moved over.
Thank you!
PS. If you're curious this is what my drop event handler looks like at the moment:
dropit: function (node, data, dropRec, dropPosition) {
console.log('this');
console.log(this);
console.log('node');
console.log(node);
console.log('data');
console.log(data);
console.log('droprec');
console.log(dropRec);
console.log('dropPosition');
console.log(dropPosition);
},
As you can see, I haven't gotten very far ^_^
Alright, I figured out a way of doing it that seems to be less then ideal... but it works so until someone provides a better solution I'll be stuck doing it like this:
dropit: function (node, data, dropRec, dropPosition) {
if (node.dragData.records[0].store.$className == "AM.store.BacklogCards")
{
data.records[0].set('state_id', 1);
this.getBacklogCardsStore().sync();
}
else if (node.dragData.records[0].store.$className == "AM.store.InprogressCards")
{
data.records[0].set('state_id', 2);
this.getInprogressCardsStore().sync();
}
else if (node.dragData.records[0].store.$className == "AM.store.ReviewCards")
{
data.records[0].set('state_id', 3);
this.getReviewCardsStore().sync();
}
else
{
data.records[0].set('state_id', 4);
this.getDoneCardsStore().sync();
}
I noticed that node.dragData.records[0].store.$className points to defined store that is what the grid bases itself on.
Using the data.records[0].set('state_id', 1); sets the state_id for the row that was moved over and then finally, I call the sync function to update the db with the new row information.