How can I extract increasing consecutive values? - iterator

I have a sample array of objects...
const entries = [
{
userID: 1,
date: '2019/06/15',
numSteps: 3577,
minutesActive: 140,
flightsOfStairs: 16
},
{
userID: 1,
date: '2019/06/16',
numSteps: 6637,
minutesActive: 175,
flightsOfStairs: 36
},
{
userID: 1,
date: '2019/06/17',
numSteps: 14329,
minutesActive: 168,
flightsOfStairs: 18
},
{
userID: 1,
date: '2019/06/18',
numSteps: 4419,
minutesActive: 165,
flightsOfStairs: 33
},
{
userID: 1,
date: '2019/06/19',
numSteps: 8429,
minutesActive: 275,
flightsOfStairs: 2
},
{
userID: 1,
date: '2019/06/20',
numSteps: 14478,
minutesActive: 140,
flightsOfStairs: 12
},
{
userID: 1,
date: '2019/06/21',
numSteps: 6760,
minutesActive: 135,
flightsOfStairs: 6
},
{
userID: 1,
date: '2019/06/22',
numSteps: 10289,
minutesActive: 119,
flightsOfStairs: 6
},
{
userID: 1,
date: '2019/06/23',
numSteps: 8213,
minutesActive: 122,
flightsOfStairs: 27
},
{
userID: 1,
date: '2019/06/24',
numSteps: 11654,
minutesActive: 270,
flightsOfStairs: 19
}
]
I am trying to find instances of increasing numSteps through a for loop, so if there are consecutive days of increasing steps, those days get pushed into a new array. This is my loop...
let dates = []
for (var i = 0; i < this.entries.length - 1; i++) {
if (this.entries[i].numSteps < this.entries[i + 1].numSteps) {
dates.push(this.entries[i])
}
}
I am very close to getting this to work, but can't figure out how to push the final value before the condition is met. I should be getting the first three index pushed into the new array, but am only getting two. I see why this is happening, because by the time I hit the third index, the condition in my loop is no longer true. I am just not sure how I can push the indexes that meet the condition and the one directly after that. Any suggestions? Thanks!

You need to make the for loop cover the full range, then enhance the if statement to compare with both next and previous.
let len = this.entries.length;
for (var i = 0; i < len ; i++) {
if ((i < len - 1 && this.entries[i].numSteps < this.entries[i + 1].numSteps)
|| (i > 0 && this.entries[i - 1].numSteps < this.entries[i].numSteps)) {
dates.push(this.entries[i])
}
}

Related

Apex Line Area chart is not getting displayed on the page in Vuejs

I am stuck on a page where i am not able to display the charts on the page.
To make it simplify what I have done is, here is the code sandbox:
I see there an error in console about the data, I am not sure about it.
https://codesandbox.io/s/compassionate-snyder-bckoq
I want to display the chart like this (as an example), but I am not able to display on the code sandbox
Please help.
The format of series is not aligned with ApexCharts.
You need to transform the data to match with ApexChart format.
Please see the changes in the codesandbox.
https://codesandbox.io/s/small-dew-eztod?file=/src/components/HelloWorld.vue
options: {
// X axis labels
xaxis: {
type: 'date',
categories: ["2021-05-04", "2021-05-05", "2021-05-07"]
},
},
series: [
{
name: "total",
data: [2, 2, 1],
},
{
name: "pending",
data: [0, 1, 0],
},
{
name: "approved",
data: [2, 1, 1],
},
{
name: "rejected",
data: [0, 0, 0],
},
],
Transform data to fit ApexChart
const data = {
"2021-05-04": {
total: 2,
pending: 0,
approved: 2,
rejected: 0,
},
"2021-05-05": {
total: 2,
pending: 1,
approved: 1,
rejected: 0,
},
"2021-05-07": {
total: 1,
pending: 0,
approved: 1,
rejected: 0,
},
};
const xaxis = {
type: "date",
categories: Object.keys(data).map((key) => key), // ['2021-05-04', '2021-05-05', '2021-05-07']
};
let statusObj = [];
for (const dataValue of Object.values(data)) { // get the values from keys '2021-05-04', '2021-05-05' ...
// loop the values, e.g. 1st loop: { total: 2, pending: 0, approved: 2, rejected: 0, }
for (const [key, value] of Object.entries(dataValue)) {
// take 'total' as example, find if statusObj already has { name: 'total', data: [x] }, e.g. statusObj = { name: 'total', data: [1] }
const existingStatusIndex = Object.keys(statusObj).find(
(sKey) => statusObj[sKey].name === key
);
// if yes, return the index of it
if (existingStatusIndex) {
// add new data value to existing data object. e.g. { name: 'total', data: [1, 2] }
statusObj[existingStatusIndex].data.push(value);
continue;
}
// if no, create a new object and add it to statusObj
statusObj.push({
name: key,
data: [value],
});
}
}
Output:
xaxis {
type: 'date',
categories: [ '2021-05-04', '2021-05-05', '2021-05-07' ]
}
statusObj [
{ name: 'total', data: [ 2, 2, 1 ] },
{ name: 'pending', data: [ 0, 1, 0 ] },
{ name: 'approved', data: [ 2, 1, 1 ] },
{ name: 'rejected', data: [ 0, 0, 0 ] }
]

