How to filter stacked bar chart? - bar-chart

I found following example for a stacked bar chart with dc.js:
https://dc-js.github.io/dc.js/examples/stacked-bar.html
If I click on some (or several) legend item, I would like the chart to
only show the corresponding items (e.g. red and blue) and
adapt the total numbers to only consider the selected items
I already managed to add some click event to the legend entries:
chart.on('pretransition.hideshow', ()=> {
chart.selectAll('.dc-legend-item')
.on('click', function (data, index, nodeList) {
const stackName = data.name;
if(data.hidden){
chart.showStack(stackName);
} else {
chart.hideStack(stackName);
}
dc.redrawAll();
});
});
This hides some stack but the sum is not shown as expected (multiplie, overlapping values are shown).
=>How can I filter the data correctly?
I also tried to use chart.filter() but that only seems to be able filter the x axis and not the stacks.
Currently, if I hover over a legend entry, the chart already adapts but does not show the wanted behavior.

Thanks to Gordon I found following solution:
Step 1: Create an extra dimension for the stack property:
const stackDimension = crossFilter.dimension(d => d.stackProperty);
Step 2: Create an event handler and filter on that dimension:
const selectedStackNames = [];
const legendItemClickHandler = (data, index, nodeList) => {
const stackName = data.name;
if(selectedStackNames.includes(stackName)){
const index = selectedStackNames.indexOf(stackName);
selectedStackNames.splice(index,1);
} else {
selectedStackNames.push(stackName);
}
if(selectedStackNames.length){
stackDimension.filter((name)=>{
return selectedStackNames.includes(name);
});
} else {
stackDimension.filter(null);
}
dc.redrawAll();
};
chart.on('pretransition.hideshow', ()=> {
chart.selectAll('.dc-legend-item')
.on('click', legendItemClickHandler);
});
Step 3: Highlight selected legend items
chart.on('pretransition.show', ()=> {
chart.selectAll('.dc-legend-item')
.on('click', legendItemClickHandler);
const selectedStackNames = new Set(
stackDimension.top(Infinity)
.map(d=>d.stackProperty)
);
chart.selectAll('.dc-legend-item')
.each((data, index, nodeList)=>{
const node = nodeList[index];
const colorRect = node.children[0];
if(selectedStackNames.has(data.name)){
colorRect.style.outline = "1px solid grey";
colorRect.opacity="";
data.hidden=false;
} else {
colorRect.style.outline = "";
data.hidden=true;
colorRect.opacity="0.3";
}
});
});

Related

accessing table cells from puppeteer

I need to be able to validate the values in specific table cells, and later, to click on a particular cell that holds a link. I get that Node and the browser (or emulator) are two different process spaces, so I can't pass references. I was hoping that puppeteer would hide this fact in a read-only manner such as return someArray; in a function run in the browser context being "magically" replicated by puppeteer on the Node side, but alas.
test("get a certain row from a certain table", async function getRow() {
await page.waitForSelector("#actionItemsView-table");
const
cellText = await page.evaluate(function getCells() {
const
row = Array.from(document.querySelectorAll("#actionItemsView-table tbody tr"));
for (let i = row.length - 1; i >= 0; --i) {
// the row we want is the one that has text of interest in cells[2]
if (row[i].cells[2] === "some text that identifies the row of interest") {
return row[i]; // we can't pass this back to Node, so this is wrong
// but some version of this what we need to do
}
}
return null; // no such row
});
console.log(cellText); // cellText is an empty array
}, testTimeout);
Lacking that, I have run through various intermediate experiments, all the way to this, seemingly simplest case, just to get something that works and then work my way back up to what I need, but this doesn't work either:
test("get the text from a single cell", async function getInnerText() {
await page.waitForSelector("#actionItemsView-table");
const
cellText = await page.evaluate(function getText() {
let
ct,
row = Array.from(document.querySelectorAll("#actionItemsView-table tbody tr"));
for (let i = row.length - 1; i >= 0; --i) {
if (row[i].cells[2] === "some text that identifies the row of interest") {
ct = row[i].cells[3].innerText; // the text of the next cell to the right
break;
}
}
return ct; // ct is not a string!
});
console.log(cellText); // cellText is undefined!
}, testTimeout);
If I do things like
document.querySelect("#actionItemsView-table").rows[2].cells[3].innerText
they work, so my selectors and javascript syntax seems to be correct.
There has to be a way to do this and it has to be way easier than I have made it -- what am I missing? Why is the above not working but something like this does work:
await page.$eval("input[name=emailAddr]", function setId(el, id) { el.value = id; return id; }, id);
Here's an easier way to find that cell:
await page.evaluate(() => {
let td = [...document.querySelectorAll("td")].find(td => td.innerText === "something")
return td?.nextElementSibling?.innerText
})
This will return the text or undefined

Function inside a Function not calling in React Native

