i have a line chart showing donations per month. however i have records showing with months without donations. my json data looks like this.
"content": [
{
"donation_amount": "10",
"avg_donation_amount": 10.0,
"transaction_count": 1,
"month": 2
},
{
"donation_amount": "60",
"avg_donation_amount": 60.0,
"transaction_count": 1,
"month": 3
},
{
"donation_amount": "1556",
"avg_donation_amount": 97.00,
"transaction_count": 3,
"month": 4
}
]
which month represents for ex: 2 is february, 3 is march, 4 is april. now i still need to show that there is no donation came from the month of january.
this is my js file
async countDonationsPerMonth(){
let URL = BASE_URL+"donors_by_month";
let x = [];
let y = [];
let item = [];
try {
const response = await fetch(URL,{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bareer ' + this.getUserAuth()
}
})
const data = await response.json();
let content = data.content;
content.map((item, key) =>
y.push(item.donation_amount)
);
this.setState({
donation_amount: y
})
}catch(err){
console.log(err)
}
}
render() {
const data = {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
datasets: [
{
fill: false,
backgroundColor: 'rgba(75,192,192,0.4)',
borderColor: 'rgba(75,192,192,1)',
borderCapStyle: 'butt',
borderDash: [],
borderDashOffset: 0.0,
data: this.state.donation_amount
}
]
};
return (
<div>
<Card title="Campaign Donations">
<Line
data={data}
width={150}
height={40}
/>
</Card>
</div>
);
}
expected output for data[0,10,60,1556,0,0,0,0,0,0,0,0]
i still wants to push to array with zero donation_amount.
any help would be much appreciated. thanks
use this
y=Array.from(Array(12)).fill(0);
content.map((item,i) =>{y[parseInt(item.month)-1]=parseInt(item.donation_amount)});
.
output example
.
content = [{
"donation_amount": "10",
"avg_donation_amount": 10.0,
"transaction_count": 1,
"month": 2
},
{
"donation_amount": "60",
"avg_donation_amount": 60.0,
"transaction_count": 1,
"month": 3
},
{
"donation_amount": "1556",
"avg_donation_amount": 97.00,
"transaction_count": 3,
"month": 4
}
];
y = Array.from(Array(12)).fill(0);
content.map((item, i) => {
y[parseInt(item.month) - 1] = parseInt(item.donation_amount)
});
console.log(y);
Related
I have a CartSummary component where I show the products that are added to the cart. When the user triggers addProduct method, the state reloads and re-fetchs the cart from the server. In short, I save the cart information in database, when somenone add/remove a product from the cart I reload the cart. However, I get the the above error. It might be caused by asynchronous programming. I tried to use loader before the cart information arrives to the client side, but it didn't work. Also, the state is not reloaded when I add a new product to the cart. I tried to log the cart info to the console each time(marked in CartSummary class), it seems the cartItems is empty at first, but then it refilled.That's why I made a codition such that cart.cartItems.length>0 ?.... : .... Still not working.
CartSummary component where I show the cart details to the user.
import React, {useEffect} from 'react';
import {Badge, DropdownItem, DropdownMenu, DropdownToggle, Spinner, UncontrolledDropdown} from "reactstrap";
import {useDispatch, useSelector} from "react-redux";
import {cartActions} from "../redux/slice/cartSlice";
import {useNavigate} from "react-router-dom"
import alertify from "alertifyjs";
import {fetchCart} from "../redux/thunk/cartActionThunk";
import {PageSpinner} from "./spinner/Spinner";
const CartSummary = () => {
const cart = useSelector(state => (state.cartStore.cart))
const isLoading = useSelector(state => (state.uiStore.isLoading))
const dispatch = useDispatch()
const handleRemoveFromCart = (product) => {
dispatch(cartActions.removeFromCart(product.id))
alertify.error(product.productName + " removed from the cart", 1)
}
const navigate = useNavigate()
useEffect(() => {
}, [dispatch])
console.log(cart) // HERE I LOG THE CART
return (
<div>
<UncontrolledDropdown nav inNavbar>
<DropdownToggle nav caret>
Cart
</DropdownToggle>
<DropdownMenu>
{
isLoading ?
<PageSpinner></PageSpinner>
:
cart.cartItems.map((item) => (
<DropdownItem
style={{
justifyContent: "space-between",
display: "flex",
alignContent: "center",
margin: 10
}}
key={item.id}>
{item.product.productName}
<Badge color="success">{item.totalQuantity}</Badge>
</DropdownItem>
))
}
<DropdownItem divider/>
<DropdownItem style={{textAlign: "end"}}> <Badge
color="success">${cart.totalPrice}</Badge></DropdownItem>
<DropdownItem style={{textAlign: "center"}} onClick={() => navigate("/cart-details")}>Show
cart details</DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
);
};
export default CartSummary;
Cart Actions Thunk
import {API_URL} from "../../const/url";
import {cartActions} from "../slice/cartSlice";
import alertify from "alertifyjs";
import {uiActions} from "../slice/uiSlice";
export const addToCart = (product) => {
const productDto = {
"id": product.id,
"productName": product.productName,
"quantityPerUnit": product.quantityPerUnit,
"unitPrice": product.unitPrice,
"unitsInStock": product.unitsInStock,
"categoryId": product.category.id
}
const userId = 1;
return (dispatch) => {
dispatch(uiActions.setIsLoading(true))
fetch(API_URL + '/cartItem?userId=' + userId, {
method: 'POST',
headers: {"Content-Type": "application/json"},
body: JSON.stringify(productDto)
}
).then((response) => {
if (!response.ok) {
throw Error("Couldn't add " + productDto.productName + " to the cart.")
}
return response.json()
}).then((result) => {
dispatch(cartActions.addProduct(result))
dispatch(uiActions.setIsLoading(false))
alertify.success(productDto.productName + " added successfully.")
}).catch((err) => {
dispatch(uiActions.setError(err))
dispatch(uiActions.setIsLoading(false))
alertify.error(err.message)
})
}
}
export const fetchCart = () => {
const userId = 1;
return (dispatch)=>{
dispatch(uiActions.setIsLoading(true))
fetch(API_URL + '/cartItem?userId=' + userId, {
method: 'GET'
}).then((response)=>{
if(!response.ok){
throw Error("Couldn't fetch cart data")
}
return response.json()
}).then((result)=>{
dispatch(cartActions.fetchCart(result))
dispatch(uiActions.setIsLoading(false))
}).catch((err)=>{
dispatch(uiActions.setError(err))
dispatch(uiActions.setIsLoading(false))
alertify.error(err.message)
})
}
}
export const removeFromCart = (product) => {
return (dispatch) => {
fetch(API_URL + '/')
}
}
CartSlice
const cartSlice = createSlice({
name: 'cart',
initialState: {cart: {cartItems: [], totalPrice: 0, totalQuantity: 0}},
reducers: {
//payload is product
addProduct(state, action) {
state.cart.cartItems.push(action)
},
//payload is product id
removeFromCart(state, action) {
const existingCartItem = state.cart.cartItemList.find((cartItem) => cartItem.product.id === action.payload)
state.cart.totalPrice -= existingCartItem.totalPrice;
state.cart.totalQuantity--;
state.cart.cartItemList = state.cart.cartItemList.filter((cartItem) => cartItem.product.id !== action.payload)
},
fetchCart(state, action) {
state.cart = action.payload
}
}
})
export const cartActions = cartSlice.actions;
export default cartSlice;
Json structure for cart
{
"id": 1,
"cartItems": [
{
"id": 19,
"totalQuantity": 1,
"totalPrice": 12.5,
"product": {
"id": 3,
"productName": "Scottish Longbreads",
"quantityPerUnit": "10 boxes x 8 pieces",
"unitPrice": 12.5,
"unitsInStock": 6,
"categoryId": 3
}
},
{
"id": 20,
"totalQuantity": 1,
"totalPrice": 31.0,
"product": {
"id": 10,
"productName": "Ikura",
"quantityPerUnit": "12 - 200 ml jars",
"unitPrice": 31.0,
"unitsInStock": 31,
"categoryId": 8
}
},
{
"id": 21,
"totalQuantity": 2,
"totalPrice": 69.6,
"product": {
"id": 4,
"productName": "Mozzarella di Giovanni",
"quantityPerUnit": "24 - 200 g pkgs.",
"unitPrice": 34.8,
"unitsInStock": 14,
"categoryId": 4
}
},
{
"id": 22,
"totalQuantity": 1,
"totalPrice": 37.0,
"product": {
"id": 6,
"productName": "Queso Manchego La Pastora",
"quantityPerUnit": "10 - 500 g pkgs.",
"unitPrice": 37.0,
"unitsInStock": 86,
"categoryId": 6
}
},
{
"id": 23,
"totalQuantity": 1,
"totalPrice": 38.0,
"product": {
"id": 8,
"productName": "Queso Manchego La Pastora",
"quantityPerUnit": "10 - 500 g pkgs.",
"unitPrice": 38.0,
"unitsInStock": 86,
"categoryId": 8
}
},
{
"id": 24,
"totalQuantity": 1,
"totalPrice": 33.25,
"product": {
"id": 5,
"productName": "Wimmers gute Semmelknödel",
"quantityPerUnit": "20 bags x 4 pieces",
"unitPrice": 33.25,
"unitsInStock": 22,
"categoryId": 5
}
},
{
"id": 25,
"totalQuantity": 1,
"totalPrice": 13.0,
"product": {
"id": 2,
"productName": "Original Frankfurer grüne So",
"quantityPerUnit": "12 boxes",
"unitPrice": 13.0,
"unitsInStock": 11,
"categoryId": 8
}
}
],
"totalQuantity": 7,
"totalPrice": 234.35
}
I want convert my below existing json to new json so that I can dynamically populate dropdowns.
Here I am grouping by CityId and extracting month from DeptDate
However unable filter days based on CityId wise.
Existing JSON :
const [items] = useState([
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3762,"DeptDate":"22 Jul 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3763,"DeptDate":"05 Aug 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3764,"DeptDate":"12 Aug 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3765,"DeptDate":"19 Aug 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3766,"DeptDate":"26 Aug 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3767,"DeptDate":"09 Sep 2022 "},
{"Id":502,"CityId":2,"CityName":"Ex. Mumbai","DepartureId":3768,"DeptDate":"23 Sep 2022 "},
{"Id":502,"CityId":1,"CityName":"Ex. Ahmedabad","DepartureId":3762,"DeptDate":"22 Jul 2022 "},
{"Id":502,"CityId":7,"CityName":"Ex. Delhi","DepartureId":3762,"DeptDate":"22 Jul 2022 "},
]);
to New JSON :
[
{
"Id": 502,
"CityId": 2,
"CityName": "Ex. Mumbai",
"TravelDates": [
{
"DeptMonth": "Jul",
"Dept": [
{
"Day": "22"
"DepartureId": 3762,
}
]
},
{
"DeptMonth": "Aug",
"Dept": [
{
"Day": "05"
"DepartureId": 3763,
},
{
"Day": "12"
"DepartureId": 3764,
},
{
"Day": "19"
"DepartureId": 3765,
},
{
"Day": "26"
"DepartureId": 3766,
},
]
},
{
"DeptMonth": "Sep",
"Dept": [
{
"Day": "09"
"DepartureId": 3767,
},
{
"Day": "23"
"DepartureId": 3768,
}
]
}
]
},
{
"Id": 502,
"CityId": 1,
"CityName": "Ex. Ahmedabad",
"TravelDates": [
{
"DeptMonth": "Jul",
"Dept": [
{
"Day": "22"
"DepartureId": 3762,
}
]
}
]
},
]
Currently I am using below reduce function but unable to achieve expected result.
const newJson = items.reduce((cityGroup, { CityName, CityId, DeptDate, DepartureId }) => {
var [d, m, y] = DeptDate.split(' ');
const day = `${d}`;
const month = `${m}`;
if (!cityGroup[month]) {
cityGroup[month] = [];
}
// unable to group dates by month
cityGroup[month].push({
DeptMonth: month,
Dept: [{
Day : day,
DepartureId : DepartureId
}]
});
if (!cityGroup[CityName]) cityGroup[CityName] = [];
cityGroup[CityName].push({
CityName,
CityId,
TravelDates : [
{
// to be placed here...
}
]
});
return cityGroup;
}, {});
console.log(newJson);
Please guide and thank you in advance for all support !!
I always prefer immutable data structures. This is how you could achieve it. You should be able to fill in the blank for your solution as well from here.
const groupByCityAndTravelDates = (arr) => arr.reduce((acc , cur) => {
const existing = acc[cur['CityId']];
const [d , m , y] = cur['DeptDate'].split(' ');
if (existing) {
const existingTravelDate = acc[cur['CityId']]['TravelDates'][m];
if (existingTravelDate) {
return {
...acc ,
[cur['CityId']]: {
...acc[cur['CityId']] ,
'TravelDates': {
...acc[cur['CityId']]['TravelDates'] ,
[m]: {
'DeptMonth': m ,
'Dept': [
...acc[cur['CityId']]['TravelDates'][m]['Dept'] ,
{
'DeptDay': d ,
'DepartureId': cur['DepartureId'] ,
},
],
},
},
},
};
}
return {
...acc ,
[cur['CityId']]: {
...acc[cur['CityId']] ,
'TravelDates': {
...acc[cur['CityId']]['TravelDates'] ,
[m]: {
'DeptMonth': m ,
'Dept': [
{
'DeptDay': d ,
'DepartureId': cur['DepartureId'] ,
},
],
},
},
},
};
}
return {
...acc ,
[cur['CityId']]: {
'Id': cur['Id'] ,
'CityId': cur['CityId'] ,
'CityName': cur['CityName'] ,
'TravelDates': {
[m]: {
'DeptMonth': m ,
'Dept': [
{
'DeptDay': d ,
'DepartureId': cur['DepartureId'] ,
},
],
},
},
},
};
} , {});
const toCityArray = (mappedData) => Object.keys(mappedData).map(key => {
return {
'CityId': key,
'Id': mappedData[key]['Id'],
'CityName': mappedData[key]['CityName'],
'TravelDates': Object.keys(mappedData[key]['TravelDates']).map(travelKey => {
return {
'DeptMonth': travelKey,
'Dept': mappedData[key]['TravelDates'][travelKey]['Dept']
}
})
}
})
toCityArray(groupByCityAndTravelDates(arr))
I have some takeaways for you
You will have to consider year for aggregation alongwith month at some point of time in the solution.
In general, its recommmended to use camelCase for json attributes.
I am sure you are pulling this data from an api. Its not recommended to do a lot of aggregation on the frontend, specially if the data grows. If possible transfer this aggregation to the api.
Hope this helps.
I'm trying to sort the dates from this external API in my latestResults array by latest on top to oldest on bottom but can't seem to figure out how.
Right now they're displayed with the oldest date first and it's working fine, but it's in the wrong order for me.
I tried using result in latestResults.reverse() but that just reverses the 7 items currently in the array.
HTML:
<div v-for="result in latestResults" v-bind:key="result.latestResults">
<small">{{ result.utcDate }}</small>
</div>
Script:
<script>
import api from '../api'
export default {
data () {
return {
latestResults: [],
limit: 7,
busy: false,
loader: false,
}
},
methods: {
loadMore() {
this.loader = true;
this.busy = true;
api.get('competitions/PL/matches?status=FINISHED')
.then(response => { const append = response.data.matches.slice(
this.latestResults.length,
this.latestResults.length + this.limit,
this.latestResults.sort((b, a) => {
return new Date(b.utcDate) - new Date(a.utcDate);
})
);
setTimeout(() => {
this.latestResults = this.latestResults.concat(append);
this.busy = false;
this.loader = false;
}, 500);
});
}
},
created() {
this.loadMore();
}
}
</script>
The JSON where I'm getting matches like this that has utcDate:
{
"count": 205,
"filters": {
"status": [
"FINISHED"
]
},
"competition": {
"id": 2021,
"area": {
"id": 2072,
"name": "England"
},
"name": "Premier League",
"code": "PL",
"plan": "TIER_ONE",
"lastUpdated": "2021-02-01T16:20:10Z"
},
"matches": [
{
"id": 303759,
"season": {
"id": 619,
"startDate": "2020-09-12",
"endDate": "2021-05-23",
"currentMatchday": 22
},
"utcDate": "2020-09-12T11:30:00Z",
"status": "FINISHED",
"matchday": 1,
"stage": "REGULAR_SEASON",
"group": "Regular Season",
"lastUpdated": "2020-09-13T00:08:13Z",
"odds": {
"msg": "Activate Odds-Package in User-Panel to retrieve odds."
},
},
I'm trying to transform the following JSON array data structure -
From
[
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
]
To
rows: [
{
values: [ '2019-01-01', 1, 2, 3]
},
{
values: [ '2019-01-02', 4, 5, 6]
}
]
The code that I was able to try so far is this -
function myFunction() {
var response = [
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
];
var transform = response.map(function(dailyMarks) {
var row = [];
Object.keys(response).asArray().forEach(function (field) {
switch (field) {
case 'shoes':
return row.push(dailyMarks.shoes);
case 'belt':
return row.push(dailyMarks.belt);
case 'socks':
return row.push(dailyMarks.socks);
case 'date':
return row.push(dailyMarks.date);
default:
return row.push('');
}
});
return { values: row };
});
Logger.log(transform);
}
However, I'm running into this error -
TypeError: Cannot find function asArray in object 1,2. (line XX, file "Code")
Pretty sure I'm doing something wrong but have not been able to figure out where.
Objective is simply to transform the aforementioned data structure - approach doesn't really matter.
Any help would be highly appreciated! Thanks.
In ES5,
var arr1 = [
{
date: '2019-01-01',
marks: [
{
quantity: {
shoes: 1,
belt: 2,
socks: 3,
},
},
],
},
{
date: '2019-01-02',
marks: [
{
quantity: {
shoes: 4,
belt: 5,
socks: 6,
},
},
],
},
];
var out = [];
arr1.forEach(function(obj) {
obj.marks.forEach(function(mark) {
out.push({
values: [obj.date].concat(
Object.keys(mark.quantity).map(function(key) {
return mark.quantity[key];
})
),
});
});
});
console.log({ rows: out });
You could take an array of keys for the order and flatmap the marks array.
var data = [{ date: "2019-01-01", marks: [{ quantity: { shoes: 1, belt: 2, socks: 3 } }] }, { date: "2019-01-02", marks: [{ quantity: { shoes: 4, belt: 5, socks: 6 } }] }],
keys = ['shoes', 'belt', 'socks'],
rows = data.map(({ date, marks }) =>
({ values: [date, ...marks.flatMap(({ quantity }) => keys.map(k => quantity[k]))] })),
result = { rows };
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let x = products.map(p=>{
return p.marks.reduce((t,m)=>{
t.push({ values: [p.date, ...Object.entries(m.quantity).map(([key, value]) => value)]})
return t;
},[])
}
).flat(2)
console.log(x)
var list=[{"date":"2019-01-01","marks":[{"quantity":{"shoes":1,"belt":2,"socks":3}}]},{"date":"2019-01-02","marks":[{"quantity":{"shoes":4,"belt":5,"socks":6}}]}];
let result = list.map(( {date, marks} ) => { return {value: [date, ...Object.values(marks[0].quantity)]};});
let wrap = {rows: result};
console.log(wrap);
I want to build a combination chart with a column chart with multiple series and a line chart. Problem is that I am getting High charts data from nested JSON response. For that I initialized array and that array is giving in series in plotoptions highcharts as you can see in the below code.
My code is like this:
var crime_data=[];
for(var i=0;i<result.themes.length;i++){
var crime={};
var test2 = result.themes[i];
var test = test2[Object.keys(test2)];
crime.name = Object.keys(result.themes[i]);
crime.data = [];
for(var k=0;k<test.yearTheme.length;k++){
var test3=test.yearTheme[k];
var test5=test3.individualValueVariable;
for(var j=0;j<test5.length;j++){
crime.data.push(test5[j].count);
};
};
crime_data.push(crime);
};
var crimeChart = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type:'column'
},
title: {
text: 'Crime'
},
xAxis: {
categories: month,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: 'Count'
}
},
credits: {
enabled: false
},
tooltip: {
shared: true,
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0,
depth: 25,
allowPointSelect: true,
cursor: 'pointer',
point: {
},
}
},
series: crime_data
});
This is Column chart I am getting when i write chart type column.
This is my Line Chart I am getting when i changed type column to spline in chart in highcharts.
And this is my JSON data(Highcharts data):
{
"boundaries": {
"boundary": [
{
"boundaryId": "55083021003",
"boundaryType": "USA_CITY",
"boundaryRef": "C1"
}
]
},
"themes": [
{
"AssaultCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [
{
"name": "2013 Assault Crime",
"description": "Assault Crime for 2013",
"count": 18901
},
{
"name": "2014 Assault Crime",
"description": "Assault Crime for 2014",
"count": 17707
}
]
}
},
{
"BurglaryCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [
{
"name": "2013 Burglary Crime",
"description": "Burglary Crime for 2013",
"count": 17743
},
{
"name": "2014 Burglary Crime",
"description": "Burglary Crime for 2014",
"count": 14242
}
]
}
}
]
}
I want to combine both of them in the same container with same data.The problem is in how to tell highcharts multiple series should be represented with line and with column type with same data.For this when i write series:[{ data: crime_data ,type: spline }] instead of series:crime_data In that case I am not getting Highcharts data. Can anyone Please help me how should i do this.Please suggest me.
Pass your data, like below format. add type of chart in each data series;
Here i replaced type value but with same data.
[{
type: 'line',
name: 'AssaultCrimeTheme',
data: [3, 2, 1, 3, 4]
}, {
type: 'line',
name: 'BurglaryCrimeTheme',
data: [2, 3, 5, 7, 6]
}, {
type: 'column',
name: 'AssaultCrimeTheme',
data: [3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'BurglaryCrimeTheme',
data: [2, 3, 5, 7, 6]
},]
Here is fiddle for more details.
Here is a complete example using your data.
const json = {
"boundaries": {
"boundary": [{
"boundaryId": "55083021003",
"boundaryType": "USA_CITY",
"boundaryRef": "C1"
}]
},
"themes": [{
"AssaultCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [{
"name": "2013 Assault Crime",
"description": "Assault Crime for 2013",
"count": 18901
}, {
"name": "2014 Assault Crime",
"description": "Assault Crime for 2014",
"count": 17707
}]
}
}, {
"BurglaryCrimeTheme": {
"boundaryRef": "C1",
"individualValueVariable": [{
"name": "2013 Burglary Crime",
"description": "Burglary Crime for 2013",
"count": 17743
}, {
"name": "2014 Burglary Crime",
"description": "Burglary Crime for 2014",
"count": 14242
}]
}
}]
}
// Create categories object in order filter duplicates
const cats = {}
const series = json.themes.map((o) => {
const key = Object.keys(o)[0]
return {
name: key,
data: o[key].individualValueVariable.map((o) => {
cats[o.name] = 1
return { category: o.name, y: o.count }
})
}
})
// Convert categories object to array
const categories = Object.keys(cats)
// Chart options
const options = {
chart: {type: 'column'},
xAxis: {categories: categories},
series: series
}
// Create chart
const chart = Highcharts.chart('container', options)
console.log(series, categories)
Live example: https://jsfiddle.net/Lo323gq3/
Output below: