Crossfilter barchart does not render - dc.js

I am new to Crossfilter and JS. I can't figure out why this barchart won't render. I've tried several date formats. Link to my jsfiddle is below. Any help, please?
It is basically reading a loan dataset in JSON format and attempting to barchart the count by day over time.
https://jsfiddle.net/5q1dddgt/2/
<div id="time-chart"></div>
/**
* Created on 3/13/17.
*/
var mortgageJson = [{
"index": 0,
"full_fips": "04013",
"defaulted_balance": 0.0,
"original_balance": 148000.0,
"county_name": "Maricopa County",
"state": "AZ",
"oltv": 79,
"dti": 30.0,
"originationMth": "1999-02-01T00:00:00.000Z",
"defaultRate": 0.0
}, {
"index": 1,
"full_fips": "04021",
"defaulted_balance": 0.0,
"original_balance": 148000.0,
"county_name": "Pinal County",
"state": "AZ",
"oltv": 79,
"dti": 30.0,
"originationMth": "1999-02-01T00:00:00.000Z",
"defaultRate": 0.0
}];
var mortgageSummary = mortgageJson;
var dateformat=d3.time.format("%m-%d-%Y");
mortgageSummary.forEach(function(d) {
d.originationMonth = new Date(d.originationMth).toLocaleDateString("en-GB");
});
var ndx = crossfilter(mortgageSummary);
var dateDim = ndx.dimension(function(d) {
return d["originationMonth"];
});
var originationByTime = dateDim.group().reduceCount(function(d) { return d.originationMonth;});
var totalOrigination = ndx.groupAll().reduceSum(function(d) {
return d["original_balance"];
});
var max_county = originationByTime.top(1)[0].value;
var minDate = dateDim.bottom(1)[0]["originationMonth"];
var maxDate = dateDim.top(1)[0]["originationMonth"];
console.log(minDate);
console.log(maxDate);
var timeChart = dc.barChart("#time-chart");
timeChart
.width(600)
.height(160)
.margins({
top: 10,
right: 50,
bottom: 30,
left: 50
})
.dimension(dateDim)
.group(originationByTime)
.transitionDuration(500)
.x(d3.time.scale().domain([minDate, maxDate]))
.xUnits(d3.time.days)
.elasticX(true)
.elasticY(true)
.xAxisLabel("Year")
.yAxis().ticks(4);
dc.renderAll();

Take a look at the browser console and you'll see some of the problems. Your inclusion of firebug-lite is causing lots of errors. I'd recommend you just use the developer tools included in your browser.
Other changes:
You want an actual date object as your dimension rather than a string, so I changed
mortgageSummary.forEach(function(d) {
d.originationMonth = new Date(d.originationMth).toLocaleDateString("en-GB");
});
to
mortgageSummary.forEach(function(d) {
d.originationMonth = new Date(d.originationMth);
});
And group.reduceCount doesn't take any arguments (reduceSum does), so this will work fine:
var originationByTime = dateDim.group().reduceCount();
I also included dc.css as a dependency, which helps a lot with formatting.
Here's the working example: https://jsfiddle.net/5q1dddgt/4/

Related

mouseZoomable does not work with elasticX on line chart

I have code of lineChart
as below,
var ndx = crossfilter(data),
dim = ndx.dimension(function(d) {return d.index;}),
profitGrp = dim.group().reduceSum(function(d) { return d.profit});
var profitChart = dc.lineChart("#profit-chart")
.width($("#profit-chart").parent().width())
.height(400)
.dimension(dim)
.mouseZoomable(true)
.x(d3.scale.linear()).xAxisPadding(0.25).elasticX(true)
.group(profitGrp, "Profit")
.renderHorizontalGridLines(true)
.elasticY(true)
.legend(dc.legend().x(400).y(10).itemHeight(13).gap(5))
.margins({left: 100, right: 40, top: 40, bottom: 40})
.brushOn(false);
But I can't mouse zoom in/out.
What should I do? I think it is because of elasticX(true)
Right, zoom is contradictory to elasticX(true)
One trick, if you want "elastic once" behavior, is:
chart.on('postRender', function(chart) {
chart.elasticX(false);
});
http://dc-js.github.io/dc.js/docs/html/dc.baseMixin.html#on
In my case Gordon answer didn´t work.
So there is another aproach, try to use "preRedraw" event:
chart.on('preRedraw', function(chart) {
chart.elasticX(false);
});

All tickvalues not getting displayed on X axis