Ramda - get array of objects using ids from other array

I have two sets of data and I would like to use the first one to get an array of objects from the second one. I tried to deal with it by myself but I am missing few steps.
Here is set of ids to use:
const idSet = {
"41": {
"id": "41"
},
"42": {
"id": "42"
},
"43": {
"id": "43"
}
}
And here is second set:
const nodes = {
"3": {
"nodeCommentId": 3,
"nodeId": 43,
},
"4": {
"nodeCommentId": 4,
"nodeId": 41
},
"6": {
"nodeCommentId": 6,
"nodeId": 42
},
"7": {
"nodeCommentId": 7,
"nodeId": 44
},
}
I need to search by id and nodeId so I tried to use something like this to get only ids from first set:
const ids = R.compose(
R.values(),
R.pluck('id')
)(idSet)
I also came up with something like: R.filter(R.compose(R.flip(R.contains)(ids), R.prop('nodeId')), nodes);
But then I have nodeId which is a number and not a string plus I need an array of objects without keys.
Desired output:
[
{
nodeCommentId: 3,
nodeId: 43
},
{
nodeCommentId: 4,
nodeId: 41
},
{
nodeCommentId: 6,
nodeId: 42
}
]
Any help will be appreciated.
This is probably too ugly to use, but it might be a start at a nice solution:
const nodesById = (idSet) => {
const ids = map (Number, pluck ('id') (values (idSet)))
return pipe (values, filter (pipe (prop('nodeId'), contains(__, ids))))
}
const idSet = {41: {id: "41"}, 42: {id: "42"}, 43: {id: "43"}}
const nodes = {3: {nodeCommentId: 3, nodeId: 43, }, 4: {nodeCommentId: 4, nodeId: 41}, 6: {nodeCommentId: 6, nodeId: 42}, 7: {nodeCommentId: 7, nodeId: 44}}
console .log (
nodesById (idSet) (nodes)
)
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {map, pluck, values, pipe, filter, prop, contains, __} = R </script>
I'm sure that with a little work, we could make this entirely point-free, but I doubt that will help readability.
Transform the idSet to an array of numbers, and then user R.innerJoin to get the items with the matching nodeId:
const { pipe, values, pluck, map, innerJoin, __, curry } = R
const getIds = pipe(values, pluck('id'), map(Number))
const getNodesById = curry((idSet, nodes) =>
pipe(
values,
innerJoin(
({ nodeId }, id) => nodeId === id,
__,
getIds(idSet)
)
)(nodes)
)
const idSet = {41: {id: "41"}, 42: {id: "42"}, 43: {id: "43"}}
const nodes = {3: {nodeCommentId: 3, nodeId: 43, }, 4: {nodeCommentId: 4, nodeId: 41}, 6: {nodeCommentId: 6, nodeId: 42}, 7: {nodeCommentId: 7, nodeId: 44}}
const result = getNodesById(idSet)(nodes)
console.log(result)
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>

How to merge two element in a array Vue.js

I just get stuck here....
I have get a list from my database with can have same Id_Plane but different DateCreated, Starts, Ends...
How do I compute 2 element with same ID to 1 element with 2 DateCreated, Starts, Ends
Thanks
Here is my data for example
The below code will give you an array with unique 'Id_plane' by keeping the first object data.
let data = [
{
DateCreated: "2020-10-10",
Ends: 15.5,
Id_plane: 1,
Id_sale: 4,
Id_scheduler: 6,
Starts: 7,
__isset_bitfield: 31
},
{
DateCreated: "2020-10-11",
Ends: 17,
Id_plane: 1,
Id_sale: 4,
Id_scheduler: 6,
Starts: 7,
__isset_bitfield: 31
},
{
DateCreated: "2020-10-12",
Ends: 17,
Id_plane: 2,
Id_sale: 4,
Id_scheduler: 6,
Starts: 4.2,
__isset_bitfield: 40
},
{
DateCreated: "2020-10-11",
Ends: 17,
Id_plane: 2,
Id_sale: 4,
Id_scheduler: 6,
Starts: 7,
__isset_bitfield: 31
},
];
data.map((item, index) => {
let matchingItems = data.filter(el => el.Id_plane === item.Id_plane);
matchingItems.map(matchingItem => {
let key = data.indexOf(matchingItem)
if (key !== index) {
data.splice(key, 1);
}
});
});
console.log(data);
From what I understood you want to return a new list based on the id_plane.
let list = [
{
id_plane: 1,
date_created: "2020-10-10"
},
{
id_plane: 1,
date_created: "2020-10-11"
},
{
id_plane: 4,
date_created: "2020-10-12"
},
{
id_plane: 10,
date_created: "2020-10-13"
},
{
id_plane: 1,
date_created: "2020-10-14"
},
{
id_plane: 4,
date_created: "2020-10-15"
}
];
var ids = list.map(e => e.id_plane).filter((x, i, a) => a.indexOf(x) == i);
var arr = {};
ids.forEach(i => {
arr[i] = list.filter(e => {
return e.id_plane === i;
});
});
console.log(arr);

