How to find max value from a 2D matrix using D3.js - d3.js

I have data of the following format
var data=[[5,2,3,6],[10,22,10,5],[2,3,4,5],[50,30,20,13]];
That means its a M*N array actually. How can i use d3.max from this array. I need the get the single value i.e. 50. I was trying with
var max=d3.max(data,function(d){return d});
But it's not working. Can anyone help me?
Thanks in advance

Your code will try to find the maximum of four arrays. What you actually need is another call to d3.max within the other call:
var max = d3.max(data, function (d) {
return d3.max(d);
});

Related

Cannot display the highest value when using crossfilter.js

I am trying to display the top value, found by crossfilter, in dc.js, but I get
Uncaught TypeError: _chart.group(...).value is not a function
Any help?
This is my code
var ndx = crossfilter(projectsJson);
var highPriceDim = ndx.dimension(function(d) { return d.High; });
var highGrp = highPriceDim.top(1);
console.log(highGrp);
var highGrpND = dc.numberDisplay("#max-price-nd");
highGrpND.group(highGrp)
.formatNumber(d3.format("d"))
.valueAccessor(function(d){return d ; })
.formatNumber(d3.format(".4f"));
Thanks for any help
highGrp is an array. Try highGrpND.group(highGrp[0]) instead.
You should be able to just do
highGrpND.group(highPriceDim.group())
since the numberDisplay will look for either a value method, or failing that, take .top(1)
https://github.com/dc-js/dc.js/blob/develop/src/number-display.js#L81
(which is kind of a messy design, but hey if it works...)
This is better than calculating the top(1) at setup time, since it will be calculated every time the charts are drawn, rather than just once, which is probably what you want.

How to generate line chart with discrete value, not time serial, as x-axis

Sorry for this silly question, but I am lost and hope any other expert can help me.
I need to draw a bar chart, but the x axis is NOT time series, it is discrete values.
var ndx = crossfilter( self.getStatus( contracts ));
var skuDim = ndx.dimension( function(d){
return d.sku;
});
var skuDimCount = skuDim.group().reduceCount();
var chartLineContractSku= dc.barChart("#chart-line-contract-sku");
chartLineContractSku
.width(500)
.height(200)
.dimension(skuDim)
.group(skuDimCount)
.x(d3.scale.linear().domain(skus))
.legend(dc.legend());
the skus is:
array of sku:
["PAR-ND-SRX1-SPCNPC", "SVC-ND-M10i", "SVC-CP-SRX3400", "SVC-ND-SRX3400", "SVC-ND-SRX3-IOC", "SVC-CP-SRX3-IOC", "SVC-CP-SRX3-NPC", "SVC-3-ND-SRX3-IOC", "SVC-CP-SRX3-SPC", "SVC-ND-SRX3-SPC"]
which is used to group dimension the input data.
But the output graph is always empty.
Can anyone tell me how to fix this? And how to generate the barChart with discrete value? Also, another question is how to make the label vertical? as we have quite a lot skus.
Thanks
Gordon is correct in saying that you should use ordinal scale to get your desired result. Replace your d3.scale.linear code with
x(d3.scale.ordinal().domain(skus))
Look at this as an example
http://bost.ocks.org/mike/bar/3/

Control what elements get shown in dc.js datatable

I'm stuck on a seamingly easy problem with dc.js and crossfilter.
I have a datatable on a dimension and it shows my data correctly. The problem is that I want to show the 'worst' data items but the datatable picks the 'best' items in the filters.
The following is a scetch of the current table code.
var alertnessDim = ndx.dimension(function(d) {return d.alertness1;});
dc.dataTable(".dc-data-table")
.dimension(alertness1)
.group(function (d) {
return d.DATE.getYear();
})
.columns([
function (d) {
return d.DATE;
},
function (d) {
return d['FLEET'];
},
function (d) {
return d.alertness1;
}
])
.sortBy(function (d) {
return d.alertness1;
})
.order(d3.ascending);
This connects to the crossfilter properly and it sorts the items in the correct order, but the 25 items it is showing are the ones with the highest alertness values, not the lowest.
Anyone have any ideas on how to solve this, preferbly without creating another dimension?
You are right to be confused here. You would think this would be a supported use case but it is not, as far as I can tell. The data table uses dimension.top so it is always going to take the highest values.
So I don't think there is a way around using a special dimension with opposite ordering/keys. For the other charts you could use group.order in order (heh) to get it to return the lowest values. But the data table doesn't use a group because it's not reducing its values.
It's confusing that the data table also has an order parameter which doesn't help here.
Hope that is acceptable. Otherwise I think you'd have to poke around in the code. Pull Requests always welcome! (preferably with tests)
One quick way to achieve descending sort on a specific column, is to sort by its negative value:
.sortBy(function(d){ return -d.ALARM_OCCURRENCE; }); // show highest alarm count first

