How to dynamically add formatted ticks? - javascript

I have a bubble chart that I'm trying to add formatted ticks to. I also have the array that contains the strings I want to replace the numbered ticks with. An example of how my array will look like is this: ["A", "B", "C", "D"]. This array will vary in length and values on run time, but it will still contain strings. Preformatted ticks will range from 1 - length of array. 1 will be replaced with "A", 2 will be replaced with "B" and so forth. Because the array is only known during run time, I cannot do this:
hAxis: {
ticks: [
{v: 1, f: 'A'},
{v: 2, f: 'B'},
{v: 3, f: 'C'},
{v: 4, f: 'D'}
]
},
How can I output the ticks in the correct format? I've tried using a for-loop to mimic the style of the ticks format, but I am not doing it correctly.

Try this:
var input = ["A", "B", "C", "D"];
var ticks = input.map(function(item, index) {
return { v: index + 1, f: item };
});
console.log(ticks);

Related

how to get the x values from the sorted 'y' array [duplicate]

I have 2 arrays:
[2, 4, -2, 4, 1, 3]
["a", "b", "c", "d", "e", "f"]
and I want them to be sorted by the numerical array:
// output
[-2, 1, 2, 3, 4, 4] // <-sorted by numerical order
["c", "e", "a", "f", "b", "d"] // sorted exactly the same order as the first array
while its actually not important if "b" or "d" comes first (they both have 4 in this example)
I found many questions about this online but none of them worked for me can anyone help me with that?
You could sort the keys of the first array based on their value. This will return an array with indices of the array sorted based on the value of numbers array. Then use map to get the sorted values based on the indices
const numbers = [2, 4, -2, 4, 1, 3],
alphabets = ["a", "b", "c", "d", "e", "f"]
const keys = Array.from(numbers.keys()).sort((a, b) => numbers[a] - numbers[b])
const sortedNumbers = keys.map(i => numbers[i]),
sortedAlphabets = keys.map(i => alphabets[i])
console.log(
sortedNumbers,
sortedAlphabets
)
A standard method is to take the indices of the key array for sorting and sort the indices as pattern for all other arrays by taking the index and the value from the key array.
At the end map the sorted arrays.
var array1 = [2, 4, -2, 4, 1, 3],
array2 = ["a", "b", "c", "d", "e", "f"],
indices = [...array1.keys()].sort((a, b) => array1[a] - array1[b]);
[array1, array2] = [array1, array2].map(a => indices.map(i => a[i]));
console.log(...array1);
console.log(...array2);
I would recommend storing the entire thing in a Map. That way, you can independently sort the first array however you want and then use those values as keys to call respective value of second array.
You can do this in a single line by associating your two arrays and then ordering the items:
const x = ["a", "b", "c", "d", "e", "f"]
const y = [2, 4, -2, 4, 1, 3]
const result = y.map((val, index)=>({x:x[index], y:val})).sort((a,b)=>a.y-b.y).map(v=>v.x)
// -> ["c", "e", "a", "f", "b", "d"]

Javascript object fixed sort by key

