Javascript get value in json based on another value - javascript

I have a json similar to this one
{
"id": "1",
"month": "January",
"type": "inc",
"Value": "780.00",
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": "80.00",
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": "100.00",
"year": "2018",
},...
Now I need to get all the Value from the object for all the months, as you can see I may have more objects with the same month name. The closer I got to was creating 2 arrays 1 with the list of Months and 1 with the value but I got stuck, can someone lead me to the correct path?
The desired output would be to get an array like that ["January"=>1500, "February"=>2000...] or have 2 arrays, 1 with the list of months where there is income (I already have it) and the second the total income for these months, so it's like this: ["January", "February", "March"..] and the second one [1500, 2000, 300...]

You can use the function Array.prototype.reduce to sum each Value by month.
let arr = [{ "id": "1", "month": "January", "type": "inc", "Value": "780.00", "year": "2018", }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018", }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018", }],
result = arr.reduce((a, {month, Value}) => {
a[month] = (a[month] || 0) + +Value;
return a;
}, Object.create(null));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

I actually can barely understand what you would like to achieve. Please provide some example.
If I understood you correctly, you can use map function of js array to map each object to its Value.
let arr = [...];
console.log(arr.map(item => item.Value));

You can do
var fabuaryDate = yourdata
.filter(function(data) { return data.month == "February" })
.map(function(x){return {value: x.Value} })

To get result in following format :
{
jan : [1,2,3],
feb : [3,4,5,6],
april : [3,4,5]
}
do this :
var output = {}
arr.forEach(element => {
if(!output[element.month]){
output[month] = new Array();
}
output[month].push(element.value);
});

You can iterate the object and fill an array with the values of the field you want to extract, like so:
const data = [ {
"id": "1",
"month": "January",
"type": "inc",
"Value": 780.00,
"year": "2018",
},
{
"id": "2",
"month": "January",
"type": "inc",
"Value": 80.00,
"year": "2018",
},
{
"id": "3",
"month": "February",
"type": "inc",
"Value": 100.00,
"year": "2018",
}];
let dataArray = data.reduce((accum, d) => {
if(!accum[d.month]) accum[d.month] = 0;
accum[d.month] += d.Value;
return accum;
},{});
console.log(dataArray);

Although you don't seem to be clear enough with what have you tried here is an example of what you could do in order to read all the values inside the json.
function myFunction(item) {
console.log(item.month + " with the value " + item.Value)
}
var jsonArray = [{"id": "1","month": "January", "type": "inc", "Value": "780.00", "year": "2018" }, { "id": "2", "month": "January", "type": "inc", "Value": "80.00", "year": "2018" }, { "id": "3", "month": "February", "type": "inc", "Value": "100.00", "year": "2018" }];
jsonArray.forEach(myFunction);
Since you're working with an array of objects you must access to each of the objects in the array and then get the attribute that you require.
Hope this help, have a great day.

Related

Merge array of an object based on a common field

I have an object that looks like as follows:
[
{
"Net_Amount": 499,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA01",
"Month": "Jan"
},
{
"Net_Amount": 902,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA02",
"Month": "Jan"
},
{
"Net_Amount": 1860,
"Date": "2022-10-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA",
"Month": "Oct"
},
{
"Net_Amount": 1889,
"Date": "2022-11-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA",
"Month": "Nov"
}
]
Now, if you will look carefully, I have a common field Month in the objects and I want merge the objects based on this common field only. How I want my object to be formatted is as :
[
{
"Month": "Jan",
"varData": [{
"Net_Amount": 499,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA01"
},
{
"Net_Amount": 902,
"Date": "2022-01-09T18:30:00.000Z",
"Scheme_Name": "CUSTOMERWINBACKJCA02"
}]
},
{
"Month": "Oct",
"varData": [{
"Net_Amount": 1860,
"Date": "2022-10-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA"
}]
},
{
"Month": "Nov",
"varData": [{
"Net_Amount": 1889,
"Date": "2022-11-01T18:30:00.000Z",
"Scheme_Name": "CUSTOMERCONNECTJCA"
}]
}
]
I can do it by iterating over the array and checking if month is same, then pushing the other key and its value of object in the varData but I want to know if there is any shortcut or inbuilt function which I can use to achieve my purpose.
I don't think that there is some better built-in solution then iterating the array.
But if you use month names as keys then the code could be quite straightforward (the output is not exactly the same but quite similarly structured).
const result = {}
for (const entry of list) {
if (!result[entry.Month]) {
result[entry.Month] = []
}
result[entry.Month].push(entry)
}
See jsfiddle.
If you need the output that is exactly specified in the question then you can use the following code:
let result = {}
for (const entry of list) {
const month = entry.Month
if (!result[month]) {
result[month] = {
"Month": month,
"varData": []
}
}
delete entry.Month
result[month].varData.push(entry)
}
result = Object.values(result)
See jsfiddle
const data = [{"Net_Amount":499,"Date":"2022-01-09T18:30:00.000Z","Scheme_Name":"CUSTOMERWINBACKJCA01","Month":"Jan"},{"Net_Amount":902,"Date":"2022-01-09T18:30:00.000Z","Scheme_Name":"CUSTOMERWINBACKJCA02","Month":"Jan"},{"Net_Amount":1860,"Date":"2022-10-01T18:30:00.000Z","Scheme_Name":"CUSTOMERCONNECTJCA","Month":"Oct"},{"Net_Amount":1889,"Date":"2022-11-01T18:30:00.000Z","Scheme_Name":"CUSTOMERCONNECTJCA","Month":"Nov"}]
console.log([...new Set(data.map(i=>i.Month))].map(Month=>
({Month, varData: data.filter(({Month:m})=>m===Month).map(({Month,...o})=>o)})))
const dataArr = [
{
Net_Amount: 499,
Date: "2022-01-09T18:30:00.000Z",
Scheme_Name: "CUSTOMERWINBACKJCA01",
Month: "Jan",
},
{
Net_Amount: 902,
Date: "2022-01-09T18:30:00.000Z",
Scheme_Name: "CUSTOMERWINBACKJCA02",
Month: "Jan",
},
{
Net_Amount: 1860,
Date: "2022-10-01T18:30:00.000Z",
Scheme_Name: "CUSTOMERCONNECTJCA",
Month: "Oct",
},
{
Net_Amount: 1889,
Date: "2022-11-01T18:30:00.000Z",
Scheme_Name: "CUSTOMERCONNECTJCA",
Month: "Nov",
},
];
const outputObj = dataArr.reduce((acc, crt) => {
acc[crt.Month] ??= [];
acc[crt.Month].push(crt);
return acc;
}, {});
const outputArr = Object.values(outputObj).map((item) => ({ Month: item[0].Month, varData: item }));
console.log(outputArr);

