I am tring to make a WBS chart using highcharter R package.
I wish to be able to plot the differents tasks per actions in a straight way under the box whom they come from, rather than in wages. I struggle to find the appropriate option to control this. (even after checking this here https://api.highcharts.com/highcharts/plotOptions.organization)
See the code below and what does it returns. Which is almost what I expected, but not exactly. I found the way to control the column position, but this is not working for rows. Moreover the task order is mixed in a weird way for the tasks in column 8 which is not expected of course.
library(highcharter)
highchart() %>%
hc_chart(type = 'organization', inverted = TRUE) %>%
hc_title(text = 'WBS') %>%
hc_add_series(
name = 'WBS',
data = list(
#Liste action
list(from = 'T', to = 'A1'),
list(from = 'T', to = 'A2'),
list(from = 'T', to = 'A3'),
list(from = 'T', to = 'A4'),
#A1
list(from = 'A1', to = 'b1'),
list(from = 'b1', to = 'P'),
list(from = 'P', to = 'F1'),
list(from = 'F1', to = 'AqDo'),
list(from = 'AqDo', to = 'Ay1'),
list(from = 'Ay1', to = 'R1'),
list(from = 'R1', to = 'Ar1'),
#A2
list(from = 'A2', to = 'b2'),
list(from = 'b2', to = 'Cx'),
list(from = 'Cx', to = 'F2'),
list(from = 'F2', to = 'Pr'),
list(from = 'Pr', to = 'Ay2'),
list(from = 'Ay2', to = 'R2'),
list(from = 'R2', to = 'Ar2'),
#A3
list(from = 'A3', to = 'b3'),
list(from = 'b3', to = 'Cx'),
list(from = 'Cx', to = 'F3'),
list(from = 'F3', to = 'Pr'),
list(from = 'Pr', to = 'Ay4'),
list(from = 'Ay4', to = 'R3'),
list(from = 'R3', to = 'Ar3'),
#A4
list(from = 'A4', to = 'Ar4')
),
nodes = list(
#task list
list(id = 'T', name = "name", title = "title", color = '#081358', dataLabels = list(color = 'white'), column = 0),
list(id = 'A1', title = 'action1', color = '#2D2F51', dataLabels = list(color = 'white'), column = 1),
list(id = 'A2', title = 'action2', color = '#2D2F51', dataLabels = list(color = 'white'), column = 1),
list(id = 'A3', title = 'action3', color = '#2D2F51', dataLabels = list(color = 'white'), column = 1),
list(id = 'A4', title = 'action4', color = '#2D2F51', dataLabels = list(color = 'white'), column = 1),
#A1
list(id = 'b1', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 2),
list(id = 'P', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 3),
list(id = 'F1', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 4),
list(id = 'AqDo', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 5),
list(id = 'Ay1', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 6),
list(id = 'R1', title = 'A1', color = '#9EC3E7', dataLabels = list(color = 'black'), column = 7),
list(id = 'Ar1', title = 'A1', color = '#B94331', dataLabels = list(color = 'white'), column = 8),
#A2
list(id = 'b2', title = 'A2', color = '#2491A9', dataLabels = list(color = 'black'), column = 2),
list(id = 'Cx', title = 'A2 + A3', color = '#2BA8C4', dataLabels = list(color = 'black'), column = 3),
list(id = 'F2', title = 'A2', color = '#2491A9', dataLabels = list(color = 'black'), column = 4),
list(id = 'Pr', title = 'A2 + A3', color = '#2BA8C4', dataLabels = list(color = 'black'), column = 5),
list(id = 'Ay2', title = 'A2', color = '#2491A9', dataLabels = list(color = 'black'), column = 6),
list(id = 'R2', title = 'A2', color = '#2491A9', dataLabels = list(color = 'black'), column = 7),
list(id = 'Ar2', title = 'A2', color = '#B94331', dataLabels = list(color = 'white'), column = 8),
#A3
list(id = 'b3', title = 'A3', color = '#34D1F4', dataLabels = list(color = 'black'), column = 2),
list(id = 'F3', title = 'A3', color = '#34D1F4', dataLabels = list(color = 'black'), column = 4),
list(id = 'Ay4', title = 'A3', color = '#34D1F4', dataLabels = list(color = 'black'), column = 6),
list(id = 'R3', title = 'A3', color = '#34D1F4', dataLabels = list(color = 'black'), column = 7),
list(id = 'Ar3', title = 'A3', color = '#B94331', dataLabels = list(color = 'white'), column = 8),
#A4
list(id = 'Ar4', title = 'A4', color = '#B94331', dataLabels = list(color = 'white'), column = 8)
)
)
and see the plot below
Maybe the answer could be found by modifying the css, or html, or javaScript source code ? but this would not be logical as an R package has been created to use highchart from Rstudio.
I have created a horizontal bar chart using d3.js and every thing works fine if no identical columns values(here it is 'response' field) occurs.
eg: var data = [{
"answer": "Answer2",
"response": 5,
"total": 7,
"color": "#ff4700"
}, {
"answer": "Answer3",
"response": 5,
"total": 7,
"color": "#0ED5EE"
}, {
"answer": "Answer4",
"response": 1,
"total": 7,
"color": "#31EE0E"
}];
If we provide same value on 'response' field( say repeating 5) , the resultant bar count will be not matched as expected, otherwise it will draw perfectly.
Can you please help me to sort out this issue.
Thanks and regards
For y domain give unique name in your case answer:
.domain(data.map(function(d) {
return d.answer;
}));
Then for the y axis give tick format:
.tickFormat(function(d, i){
var d = data[i];
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%'; })
working code here
The y axis domain value must be unique for it to work properly.
So your response value is not unique and in theory your answer does not have to be unique either. Furthermore, using answer as domain and then getting the data by index seems dirty and may cause unexpected results when (re-)sorting the data.
To get unique values for your y domain you could add an unique id to each of your data objects e.g.:
var data = [{
"uniqueId": 1,
"answer": "Answer2",
"response": 5,
"total": 7,
"color": "#ff4700"
},....]
y.domain(data.map(function(d) { return d.uniqueId; }));
And then add a tickFormat to the yAxis:
yAxis.tickFormat(function(id, i){
var d = data.find(function(d) { return d.uniqueId === id; });
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%';
})
result: https://jsfiddle.net/rd8z5k32/1/
Alternatively you could just use the indexes of the data array as domain:
y.domain(d3.range(data.length));
yAxis.tickFormat(function(_d, i){
var d = data[i];
var percentage = parseFloat( (d.response/d.total) * 100).toFixed(1)
return percentage + '%';
})
I have an object {"1": "a", "2": "b", "3": "c"}
How could I get max key?
I don't need a value, just key, so I would like to have 3 of type number
Use Object.keys to get all key values and from them get the largest using Math.max method with Function#apply method.
var obj = {
"1": "a",
"2": "b",
"3": "c"
};
console.log(
Math.max.apply(null, Object.keys(obj))
)
// or with ES6 spread syntax
console.log(
Math.max(...Object.keys(obj))
)
Here is an alternative using reduce() on the keys:
var data = {"1": "a", "2": "b", "3": "c"};
var max = Object.keys(data).reduce(function(a, b) {
return a > +b ? a : +b;
});
console.log(max);
var data = {"1": "a", "2": "b", "3": "c"}
var max = 0;
for (var property in data) {
max = (max < parseFloat(property)) ? parseFloat(property) : max;
}
console.log(max);
I have a single array having multiple values in that as shown in code below.
tempstraindatasource
tempstraindatasource[0] = {
A = "0",
B = "1",
C = "2",
D = "3"
}
tempstraindatasource[1] = {
A = "4",
B = "5",
C = "6",
D = "7"
and so on like wise I have many data exist in single array
}
I want to do one procedure that finds the data are consist or not in single line like I want to find Species having name "A" = "0" or any value "B" = "0" or "C" = "0"! How can I do it in single line? Please some one help me to do this.
Thanks in advance and appreciate as well.
You could use Array#forEach for the array and check if any of the properties have the value, you need with Array#some, and push the index then to the result array.
var data = [{ a: 0, b: 1, c: 2, d: 3 }, { a: 4, b: 5, c: 6, d: 7 }],
indices = [];
data.forEach(function (a, i) {
Object.keys(a).some(function (k) {
return a[k] === 0;
}) && indices.push(i);
});
console.log(indices);
As stated in comments your question needs editing (or better a total rewrite) but I think what you need is this
var fruits = [{name: 'banana', cost: 5}, {name: 'apple', cost:2}];
var filteredArray = fruits.map(function(fruit, index){
fruit.index = index;
return fruit;
}).filter(function(fruit){
return fruit.name === 'banana';
});
document.write(JSON.stringify(filteredArray));
I want a way to load 52 cards in an Array without having to hard code it.
I have an array suits which contains "H" , "C" , "S" , "D" prefixes for each suit.
I need to have a single array cards[52] with values H1-H13,S1-S13 etc.
The problem i am facing is i can load cards[0] to cards[12] fairly easily, but how do i load the next card in cards[13] ?
You can do something like this:
var suits = new Array("H", "C", "S", "D");
var cards = new Array();
// changed 3 to 4 to display all four suits
var cnt = 0;
for(i=0; i<4; i++)
for(j=1; j<=13; j++)
cards[cnt++] = suits[i] + j;
Try:
var suits = ["H", "C", "S", "D"], cards = [], n = 0;
while(n < 4){
for(i = 1; i < 13; i++)
cards.push(suits[n] + i);
n++;
}
You can either load all 52 cards into a single array, as you were thinking:
var suits = ['H', 'C', 'S', 'D'];
var cards = [];
var suitIndex = 0;
for(var i = 0 i < 52; i++) {
cards.push(suits[suitIndex] + (i % 13));
// if remainder after division by 13 is zero,
// you know you've hit a multiple of 13 and need to switch suits.
if (i % 13 == 0 && suitIndex < suits.length) {
suitIndex++;
}
}
Or you can create 4 different card arrays and switch to a different array when you fill one.
Frankly there isn't any good reason to generate the deck dynamically when you can do it faster and in just a few lines by hand:
var cards = [
"H1", "H2", "H3", "H4", "H5", "H6", "H7",
"H8", "H9", "H10", "H11", "H12", "H13",
"C1", "C2", "C3", "C4", "C5", "C6", "C7",
"C8", "C9", "C10", "C11", "C12", "C13",
"S1", "S2", "S3", "S4", "S5", "S6", "S7",
"S8", "S9", "S10", "S11", "S12", "S13",
"D1", "D2", "D3", "D4", "D5", "D6", "D7",
"D8", "D9", "D10", "D11", "D12", "D13"
]