Related
I am using highcharts library to plot Sankey chart with our data, which has many number of nodes in each column. My issue is links width is reduces when it is between one of nodes on the top and one of the nodes are a bit lower than that. More longer the link is more width reduces.
I am wondering if there is any work around or some simple thing from documentation that I am missing. Any help is appreciated. Below is the fiddle
https://jsfiddle.net/Saibabu276/cqj2n413/
Highcharts.chart('container', {
title: {
text: 'Highcharts Sankey Diagram'
},
chart: {
height: 1000
},
accessibility: {
point: {
valueDescriptionFormat: '{index}. {point.from} to {point.to}, {point.weight}.'
}
},
series: [{
keys: ['from', 'to', 'weight'],
data: [
['Brazil', 'Portugal', 5],
['Brazil', 'France', 1],
['Brazil', 'Spain', 1],
['Brazil', 'England', 1],
['Canada', 'Portugal', 1],
['Canada', 'France', 5],
['Canada', 'England', 1],
['Mexico', 'Portugal', 1],
['Mexico', 'France', 1],
['Mexico', 'Spain', 5],
['Mexico', 'England', 1],
['USA', 'Portugal', 1],
['USA', 'France', 1],
['USA', 'Spain', 1],
['USA', 'England', 5],
['Portugal', 'Angola', 2],
['Portugal', 'Senegal', 1],
['Portugal', 'Morocco', 1],
['Portugal', 'South Africa', 3],
['France', 'Angola', 1],
['France', 'Senegal', 3],
['France', 'Mali', 3],
['France', 'Morocco', 3],
['France', 'South Africa', 1],
['Spain', 'Senegal', 1],
['Spain', 'Morocco', 3],
['Spain', 'South Africa', 1],
['England', 'Angola', 1],
['England', 'Senegal', 1],
['England', 'Morocco', 2],
['England', 'South Africa', 7],
['South Africa', 'China', 5],
['South Africa', 'India', 1],
['South Africa', 'Japan', 3],
['Angola', 'China', 5],
['Angola', 'India', 1],
['Angola', 'Japan', 3],
['Senegal', 'China', 5],
['Senegal', 'India', 1],
['Senegal', 'Japan', 3],
['Mali', 'China', 5],
['Mali', 'India', 1],
['Mali', 'Japan', 3],
['Morocco', 'China', 5],
['Morocco', 'India', 1],
['Morocco', 'Japan', 3]
],
type: 'sankey',
name: 'Sankey demo series'
}]
});
To set the connection between nodes option series.sankey.curveFactor add a possibility to make the line straight completely or change the curve to lover.
Higher numbers makes the links in a sankey diagram or dependency wheelrender more curved. A curveFactor of 0 makes the lines straight.
plotOptions: {
sankey: {
nodeWidth: 10,
curveFactor: 0.1
}
},
Live demo:
https://jsfiddle.net/BlackLabel/6ac2syzx/
How to draw a stacked chart and column chart in a single highchart
Yes, all you have to do is set the appropriate x value.
series: [{
data: [
[0, 1],
[1, 3],
[2, 5]
]
}, {
data: [
[0, 2],
[1, 2],
[2, 4]
]
}, {
data: [
[3, 8]
]
}]
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4992/
API Reference: https://api.highcharts.com/highcharts/series.column.data
My JSfiddle: https://jsfiddle.net/sathishkumar_v/sw0fa4m8/2/.
Highcharts.chart('container', {
title: {
text: 'Highcharts Sankey Diagram'
},
series: [{
keys: ['from', 'to', 'weight'],
data: [
['Brazil', 'Portugal', 5 ],
['Brazil', 'France', 1 ],
['Brazil', 'Spain', 1 ],
['Brazil', 'England', 1 ],
['Canada', 'Portugal', 1 ],
['Canada', 'France', 5 ],
['Canada', 'England', 1 ],
['Canada', 'Brazil', 4 ],
],
type: 'sankey',
name: 'Sankey demo series'
}]
});
We have two from side labels: Brazil, and Canada. The to side has the labels: Portugal, France, Spain, England, and Brazil.
The plotted graph is failing to display the Brazil label at right side as expected. Instead, it is showing the Brazil label in the bottom left corner.
I think you will need to change the data order like that :
data: [
['Canada', 'Brazil', 4 ], // In first position
['Brazil', 'Portugal', 5 ],
['Brazil', 'France', 1 ],
['Brazil', 'Spain', 1 ],
['Brazil', 'England', 1 ],
['Canada', 'Portugal', 1 ],
['Canada', 'France', 5 ],
['Canada', 'England', 1 ],
],
Fiddle
Edit 2nd solution
Use nodes Api Doc
data: [
['Brazil', 'Portugal', 5 ],
['Brazil', 'France', 1 ],
['Brazil', 'Spain', 1 ],
['Brazil', 'England', 1 ],
['Canada', 'Portugal', 1 ],
['Canada', 'France', 5 ],
['Canada', 'England', 1 ],
['Canada', 'Brazil-end', 4 ],
],
nodes: [{
id: 'Brazil-end',
name: 'Brazil'
}
],
Fiddle
I have 4 fields in a document which is name, online, like and score. I want to ordering by multiple fields and conditions collection of million documents with pagination.
Example some documents :
My user documents :
{ "_id": 1, "name": "A", "online": 1, "like": 10, "score": 1 },
{ "_id": 2, "name": "B", "online": 0, "like": 9, "score": 0 },
{ "_id": 3, "name": "C", "online": 0, "like": 8, "score": 1 },
{ "_id": 4, "name": "D", "online": 1, "like": 8, "score": 0 },
{ "_id": 5, "name": "E", "online": 1, "like": 7, "score": 1 },
{ "_id": 6, "name": "F", "online": 0, "like": 10, "score": 0 },
I will explain my point with the following example (example using an array).
Example in ruby language, I have an array structure looks like :
[["A", 1, 10, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["F", 0, 10, 0]]
If online is 1 should be sort again by descending of like, but when online is 0 should be sort again by descending of score.
example sort :
list.sort{|a, b| a[1] == 1 ? ([-a[1], -a[2]] <=> [-b[1], -b[2]]) : ([-a[1], -a[3]] <=> [-b[1], -b[3]]) }
Result like this :
[["A", 1, 10, 1],
["D", 1, 8, 0],
["E", 1, 7, 1],
["B", 0, 9, 1],
["C", 0, 8, 1],
["F", 0, 10, 0]]
That is an array sort, but my problem is I have collection of mongodb and million documents, I can't use an array sort, because it will heavy load to database, should get all documents and convert to array (including sorting) and than paginate them, I think that's a bad idea.
I have try with order()/order_by() mongoid's optional method like :
User.
order_by([:online, :desc], [:like, :desc], [:score, :desc]).
hint(online: -1, like: -1, score: -1).
page(1).per(10)
But that query is only order by online and score, is there sort method in mongoid like an array sorting? or there is something like bubble sort in mongodb?
same problem here : Ruby on Rails: Concatenate results of Mongoid criterias and paging, merge method doesn't helped me because it can be replace the first criteria.
Using aggregation $cond
User.collection.aggregate([
{
"$project" => {
"id" => 1,
"name" => 1,
"online" => 1,
"like" => 1,
"score" => 1,
"sort" => {
"$cond" => {
"if" => {
"$eq" => ["$online", 1]
},
"then" => "$like",
"else" => "$score"
}
}
}
},
{
"$sort" => {
"online" => -1,
"sort" => -1,
"id" => 1
}
},
{
"$skip" => 0
{
"$limit" => 12
}
])
references :
https://docs.mongodb.com/manual/reference/operator/aggregation/cond/
https://www.oodlestechnologies.com/blogs/How-to-use-Conditional-Statements-for-sorting-data-in-MongoDB
Assuming fields score , like and online are numeric , based on the condition we can create an auxiliary field that is a sum of online and like or online and score. Following which we can sort on the new field and any other required field.
db.collection aggregate([ {"$addFields": {"refCount":{"$cond":{"if":{"$eq":["$online", 1]}, "then":{"$add": ["$online", "$like"]}, "else": {"$add": ["$online", "$score"]} } } }},{ "$sort": { "refCount": -1 ,"id":1} },{"$project":{"id": 1, "name": 1, "online": 1, "like": 1,"score":1}},{ "$limit": 10 } ])
The first stage of the pipeline build the auxiliary field refcount. This field is then used in $sort along with id . In the next stage we have a projection of required fields , followed by limit clause.
Instead of numeric , if these fields were strings, a padded concatenation of fields would be required.
In a stacked chart with a data series in the format of [x, y] there is a larger margin on the left and on the right side. I have created the following jsfiddle to with sample data:
http://jsfiddle.net/ymyrA/4/
The code of the chart is as follows:
$(function () {
var chart = new Highcharts.Chart({
chart: {"renderTo": "container", "type": "column"},
colors: ["#2f7ed8", "#0d233a", "#8bbc21", "#910000", "#1aadce", "#492970", "#f28f43", "#77a1e5", "#c42525", "#a6c96a", "#4572A7", "#AA4643", "#89A54E", "#80699B", "#3D96AE", "#DB843D", "#92A8CD", "#A47D7C", "#B5CA92"],
credits: {"enabled": false},
plotOptions: {"column": {"stacking": "normal"}},
series: [
{"name": "Muster1", "data": [
[11, 1],
[32, 1]
]},
{"name": "Muster2", "data": [
[11, 7],
[12, 4],
[14, 4],
[15, 1],
[16, 1],
[17, 4],
[18, 6],
[19, 2],
[20, 1],
[21, 1],
[22, 1],
[25, 3],
[26, 2],
[28, 1],
[29, 1],
[30, 1]
]},
{"name": "Muster 3", "data": [
[11, 2],
[13, 2],
[15, 1],
[16, 3],
[18, 5],
[19, 11],
[20, 8],
[21, 1],
[23, 3],
[24, 12],
[27, 3],
[28, 4],
[30, 3],
[31, 3],
[33, 3],
[34, 3]
]}
],
title: {"text": null},
xAxis: {"title": {"text": "Week"}},
yAxis: {"title": {"text": "Count"}}
});
});
I have tried with min and max values, categories, etc. and nothing worked out. How can I adjust the chart to be displayed in full size?
I have updated the code and the jsfiddle with the proper sorting. I was using 3.0 and not 3.05 therefore I had no errors in the console. With the latest version I have to issues remaining. One is the above mentioned large margin at the right and left side and the other one is i am unable (even with tickInterval) to have a tick per calendar week. Based on the above mentioned sample the entire chart should have the range from x=11 to x=34 with a tick on each x.
The problem is with calculated pointRange for first series - when you have only two points, for x=11 and x=31 it is assumed that minimum interval between points in that series is 20, so Highcharts will try to set interval something about 20. For such cases you need to use pointRange for example set it to 1, see: http://jsfiddle.net/ymyrA/5/