D3js json links search using 2 attributes - json

so I have a page showing pathways between nodes with a json file like this:
{"nodes":[
{"name":"Node 1", "Number":"01", "x":"48.23", "y":"638.54", "Status":"starting"},
{"name":"Node 2", "Number":"02", "x":"129.05", "y":"658.49", "Status":"starting"},
{"name":"Node 3", "Number":"03", "x":"174", "y":"687.79", "Status":"starting"},
{"name":"Node 4", "Number":"04", "x":"169.96", "y":"626.92", "Status":"starting"},
{"name":"Node 5", "Number":"05", "x":"263.65", "y":"631.47", "Status":"starting"}
],
"links":[
{"source": 1, "target": 2, "value": 2},
{"source": 1, "target": 3, "value": 8},
{"source": 1, "target": 4, "value": 5},
{"source": 2, "target": 3, "value": 4},
{"source": 2, "target": 4, "value": 9}
]
}
At the moment I have it set up so that when ever I click on a node it shows all pathways to other nodes. What I want is another mode, where when I click on the node it only shows the pathway with the highest "value" attribute for that corresponding source value.
I have tried looking online for some d3js examples of something like this but haven't found anything and have no idea where to start.
atm I am using a d3.selectAll function to find all pathways for source 1 when i click on node 1 like this:
d3.selectAll(".from" + d.nodes[0].Number + ":not(.pathlabel)")
.transition()
.duration(10)
.style("stroke", "blue")
.style("display", "block")
.style("stroke-opacity", blueActive[d.nodes[0].Number])
;
My code is based on this example: http://bl.ocks.org/fhernand/9a9f93f2a6b0e83a9294
My code is on jsfiddle:
jsfiddle.net/jgs6d7fv
I just want to know how to search through my JSON file using d3.js to find a specific link based on the source and the value attributes.

