consider the example shown in the link Labeling the axis with alphanumeric characters. Is this the correct way to parse var data?
var data = []
d3.csv("data.csv", function(data) {
data = data.forEach(function(d) { return [ x[d[0]], y[d[1]]] });
console.log(data)
});
data.csv should hold these values
[2, 2],
[3, 3],
[4, 4],
[5, 4],
[5.5, 5],
[6, 6],
[6, 7],
[6.5, 8],
[6.5, 16],
[17, 16]
Assuming that you meant that data should hold those values, your data.csv should look like the following:
first,second
2,2
3,3
4,4
5,4
5.5,5
6,6
6,7
6.5,8
6.5,16
17,16
And then you can parse it using the names of the fields:
var data = []
d3.csv("data.csv", function(csvData) {
// By default, all the values read are treated as strings.
// So have to make them numbers explicitly
data = csvData.forEach(function(d) { return [ +d.first, +d.second ] });
console.log(data);
// Draw the chart here.
});
Related
I have a 2D array (grid) of 2D arrays (chunks) for a game I'm developing:
const c1 = [[1, 2],
[3, 4]]
const c2 = [[5, 6],
[7, 8]]
const c3 = [[9, 0],
[1, 2]]
const c4 = [[3, 4],
[5, 6]]
const grid_of_chunks = [[c1, c2],
[c3, c4]];
and I want to reduce/flatten the grid_of_chunks to:
[[1, 2, 5, 6],
[3, 4, 7, 8],
[9, 0, 3, 4],
[1, 2, 5, 6]]
I've been able to implement a functional solution for this (in 2 lines of Clojure), but I'm struggling to wrap my head around translating it to functional JavaScript, and bridging the gap between the two language's map semantics (JS map only accepts one array, whereas Clojure's map accepts many collections...).
This is as far as I got:
function join_grid_of_chunks(gofc) {
const joined_horiz = gofc.map(
gofc_row => [].map.apply(gofc_row, [cs => [].concat.apply(cs)])
);
return [].concat.apply(joined_horiz);
}
Edit: Clojure solution (which works for uniformly-sized square chunks, in an arbitrarily sized square grid):
(defn join-grid-of-chunks [gofc]
(let [joined (map #(apply map concat %) gofc)]
(apply concat joined)))
A more general solution using flatMap is to map over the indices from the first chunk of each grid row.
function joinGridOfChunks(grid) {
return grid.flatMap(row => row[0].map((_, i) => row.flatMap(chunk => chunk[i])))
}
With a zip function (such as the one in lodash), you could write it slightly more elegantly as:
function zip(...arrays) {
return arrays[0].map((_, i) => arrays.map(arr => arr[i]))
}
function joinChunks(chunks) { // Horizontally join an array of chunks e.g. [[[1,2],[3,4]], [[5,6],[7,8]]] --> [[1,2,5,6],[3,4,7,8]]
return zip(...chunks).map(row => row.flat())
}
console.log(gridOfChunks.flatMap(joinChunks));
zip plus map seems to be close to Clojure's map with multiple collections. This should work for any shape 2d chunks in a 2d grid.
Here's what I have:
const c1 = [[1, 2], [3, 4]];
const c2 = [[5, 6], [7, 8]];
const c3 = [[9, 0], [1, 2]];
const c4 = [[3, 4], [5, 6]];
const grid_of_chunks = [
[c1, c2],
[c3, c4]
];
function transform(input) {
return input.flatMap(rows => {
return rows.reduce((result, chunk) => {
chunk.forEach((row, rowIndex) => {
result[rowIndex] = result[rowIndex] || [];
result[rowIndex].push(...row);
});
return result;
}, []);
});
}
console.log(transform(grid_of_chunks));
Should work for NxN chunks and MxM grid
["Ahmed", 8],
["Clement", 10],
["Elamin", 6],
["Adam", 7],
["Tayoa", 11],
["Nina", 10],
["Bob", 9],
["Lee", 1]
In the above array, how can I retrieve names value whose second key value is greater than 8?
any help appriciated.Thank you
This approach requires iterating over the array twice by first filtering out the invalid elements and then mapping over the array to pluck out the name.
Note that this is leveraging array destructuring which allows us to nicely give the value at a given index a name, rather than trying to remember the index offset and what it means.
const data = [
["Ahmed", 8],
["Clement", 10],
["Elamin", 6],
["Adam", 7],
["Tayoa", 11],
["Nina", 10],
["Bob", 9],
["Lee", 1]
]
const filtered = data.filter(([_name, num]) => num > 8).map(([name]) => name)
console.log(filtered)
You can reduce() the array in one pass by checking if the second element in the array (age?) is more than 8, if so, add the first element in the array (the name) to the accumulator array, like so:
let arr = [
["Ahmed", 8],
["Clement", 10],
["Elamin", 6],
["Adam", 7],
["Tayoa", 11],
["Nina", 10],
["Bob", 9],
["Lee", 1],
];
let result = arr.reduce((acc, [name, age]) => (age > 8 && acc.push(name), acc), []);
console.log(result);
I am using a url to fetch data that constantly updates and changes. It comes back in the form of an array like this:
[[0,14],[1,11],[2,15],[3,12],[4,8],[5,8],[6,9],[7,9],[8,9],[9,7]].
I would like this to be transformed so I can use it in a chart.js
I think I should convert it to a json file, but don't really know how it works because the fetch needs to be initialized every 5 seconds and that new data has to be put in the json file every time and then displayed in the chart.js.
I got the data in the updatingArray[], but i'm stuck now.
function getDataFromDatapointsUrl(){
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = 'https://canvasjs.com/services/data/datapoints.php)';
fetch(proxyurl + url)
.then(response => response.text())
.then(contents => createArrayForUpdatingData(contents));
}
getDataFromDatapointsUrl();
// setInterval(getDataFromDatapointsUrl, 500);
var updatingDataArray = [];
function createArrayForUpdatingData(updatingData){
updatingDataArray.push(updatingData);
}
I would like the data from the array to be split up in the chart.
[[0,14],[1,11],[2,15],[3,12],[4,8],[5,8],[6,9],[7,9],[8,9],[9,7]].
So the 0,1,2,3,4,5,6,... should become the x-axis and the 14,11,15, ... should become the value of the chart-line, bar-, pie, whatever you like it to visualized like.
Based on your example you can simply iterate updatingDataArray and push each value to a separate array that you then pass to Chart.js:
var updatingDataArray = [
[0, 14],
[1, 11],
[2, 15],
[3, 12],
[4, 8],
[5, 8],
[6, 9],
[7, 9],
[8, 9],
[9, 7]
];
var labels = [],
values = [];
updatingDataArray.forEach(function(val, idx) {
labels.push(val[0]);
values.push(val[1]);
});
new Chart(document.getElementById("chart"), {
type: "line",
data: {
labels: labels,
datasets: [{
data: values
}]
},
options: {}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js"></script>
<canvas id="chart"></canvas>
Problem
I have an array of arrays:
const multiple = [[1, 2, null, 7], [6, 8, 9, 1]]
Now I'd like to remove all null values and the corresponding element from the other array which results in:
[[1, 2, 7], [6, 8, 1]]
I'm able to do that but I'm looking for a solution with _.flow.
Approach
This is my approach that doesn't return an array of arrays and also doesn't remove the element from the other array.
_.flow([
xorWith(_.isNull)
])([1, 2, null, 7], [6, 8, 9, 1])
1. Update
My input will always be [[ // Elements], [ // Elements]]. It wasn't clear at my approach.
const multiple = [[1, 2, null, 7], [6, 8, 9, 1]];
const withoutNulls = (arr) => _.every(arr, _.negate(_.isNull));
const result = _.flow(
_.zip,
(tuples) => _.filter(tuples, withoutNulls),
_.unzip
)(...multiple)
console.log(result);
<script src="https://unpkg.com/lodash#4.17.5/lodash.js"></script>
Does that suit your needs, or you want it exactly with your functions set?
I can't get the basic idea of yours, because the flow function accepts functions and call them in chain, but it is not as in your case.
_.flow((...args) => _.map(args, arr => _.filter(arr, v => !_.isNull(v))), console.log)([1, 2, null, 7], [6, 8, 9, 1])
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.5/lodash.min.js"></script>
I'm using d3.js and nvd3.js to display some data from different datasets. One of the sets (A) contains the absolute number of orders, the other set (B) contains the number of orders from new customers, such that A >= B for every position. Example:
[{
key : 'orders',
values: [[1, 10], [2, 5], [3, 8], ...]
},{
key : 'orders by new customers',
values: [[1, 4], [2, 0], [3, 4], ...]
}]
I'd like to use a stacked multibar chart to display those series. In "Grouped" view, everything works nicely and I have both bars grouped beneath each other. However, when I switch to "Stacked" mode I was expecting, that the overall number does not change. It appeared that nv3d.js is then adding up both values and i get a new overall value.
Is there a way to change the calculation when switching to stacked mode? I was digging through the source code, but could not find a usable method to achieve this.
Thanks in advance!
If I understood your problem correctly, it would make more sense to restructure your data to make it conceptually match with bars being 'stacked' (which implies two values being added together), to something like this where:
orders = recurring orders + orders by new customers
[{
key : 'recurring orders',
values: [[0, 6], [0, 5], [0, 4], ...]
},{
key : 'orders by new customers',
values: [[1, 4], [2, 0], [3, 4], ...]
}]