I am making a stacked multi chart bar graph like this one
http://nvd3.org/examples/multiBar.html
Till now I am able to push my values on Y- axis and X axis too but the problem I am facing is that the all the values are not getting displayed on the x axis but only 10 values are getting displayed . I am using nvD3 library in my angular code . and displaying date on x axis.
$scope.options1 = {
chart: {
type: 'multiBarChart',
height: 600,
margin: {
top: 20,
right: 20,
bottom: 200,
left: 45
},
clipEdge: false,
duration: 500,
stacked: true,
groupSpacing: 0.1,
useInteractiveGuideline: true,
showMaxMin: false,
xAxis: {
axisLabel: 'Timeline',
showMaxMin: false,
tickFormat: function(d) {
return d3.time.format('%d-%m-%y')(new Date(d))
},
xScale:d3.time.scale(),
rotateLabels: '-70'
},
yAxis: {
axisLabel: 'Pending Bills',
axisLabelDistance: -20,
groupSpacing: 0.1,
tickFormat: function(d) {
return d3.format(',f')(d);
}
}
}
};
generating ticking value array using this function
$scope.options1.chart.xAxis.tickValues = function() {
var xTick = _.map(data.data.data[0].values, function(value) {
return value.x;
});
xTick = _.sortBy(xTick, function(date){ return new Date(date); });
console.log(xTick);
return xTick;
}
the output of the console.log(xTick) is something like this which is all dates -
["2015-09-01", "2015-09-02", "2015-09-03", "2015-09-04", "2015-09-05",
"2015-09-06", "2015-09-07", "2015-09-08", "2015-09-09", "2015-09-10",
"2015-09-11", "2015-09-12", "2015-09-13", "2015-09-14", "2015-09-15",
"2015-09-16", "2015-09-17", "2015-09-18", "2015-09-19", "2015-09-20",
"2015-09-21", "2015-09-22", "2015-09-23", "2015-09-24", "2015-09-25",
"2015-09-26", "2015-09-27", "2015-09-28", "2015-09-29", "2015-09-30",
"2015-10-01", "2015-10-02", "2015-10-03", "2015-10-04", "2015-10-05",
"2015-10-06", "2015-10-07", "2015-10-08", "2015-10-09", "2015-10-10",
"2015-10-11", "2015-10-12", "2015-10-13", "2015-10-14", "2015-10-15",
"2015-10-16", "2015-10-17", "2015-10-18", "2015-10-19", "2015-10-20"]
as much I read about the it. all the dates should be get plotted on x axis but they are not
If you want to display all the ticks on X-Axis, you can add this option to your chart options :
"reduceXTicks": false,
For extended option page you can visit :
Angular NVD3 - MultiBarChart
Hope it helps.
chart: {
type: 'chartType',
xAxis: {
ticks:8
}
}
You can try "ticks" property if you want to display a specific number of ticks on the axis.

dc.js - How set brush (with specific width) to barChart on load

On load i see this, all data set without filters:
Picture: what i have
I want to see this, brush(selector) picked last 21 day already on load:
Picture: what i want
Solved! click for answer
Here i saw similar question, but not works for me
dc.js - is it possible to show the user grab handles upon page load
var lineChart = dc.lineChart(".chart-line-graph");
var dateRangeChart = dc.barChart('.chart-date-range');
var hourDim = ndx.dimension(function(d) {return d.hour;});
var valueByHour = hourDim.group().reduceSum(function(d) {return d.value;});
var minDate = hourDim.bottom(1)[0].date;
var maxDate = hourDim.top(1)[0].date;
lineChart
.renderArea(true)
.width(1360)
.height(350)
.transitionDuration(200)
.margins({top: 30, right: 50, bottom: 45, left: 80})
.dimension(hourDim)
.mouseZoomable(true)
.rangeChart(dateRangeChart)
.brushOn(false)
.x(d3.time.scale().domain([minDate,maxDate]))
.elasticY(true)
.group(value)
.renderHorizontalGridLines(true);
var dayDim = ndx.dimension(function (d) {return d.day;});
var groupByDayDim = moveDays.group();
dateRangeChart
.width(1360)
.height(35)
.margins({top: 0, right: 50, bottom: 20, left: 80})
.dimension(moveDays)
.group(volumeByMonthGroup)
.centerBar(false)
.gap(1)
.x(d3.time.scale().domain([minDate,maxDate]))
.round(d3.time.week.round)
.alwaysUseRounding(true)
.xUnits(d3.time.days);
dateRangeChart
.yAxis().ticks(0);
If i add this:
lineChart
.filter(dc.filters.RangedFilter(d3.time.day.offset(xrange[1], -21), d3.time.day.offset(xrange[1], 1)))
Then barChart are filtered, but not selected
I solved my first problem!
Just added filter after all code (after renderAll()) and then call redrawAll()
Screenshot, how it looks like for now, on load charts

Error with .compose using dc.js

