How to iteratively expand nodes (on clicking) using popoto.js? - neo4j

I am developing a web interface to the neo4j database using popoto.js. Currently, I am able to display a start node and expand the graph up to 3-4 levels by clicking on the node relationships. It seems that the underlying query that popoto uses gets updated along with the expanding graph and after a certain point the query becomes invalid and popoto resets the graph. What I am trying to create is an interface where I can expand any node in the graph (and hence expanding the overall graph) similar to what is possible in the neo4j browser. How can I achieve this?

Popoto.js handles this automatically but the schema has to be defined in the following way to assist it.
export const schema = {
Person: {
label: "Person",
value: {
name: ""
},
rel: [
{
label: "works_at",
target: {
label: "company",
},
},
{
label: "studies_at",
target: {
label: "college",
}
}
]
},
Company: {
label: "company",
value: {
name: ""
},
rel: [
{
label: "works_at",
target: {
label: "person",
},
}
]
}
}

Related

How can i get duplicate node CYPHER Neo4j

I have a question How can i I get some nodes with same property (for example same name property). In SQL i would use GROUP BY, but in CYPHER i don't have idea what should i use to group them. Below I added my simple input and example output to visualizate my problem.
[
{
id:1,
name: 'name1'
},
{
id:2,
name: 'name2'
},
{
id:3,
name: 'name2'
},
{
id:4,
name: 'name3'
},
{
id:5,
name: 'name3'
},
{
id:6,
name: 'name3'
},
{
id:7,
name: 'name4'
},
{
id:8,
name: 'name5'
},
{
id:9,
name: 'name6'
},
{
id:10,
name: 'name6'
}
]
My solution should gave me this:
[
{
count:2,
name: 'name2'
},
{
count:3,
name: 'name3'
},
{
count:2,
name: 'name6'
}
]
Thank you in advance for your help
In Cypher, when you aggregate (for the straight-forward cases) the grouping key is formed from the non-aggregation terms.
If nodes have already been created from the input (let's say they're using the label :Entry), then we can get the output you want with this:
MATCH (e:Entry)
RETURN e.name as name, count(e) as count
The grouping key here is name, which becomes distinct as the result of the aggregation. The result is a row for each distinct name value and the count of nodes with that name.

How to highlight tree node on click of button in element-ui

I am having el-tree> element and 1 button showNode.
so on click of this button i want to highlight a node with given index.
How to call highlight-current on click of button?
From documentation:
highlight-current: whether current node is highlighted
highlight-current is just a read-only attribute, in order to highlight a specific node, you have to call the method setCurrentKey
setCurrentKey: set highlighted node by key, only works when node-key is assigned, the param (key) is the node's key to be highlighted
So, you need first to add a key to every node, using the property key:
node-key: unique identity key name for nodes, its value should be unique across the whole tree
Like following example:
<el-tree
:data="myData"
node-key="id">
</el-tree>
And then, call the method setCurrentKey on the click event attached to your button:
<el-button #click="setCurrentKey(myData[index].id)">Highlight the n-index node</el-button>
I hope it helps you, bye.
Updated: The code above works only on 2.x version, here an example to highlite a node on version 1.4.13 (but I can't expand a node, so I had to expand all the tree):
var Main = {
data() {
return {
data: [{
label: 'Level one 1',
id: 1,
children: [{
label: 'Level two 1-1',
id: 11
}]
}, {
label: 'Level one 2',
id: 2,
children: [{
label: 'Level two 2-1',
id: 21,
children: [{
label: 'Level three 2-1-1',
id: 211
}]
}, {
label: 'Level two 2-2',
id: 22,
children: [{
label: 'Level three 2-2-1',
id: 221
}]
}]
}],
defaultProps: {
children: 'children',
label: 'label'
}
};
},
methods: {
handleNodeClick(data) {
console.log(data);
},
renderContent(h, { node, data, store }) {
let btn = h('span', {
props: {type: 'success'},
domProps: {
innerHTML: data.label,
id: "node-id-" + data.id
}
})
return btn
},
handleBtnClick(){
//Highlite the 211
document.getElementById("node-id-211").style.backgroundColor="yellow";
}
}
};
var Ctor = Vue.extend(Main)
new Ctor().$mount('#app')
#import url("//unpkg.com/element-ui#1.4.13/lib/theme-default/index.css");
<script src="//unpkg.com/vue/dist/vue.js"></script>
<script src="//unpkg.com/element-ui#1.4.13/lib/index.js"></script>
<div id="app">
<el-tree :data="data" :props="defaultProps" #node-click="handleNodeClick" :render-content="renderContent" :default-expand-all="true"></el-tree>
<el-button #click="handleBtnClick">Highlight the 211 node</el-button>
</div>

Mixed Chart Types using Chartkick/Highcharts on Rails

I'm trying to create a mixed column/line chart using Highcharts.
I've been trying to use the library functionality to set one of my data series to be of type "line". I have tried a few different approaches, but I can't seem to figure out how to pass the type parameter of a given series using the Highcharts API.
<%= column_chart( ChartData.new(#forecast).revenue_and_net_income, library: {
title: {
text: "Revenue and Net Income"
},
series: [{
1 => {
type: "line"
}
}],
} ) %>
Where my data come from the following method:
def revenue_and_net_income
data = [
{
name: "Revenue",
data: revenue_by_year
},
{
name: "Net Income",
data: net_income_by_year,
}
]
end
Not sure what I'm doing wrong? I only seem to be able to access the Highcharts API methods listed under 'Chart', none of the series options etc. seem to work. Can anyone point me in the right direction for how to successfully get this to work?
you can try this way.
<%= line_chart [
{
name: "Amount", type: "column", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
},
{
name: "Test", type: "line", data: #cause.donations.map {
|t| [t.user.name, t.amount]
}
}
],
prefix: "$",
adapter: "highcharts"
%>
just don't care line_chart, column_chart or anythings... ONLY custom type in data. OK

