My data array:
var data = [{glazed: 3.50, jelly: 4.50, powdered: 1.00, sprinkles: 3.50, age: 21, responses: 2,name:"test"},
{glazed: 2.83, jelly: 3.50, powdered: 1.83, sprinkles: 4.50, age: 22, responses: 6,name:"test"},
{glazed: 3.25, jelly: 4.75, powdered: 2.25, sprinkles: 3.50, age: 23, responses: 4,name:"test"},
{glazed: 1.50, jelly: 4.00, powdered: 2.50, sprinkles: 4.00, age: 25, responses: 2,name:"test"}];
If I wanted to find extent of either glazed or jelly or powdered or sprinkles to use for scaling, I would use a code as below..
var x = d3.scale.linear()
.domain(d3.extent(data, function (d) {
return d.glazed;//or jelly etc..
}))
.range([0, width]);
What would I need to do to get the extent of all values in glazed, jelly, powdered and sprinkles rather all values which are not age, responses and name.
This is because json file gets created dynamically and so I will have no idea of the key values except age, responses and name.
So, my requirement is that it should give me min as 1.5 (from glazed) and max as 4.75 (from jelly)
Any help is sincerely appreciated..
Thanks
Assuming that you want to be able to handle any key values except age
, responses
and name
, and that others in addition to glazed
, jellied
, powdered
& sprinkled
might appear, this approach should work to calculate max and min values:
var keys_to_ignore = ["age", "responses", "name"]
data.forEach( function (row)
{
//Use d3.entries to create key\values
var data_entries = d3.entries(row)
// Add the 'current maximum' and 'current_min' based off the previous rows
// If this is the first row, the extent will be undefined
if (typeof extent !== "undefined") {
data_entries.push({"key":"current_max", "value":extent[1]})
data_entries.push({"key":"current_min", "value":extent[0]})
}
// now calculate the extent (max / min)
extent = d3.extent(data_entries, function (d) {
// Ignore specified keys
if (keys_to_ignore.indexOf(d.key) == -1) {
return d.value;
}
});
});
console.log(extent)
Using d3.entries
will create objects with a key and value attribute, making the data easier to manage.
Working fiddle here: http://jsfiddle.net/henbox/aa4d0z81/
I feel like there's a more elegant way to do this, but I haven't managed to figure it out
var x = d3.scale.linear()
.domain(d3.extent(data.map(function (item) {
return (item.glazed);
})))
.range([0, width]);
map()
returns [3.5, 2.83, 3.25, 1.5]
extent()
returns [1.5, 3.5]
In case you need absolute minimum and maximum for all properties of the data
, you should concatenate arrays:
var x = d3.scale.linear()
.domain(d3.extent(
[].concat(data.map(function (item) {
return (item.glazed);
}), data.map(function (item) {
return (item.jelly);
}), data.map(function (item) {
return (item.powdered);
}), data.map(function (item) {
return (item.sprinkles);
}))))
.range([0, width]);
Finally, if you have a list of valuable properties, you should replace [].concat(...)
expression by anonymous function and call it immediately like this: function(array, names){...}(data, temp)
. You should know, in JavaScript array.property
and array["property"]
-- are the same calls.
var temp = ["glazed", "jelly", "powdered", "sprinkles"];
var width = 1000;
var data = [{glazed: 3.50, jelly: 4.50, powdered: 1.00, sprinkles: 3.50, age: 21, responses: 2,name:"test"},
{glazed: 2.83, jelly: 3.50, powdered: 1.83, sprinkles: 4.50, age: 22, responses: 6,name:"test"},
{glazed: 3.25, jelly: 4.75, powdered: 2.25, sprinkles: 3.50, age: 23, responses: 4,name:"test"},
{glazed: 1.50, jelly: 4.00, powdered: 2.50, sprinkles: 4.00, age: 25, responses: 2,name:"test"}];
var x = d3.scale.linear()
.domain(d3.extent(
function(array, names){
var res = [];
array.forEach(function(item){
names.forEach(function(name){
res = res.concat(item[name]);
});
});
return(res);
}(data, temp)
))
.range([0, width]);
DEMO: http://jsfiddle.net/v5qzuuhj/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With