I'm using the same example passed by you http://bl.ocks.org/fhernand/9a9f93f2a6b0e83a9294
This will get you all the list of link data from
d3.max(d3.selectAll(".from" + d.nodes[0].Number + ":not(.pathlabel)").data()
To get the maximum pass to a player you need to find the max pass from that is done like this
var from_max = d3.max(d3.selectAll(".from" + d.nodes[0].Number + ":not(.pathlabel)").data(), function (d) {
return (d.value);
});
To get the maximum pass to a player you need to find the max pass to that is done like this
//this will calculate the max for to
var to_max = d3.max(d3.selectAll(".to" + d.nodes[0].Number + ":not(.pathlabel)").data(), function (d) {
return (d.value);
});
Now you can display or hide the path on the basis of the max path thats done like this using the display css attribute:
d3.selectAll(".to" + d.nodes[0].Number + ":not(.pathlabel)")
.transition()
.duration(10)
.style("stroke", "orange")
.style("display", function (d) {
if (d.value == to_max) {
return "block"
} else {
return "none"
}
})
Working fiddle I have added comments here.

Related

Dash dataTable Conditional Formatting for specific cell value doesn't work

I have a multiple header data frame and I succeeded to extract the column names by two functions.
I have comparison rows in my data every third line (that compares the two rows values before it) and contains one of the values: "Imporoved", "Not Improved" etc...
For example the table looks something like that:
measure1 | measure2
previouse 70 | 80
new 60 | 100
compare IMPROVED | SIGNIFICANT DEGRADED
I'm trying to add conditional formatting that will color a cell in a certain way if it equals to one of the options of the comparison values. The conditional formatting does not work in a way it does not raise an error but does not display any of the highlighting.
I tried the following code:
style_data_conditional=
[{
'if': {
'filter_query': '{{{col}}} = "SIGNIFICANT DEGRADED"'.format(
col=col),
'column_id': col
},
'backgroundColor': 'black',
'color': '#FF1616'
} for col in columns_names
]
+
[
{
'if': {
'filter_query': '{{{col}}} = "NOT IMPROVED"'.format(
col=col),
'column_id': col
},
'backgroundColor': 'CD7B05',
'color': '#D3C4AF'
} for col in columns_names
]
+
[
{
'if': {
'filter_query': '{{{col}}} = "IMPROVED"'.format(
col=col),
'column_id': col
},
'backgroundColor': '82C729',
'color': '#F4FFE7'
} for col in columns_names
]
+
[
{
'if': {
'filter_query': '{{{col}}} = "SIGNIFICANT IMPROVED"'.format(
col=col),
'column_id': col
},
'backgroundColor': '8FFF0C',
'color': 'white'
} for col in columns_names
]
At first I had a problem with accessing the column names because of the multi headers, but I fixed it and "columns_names" is a list containing the actual columns names (for example columns_names = [['counter1', 'Average'],['counter1', 'max'],...]).
I don't know why the it won't display, the table remains white.
Will appreciate some help!

Hovering on one sentence should highlight matching sentence in another panel in Angular

I have 2 different JSON arrays displayed separately using a simple *ngFor loop on the same page. Ex-
json1: [ {
"order": 1,
"similarity": 0.82,
"sentence": "I would like to speak with :name:.",
"matching_sentence": "Hello, I would like to speak with Luke.",
"matching_line": 0
}]
json2: [ {
"order": 0,
"similarity": 0.82,
"sentence": "Hello, I would like to speak with Luke.",
"matching_sentence": "I would like to speak with :name:.",
"matching_line": 1,
"channel": 1,
"timeFrom": 15,
"timeTo": 20
}]
So, order property from json1 matches matching_line property of json2 and vice versa. So, what I need to achieve is that on mouse hover of json1, json2 should also be highlighted and on mouse hover of json2, json1 should also be highlighted.
This code is written in Angular 11 so, any solution whether it is by css or typescript is welcome.
You can achieve it using mouse enter leave events and keeping track of the active class
<div
*ngFor="let item of json1"
[ngClass]="{'highlight': item.order === activeHover}"
(mouseenter)="onHoverChange(item.order)"
(mouseleave)="onHoverChange(null)">
{{item.sentence}}
</div>
<div
*ngFor="let item of json2"
[ngClass]="{'highlight': item.matching_line === activeHover}"
(mouseenter)="onHoverChange(item.matching_line)"
(mouseleave)="onHoverChange(null)">
{{item.sentence}}
</div>
// in ts file
onHoverChange(value: number | null) {
this.activeHover = value;
}
Running sandbox link

NetSuite - Creating PO with line items

Using Restlets I can create any records in NetSuite. However, how do we create records with line items? I know we can use the getLineItemCount, loop through these items and use the setLineItemValue to set the line item.
What I'm not sure about is how we would pass such data to start with. So, we expect an external system to submit some data which I would then need to create POs with line items using my Restlet.
I would ideally like to test this using fire fox Poster, but not sure how to model the data. Something like this works fine to create a normal record using poster by passing data like:
{ "subsidiary" : 2, "entity" : 1084,"currency" : 2,"approvalstatus" : 2}
But how would we send line item data?
My JSon Object looks like this:
{"subsidiary" : 2,
"entity" : 1275,
"currency" : 2,
"approvalstatus" : 2,
"item": [{"item" : -3, "taxrate": 6},
{"item" : -3, "taxrate": 6}]
}
I tried getting the data out of the nested jason object with the below code but doesn't quite work...the itemid is blank
for (var x = 1; x <= jsonobject.item.length; x++)
{
var itemid = record.getLineItemValue('item', jsonobject.item['item'], x);
nlapiLogExecution('DEBUG', 'itemid', itemid)
record.setLineItemValue('item', itemid, x);
}
You could try using an array within your JSON to encapsulate the line items such as:
{"subsidiary" : 2,
"entity" : 1084,
"currency" : 2,
"approvalstatus" : 2,
"items": [{name:"item1", price: "100"},
{name:"item2", price:"200"}]
}
Your RESTlet code would have to then digest this, and call the relevant NS functions you mention.
As TonyH mentioned, your code has a bug wherein you should be getting the array index first. In addition, your index should start at 0, not 1, since you are going through a JS array, not a NetSuite sublist:
for (var x = 0; x < jsonobject.item.length; x++)
{
var itemid = jsonobject.item[x]['item'];
}
The same would go if you want to get the tax rate:
for (var x = 0; x < jsonobject.item.length; x++)
{
var taxrate = jsonobject.item[x]['taxrate'];
}

Bubble chart in d3.js

http://plnkr.co/edit/7aw93EnMyCR3HjTu1uHa?p=preview
I have added the working fiddle.
I need to plot bubble chart on the basis of "profit" value in properties of "taluks.geojson" file.
This is working for flare.json but not for taluks.geojson file.
I have tried modifying the code in index.html as-
d3.json("taluks.geojson", function(error, root) { if (error) throw error;
var node = svg.selectAll(".node") .data(bubble.nodes(classes(root)) .filter(function(d) { return !d.properties; }))
// Returns a flattened hierarchy containing all leaf nodes under the root.
function classes(root) {
var classes = [];
function recurse(name, node) { if (node.properties) node.properties.forEach(function(child) { recurse(node.name, child); }); else classes.push({packageName: name, className: node.NAME_2, value: node.profit}); }
recurse(null, root); return {properties: classes}; }
But the code is not working for taluks.geojson but only working for flare.json.
Please help regarding how to plot bubble chart on the basis of profit in properties of taluks.geojson file.
Please kindly suggest any further modificatons.
Thank you.
To render bubble chart or tree chart data should be in relational format parent and child, If you see flare.json data
{
"name": "flare",//root parent or level 0
"children": [
{
"name": "analytics",//child node or level 1
"children": [
{
"name": "cluster", //child node to analytics or level 2
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
}]
}]
}
/*
* In the above the data is hierarchical here flare will be like parent and children are in children array, name will be name of the node and at the end node or leaf node we don't have any children so here we reached to leaf
and taluks.geojson is not having the structure of desired manner. So we have to make it into our desired structure.
*
*/
var data= d3.nest().key(function(d){ return d.properties.NAME_2;}).key(function(d){ return d.properties.NAME_3;}).entries(root.features);
/*
* d3.nest function will perform the grouping operation mentioned/returned by the key function, this function is used to group elements by using key and it takes the data from entries function.
* so as per above code we are grouping by NAME_2 which is district name and again we are grouping that data based on NAME_3
* from above we'll get data in below format
* [{"key":"East Godavari","values":[
* {"key":"Kottapeta","values":[
* {"type":"Feature","properties":{"NAME_2":"East Godavari","NAME_3":"Kottapeta","profit":326,"npa":174},
* "geometry":{"type":"MultiPolygon","coordinates":[
* [[[81.75195312500006,16.772489547729492],[81.76336669921892,16.7611598968507],[81.7764129638673,16.755041122436637],[81.76336669921875,16.7611598968507],[81.75195312500006,16.772489547729492]]]
* ]}}]
* },
* {"key":"Rajahmundry","values":[{"type":"Feature","properties":{"NAME_2":"East Godavari","NAME_3":"Rajahmundry","profit":1762,"npa":1683},"geometry":{"type":"MultiPolygon","coordinates":[
* [[[81.71717071533203,17.0606307983399],[81.72284698486357,17.047969818115348],[81.72709655761736,17.035369873046875],[81.72931671142607,17.02490997314453],[81.73168945312517,17.009309768676758],[81.73249053955084,16.990680694580135],[81.731689453125,17.009309768676758],[81.7293167114259,17.02490997314453],[81.72709655761719,17.035369873046875],[81.7228469848634,17.047969818115348],[81.71717071533203,17.0606307983399]]],
* ]}}]
* },
* {"key":"Rampa Chodavaram","values":[{"type":"Feature","properties":{"NAME_2":"East Godavari","NAME_3":"Rampa Chodavaram","profit":376,"npa":362},"geometry":{"type":"MultiPolygon","coordinates":[[[[81.64000701904303,17.217769622802678],[81.63854217529308,17.24398994445812],[81.64405822753918,17.25922966003418],[81.64591217041021,17.293151855468864],[81.64405822753935,17.25922966003418],[81.63854217529325,17.24398994445812],[81.64000701904303,17.217769622802678]]],
* [[[81.51127624511724,17.463871002197266],[81.51648712158232,17.458469390869084],[81.52410888671903,17.454042434692326],[81.53122711181658,17.4517498016358],[81.55007171630854,17.447589874267692],[81.5312271118164,17.4517498016358],[81.52410888671886,17.454042434692326],[81.51648712158214,17.458469390869084],[81.51127624511724,17.463871002197266]]]]}}]
* },
* {"key":"Razole","values":[
* {"type":"Feature","properties":{"NAME_2":"East Godavari","NAME_3":"Razole","profit":1185,"npa":1141},"geometry":{"type":"MultiPolygon","coordinates":[
* [[[81.6993026733399,16.41020011901867],[81.70881652832048,16.383939743041992],[81.7134628295899,16.35638809204113],[81.70881652832031,16.383939743041992],[81.6993026733399,16.41020011901867]]],
* ]}}]
* }
* .........
* ]}]
To know more about d3 nest function go this link https://github.com/mbostock/d3/wiki/Arrays
* above structure is generated by d3.nest function, now we need to arrange that data into parent child hierarchical data, for this we are using below code
*/
var myData={name:'flare', children:[]};//this will be root
data.forEach(function(distc){
var dis={};
dis.name=distc.key;//here distc will hold one level write console.log(distc); and observe the data
dis.children = [];
myData.children.push(dis);
distc.values.forEach(function(chil){
var chis={};
chis.name=chil.key;
// chis.children=chil.values;
chis.size=chil.values[0].properties.profit;//we are using size as value in recurse function of classes function and we want to display bubble chart on profit value
dis.children.push(chis);
});
});
console.log(myData);//myData has the desired structure
root=myData;//assigning that json to root variable
I think you know what happens with the rest of the code.
Hope everything is clear, If not ask me for more.
:D
In order to create bubble chart we are using d3 pack layout, this layout we are generated at
var bubble = d3.layout.pack()
.sort(null)
.size([diameter, diameter])
.padding(1.5); and this bubble calling nodes at this line
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))//here bubble.nodes takes the json, that json should be in leaf structure, nodes function will generate relational data, write console.log(bubble.nodes(classes(root))); Here we are using classes function, because flare.json has already relational format json but bubbles.nodes need leaf structure so in classes function we are converting that flare.json relational structure into leaf
.filter(function(d) { return !d.children; }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

Bar chart with two series of different date/values ranges

I am using jqplot through Primefaces and Have input to Bar Chart like this:
Series 1:
label: "Company 1"
data: {"01-05-2015": 10, "06-05-2015": 3}
Series 2:
label: "Company 2"
data: {"03-05-2015": 10, "06-05-2015": 3}
When I pass this data as BarChartModel, I got data wrongly drawn on the chart.
The data follows the first series, as the Series 2 is drawn after the Series 1 dates. I've to convert the data to be as follows in order to get the chart drawn fine:
Series 1:
label: "Company 1"
data: {"01-05-2015": 10, *"03-05-2015": 0*, "06-05-2015": 3}
Series 2:
label: "Company 2"
data: { *"01-05-2015": 0* , "03-05-2015": 10, "06-05-2015": 3}
Notice the data items between * and *.
Any advice here? (if using DateAxis helps?)
I had the same problem with LinearChartModel when I has not using DateAxis.
As a workaround, I filled my series with all possible data and then reordered the list. Urg!
Should work with BarChartModel too.
Using DateAxis you just need to add your date axis with the timestamp, like this:
serie.set(new Date().getTime(), new Double(123));
or this
serie.set("2015-09-08", new Double(123));
Put the DateAxis in your LineChartModel like this:
DateAxis axis = new DateAxis("Data da inspeção");
linearModel.setZoom(true);
linearModel.getAxes().put(AxisType.X, axis);
linearModel.setExtender("linhaSetor");
And format your date in the extender.js:
function linhaSetor() {
this.cfg.axes.xaxis.tickOptions = {
show : true,
angle : 45,
formatString : '%d/%m/%y %Hh'
};
}
You don't even need to put the data in order.