I am new to react-native and calling a function inside a fucntion.
I have done as below so far :
Step 1 : Created a function _snapshotToArray to convert the firebase snapshot to Arrray.
_snapshotToArray(snapshot) {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
Step 2 : Created another function as below and calling _snapshotToArray inside it.
_readUserDataFromFirebaseConsole() {//once and on
firebase.database().ref('Users/').on('value', function (snapshot) {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}
Talking about this call :
console.log(this._snapshotToArray(snapshot));
When I press CTRL+CLick, it not letting me to navigate to body of the fuction _snapshotToArray.
In Device am getting below error :
_snapshotToArray is not defined
What might be the issue ?
I'm not at my PC right now, so I cannot test it, but from looking at your code, you need to use a different function notation to allow the varibale access of/from parent methods and parent class.
_snapshotToArray = snapshot => {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
and
_readUserDataFromFirebaseConsole = () => {
firebase.database().ref('Users/').on('value', snapshot => {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}

How to do pagination in react native?

i am looking for a nice document explaining well about pagination in react native.I can't find a one i'm looking for.I'm fetching the data from server (set of 15 questions and answers).I want to display single question in a page with a next or previous button at the bottom.How to do this?Now i'm displaying all the 15 questions in a single page with ScrollView. But i want pagination.Please help me.
The library react-native-swiper would be the best to use in such a scenario.The example is mentioned in the following link here.
This library uses ScrollView , with a snap animation effect for each item and also contains the customized next and previous button as mentioned here.
var start=0; // above class
var end=100;
fetchData = () => {
var mydata = realm.objects('Product_Info');
this.setState({dbData: mydata})
console.log("fetch---------- paggingData.start--> " + start);
console.log("fetch---------- paggingData.end--> " + end);
var newData = mydata.filtered('prodId > $0 AND prodId <= $1' , start, end); // TODO Logic fetch Data
let paggingData =[];
paggingData = JSON.parse(JSON.stringify(this.state.paggingData));
Object.keys(newData).map(key => {
paggingData.push(newData[key])
})
this.setState({
paggingData
}, () => {
console.log('Search-------------------------------PAGGGING DATA \n', this.state.paggingData)
})
this.setState({dataProvider: dataProvider.cloneWithRows(paggingData)}) //TODO ... working in RecyclerView both
}
onScroll = () => {
console.log("Scrolling");
}
onEndReached = () => {
console.log("\n\n\n\n\--------------------------------------------Reached to End---------------------------------------------");
start = end;
end = end+100;
this.fetchData()
}
<RecyclerListView
layoutProvider={this.layoutProvider}
dataProvider={this.state.dataProvider}
rowRenderer={this.rowRenderer}
onEndReached={this.onEndReached}
onScroll={this.onScroll}
/>

Autodesk Forge - How to stop recoloring of object when selected

Our elements are color coded so when a user selects one we just want to isolate it in the views (which works as expected) BUT we don't want it to change to the selection color - where can we control this?
Use selection event to find which object has been selected, cancel the selection and isolate the selected dbId, is this the behavior you are looking for?
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.Basic = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _this = this;
_this.load = function () {
console.log('LOAD')
viewer.addEventListener(
Autodesk.Viewing.AGGREGATE_SELECTION_CHANGED_EVENT, function(e) {
//console.log(e)
if(e.selections.length) {
var dbId = e.selections[0].dbIdArray[0]
viewer.select([])
viewer.isolate(dbId)
}
})
return true;
};
_this.unload = function () {
Autodesk.Viewing.theExtensionManager.unregisterExtension(
"Autodesk.ADN.Viewing.Extension.Basic");
return true;
};
};
Autodesk.ADN.Viewing.Extension.Basic.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.Basic.prototype.constructor =
Autodesk.ADN.Viewing.Extension.Basic;
Autodesk.Viewing.theExtensionManager.registerExtension(
"Autodesk.ADN.Viewing.Extension.Basic",
Autodesk.ADN.Viewing.Extension.Basic);
In case you want to keep the selection just not make it blue in the UI, you can change the selection material's opacity to see-through:
viewer.impl.selectionMaterialBase.opacity = 0;
viewer.impl.selectionMaterialTop.opacity = 0;
Now when you click on an object it won't turn blue.

Kendo hierarchy grid -- get count of child rows on selecting master row

I think this is probably pretty simple, but I need pointing in the right direction.
I've got a master/child grid and I'd simply like to be able to get a count of child rows when selecting (or various other actions, e.g. save or edit ) the master row.
Thanks
I created a fiddle and played around a bit. It's not always working, e.g. when you haven't got the details grid yet or when opening a detail row for the first time, but it should give you an idea on how get the cound of a hierarchical grid.
Fiddle: http://jsfiddle.net/9BGpr/
Open console to get output.
Main code is here:
selectable: 'row',
change: function (e) {
var kendoGrid = this;
setTimeout(function () {
console.log("e", e)
var $selectedRow = kendoGrid.select();
if ($selectedRow.length != 1) {
console.log("Please select a single row!");
return false;
}
if ($selectedRow.hasClass('k-master-row')) {
var $detailRow = $selectedRow.next().filter('.k-detail-row');
if ($detailRow.length === 0) {
console.log("Could not find detail row!");
return false;
}
var $detailGrid = $detailRow.find('.k-grid');
if ($detailGrid.length === 0) {
console.log("Could not find grid in detail row!");
return false;
}
var kendoGridDetails = $detailGrid.getKendoGrid();
console.log("Total of records in detail grid: " + kendoGridDetails.dataSource.total());
}
});