On-click event display data on heap map in highcharts

This image contains details about the number of projects was uploaded by the particular user
I am using heapmap highchart to display project details of a user.
on Y-axis => represents week of the days which ranges from 0 to 6
eg. Mon = 0, Tue= 1,....Sun=6
on X-axis => represents months, which ranges from 0 to 11
eg. Jan = 0, Feb = 1, ... Dec = 11
Data format
X Y Data
[0 ,1 , 3]
Suppose, 3 projects was uploaded by a user on monday in the month of January.
When I click on that 3 on heap map then it should display a pop box,
which should include project name,date and time
eg. Project Name : image recognition
Date : Uploaded on Jan 4,2019
Time : 10:04:00
In this I have hardcoded the data.
https://jsfiddle.net/k9hyfjmL/
This code retrieve data from mysql database and populates on heap map, which indicates number of projects was uploaded by a user.
$(document).on('click', '.click_once', function()
{
$.ajax(
{
url: '/profile/heap_map_data',
type: 'GET',
success: function(response)
{
var chart_data = [];
var skip_1st_data = 1;
var take_Data_upto = 0;
for (var i = 0, len = response.length; i < len; i++)
{ if(skip_1st_data == 1)
{
skip_1st_data = 2;
}
else{
take_Data_upto = take_Data_upto + 1;
chart_data.push(response[i]);
if(take_Data_upto == 31)
{
break;
}
}
}
console.log(chart_data)
Highcharts.chart('heap_map_chart',
{
chart:
{
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1,
},
title:
{
text: 'Project Details'
},
xAxis:
{
categories: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
},
yAxis:
{
categories: ['Mon','Tue','Wed','Thur','Fri','Sat','Sun'],
title: null
},
colorAxis:
{
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0]
},
legend:
{
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip:
{
formatter: function ()
{
return + this.point.value + ' <b> project was uploaded on ' + this.series.xAxis.categories[this.point.x] + ' date, 2019' + '<br /> click to view more' ;
}
},
series: [
{
borderWidth: 1,
data: chart_data,
dataLabels:
{
enabled: true,
color: '#000000'
}
}]
});
},
error : function(jqXHR, textStatus, errorThrown)
{
console.log('jqXHR:');
console.log(jqXHR);
console.log('textStatus:');
console.log(textStatus);
console.log('errorThrown:');
console.log(errorThrown);
alert(errorThrown);
}
});
});
You can use point.events.click function to display some more information in another HTML element:
series: [{
point: {
events: {
click: function() {
document.getElementById('moreInfo').innerText =
'value: ' + this.value;
}
}
},
...
}]
Live demo: https://jsfiddle.net/BlackLabel/p261zg9d/
API Reference: https://api.highcharts.com/highcharts/series.heatmap.point.events.click

Chartist Pie Char Custom Label

I am trying to customize the label of Chartist Pie Chart so that it will show both the label and value.
So in the example below, I would want the label to show "Bananas - 20", "Apples - 15", "Grapes - 40". I know I can just change the labels:, but is there a way to do that with the labelInterpolationFnc?
https://jsfiddle.net/ckmz7L1p/
var data = {
labels: ['Bananas', 'Apples', 'Grapes'],
series: [20, 15, 40]
};
var options = {
labelInterpolationFnc: function(value) {
return value[0]
}
};
var responsiveOptions = [
['screen and (min-width: 640px)', {
chartPadding: 30,
labelOffset: 100,
labelDirection: 'explode',
labelInterpolationFnc: function(value) {
return value;
}
}],
['screen and (min-width: 1024px)', {
labelOffset: 80,
chartPadding: 20
}]
];
new Chartist.Pie('.ct-chart', data, options, responsiveOptions);
Got it figured out. Didn't realize labelInterpolationFnc can take function with both value and index parameters.
var data = {
labels: ['Bananas', 'Apples', 'Grapes'],
series: [20, 15, 40]
};
var options = {
width: "400px",
height: "400px",
labelInterpolationFnc: function(value, idx) {
return value + " - " + data.series[idx];
}
};
var responsiveOptions = [
['screen and (min-width: 640px)', {
chartPadding: 0,
labelOffset: 0,
labelDirection: 'explode',
labelInterpolationFnc: function(value, idx) {
return value + " - " + data.series[idx];
}
}],
['screen and (min-width: 1024px)', {
labelOffset: 30,
chartPadding: 0
}]
];
new Chartist.Pie('.ct-chart', data, options, responsiveOptions);