For NVD3 lineChart Remove Missing Values (to be able to interpolate)

I am using NVD3 to visualise data on economic inequality. The chart for the US is here: http://www.chartbookofeconomicinequality.com/inequality-by-country/USA/
These are two lineCharts on top of each other. The problem I have is that there are quite a lot of missing values and this causes two problems:
If I would not make sure that the missing values are not visualised the line Chart would connect all shown values with the missing values. Therefore I used the following to not have the missing values included in the line chart:
chart = nv.models.lineChart()
.x(function(d) { return d[0] })
.y(function(d) { return d[1]== 0 ? null : d[1]; })
But still if you hover over the x-axis you see that the missing values are shown in the tooltip on mouseover. Can I get rid of them altogether? Possibly using remove in NVD3?
The second problem is directly related to that. Now the line only connects values of the same series when there is no missing values in between. That means there are many gaps in the lines. Is it possible to connect the dots of one series even if there are missing values in between?
Thank you for your help!
As Lars showed, getting the graph to look the way you want is just a matter of removing the missing values from your data arrays.
However, you wouldn't normally want to do that by hand, deleting all the rows with missing values. You need to use an array filter function to remove the missing values from your data arrays.
Once you have the complete data array as an array of series objects, each with an array of values, this code should work:
//to remove the missing values, so that the graph
//will just connect the valid points,
//filter each data array:
data.forEach(function(series) {
series.values = series.values.filter(
function(d){return d.y||(d.y === 0);}
);
//the filter function returns true if the
//data has a valid y value
//(either a "true" value or the number zero,
// but not null or NaN)
});
Updated fiddle here: http://jsfiddle.net/xammamax/8Kk8v/
Of course, when you are constructing the data array from a csv where each series is a separate column, you can do the filtering at the same time as you create the array:
var chartdata = [];//initialize as empty array
d3.csv("top_1_L-shaped.csv", function(error, csv) {
if (error)
return console.log("there was an error loading the csv: " + error);
var columndata = ["Germany", "Switzerland", "Portugal",
"Japan", "Italy", "Spain", "France",
"Finland", "Sweden", "Denmark", "Netherlands"];
for (var i = 0; i < columndata.length; i++) {
chartdata[i].key = columndata[i];
chartdata[i].values = csv.map(function(d) {
return [+d["year"], +d[ columndata[i] ] ];
})
.filter(function(d){
return d[1]||(d[1] === 0);
});
//the filter is applied to the mapped array,
//and the results are assigned to the values array.
}
});

How to get quantize values

is there a way to get the start and end values of the quantizes of an quantize scale.
The range is defined by 5 colors ans the domain by d3.min and d3.max function on my data from an json file.
I need them for my legend of an choropleth map.
Thank you for helping.
Carsten
Thats my code
var quantizecolors = ["#d7191c","#fdae61","#ffffbf", "#a6d96a","#1a9641"];
var colorEnerg = d3.scale.quantize().range(quantizecolors);
colorEnerg.domain([
d3.min(collection.features, function(d){return d.properties.EB/d.properties.BEVZ;}),
d3.max(collection.features, function(d){return d.properties.EB/d.properties.BEVZ;})
]);
I assume that you're asking about the minimum and maximum domain values. Apart from saving them when you're setting them, you can also call colorEnerg.domain() without any values, which will return the array [min, max].
You can get the position of the breaks by computing the number and position of intervals:
var dom = colorEnerg.domain(),
l = (dom[1] - dom[0])/colorEnerg.range().length,
breaks = d3.range(0, colorEnerg.range().length).map(function(i) { return i * l; });

Resources