I am trying to create a composite of 2 line charts with dc.js.
But I get this error everytime:
Uncaught TypeError: timeChart.width(...).height(...).x(...).elasticY(...).margins(...).dimension(...).compose is not a function
it is a time series where I want to plot netCommercialPosition and netCommercialPosition as two seperate line. It works when I stack them but not when i want to use .compose.
I have followed several examples such as:
Dual Y axis line chart in dc.js
http://dc-js.github.io/dc.js/examples/series.html
So hopefully I use the .compose element correctly
my data set is a json with the following structure:
[{"CFTC_Commodity_Code": 1, "Net_Commmercial_Position": -113520, "Report_Date_as_MM_DD_YYYY": "14/07/2015", "Net_Fund_Position": -12246, "Price": 583.5, "Net_ Commmercial_Position": 3877, " },{…}]
here is my code:
d3.json("/donorschoose/COT", function (error, dataset1){
var ymdFormat = d3.time.format("%d/%m/%Y");
dataset1.forEach(function(p) {
p.Report_Date_as_MM_DD_YYYY = ymdFormat.parse(p.Report_Date_as_MM_DD_YYYY);
});
var COTProjects = dataset1;
var ndx = crossfilter(COTProjects);
var all = ndx.groupAll();
FilterDimension = ndx.dimension(function (d) {
return d.CFTC_Commodity_Code;
});
var dateDim = ndx.dimension(function(d) { return d.Report_Date_as_MM_DD_YYYY; });
var Prices = dateDim.group().reduceSum(function(d) {return d.Price; });
var netFundPosition = dateDim.group().reduceSum(function(d) {return d.Net_Fund_Position; });
var netCommercialPosition = dateDim.group().reduceSum(function(d) {return d.Net_Commmercial_Position; });
var minDate = dateDim.bottom(1)[0]["Report_Date_as_MM_DD_YYYY"];
var maxDate = dateDim.top(1)[0]["Report_Date_as_MM_DD_YYYY"];
var timeChart = dc.lineChart("#time-chart");
actualValuesChart = dc.lineChart(timeChart)
.group(netFundPosition)
normValuesChart = dc.lineChart(timeChart)
.group(netCommercialPosition)
timeChart
.width(650)
.height(260)
.x(d3.time.scale().domain([minDate, maxDate]))
.elasticY(true)
.margins({top: 0, right: 5, bottom: 20, left: 40})
.dimension(dateDim)
.compose([actualValuesChart,normValuesChart])
.transitionDuration(500)
.yAxis().ticks(4);
.brushOn(false)
FilterDimension.filter(1)
dc.renderAll();
});
Any help appreciated
thanks in advance
I found the solution, my problem was that I was trying to call compose() from a lineChart object instead of a compositeChart object.
dc.js-s doc

NVD3 x axis time scale misaligned

Im trying to set up a line chart nvd3 graphic, but im getting time value on x axis not vertically aligned, heres the code:
function fillData() {
var test1 = [],
test2 = [],
test3 = [];
var now = new Date(),
day = 1000*60*60*24;
var cont = 0;
for (var i = now - 9*day; i < now; i+=day)
{
var arr = [400,431,401,430,429,450,448,498,421,421];
var arr1 = [420,415,421,410,439,430,468,448,441,421];
var arr2 = [410,425,431,420,459,420,458,438,451,421];
test1.push({x: i, y: arr[cont]});
test2.push({x: i, y: arr1[cont]});
test3.push({x: i, y: arr2[cont]});
cont+=1;
} // fin for
return [
{
values: test1,
area: true,
key: 'test1',
color: '#81BA63'
},
{
values: test2,
area: true,
key: 'test2',
color: '#EAEAEA'
},
{
values: test3,
area: true,
key: 'test3',
color: '#6389BA'
}
];
}
nv.addGraph(function() {
var chart = nv.models.lineChart()
.margin({top: 0, bottom: 25, left: 45, right: 0})
.showLegend(true)
.forceY([300,500])
chart.yAxis
.showMaxMin(true)
.tickFormat(d3.format('.02'))
chart.xAxis
.showMaxMin(false)
.tickFormat(function(d) { return d3.time.format('%d - %b')(new Date(d)) });
chart.xScale(d3.time.scale());
d3.select('#sources-chart-line svg')
.datum(fillData())
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
problem screenshot: http://oi57.tinypic.com/i6gq2t.jpg
Thanks in Advance!!
The problem is that the number of data points (9) and axis ticks (8) is different. D3 picks "representative" ticks for the scale, which aren't necessarily aligned with the data points. Therefore, you get ticks between data points for which the date is still correct, but not at exactly midnight like the data points.
One way of fixing this is to explicitly specify the tick values:
var data = fillData();
chart.xAxis
.tickValues(data[0].values.map(function(d) { return d.x; }));
This is a bit ugly, but it shows the principle and you can refactor the code to make these values better accessible.

Resources