I'm trying to use quoted text in one of node's attributes:
var network_json = {
dataSchema: {
nodes: [ { name: "label", type: "string" },
{ name: "foo", type: "string" }
]
},
data: {
nodes: [ { id: "1", label: "1", foo: "Text without quotes" },
{ id: "2", label: "2", foo: "Some \"quoted\" text" }
]
}
};
vis.draw({network: network_json});
And then making listeners for each node:
vis.addListener("click", "nodes", function(event) {
alert(event.target);
})
But I've got "Unexpected token ILLEGAL" error while clicking on a node with quoted text.
How should I screen quotes there?
For people who have same problem, it's a bug.
They promise they would fix it in next stable release.
https://groups.google.com/d/topic/cytoscapeweb-discuss/GWU0deOaaRs/discussion
They send fixed swf to email by request.
Related
I would like to generate a tree from the following object:
configuration:
{
name: "General",
icon: "general",
children: [
{
name: "Line 1",
icon: "line",
children: [
{
name: "Area 1",
icon: "area",
children: [
{ name: "Y", icon: "x" },
{ name: "Z", icon: "z" },
],
},
{ name: "Area 2", icon: "line" },
],
},
{
name: "Line 2,
icon: "line",
children: [{ name: "Area 3", icon: "area" }],
},
],
},
In html I have my own custom element:
<my-details>
<div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
${this.children} // ???
</my-details>`;
so I created the function:
createHierarchy() {
if (configuration?.length > 0) {
const details = _configuration.map(({ name, icon }) => {
return ` <my-details>
<div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
${this.children}
</my-details>`;
});
hierarchyContainer.innerHTML = details?.join("");
}
}
but I don't know how to convert this structure in a loop or map to a tree, each element of the hierarchy should be a my-details element and have a name as a slot and in the middle it should have children
the structure should look like this:
hierarchy tree
What you are looking for is a recursive function. Which is a function that calls itself.
It should end up looking something like this:
function parseNode(node) {
let html = `<my-details>
<div slot="summary">
<my-icon name="${node.icon}"></my-icon>
${node.name}.
</div>`;
if(node.children) {
node.children.forEach(childNode => {
html += parseNode(childNode);
})
;}
html += '</my-details>';
return html;
}
parseNode(configuration);
This example turns your entire configuration into an html string (or it should it is untested). You can output to your document/component.
Note that it relies on all nodes having a name and an icon and a possible "children" has to be an array.
In Javascript, if we have a scenario in which there is a large object and we need to access its properties then which approach is better?
Suppose we have this object:
let largeObj = {
items: {
item: [
{
id: "0001",
type: "donut",
name: "Cake",
ppu: 0.55,
batters: {
batter: [
{
id: "1001",
type: "Regular"
},
{
id: "1002",
type: "Chocolate"
},
{
id: "1003",
type: "Blueberry"
},
{
id: "1004",
type: "Devil's Food"
}
]
},
topping: [
{
id: "5001",
type: "None"
},
{
id: "5002",
type: "Glazed"
},
{
id: "5005",
type: "Sugar"
},
{
id: "5007",
type: "Powdered Sugar"
},
{
id: "5006",
type: "Chocolate with Sprinkles"
},
{
id: "5003",
type: "Chocolate"
},
{
id: "5004",
type: "Maple"
}
]
}
]
}
}
and we want to create firstBatterAndTopping object which has first batter and first topping data. Now, if we access properties of this object in below three ways, which approach is better in terms of performance. Is there any difference in these or these will perform the same. Or is there any other scenario like this in which this will impact performance?
let firstBatterAndTopping = {
batterId: largeObj.items.item[0].batters.batter[0].id,
batterType: largeObj.items.item[0].batters.batter[0].type,
toppingId: largeObj.items.item[0].topping[0].id,
toppingType: largeObj.items.item[0].topping[0].type
}
or
let firstItem = largeObj.items.item[0];
let firstBatterAndTopping = {
batterId: firstItem.batters.batter[0].id,
batterType: firstItem.batters.batter[0].type,
toppingId: firstItem.topping[0].id,
toppingType: firstItem.topping[0].type
}
or
let firstItem = largeObj.items.item[0];
let firstBatter = firstItem.batters.batter[0];
let firstTopping = firstItem.topping[0]
let firstBatterAndTopping = {
batterId: firstBatter.id,
batterType: firstBatter.type,
toppingId: firstTopping.id,
toppingType: firstTopping.type
}
Try immer out! Is a javascript library very useful for managing complex objects with a lot of nests.
Following a simple scenario:
import produce from "immer"
const baseState = [
{
title: "Learn TypeScript",
done: true
},
{
title: "Try Immer",
done: false
}
]
const nextState = produce(baseState, draftState => {
draftState.push({title: "Tweet about it"})
draftState[1].done = true
})
// the new item is only added to the next state,
// base state is unmodified
expect(baseState.length).toBe(2)
expect(nextState.length).toBe(3)
// same for the changed 'done' prop
expect(baseState[1].done).toBe(false)
expect(nextState[1].done).toBe(true)
// unchanged data is structurally shared
expect(nextState[0]).toBe(baseState[0])
// ...but changed data isn't.
expect(nextState[1]).not.toBe(baseState[1])
I try to mapping nested JSON in React JS.
My JSON data like this,
"beautifuldata": [
{ "id":"1", "name":"a"},
{ "id":"2", "name":"b"},
{ "id":"3", "name":"c"},
{ "id":"4", "name":"d"},
{ "id":"5", "name":"e"},
{ "id":"6", "name":"f"},
{ "id":"7", "name":"g"}]
this data came from an API. And I can write my data to the console. But everything went wrong when I try to access the inner side. For example, I want to get id from my JSON data,
I try this
[beautifuldata].map(x => console.log(x));
this code line gave all data,
[beautifuldata].map(x => console.log(x.id));
this code line gave me undefined. I want to access all data inside my JSON. What am I missing?
You are returning the whatever console.log(x.id) returns which is undefined;
You need to return the x.id
let obj = {
beautifuldata: [
{ id: "1", name: "a" },
{ id: "2", name: "b" },
{ id: "3", name: "c" },
{ id: "4", name: "d" },
{ id: "5", name: "e" },
{ id: "6", name: "f" },
{ id: "7", name: "g" },
],
};
const result = obj.beautifuldata.map((x) => x.id);
console.log(result);
remove [ ] from this line
[beautifuldata].map(x => console.log(x.id));
To read
beautifuldata.map(x => console.log(x.id));
EDIT
If you want to access data outside the map function,
beautifuldata.map(x => {
/* Work with x properties here*/
console.log(x.id)
return x
}
// thanks to #mhodges
I suggest a solution like below might be an appropriate approach.
var rst = {
"beautifuldata": [
{ "id":"1", "name":"a"},
{ "id":"2", "name":"b"},
{ "id":"3", "name":"c"},
{ "id":"4", "name":"d"},
{ "id":"5", "name":"e"},
{ "id":"6", "name":"f"},
{ "id":"7", "name":"g"}]
}
rst.beautifuldata.map(i => console.log(i.id));
/* -- or --- */
rst.beautifuldata.forEach(i => console.log(i.id));
Hope that helps or gives you a hint.
I have a list of nested items in the JSON object. I have to filter only root nodes (parent).
The below is the JSON object.
const myJSON = [
{
__typename: 'Query', node:
{
__typename: 'Item', childItems: [Object], id: 'a', label: 'node1', url: '#', parent: null
}
},
{
__typename: 'Query', node:
{
__typename: 'Item', childItems: [Object], id: 'b', label: 'node2', url: '#', parent: null
}
},
{
__typename: 'Query', node:
{
__typename: 'Item', childItems: [Object], id: 'a', label: 'node3', url: '#', parent: 'node1'
}
}
]
this is my javascript code and the object is retrieved inside the object variable.
I want to filter only labels of parent nodes from the above object.
My desire output should be:
node1
node2
node3
node4
In order to obtain only the desired properties after the .filter() method, you can use the .map() method to transform the final array.
Note that I changed item.node.parent == null to !item.node.parent. Like this it doesn't look just for those which are null, but for those which are falsy. Change it again to null if that is the behaviour you are expecting.
As you can see in the snippet, using map can tell which property of the array I want to keep
EDIT: Answering your comment, of course you can select more than one property using the .map() method, as long as you format it as an object. The function filterParentAndObtainLabelAndUrl(input) returns label and url. As you can see, you can easily add as many as you want
const filterParentAndObtainLabelValue = (input) => {
return input.filter(element => !element.node.parent)
.map(element => element.node.label);
}
const filterParentAndObtainLabelAndUrl = (input) => {
return input.filter(element => !element.node.parent)
.map(element => {
return ({
label: element.node.label,
url: element.node.url
})
})
}
const inputJSON = [{ "__typename": "Query", "node": { "__typename": "Item", "childItems": [null], "id": "a", "label": "node1", "url": "#", "parent": null } }, { "__typename": "Query", "node": { "__typename": "Item", "childItems": [null], "id": "b", "label": "node2", "url": "#", "parent": null } }, { "__typename": "Query", "node": { "__typename": "Item", "childItems": [null], "id": "a", "label": "node3", "url": "#", "parent": "node1" } }]
console.log('Just the label: ', filterParentAndObtainLabelValue(inputJSON))
console.log('Label and url: ', filterParentAndObtainLabelAndUrl(inputJSON))
I am writing a script to update(add and rename) certain fields, which are part of an embedded document within the ones stored in the db collection.
to give an example document:
{
_id: UUID("025bda29-0d09-4923-8f7f-ea2e825be2c8"),
name: "test",
sets: [
{
"name": "1",
"values": [
{
name: "a",
value: 5
}
]
},
{
"name": "2",
"values": [
{
name: "a",
value: 3
}
]
}
]
}
This is my script:
function convertGroup (group) {
for (var i = 0; i < group.sets.length; i++) {
var set = group.sets[i];
var oldValuesField = "sets." + i.toString() + ".values";
var mainValuesField = "sets." + i.toString() + "mainValues";
var additionalValuesField = "sets." + i.toString() + ".additionalValues";
db.getCollection('group').updateOne({
"_id" : group._id
}, {
$set: {
mainValuesField : set.values,
additionalValuesField : [ ]
},
$unset: {
oldValuesField: ""
}
});
}
}
db.getCollection('group').find({'sets.0.mainValues': {$exists: false}}).forEach(convertGroup);
According to the documentation the $rename does not work on arrays, that is why I used set and unset.
what happens when I run this code, is that I get the mainValues field and additionalValues field in the group document, and not in the set documents.
this is what I want it to become:
{
_id: UUID("025bda29-0d09-4923-8f7f-ea2e825be2c8"),
name: "test",
sets: [
{
"name": "1",
"mainValues": [
{
name: "a",
value: 5
}
],
"additionalValues": [ ]
},
{
"name": "2",
"mainValues": [
{
name: "a",
value: 3
}
],
"additionalValues": [ ]
}
]
}
Can anyone explain to me why this happens and how I can make this work the way I want it to?
I managed to fix it by rewriting the script like this:
function convertGroup(group) {
group.sets.forEach(function (set) {
if (!set.mainValues) {
$set : {
set.mainValues = set.values
}
}
if (!set.additionalValues) {
$set : {
set.additionalValues = []
}
}
});
db.getCollection('group').update({'_id': group._id}, group);
}
db.getCollection('group').find({'sets.mainValues': {$exists: false}}).forEach(convertGroup)
the different is mostly not using the notation 'sets.[index].values' but editing it directly on the json and using 'update' instead of 'updateOne'