I want to give a fixed order to an array of javascript objects and I've trying with the answer of this post but they are pointing to the value, not the keys.
fixed_order = ['group','A,'N','R']
data=[
{group: "a", A: 8, N: 6}
{group: "b", N: 4, A: 20, R: 1}
{group: "c", A: 7}
]
I've try with something like this but doesn't work.
data.sort(function (a, b) {
return fixed_order.indexOf(a.keys()) - fixed_order.indexOf(b.keys());
});
the result shoulb be something like this:
data=[
{group: "a", A: 8, N: 6}
{group: "b", A: 20, N: 4, R: 1}
{group: "c", A: 7}
]
You should not attempt to put object properties in a specific order. Objects are better thought of as unordered collections of properties. Even though modern engines implement the order defined by recent EcmaScript specifications, it is not considered good practice to make your code rely on that.
Instead, change your inner data structure from plain objects to arrays. An array is the recommended data structure when order is important.
const fixedOrder = ['group', 'A', 'N', 'R'];
const data = [
[["group", "a"], ["A", 8], ["N", 6]],
[["group", "b"], ["N", 4], ["A", 20], ["R", 1]],
[["A", 7], ["group", "c"]]
];
for (const row of data) {
row.sort((a, b) => fixedOrder.indexOf(a[0]) - fixedOrder.indexOf(b[0]));
}
console.log(data);

Unexpected 'sortBy' Behavior with Ramda

Application of 'sortBy' producing unexpected results.
I've gotta be doing something stoopid. This is such a basic operation.
const input = [4,3,2,1];
const sort = list => R.sortBy(R.ascend(R.identity))(list);
console.log(sort(input)); // [ 4, 3, 2, 1 ]
I would expect the output of the 'console.log' invocation to be [ 1, 2, 3, 4 ], but it is not: the output is [ 4, 3, 2, 1 ], same as the input. What am I doing wrong?
As pointed out by Aadit M Shah in the comments you're not using sortBy correctly.
Here's quick overview of how to sort in Ramda:
sort
Returns a copy of the list, sorted according to the comparator function, which should accept two values at a time and return a negative number if the first value is smaller, a positive number if it's larger, and zero if they are equal.
One case use subtract to sort in ascending order:
sort(subtract, [4, 1, 2, 3]);
//=> [1, 2, 3, 4]
Or to sort in descending, just flip it:
sort(flip(subtract), [4, 1, 2, 3]);
//=> [4, 3, 2, 1]
sort simply expects a function that can accept two parameters which can be compared with < or >.
So how would you sort an array of strings? Strings can be compared with < or > but using subtract wouldn't make sense. This is where ascend (or descend) can be useful:
Makes an ascending comparator function out of a function that returns a value that can be compared with < and >.
sort(ascend(identity), ["b", "a", "B", "A"]);
//=> ["A", "B", "a", "b"]
And if you want to make a case insensitive comparison:
sort(ascend(toLower), ["b", "a", "B", "A"]);
//=> ["a", "A", "b", "B"]
sortBy
As we saw, sort expects that you supply it with a function that accepts two parameters that can be compared together using < or >. Numbers and strings can be compared with these operators so if you can give them to Ramda directly then:
sortBy(identity, [4, 1, 2, 3]);
//=> [1, 2, 3, 4]
is the same as:
sort(subtract, [4, 1, 2, 3]);
//=> [1, 2, 3, 4]
However as far as I can tell, sortBy will always sort things in ascending order.
sortWith
You use sortWith when you can have multiple sort criteria:
Sort by age in ascending order
Sort by name in descending order
sortWith([ascend(prop('age')), descend(prop('name'))], [
{age: 40, name: 'John'},
{age: 40, name: 'Zack'},
{age: 10, name: 'Liam'},
{age: 20, name: 'Bill'}
]);
//=> [
//=> {age: 10, name: "Liam"},
//=> {age: 20, name: "Bill"},
//=> {age: 40, name: "Zack"},
//=> {age: 40, name: "John"}
//=> ]

How to select a Array index element with respect of its one of Value?

I have a Array
var arr=[{t: "Lokanath", v: 0},
{t: "Das", v: 1}]
Is there any way that i can get the Record t: "Das", v: 1 based on the value of v i.e. v:1
Array.prototype.filter()
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
You can use filter() in the following way:
var a=[{text: "Lokanath", value: 0, id: 100},
{text: "Das", value: 1, id: 101}];
var das = a.filter(p => p.text=='Das');
console.log(das[0]);
Please Note: Since filter() returns an array, you have to use index to take the object.
var arr=[{text: "Lokanath", value: 0, id: 100},
{text: "Das", value: 1, id: 101}]
arr.find(d => d.text == "Das")
you can use filter method to do that.
var arr=[{text: "Lokanath", value: 0, id: 100},{text: "Das", value: 1, id: 101}];
console.log(arr.filter(o => o.text=='Das')[0]);

Merge two objects with different keys in chartjs bar

I have two jsons:
first: {
"a": 1,
"b": 9,
"c": 12,
"d": 5
}
and
second: {
"a": 7,
"e": 8,
"b": 11,
"f": 7
}
and i want to create chartjs bar that include both json (with two datasets).
The labels should be 'a', 'b', 'c', 'd', 'e', 'f' and the "first" dataset's data will be: 1, 9, 12, 5, 0, 0. The "second" dataset's data will be: 7, 11, 0, 0, 8, 7.
My code right now:
var barChartData = {
labels: Object.keys(first),
datasets:[
{
label:'first',
data: Object.values(first)
},
{
label: 'second',
data: Object.values(second)
}]
};
window.myBar = new Chart(document.getElementById("barChart").getContext("2d"),
{
type:'bar',
data: barChartData
});
The problem is that i want the labels to be from the keys of both 'first' and 'second' jsons and not just from the 'first' and also that the values will be suitable to the keys.
Is there any simple way to do this?
It looks like you want both objects to have the same keys but with a value of zero when the keys aren't defined. There are several ways to do this. One option would be to make a list of the combined keys of both objects and just loop over them setting the object's value to 0 if the key doesn't exist:
let first = {"a": 1,"b": 9,"c": 12,"d": 5 }
let second = {"a": 7,"e": 8,"b": 11,"f": 7}
Object.keys(Object.assign({}, first, second)) // get combined keys
.forEach(k => {
if (!first.hasOwnProperty(k)) first[k] = 0; // set 0 if key is not in object
if (!second.hasOwnProperty(k)) second[k] = 0;
})
console.log(first, second)

Categories

Resources