Exporting CSV from ui-grid with cell display rather than the source value

I have a table done with ui-grid and this table has a column with cellFilter definition like this:
{ field: 'company', cellFilter: 'mapCompany:row.grid.appScope.companyCatalog' }
My gridMenu custom item is configured like this:
gridMenuCustomItems: [
{
title:'Custom Export',
action: function ($event) {
var exportData = uiGridExporterService.getData(this.grid, uiGridExporterConstants.ALL, uiGridExporterConstants.ALL, true);
var csvContent = uiGridExporterService.formatAsCsv([], exportData, this.grid.options.exporterCsvColumnSeparator);
uiGridExporterService.downloadFile (this.grid.options.exporterCsvFilename, csvContent, this.grid.options.exporterOlderExcelCompatibility);
},
order:0
}
]
The table is displayed correctly, but when I try to export to CSV, the Company column is exported with empty value. Here is my Plunkr.
Any suggestion will be appretiated
References
I did some research and according to ui-grid Issue #4948 it works good when the Company column is filled with an static catalog. Here is a Plunkr demostrating that.
As you mentioned, there is an export issue when the values in the column are not static, so I forked your plunker with a solution that creates the company mapping for each data object and adds it as a key-value once you get the company catalog back:
$http.get('https://api.github.com/users/hadley/orgs')
.success(function(data) {
$scope.companyCatalog = data;
angular.forEach($scope.gridOptions.data, function(item) {
var compMap = uiGridFactory.getMapCompany(item.company, $scope.companyCatalog);
item.mappedCo = compMap;
});
});
I've kept the original company column but made it invisible (rather than overwriting it), so it exports with the rest of the data in the csv. New column defs:
columnDefs: [
{ field: 'name' },
{ field: 'mappedCo', name: 'Company'},
{ field: 'company', visible: false }
]
Also, in the case that you were getting your data from a server, you would have to ensure that the data and the catalog returned before you run the mapping function. This solution may not work in your particular use case; I don't know.
I found a solution to the CSV export to be able to display the cell display value.
My mistake was using row.grid instead of this.grid at the mapCompany cell filter:
columnDefs: [
{ field: 'name' },
{ field: 'company', cellFilter: 'mapCompany:row.grid.appScope.companyCatalog' }
],
The right way to use it is using this:
columnDefs: [
{ field: 'name' },
{ field: 'company', cellFilter: 'mapCompany:this.grid.appScope.companyCatalog' }
],
Here is my Plunkr.

Select project children on parent select

I am implementing a project picker for a Rally custom app and would like to select a projects children automatically when the parent is selected from the picker. I was able to get the ObjectID and Name of the objects I want to select but can't seem to get them to be selected from the picker. I attempted this using the "fireEvent" method but had no success. Here's what I have so far:
var teamPick = this.down('#filterPanel').add({
xtype: 'rallymultiobjectpicker',
id: 'teams',
modelType: 'project',
fieldLabel: 'Teams',
listeners: {
select: function(field, selected) {
Ext.create('Rally.data.WsapiDataStore', {
autoLoad: true,
fetch: [ 'Name', 'ObjectID' ],
filters: [
{ property: 'Parent.ObjectID', value: selected.ObjectID }
],
model: 'Project',
listeners: {
load: function(store, data) {
Ext.Array.each(data, function(child) {
console.log(child.get('Name')); //Logs the child name
});
}
}
});
},
scope: this
}
});
Are you using 2.0p3? There was a known issue with events not being correctly fired in the MultiObjectPicker. This should be resolved in 2.0p4. I ran your code in a 2.0p4 app and it functioned as expected.
As a side note your child project query can be written like this as well:
filters: [
{ property: 'Parent', value: '/project/' + selected.ObjectID }
]
The 2.0p4 version of the component also added a new event called selectionchange which gives you an array of the currently selected values (since it is a multi select picker). There are individual select and deselect events that fire when a specific item is selected/deselected.
I was able to accomplish this without the use of the fireEvent method. Instead, I used the getValue and setValue methods and added the child projects to the state manually:
this.down('#filters').add({
xtype: 'rallymultiobjectpicker',
id: 'teams',
modelType: 'project',
listeners: {
blur: function() { this.down('#teams').collapse(); },
select: function(field, selected) {
Ext.create('Rally.data.WsapiDataStore', {
autoLoad: true,
fetch: [ 'Name', 'ObjectID' ],
filters: [
{ property: 'Parent.ObjectID', value: selected.ObjectID }
],
model: 'Project',
listeners: {
load: function(store, data) {
var selected = this.down('#teams').getValue();
Ext.Array.each(data, function(child) {
selected.push(child.data);
});
this.down('#teams').setValue(selected);
},
scope: this
}
});
}
scope: this
}
});

Resources