Group array of objects by common properties [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I want to get the count for only existing week.I want to get the calculation for month wise with week specific.
Now I can get the weekly count of each month.Now I want to display the week only for existing week.Now showing 0.for eg;may have value for week1 and week 2 I want to display only week1 and week 2 count in response for the month may.for july need to display week1 and week3
const response=[
{
"UserName": "User1",
"week": "Week 1",
"Type": "type3",
"months": "May",
"count": 2
},
{
"UserName": "User1",
"week": "Week 2",
"Type": "type1",
"months": "Jun",
"count": 1
},
{
"UserName": "User1",
"week": "Week 1",
"Type": "type2",
"months": "Jun",
"count": 1
},
{
"UserName": "User1",
"week": "Week 2",
"Type": "type1",
"months": "May",
"count": 1
},
{
"UserName": "User1",
"week": "Week 3",
"Type": "type2",
"months": "July",
"count": 1
},
{
"UserName": "User2",
"week": "Week 1",
"Type": "type3",
"months": "May",
"count": 2
},
{
"UserName": "User2",
"week": "Week 2",
"Type": "type1",
"months": "Jun",
"count": 1
},
{
"UserName": "User2",
"week": "Week 1",
"Type": "type2",
"months": "Jun",
"count": 1
},
{
"UserName": "User2",
"week": "Week 2",
"Type": "type1",
"months": "May",
"count": 1
},
{
"UserName": "User2",
"week": "Week 1",
"Type": "type2",
"months": "July",
"count": 1
}
];
const WEEKS = ["Week 1", "Week 2", "Week 3", "Week 4"];
const result = response.reduce((acc, obj) => {
existingObj = acc.find(ele => ele.UserName == obj.UserName && ele.month == obj.months && ele.Type == obj.Type)
if (existingObj) {
existingObj.Week1 += WEEKS.indexOf(obj.week) == 0 ? obj.count : 0;
existingObj.Week2 += WEEKS.indexOf(obj.week) == 1 ? obj.count : 0;
existingObj.Week3 += WEEKS.indexOf(obj.week) == 2 ? obj.count : 0;
existingObj.Week4 += WEEKS.indexOf(obj.week) == 3 ? obj.count : 0;
} else {
acc.push({
UserName: obj.UserName,
month: obj.months,
Type: obj.Type,
Week1: WEEKS.indexOf(obj.week) == 0 ? obj.count : 0,
Week2: WEEKS.indexOf(obj.week) == 1 ? obj.count : 0,
Week3: WEEKS.indexOf(obj.week) == 2 ? obj.count : 0,
Week4: WEEKS.indexOf(obj.week) == 3 ? obj.count : 0,
});
}
return acc;
}, []);
console.log(result);
expected as
[{"UserName":"user1","month":"May","Type":"Type3","Week1":2,"Week3":3},
{"UserName":"user2","month":"May","Type":"Type3","Week1":2},
{"UserName":"user1","month":"May","Type":"Type1","Week2":1},
{"UserName":"user2","month":"May","Type":"Type1","Week2":1,},
{"UserName":"user1","month":"Jun","Type":"Type1","Week2":1},
{"UserName":"user2","month":"Jun","Type":"Type1","Week2":1},
{"UserName":"user1","month":"Jun","Type":"Type2","Week1":1},
{"UserName":"user2","month":"Jun","Type":"Type2","Week1":1},
{"UserName":"user1","month":"Jul","Type":"Type2","Week3":1},
{"UserName":"user1","month":"Jul","Type":"Type2","Week1":1},
]
If the point was to regroup records in source array by UserName and month properties, you may build up the Map (using Array.prototype.reduce()) with composite key (comprised by UserName and month) and the value of corresponding groupped object, then extract those objects into array with Map.prototype.values():
const src = [{"UserName":"User1","week":"Week 1","Type":"type3","months":"May","count":2},{"UserName":"User1","week":"Week 2","Type":"type1","months":"Jun","count":1},{"UserName":"User1","week":"Week 1","Type":"type2","months":"Jun","count":1},{"UserName":"User1","week":"Week 2","Type":"type1","months":"May","count":1},{"UserName":"User1","week":"Week 3","Type":"type2","months":"July","count":1},{"UserName":"User2","week":"Week 1","Type":"type3","months":"May","count":2},{"UserName":"User2","week":"Week 2","Type":"type1","months":"Jun","count":1},{"UserName":"User2","week":"Week 1","Type":"type2","months":"Jun","count":1},{"UserName":"User2","week":"Week 2","Type":"type1","months":"May","count":1},{"UserName":"User2","week":"Week 1","Type":"type2","months":"July","count":1}],
result = [...src
.reduce((r, {UserName, week: w, Type, months, count}) => {
const key = UserName+"\ud8ff"+months,
week = w.replace(' ', ''),
grouppedRecord = r.get(key)
grouppedRecord ?
Object.assign(grouppedRecord, {[week]: count}) :
r.set(key, {UserName, Type, month: months, [week]: count})
return r
}, new Map)
.values()
]
console.log(result)
.as-console-wrapper{min-height:100%;}
You can first filter down for what ever you want and then loop through the whole thing with the filtered as lookup key.
Like filtering all weeks in May. Then use that for further work.
var existingWeeks = response.filter(function(obj) {
return (obj.months === "May") && (obj.User === "User1");
});

How to return and get the sum of object properties based on given filters?

I have the following object.
var data = [
{"Name":"ABC","Dept":"First","FY":"2016","Quarter":"1","Month":"April","Total":"100"},
{"Name":"ABC","Dept":"Second","FY":"2017","Quarter":"2","Month":"May","Total":"200"},
{"Name":"ABC","Dept":"First","FY":"2016","Quarter":"1","Month":"June","Total":"150"},
{"Name":"DEF","Dept":"First","FY":"2016","Quarter":"1","Month":"April","Total":"200"},
{"Name":"DEF","Dept":"Second","FY":"2017","Quarter":"2","Month":"May","Total":"100"},
{"Name":"DEF","Dept":"First","FY":"2016","Quarter":"1","Month":"June","Total":"500"}
]
I want to filter on the abve object to get:
a. I want to return Total based on my filters(ex: If I give Name as ABC, Dept as First, FY as 2016, Quarter as 1, Month as April, then it should filter/return the Total i.e 100 for the given filters)
b. Similarly, I want to return Sum of all the Totals(ex: if I give Name as ABC, Dept as First, FY as 2016 - then it should return sum of the required Total values(i.e 100+150=250) for the given FY 2016 only)
Please help me in this requirement, how can I achieve, Thanks.
I have tried below, but it is giving all the results for given Name(ex: If I give Name as ABC, then it is returning all the details ABC only)
return getData().then(res => {
res.data.filter(customerDetails =>{
if(customerDetails.Name === name && customerDetails.FY === fy && customerDetails.Quarter === quarter && customerDetails.Month === month && customerDetails.Dept === dept)
agent.add(`Details: ${name}, Dept: ${customerDetails.Dept},
FY: ${customerDetails.FY}, Quarter: ${customerDetails.Quarter}, Month: ${customerDetails.Month},
Total: ${customerDetails.Total} `);
});
});
You can use Array.filter() to do that. Filter data based on passed values, and then add Total values of filtered data to get final total.
var data = [{ "Name": "ABC", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "April", "Total": "100" }, { "Name": "ABC", "Dept": "Second", "FY": "2017", "Quarter": "2", "Month": "May", "Total": "200" }, { "Name": "ABC", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "June", "Total": "150" }, { "Name": "DEF", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "April", "Total": "200" }, { "Name": "DEF", "Dept": "Second", "FY": "2017", "Quarter": "2", "Month": "May", "Total": "100" }, { "Name": "DEF", "Dept": "First", "FY": "2016", "Quarter": "1", "Month": "June", "Total": "500" }];
function getTotal(filters) {
var total = 0;
const filteredData = data.filter(item => {
for (var key in filters) {
if (item[key] != filters[key]) {
return false;
}
}
return true;
});
filteredData.forEach(value => total += Number(value.Total));
return total;
}
console.log(getTotal({ "Name": "ABC", "Dept": "First", "FY": "2016" }));
console.log(getTotal({"Name": "DEF" }));
You could take an object with the wanted filter values and filter the array and return the sum of all Total.
function getTotal(data, filters) {
var f = Object.entries(filters);
return data
.filter(o => f.every(([k, v]) => o[k] == v))
.reduce((s, { Total }) => s + +Total, 0);
}
var data = [{ Name: "ABC", Dept: "First", FY: "2016", Quarter: "1", Month: "April", Total: "100" }, { Name: "ABC", Dept: "Second", FY: "2017", Quarter: "2", Month: "May", Total: "200" }, { Name: "ABC", Dept: "First", FY: "2016", Quarter: "1", Month: "June", Total: "150" }, { Name: "DEF", Dept: "First", FY: "2016", Quarter: "1", Month: "April", Total: "200" }, { Name: "DEF", Dept: "Second", FY: "2017", Quarter: "2", Month: "May", Total: "100" }, { Name: "DEF", Dept: "First", FY: "2016", Quarter: "1", Month: "June", Total: "500" }];
console.log(getTotal(data, { Name: 'ABC', Dept: 'First', FY: 2016, Quarter: 1, Month: 'April' })); // 100
console.log(getTotal(data, { Name: 'ABC', Dept: 'First', FY: 2016 })); // 100 + 150 = 250

Count how many objects in an array has a certain value (JavaScript)

I have an array of objects, like so:
[
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
In the future this array will contain much more objects.
I'm trying to solve this using map and for it seems to be quite complicated.
That's the challenge:
how I can count how many objects have certain value? How can I get to know how many times someone booked something to day===1? The best result would be an array like this:
[{dayOne: 2}, {dayTwo: 5}, {dayThree:1}.......and so on],
where value is the value of how many times a day was booked(key), hence how many times certain object(with certain value) has appeared in the array?
Thank you in advance!
To count objects by a condition, you can use .filter --
let firstDayCount = arr.filter(x => x.day === "1").length;
To group the result by days, you can use .reduce --
let countByDays =
arr.reduce((res, { day }) => {
res[day] = res[day] || 0;
res[day] += 1;
return res;
}, {});
If you want to format your output, you can then use a dictionary of names --
let dayNames = { 1: "dayOne", 2: "dayTwo" /* and so on */}
let formattedResult =
Object.keys(countByDays)
.map(n => { [dayNames[n]]: countByDays[n] });
Note that using a .filter for counting creates an intermediate throw-away array. We're not storing a reference anywhere, so it has to be GCed soon, but if it really affects your performance measurably in a real-life scenario, you can use a .reduce instead -- something that is called "deforestation":)
let count = arr.reduce((cnt, el) => el.day === "1" ? cnt += 1 : cnt, 0);
It'll still create an intermediate anonymous object though -- a reducer function -- so if your profiler shows this place as a bottleneck, you might be best off using a for loop. As always in such cases, it's up to you to find the right spot between performance and readability in your own real-world scenarios.
To get result exactly in that format you can do this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Note that you will need to extend the days array for every day you want to include like that. So If you want to include all 31 possible days, you need this.
const objs = [
{
"_id": "5b09cc3495cb6c0487f1166b",
"name": "ccc",
"email": "ccc#gmail.com",
"phone": "790467522",
"kidsNo": "1",
"adultsNo": "1",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b09cc6095cb6c0487f1166c",
"name": "asd",
"email": "asd#asd.pl",
"phone": "790467522",
"kidsNo": "2",
"adultsNo": "3",
"fullDate": "2018/5/1",
"year": "2018",
"month": "5",
"day": "1",
"chosenHour": "12:00",
"chosenRoom": "x",
"__v": 0
},
{
"_id": "5b0b1560c7b4fd0c33b2d52e",
"name": "dddd",
"email": "dddd#ddd.pl",
"phone": "123123112",
"kidsNo": "2",
"adultsNo": "1",
"fullDate": "2018/5/17",
"year": "2018",
"month": "5",
"day": "17",
"chosenHour": "11:00",
"chosenRoom": "x",
"__v": 0
}
]
const days = [['dayOne', 1], ['dayTwo', 2], ['dayThree', 3], ['dayFour', 4], ['dayFive', 5],
['daySix', 6], ['daySeven', 7], ['dayEight', 8], ['dayNine', 9], ['dayTen', 10],
['dayEleven', 11], ['dayTwelve', 12], ['dayThirten', 13], ['dayFourteen', 14],
['dayFifteen', 15], ['daySixteen', 16], ['daySeventeen', 17], ['dayEighteen', 18],
['dayNineteen', 19], ['dayTwenty', 20], ['dayTwentyone', 21], ['dayTwentytwo', 22],
['dayTwentythree', 23], ['dayTwentyfour', 24], ['dayTwentyfive', 25], ['dayTwentysix', 26],
['dayTwentyseven', 27], ['dayTwentyeight', 28], ['dayTwentynine', 29], ['dayThirty', 30],
['dayThirtyone', 31]];
const res = days.reduce((acc, v) => {
const obj = {};
obj[v[0]] = objs.filter(x => x.day == v[1]).length;
return acc.concat(obj);
}, []);
console.log(res);
Which in this example returns [{dayOne: 2}, {dayTwo: 0}, ..., {daySeventeen}: 1, {dayNineteen: 0}, ...]
An alternative is using the function reduce to group and count.
const array = [{"_id": "5b09cc3495cb6c0487f1166b","name": "ccc","email": "ccc#gmail.com","phone": "790467522","kidsNo": "1","adultsNo": "1","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "11:00","chosenRoom": "x","__v": 0},{"_id": "5b09cc6095cb6c0487f1166c","name": "asd","email": "asd#asd.pl","phone": "790467522","kidsNo": "2","adultsNo": "3","fullDate": "2018/5/1","year": "2018","month": "5","day": "1","chosenHour": "12:00","chosenRoom": "x","__v": 0},{"_id": "5b0b1560c7b4fd0c33b2d52e","name": "dddd","email": "dddd#ddd.pl","phone": "123123112","kidsNo": "2","adultsNo": "1","fullDate": "2018/5/17","year": "2018","month": "5","day": "17","chosenHour": "11:00","chosenRoom": "x","__v": 0}],
result = Object.values(array.reduce((a, {day}) => {
let key = `day${day}`;
(a[key] || (a[key] = {[key]: 0}))[key]++;
return a;
}, {}));
console.log(result);

Draw a line against to indicate the max value in Amcharts

I am plotting a graph which contains a lot of data.
96 plots a day and the user can fetch data for a maximum range of 62 days.
I am using Amcharts to implement the same.
I need to show the user a line against the highest value of the graph.
Can someone please help me if Amcharts provides a functionality to display the max value on the graph.
Because if it doesn't i would have to reiterate the entire object just to insert the max value in every json array which doesnt seem like a good idea.
Thanks
There's no need to iterate through all of the data. When the chart builds itself, it calculates min and max values for each value axis anyway. We can tap into those auto-calculated values and add a Guide for each of them.
We can use chart's "rendered" event to do it. When this event happens, we know that the chart is build and thus minimum and maximum values are calculated.
The value axis object will contain maxReal and minReal properties, which we will use. We will add a Guide for those values to indicate highest and lowest points.
Here's how the code looks for it:
chart.addListener( "rendered", function( event ) {
// get chart and value axis
var chart = event.chart;
var axis = chart.valueAxes[0];
// create max guide
var guide = new AmCharts.Guide();
guide.value = guide.label = axis.maxReal;
guide.lineAlpha = 0.2;
guide.lineThickness = 2;
guide.lineColor = guide.color = "#00cc00";
axis.addGuide( guide );
// create min guide
var guide = new AmCharts.Guide();
guide.value = guide.label = axis.minReal;
guide.lineAlpha = 0.2;
guide.lineThickness = 2;
guide.lineColor = guide.color = "#cc0000";
axis.addGuide( guide );
} );
And here's a a complete working code of the chart:
var chart = AmCharts.makeChart( "chartdiv", {
"type": "serial",
"theme": "light",
"path": "http://www.amcharts.com/lib/3/",
"dataProvider": [ {
"year": "1969",
"value": -0.011
}, {
"year": "1970",
"value": -0.068
}, {
"year": "1971",
"value": -0.19
}, {
"year": "1972",
"value": -0.056
}, {
"year": "1973",
"value": 0.077
}, {
"year": "1974",
"value": -0.213
}, {
"year": "1975",
"value": -0.17
}, {
"year": "1976",
"value": -0.254
}, {
"year": "1977",
"value": 0.019
}, {
"year": "1978",
"value": -0.063
}, {
"year": "1979",
"value": 0.05
}, {
"year": "1980",
"value": 0.077
}, {
"year": "1981",
"value": 0.12
}, {
"year": "1982",
"value": 0.011
}, {
"year": "1983",
"value": 0.177
}, {
"year": "1984",
"value": -0.021
}, {
"year": "1985",
"value": -0.037
}, {
"year": "1986",
"value": 0.03
}, {
"year": "1987",
"value": 0.179
}, {
"year": "1988",
"value": 0.18
}, {
"year": "1989",
"value": 0.104
}, {
"year": "1990",
"value": 0.255
}, {
"year": "1991",
"value": 0.21
}, {
"year": "1992",
"value": 0.065
}, {
"year": "1993",
"value": 0.11
}, {
"year": "1994",
"value": 0.172
}, {
"year": "1995",
"value": 0.269
}, {
"year": "1996",
"value": 0.141
}, {
"year": "1997",
"value": 0.353
}, {
"year": "1998",
"value": 0.548
}, {
"year": "1999",
"value": 0.298
}, {
"year": "2000",
"value": 0.267
}, {
"year": "2001",
"value": 0.411
}, {
"year": "2002",
"value": 0.462
}, {
"year": "2003",
"value": 0.47
}, {
"year": "2004",
"value": 0.445
}, {
"year": "2005",
"value": 0.47
} ],
"valueAxes": [ {
} ],
"graphs": [ {
"id": "g1",
"bullet": "round",
"lineColor": "#d1655d",
"lineThickness": 2,
"negativeLineColor": "#637bb6",
"valueField": "value",
"bulletField": "bullet-g1",
"labelText": "[[label-g1]]"
} ],
"chartCursor": {
"categoryBalloonDateFormat": "YYYY",
"zoomable": false
},
"dataDateFormat": "YYYY",
"categoryField": "year",
"categoryAxis": {
"minPeriod": "YYYY",
"parseDates": true,
"minorGridAlpha": 0.1,
"minorGridEnabled": true
}
} );
chart.addListener( "rendered", function( event ) {
// get chart and value axis
var chart = event.chart;
var axis = chart.valueAxes[0];
// create max guide
var guide = new AmCharts.Guide();
guide.value = guide.label = axis.maxReal;
guide.lineAlpha = 0.2;
guide.lineThickness = 2;
guide.lineColor = guide.color = "#00cc00";
axis.addGuide( guide );
// create min guide
var guide = new AmCharts.Guide();
guide.value = guide.label = axis.minReal;
guide.lineAlpha = 0.2;
guide.lineThickness = 2;
guide.lineColor = guide.color = "#cc0000";
axis.addGuide( guide );
} );
#chartdiv {
width: 100%;
height: 500px;
}
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/serial.js"></script>
<script src="http://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

Categories

Resources