I am trying filter out the items in my object by the month and push those items into a new object.
So the end result should look something like this
object[
jan:
object-1
feb
object-1
object-2
etc.]
I am using a array for the months like so
var monthsOfYear = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
Then I try and loop through that array and then the object to find the matching objects. This somewhat works but it only gives me one item in each nested object.
for (var i = 0; i < monthsOfYear.length; i++) {
var month = monthsOfYear[i];
for (var j = 0; j < response.data.length-1; j++) {
if( _.startsWith(response.data[j].description, month) ){
offeringsMonth[i] = _.assign( response.data[j]);
}
}
}
So when I console log this I get
object[
jan:
object-1
feb
object-1
etc.]
var res = _.groupBy(responce.data, function(item){
return _.find(monthsOfYear, function(month){
return _.startsWith(item.description, month);
});
});
Related
How can i do this same function of this with moment js or other library like luxon, i want to get all the previos 'n' months since the current day
for example currently is agost, i need Feb, Mar, Apr, May, Jun, Jul, the names should be in short
console.log(getPreviousNMonths(6))
function uInt(n, ceil) {
while (n < 0) {
n += ceil
}
return n % ceil
}
function getPreviousNMonths(n) {
const date = new Date()
const d = new Date(date.getTime())
const formatter = new Intl.DateTimeFormat([], { month: 'short' })
const names = []
for (let i = 0; i < n; i += 1) {
d.setMonth(uInt(d.getMonth() - 1, 12))
names.push(formatter.format(d))
}
return names.reverse()
}
Using moment.js
const names = []
for (let i = 1; i <= n; i += 1) {
let monthName = moment('2021-08-10').subtract(i, "month").startOf("month").format('MM');
names.push(monthName)
}
Or using luxon
const names = []
for (let i = 1; i <= n; i += 1) {
let monthName = DateTime.local().minus({ months: i }).toFormat("MM")
names.push(monthName)
}
I have a simple question but I don't know how to solve it.
This is my code:
for (var i = 0; i < response.data.values.length; i++) {
this.affinityZone.push({
'text': response.data.values[i].name,
**'value': response.data.values[i].id**
})
}
The 'value' is a string now. So how can my frontend read it as integer.
I tried: 'value': parseInt == response.data.values[i].id and 'value': parseInt.response.data.values[i].id.
Perhaps you're trying to do something like this
for (var i = 0; i < response.data.values.length; i++) {
this.affinityZone.push({
text: response.data.values[i].name,
value: parseInt(response.data.values[i].id, 10)
})
}
This is the answer:
'value': Number.parseInt(response.data.values[i].id)
I should insert Number to parseInt.
Thank you all.
has data
items = {
0: {id:1,name:'foo'},
1: {id:2,name:'bar'},
2: {id:1,name:'foo'}
};
I wont get counted elements like this
result = {
0: {id:1,name:'foo', count:2},
1: {id:2,name:'bar', count:1}
};
lodash has function _.countBy(items, 'name') it's got {'foo': 2, 'bar':1}, i need id too.
If pure JS approach is acceptable, you can try something like this:
Logiic:
Loop over array and copy the object and add a property count and set it to 0.
Now on every iteration update this count variable.
Using above 2 steps, create a hashMap.
Now loop over hashMap again and convert it back to array.
var items = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}, {
id: 1,
name: 'foo'
}
];
var temp = items.reduce(function(p,c){
var defaultValue = {
name: c.name,
id: c.id,
count: 0
};
p[c.name] = p[c.name] || defaultValue
p[c.name].count++;
return p;
}, {});
var result = [];
for( var k in temp ){
result.push(temp[k]);
}
console.log(result)
I want to display "population" of various countries through the years in the same line chart. The data displayed is based on selections from a multi-select dropdown "Countries". Underlying Data Table has 3 columns:
Year, Country, Population
2012,countryA,33
2013,countryA,35
2014,countryA,40
2012,countryB,65
2013,countryB,70
2014,countryB,75
2012,countryC,15
2013,countryC,20
2014,countryC,25
I am trying to create a pivoted Data View from the underlying Data Table
The code I am using is:
function drawLineChart() {
var arr = $('#country').val();
var lineChartJson = $.ajax({
url: "../json/lineChart.json",
dataType: "json",
async: false
}).responseText;
var lineChartData = new google.visualization.DataTable(lineChartJson);
var view = new google.visualization.DataView(lineChartData);
var viewCols = [0];
for(var i = 0; i < arr.length; i++) {
var viewCols1 = [{
type: 'number',
label: arr[i],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
}
}];
viewCols = viewCols.concat(viewCols1);
}
view.setColumns(viewCols);
var aggCols = [{
column: 1,
type: 'number',
label: view.getColumnLabel(1),
aggregation: google.visualization.data.sum
}];
for(var i = 2; i < 4; i++) {
var aggCols1 = [{
column: i,
type: 'number',
label: view.getColumnLabel(i),
aggregation: google.visualization.data.sum
}];
aggCols = aggCols.concat(aggCols1);
}
var pivotedData = google.visualization.data.group(view, [0], aggCols);
But this does not seem to work as expected and I just get 1 Line in the chart with values for all countries added up (although I can see the legend for 3 countries)
On the other hand if I set my View columns as below, it works as expected.
view.setColumns([0, {
type: 'number',
label: arr[0],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[0]) ? dt.getValue(row, 2) : null;
}
}, {
type: 'number',
label: arr[1],
calc: function (dt, row) {
// return values of C only for the rows where B = "bar"
return (dt.getValue(row, 1) == arr[1]) ? dt.getValue(row, 2) : null;
}
}, {
type: 'number',
label: arr[2],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[2]) ? dt.getValue(row, 2) : null;
}
}]);
What is going wrong in the loop? Is something wrong with "concat" in the loop where I am creating View Columns? I also saw the viewCols array by using console.log and it seems to have the right elements
I was trying to follow the below post:
Creating pivoted DataView from existing google charts DataTable object
the problem has to do with scope
arr[i] is undefined within calc: function (dt, row)
here is another way to pivot the data...
google.charts.load('current', {
callback: function () {
var arr = [
'countryA',
'countryB',
'countryC'
];
var lineChartData = google.visualization.arrayToDataTable([
['Year', 'Country', 'Population'],
[2012,'countryA',33],
[2013,'countryA',35],
[2014,'countryA',40],
[2012,'countryB',65],
[2013,'countryB',70],
[2014,'countryB',75],
[2012,'countryC',15],
[2013,'countryC',20],
[2014,'countryC',25]
]);
// sort by year
lineChartData.sort([{column: 0}]);
// get unique countries
var countryGroup = google.visualization.data.group(
lineChartData,
[1]
);
// build country data table
var countryData = new google.visualization.DataTable({
cols: [
{label: 'Year', type: 'number'},
]
});
// add column for each country
for (var i = 0; i < countryGroup.getNumberOfRows(); i++) {
countryData.addColumn(
{label: countryGroup.getValue(i, 0), type: 'number'}
);
}
// add row for each year / country
var rowYear;
var rowIndex;
for (var i = 0; i < lineChartData.getNumberOfRows(); i++) {
if (rowYear !== lineChartData.getValue(i, 0)) {
rowYear = lineChartData.getValue(i, 0);
rowIndex = countryData.addRow();
countryData.setValue(rowIndex, 0, rowYear);
}
for (var x = 1; x < countryData.getNumberOfColumns(); x++) {
if (countryData.getColumnLabel(x) === lineChartData.getValue(i, 1)) {
countryData.setValue(rowIndex, x, lineChartData.getValue(i, 2));
}
}
}
// draw agg table
new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table-div',
dataTable: countryData
}).draw();
// draw line chart
new google.visualization.ChartWrapper({
chartType: 'LineChart',
containerId: 'chart-div',
dataTable: countryData
}).draw();
},
packages: ['corechart', 'table']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="table-div"></div>
<div id="chart-div"></div>
I could figure out the problem with my code above.
"calc" is the callback function in loop. So only last value of loop variable "i" is visible within the loop.
Putting a wrapper function fixes it:
for(var i = 0; i <= arr.length; i++)(function(i) {
var viewCols1 = [{
type: 'number',
label: arr[i],
calc: function (dt, row) {
return (dt.getValue(row, 1) == arr[i]) ? dt.getValue(row, 2) : null;
}
}];
viewCols = viewCols.concat(viewCols1);
})(i);
I am trying to create a running sum in crossfilter to use with dc.js.
I have a set of records like the following :
records = [{"date":"2014-01-01","field1":"value1","field2":"value11","value_field":-20},
{"date":"2014-01-02","field1":"value2","field2":"value12","value_field":100},
{"date":"2014-01-03","field1":"value1","field2":"value11","value_field":-10},
{"date":"2014-01-04","field1":"value2","field2":"value12","value_field":150},
]
So far I have created a barGraph which plays nicely with the other dimensions but I would like to be able to show an line graph of the theoretical field runnning_total (along the dimension date).
To have it done in crossfilter would allow me to then group using the fieldx fields and easily get the same running total graph but restricted to a subgroup of values using dc.js.
Any help is welcome.
Since you are grouping across date (as per your date dimension), the reduce() function would be used to perform aggregations grouped by date, as per the highlighted cells in my Mickey Mouse example below:
With a running total you'd need to perform an entirely different operation, looping down the rows:
You can aggregate the data and then append the running total field as follows. I've also included an example of how to calculate an average value, using the reduce function:
records = [{ "date": "2014-01-01", "field1": "value1", "field2": "value11", "value_field": -20 },
{ "date": "2014-01-02", "field1": "value2", "field2": "value12", "value_field": 100 },
{ "date": "2014-01-03", "field1": "value1", "field2": "value11", "value_field": -10 },
{ "date": "2014-01-04", "field1": "value2", "field2": "value12", "value_field": 150 }
];
var cf = crossfilter(records);
var dimensionDate = cf.dimension(function (d) {
return d.date;
});
function reduceAdd(p, v) {
p.total += v.value_field;
p.count++;
p.average = p.total / p.count;
return p;
}
function reduceRemove(p, v) {
p.total -= v.value_field;
p.count--;
p.average = p.count ? p.total / p.count : 0;
return p;
}
function reduceInitial() {
return {
total: 0,
count: 0,
average: 0,
};
}
var average = dimensionDate.group().reduce(reduceAdd, reduceRemove, reduceInitial).all();
var averageWithRunningTotal = appendRuningTotal(average);
function appendRuningTotal(average) {
var len = average.length,
runningTotal = 0;
for (var i = 0; i < len; i++) {
runningTotal += average[i].value.total;
average[i].RunningTotal = runningTotal;
}
return average;
}
And this returns the following:
{"key":"2014-01-01","value":{"total":-20,"count":1,"average":-20},"RunningTotal":-20}
{"key":"2014-01-02","value":{"total":100,"count":1,"average":100},"RunningTotal":80}
{"key":"2014-01-03","value":{"total":-10,"count":1,"average":-10},"RunningTotal":70}
{"key":"2014-01-04","value":{"total":150,"count":1,"average":150},"RunningTotal":220}
Well I know the op already built a solution but after struggling with for a while I was able to crack it, so posting it here if someone else searches for it.
using the cumulative for the following: https://groups.google.com/forum/#!topic/dc-js-user-group/W9AvkP_dZ0U
Running Sum:
var _group = dim.group().reduceSum(function(d) {return 1;});
var group = {
all:function () {
var cumulate = 0;
var g = [];
_group.all().forEach(function(d,i) {
cumulate += d.value;
g.push({key:d.key,value:cumulate})
});
return g;
}
};
for Trailing Twelve Month calculation:
var _group = dateDim.group().reduceSum(function(d) {return d.revenue;});
var group = {
all:function () {
var g = [];
_group.all().forEach(function(d,i) {
var cumulate = 0;
var monthcount =0;
var dt =new Date( d.key);
var ct = new Date(d.key);
ct.setFullYear(ct.getUTCFullYear() -1);
_group.all().forEach(function(d2,i) {
var dt2 = new Date(d2.key);
if(dt2 <= dt && dt2 > ct){
cumulate += d2.value;
monthcount++;
}
})
if(monthcount>=11){
console.log( ' Dt ' + dt + ' ' + cumulate + ' months ' + monthcount);
g.push({key:d.key,value:cumulate})
}
});
return g;
}
};