I need to join and order 2 arrangements, and I have not succeeded.
the first array contains "categories" of pokemons
and the second array contains pokemons and some data.
I need to join both arrays, sum the power value of each pokemon and show them in this way
expected result
[
{fire: 19000},
{ rock: 2100 },
{water: 1500}
]
1st array "cateogries or types"
const pokeTypes = [
{ uuid: 1, pokemonType: "fire" },
{ uuid: 2, pokemonType: "water" },
{ uuid: 3, pokemonType: "rock" }
];
2nd array pokemons
const pokemons = [
{
name: "geodude",
pokemonTypeId: 3,
power: 900,
},
{
name: "onix",
pokemonTypeId: 3,
power: 1200,
},
{
name: "squirtle",
pokemonTypeId: 2,
power: 100,
},
{
name: "seadra",
pokemonTypeId: 2,
power: 300,
},
{
name: "goldeen",
pokemonTypeId: 2,
power: 1100,
},
{
name: "charmander",
pokemonTypeId: 1,
power: 2000,
},
{
name: "charmeleon",
pokemonTypeId: 1,
power: 4000,
},
{
name: "charizard",
pokemonTypeId: 1,
power: 7000,
},
{
name: "magmar",
pokemonTypeId: 1,
power: 6000,
},
];
I started doing a reducer and was able to generate an array of objects grouped by pokemonTypeId, I couldn't continue after this...
I tried
function sortPokemons() {
result = pokemons.reduce(
(h, pokemons) =>
Object.assign(h, {
[pokemons.pokemonTypeId]: (h[pokemons.pokemonTypeId] || []).concat({
typeId: pokemons.pokemonTypeId,
}),
}),
{}
);
console.log(result);
}
console.log(sortPokemons());
thanks!
You can easily and efficiently achive the result using Map
const pokeTypes = [
{ uuid: 1, pokemonType: "fire" },
{ uuid: 2, pokemonType: "water" },
{ uuid: 3, pokemonType: "rock" },
];
const pokemons = [
{
name: "geodude",
pokemonTypeId: 3,
power: 900,
},
{
name: "onix",
pokemonTypeId: 3,
power: 1200,
},
{
name: "squirtle",
pokemonTypeId: 2,
power: 100,
},
{
name: "seadra",
pokemonTypeId: 2,
power: 300,
},
{
name: "goldeen",
pokemonTypeId: 2,
power: 1100,
},
{
name: "charmander",
pokemonTypeId: 1,
power: 2000,
},
{
name: "charmeleon",
pokemonTypeId: 1,
power: 4000,
},
{
name: "charizard",
pokemonTypeId: 1,
power: 7000,
},
{
name: "magmar",
pokemonTypeId: 1,
power: 6000,
},
];
const map = new Map();
pokemons.forEach((o) =>
map.has(o.pokemonTypeId)
? map.set(o.pokemonTypeId, map.get(o.pokemonTypeId) + o.power)
: map.set(o.pokemonTypeId, o.power)
);
const result = pokeTypes.map((o) => ({ [o.pokemonType]: map.get(o.uuid) }));
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }
const pokeTypes = [
{ uuid: 1, pokemonType: "fire" },
{ uuid: 2, pokemonType: "water" },
{ uuid: 3, pokemonType: "rock" }
];
const pokemons = [
{
name: "geodude",
pokemonTypeId: 3,
power: 900,
},
{
name: "onix",
pokemonTypeId: 3,
power: 1200,
},
{
name: "squirtle",
pokemonTypeId: 2,
power: 100,
},
{
name: "seadra",
pokemonTypeId: 2,
power: 300,
},
{
name: "goldeen",
pokemonTypeId: 2,
power: 1100,
},
{
name: "charmander",
pokemonTypeId: 1,
power: 2000,
},
{
name: "charmeleon",
pokemonTypeId: 1,
power: 4000,
},
{
name: "charizard",
pokemonTypeId: 1,
power: 7000,
},
{
name: "magmar",
pokemonTypeId: 1,
power: 6000,
},
];
var data = pokeTypes.map(function(type) {
var res = {};
res[type.pokemonType] = pokemons.filter((item) => {
return item.pokemonTypeId === type.uuid;
}).reduce(function(sum, item) {
return sum + item.power;
}, 0);
return res;
});
console.log(data);
Can be achieved using simple immutable programming: just use array methods map() and reduce().
const pokeTypes = [
{ uuid: 1, pokemonType: "fire" },
{ uuid: 2, pokemonType: "water" },
{ uuid: 3, pokemonType: "rock" },
];
const pokemons = [
{
name: "geodude",
pokemonTypeId: 3,
power: 900,
},
{
name: "onix",
pokemonTypeId: 3,
power: 1200,
},
{
name: "squirtle",
pokemonTypeId: 2,
power: 100,
},
{
name: "seadra",
pokemonTypeId: 2,
power: 300,
},
{
name: "goldeen",
pokemonTypeId: 2,
power: 1100,
},
{
name: "charmander",
pokemonTypeId: 1,
power: 2000,
},
{
name: "charmeleon",
pokemonTypeId: 1,
power: 4000,
},
{
name: "charizard",
pokemonTypeId: 1,
power: 7000,
},
{
name: "magmar",
pokemonTypeId: 1,
power: 6000,
},
];
const totals = pokeTypes.map(({uuid, pokemonType}) => {
const total = pokemons.reduce((acc, {power, pokemonTypeId}) =>
pokemonTypeId === uuid ? acc + power : acc
, 0);
return { [pokemonType] : total };
});
console.log(totals);
And if you want to a nice clean object { fire: 19000, rock: 2100, water: 1500 }, which IMO is cleaner than array, replace the .map() with another .reduce():
const totals = pokeTypes.reduce((acc, {uuid, pokemonType}) => {
const total = pokemons.reduce((totalAcc, {power, pokemonTypeId})=>
pokemonTypeId === uuid ? totalAcc + power : totalAcc
, 0);
return {
...acc,
[pokemonType]: total,
}
}, {});
Related
I have an array with objects. I'm trying to recursively search through them and create new array with modified key's.
The array:
let response = {
users: [
{
user_id: 1661871600,
details: {
height: 150,
age: 33,
work: 1015,
school: 10,
degree: 933
},
work: [
{
id: 500,
main: 'Doctor',
description: 'Ofto',
icon: '10d',
},
],
look: {
all: 100,
},
transport: {
speed: 0.62,
max_speed: 349,
},
visibility: 10000,
hair: {
type: 0.26,
},
date: '2022-08-30 15:00:00',
},
{
user_id: 324235256,
details: {
height: 110,
age: 25,
work: 101,
school: 110,
degree: 553
},
work: [
{
id: 500,
main: 'Software',
description: 'Programmer',
icon: '11d',
},
],
look: {
all: 2,
},
transport: {
speed: 1.2,
max_speed: 49,
},
visibility: 221,
hair: {
type: 5.6,
},
date: '2021-01-30 12:00:00',
},
{
user_id: 12353743,
details: {
height: 10,
age: 75,
work: 1,
school: 114,
degree: 3
},
work: [
{
id: 500,
main: 'Pension',
description: 'Architect',
icon: '1d',
},
],
look: {
all: 6,
},
transport: {
speed: 3.2,
max_speed: 29,
},
visibility: 21,
hair: {
type: 1.6,
},
date: '2020-01-30 12:00:00',
},
],
};
I've tried using JSON.Stringify but I keep getting not desired result.
function dynamic(obj, ...keyToFind) {
const foundObj = {};
const foundObjArray: any[] = [];
keyToFind.forEach((key) => {
JSON.stringify(obj, (_, nestedValue) => {
if (nestedValue && nestedValue[a]) {
foundObj[key] = nestedValue[a];
}
return nestedValue;
});
foundObjArray.push(foundObj);
});
return foundObjArray;
}
I'm calling this function with N number of parameters:
dynamic(response, 'age', 'work', 'main', 'description', 'type', 'date');
Once it is called I'm trying to construct a new array of objects who will look like:
let foundObjArray = [
{
'age': 33,
'work': 1015,
'main': 'Doctor',
'description': 'Ofto',
'type': 5.6,
'date': '2022-08-30 15:00:00'
},
{
'age': 25,
'work': 101,
'main': 'Software',
'description': 'Programmer',
'type': 0.26,
'date': '2021-01-30 12:00:00'
},
.......
]
A JSON.stringify based approach, as initially intended by the OP, is even a reliable one, in case one wants to target any user-item's first occurring entry regardless of its nesting level/depth where each property's value is not of object or array type itself.
One just needs to come up with an according property specific regex like e.g. for the "work" key ... /"work":(?<value>[^\[{]+?)(?=,"|\})/.
The rest then can be achieved by combined map and reduce tasks, where with each item's mapping a new object is created via reducing an array of property names which has to be provided as the map method's 2nd thisArg parameter.
const response = {
users: [{
user_id: 1661871600,
details: {
height: 150,
age: 33,
work: 1015,
school: 10,
degree: 933
},
work: [{
id: 500,
main: 'Doctor',
description: 'Ofto',
icon: '10d',
}],
look: {
all: 100,
},
transport: {
speed: 0.62,
max_speed: 349,
},
visibility: 10000,
hair: {
type: 0.26,
},
date: '2022-08-30 15:00:00',
}, {
user_id: 324235256,
details: {
height: 110,
age: 25,
work: 101,
school: 110,
degree: 553
},
work: [{
id: 500,
main: 'Software',
description: 'Programmer',
icon: '11d',
}],
look: {
all: 2,
},
transport: {
speed: 1.2,
max_speed: 49,
},
visibility: 221,
hair: {
type: 5.6,
},
date: '2021-01-30 12:00:00',
}, {
user_id: 12353743,
details: {
height: 10,
age: 75,
work: 1,
school: 114,
degree: 3
},
work: [{
id: 500,
main: 'Pension',
description: 'Architect',
icon: '1d',
}],
look: {
all: 6,
},
transport: {
speed: 3.2,
max_speed: 29,
},
visibility: 21,
hair: {
type: 1.6,
},
date: '2020-01-30 12:00:00',
}],
};
function createObjectOfFirstOccurringValuesFromBoundKeyList(item) {
const itemData = JSON.stringify(item);
return this // `this` equals the bound array of property names.
.reduce((result, key) => {
const { value = null } =
RegExp(`"${ key }":(?<value>[^\[{]+?)(?=,"|\})`)
// see ... [https://regex101.com/r/ss6jlt/1]
.exec(itemData)
?.groups ?? {};
if (value !== null) {
Object
.assign(result, { [key]: JSON.parse(value) });
}
return result;
}, {})
}
const listOfFirstPropertyValueItems = response
.users
.map(createObjectOfFirstOccurringValuesFromBoundKeyList, [
'age', 'work', 'main', 'description', 'type', 'date'
]);
console.log({
listOfFirstPropertyValueItems
});
.as-console-wrapper { min-height: 100%!important; top: 0; }
let response = {
users: [
{
user_id: 1661871600,
details: {
height: 150,
age: 33,
speed_min: 296.76,
speed_max: 297.87,
work: 1015,
school: 10,
degree: 933
},
work: [
{
id: 500,
main: 'Doctor',
description: 'Ofto',
icon: '10d',
},
],
look: {
all: 100,
},
transport: {
speed: 0.62,
max_speed: 349,
},
visibility: 10000,
hair: {
type: 0.26,
},
date: '2022-08-30 15:00:00',
},
{
user_id: 324235256,
details: {
height: 110,
age: 25,
speed_min: 96.76,
speed_max: 327.87,
work: 101,
school: 110,
degree: 553
},
work: [
{
id: 500,
main: 'Software',
description: 'Programmer',
icon: '11d',
},
],
look: {
all: 2,
},
transport: {
speed: 1.2,
max_speed: 49,
},
visibility: 221,
hair: {
type: 5.6,
},
date: '2021-01-30 12:00:00',
},
{
user_id: 12353743,
details: {
height: 10,
age: 75,
speed_min: 16.76,
speed_max: 27.87,
work: 1,
school: 114,
degree: 3
},
work: [
{
id: 500,
main: 'Pension',
description: 'Architect',
icon: '1d',
},
],
look: {
all: 6,
},
transport: {
speed: 3.2,
max_speed: 29,
},
visibility: 21,
hair: {
type: 1.6,
},
date: '2020-01-30 12:00:00',
},
],
};
function getMatchedKey(arr, key) {
let matched = arr.filter(x => key.endsWith(x));
if(matched.length > 0) {
return matched[0];
}
}
function getLimitedData(data, requiredKey = []) {
var result = {};
function recurse(cur, prop) {
if (Object(cur) !== cur) {
let matchedKey = getMatchedKey(requiredKey, prop);
matchedKey != undefined && (result[matchedKey] = cur);
} else if (Array.isArray(cur)) {
for (var i = 0, l = cur.length; i < l; i++)
recurse(cur[i], prop + "[" + i + "]");
if (l == 0) {
let matchedKey = getMatchedKey(requiredKey, prop);
matchedKey != undefined && (result[matchedKey] = []);
}
} else {
var isEmpty = true;
for (var p in cur) {
isEmpty = false;
recurse(cur[p], prop ? prop + "." + p : p);
}
if (isEmpty && prop) {
let matchedKey = getMatchedKey(requiredKey, prop);
matchedKey != undefined && (result[matchedKey] = {});
}
}
}
recurse(data, "");
return result;
}
let keys = ['age', 'work', 'main', 'description', 'type', 'date'];
let output = response.users.map(a => getLimitedData(a, keys));
console.log(output);
you can do like this two by saperating objectFunction and ArrayFunction recursively
let keys = ['age', 'work', 'main', 'description', 'type', 'date'];
let response = {
users: [
{
user_id: 1661871600,
details: {
height: 150,
age: 33,
work: 1015,
school: 10,
degree: 933
},
work: [
{
id: 500,
main: 'Doctor',
description: 'Ofto',
icon: '10d',
},
],
look: {
all: 100,
},
transport: {
speed: 0.62,
max_speed: 349,
},
visibility: 10000,
hair: {
type: 0.26,
},
date: '2022-08-30 15:00:00',
},
{
user_id: 324235256,
details: {
height: 110,
age: 25,
work: 101,
school: 110,
degree: 553
},
work: [
{
id: 500,
main: 'Software',
description: 'Programmer',
icon: '11d',
},
],
look: {
all: 2,
},
transport: {
speed: 1.2,
max_speed: 49,
},
visibility: 221,
hair: {
type: 5.6,
},
date: '2021-01-30 12:00:00',
},
{
user_id: 12353743,
details: {
height: 10,
age: 75,
work: 1,
school: 114,
degree: 3
},
work: [
{
id: 500,
main: 'Pension',
description: 'Architect',
icon: '1d',
},
],
look: {
all: 6,
},
transport: {
speed: 3.2,
max_speed: 29,
},
visibility: 21,
hair: {
type: 1.6,
},
date: '2020-01-30 12:00:00',
},
],
};
// main function
const fun =(ob, k , con)=>{
// recursive object function
const objectFun =(arr)=>{
for(y in arr){
if(typeof arr[y] === "object"){
objectFun(arr[y])
}else if(Array.isArray(arr[y])){
arrayFun(arr[y])
}else if(k.includes(y)){
temp[y] = arr[y]
}}}
// recursive array function
const arrayFun =(xx) =>{
const usersList = ob[xx].map((ar, i)=>{
objectFun(ar)
con.push(temp)
temp ={}
})}
// main access key for in loop
for(x in ob){
var temp = {}
arrayFun(x)
}
return con
}
console.log(fun(response , keys , []))
.as-console-wrapper { min-height: 100%!important; top: 0; }
in given data every ingredient have its substitute option while I can
select any substitute option for example if I want to change masala
with its substitute output will change the position of substitute with
it's option and output should be given below
i want to replace masala with normal masala
i have to create a function who replace ingredient with it's substitute and interchange the position of both *
input
const oData = [
{ CurryName: 'Chiken', id: 0 },
{
ingredients: [
{
id: 1,
name: 'onion',
property: { color: 'yellow', Quantity: 'half KG', price: 120 },
subOption: [
{
id: 11,
name: 'redOnion',
property: { color: 'red', Quantity: '1 KG', price: 120 },
},
{
id: 12,
name: 'whiteOnion',
property: { color: 'white', Quantity: '2 KG', price: 120 },
},
],
},
{
id: 2,
name: 'oil',
property: { color: 'green', Quantity: 'half LT', price: 120 },
subOption: [
{
id: 21,
name: 'yellowOil',
property: { color: 'yellow', Quantity: '1 LT', price: 120 },
},
{
id: 22,
name: 'olivoOil',
property: { color: 'golden', Quantity: '2 LT', price: 120 },
},
{
id: 22,
name: 'CastrolOil',
property: { color: 'silk', Quantity: '2 LT', price: 170 },
},
],
},
{
id: 3,
name: 'masala',
property: { color: 'gray', Quantity: '1Tspoon', price: 30 },
subOption: [
{
id: 31,
name: 'garamMasala',
property: { color: 'Garam', Quantity: '2Tspoon', price: 30 },
},
{
id: 32,
name: 'chikenMasala',
property: { color: 'green', Quantity: ' 3Tspoon', price: 30 },
},
{
id: 33,
name: 'normalMasala',
property: { color: 'red', Quantity: '5Tspoon', price: 30 },
},
],
},
],
},
];
// in given data every ingredient have it's substitute option while i can select any supstitute option for example if i want to change masala with its substitute output will change the position of substitue with it's option and output should be given below
//i want to replace masala with normal masala
const output = [
{ CurryName: 'Chiken', id: 0 },
{
ingredients: [
{
id: 1,
name: 'onion',
property: { color: 'yellow', Quantity: 'half KG', price: 120 },
subOption: [
{
id: 11,
name: 'redOnion',
property: { color: 'red', Quantity: '1 KG', price: 120 },
},
{
id: 12,
name: 'whiteOnion',
property: { color: 'white', Quantity: '2 KG', price: 120 },
},
],
},
{
id: 2,
name: 'oil',
property: { color: 'green', Quantity: 'half LT', price: 120 },
subOption: [
{
id: 21,
name: 'yellowOil',
property: { color: 'yellow', Quantity: '1 LT', price: 120 },
},
{
id: 22,
name: 'olivoOil',
property: { color: 'golden', Quantity: '2 LT', price: 120 },
},
{
id: 22,
name: 'CastrolOil',
property: { color: 'silk', Quantity: '2 LT', price: 170 },
},
],
},
{
id: 33,
name: 'normalMasala',
property: { color: 'red', Quantity: '5Tspoon', price: 30 },
subOption: [
{
id: 31,
name: 'garamMasala',
property: { color: 'Garam', Quantity: '2Tspoon', price: 30 },
},
{
id: 32,
name: 'chikenMasala',
property: { color: 'green', Quantity: ' 3Tspoon', price: 30 },
},
{
id: 3,
name: 'masala',
property: { color: 'gray', Quantity: '1Tspoon', price: 30 },
}
],
},
],
},
];
console.log(output)
I suggest that define an element before 'subOption' like 'selectedOption' so you can change it more easily between them
{
selectedOption:{id: 33,
name: 'normalMasala',
property: { color: 'red', Quantity: '5Tspoon', price: 30 }},
subOption: [
{
id: 31,
name: 'garamMasala',
property: { color: 'Garam', Quantity: '2Tspoon', price: 30 },
},
{
id: 32,
name: 'chikenMasala',
property: { color: 'green', Quantity: ' 3Tspoon', price: 30 },
},
{
id: 3,
name: 'masala',
property: { color: 'gray', Quantity: '1Tspoon', price: 30 },
}
],
}
if you able to add 'selectedOption' you can use this code
let temp = oData[1].ingredients[3].subOption[3]
oData[1].ingredients[3].subOption[3].splice(3,1,oData[1].ingredients[3].selectedOption)
oData[1].ingredients[3].selectedOption=temp;
This solution may not be ideal because it changes the original data. But if you don't mind changing the original data, use this.
function swapIngredientMainSub(data, mainID, subID) {
const { ingredients } = data[1];
const targetIndex = ingredients.findIndex(({ id }) => id === mainID);
const { subOption, ...main } = ingredients[targetIndex];
const subIndex = subOption.findIndex(({ id }) => id === subID);
const sub = subOption[subIndex];
subOption[subIndex] = main;
ingredients[targetIndex] = { ...sub, subOption };
}
swapIngredientMainSub(oData, 3, 33);
console.log(JSON.stringify(oData) === JSON.stringify(output)); // true
Option 2:
function swapIngredientMainSub(data, subID) {
const { ingredients } = data[1];
const targetIndex = ingredients.findIndex(({ subOption }) =>
subOption.find(({ id }) => id === subID)
);
const { subOption, ...main } = ingredients[targetIndex];
const subIndex = subOption.findIndex(({ id }) => id === subID);
const sub = subOption[subIndex];
subOption[subIndex] = main;
ingredients[targetIndex] = { ...sub, subOption };
}
swapIngredientMainSub(oData, 33);
console.log(JSON.stringify(oData) === JSON.stringify(output)); // true
I don't know about d3 library that you have included in the tags, but you can use something like this:
const oData = [{
CurryName: 'Chiken',
id: 0
},
{
ingredients: [{
id: 1,
name: 'onion',
property: {
color: 'yellow',
Quantity: 'half KG',
price: 120
},
subOption: [{
id: 11,
name: 'redOnion',
property: {
color: 'red',
Quantity: '1 KG',
price: 120
},
},
{
id: 12,
name: 'whiteOnion',
property: {
color: 'white',
Quantity: '2 KG',
price: 120
},
},
],
},
{
id: 2,
name: 'oil',
property: {
color: 'green',
Quantity: 'half LT',
price: 120
},
subOption: [{
id: 21,
name: 'yellowOil',
property: {
color: 'yellow',
Quantity: '1 LT',
price: 120
},
},
{
id: 22,
name: 'olivoOil',
property: {
color: 'golden',
Quantity: '2 LT',
price: 120
},
},
{
id: 22,
name: 'CastrolOil',
property: {
color: 'silk',
Quantity: '2 LT',
price: 170
},
},
],
},
{
id: 3,
name: 'masala',
property: {
color: 'gray',
Quantity: '1Tspoon',
price: 30
},
subOption: [{
id: 31,
name: 'garamMasala',
property: {
color: 'Garam',
Quantity: '2Tspoon',
price: 30
},
},
{
id: 32,
name: 'chikenMasala',
property: {
color: 'green',
Quantity: ' 3Tspoon',
price: 30
},
},
{
id: 33,
name: 'normalMasala',
property: {
color: 'red',
Quantity: '5Tspoon',
price: 30
},
},
],
},
],
},
];
const selectIngredients = (obj, mainName, subName) => {
obj[1].ingredients.map(ingredient => {
if (ingredient.name === mainName) {
const optionIndex = ingredient.subOption.findIndex(element => element.name === subName);
if (optionIndex !== undefined) {
const {
id,
name,
property
} = ingredient;
ingredient.id = ingredient.subOption[optionIndex].id;
ingredient.name = ingredient.subOption[optionIndex].name;
ingredient.property = ingredient.subOption[optionIndex].property;
ingredient.subOption[optionIndex].id = id;
ingredient.subOption[optionIndex].name = name;
ingredient.subOption[optionIndex].property = property;
}
}
});
return obj;
};
console.log(selectIngredients(oData, "masala", "normalMasala"));
Good Day Developers!
I'm facing issue in JSON object received from MVC controller to AJAX success request.
The response which received is below.
[
{"name":"ERP Developer","value":2},
{"name":"Software Engineer","value":2},
{"name":"Dot Net Developer","value":2},
{"name":"Apex Developer","value":0},
{"name":"test","value":1}
]
But i want to make it like below.
{
"name": [
"ERP Developer",
"Software Engineer"
],
"Value": [
5,
10
]
}
Problem: Because i'm creating Bar chart using ECHARTS library but i want series name instead of number please see below image for reference.
function loadBarChart(data,title = "JobData",subtext = "Artistic Milliners") {
//var BarDBData = data;
var BarDBData = data;
//var BarDBData = JSON.parse('{"name":["ERP Developer","TEST"],"test":[5,10]}');
console.log(BarDBData);
var chartDom = document.getElementById('BarChart');
var myChart = echarts.init(chartDom);
var option;
option = {
title: {
text: title,
subtext: subtext
},
tooltip: {
trigger: 'axis'
},
toolbox: {
show: true,
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: 'category',
// prettier-ignore
//data: ["ERP Developer", "Software Engineer"],
data: BarDBData,
axisLabel: { interval: 0, rotate: 30 }
}
],
yAxis: [
{
type: 'value'
}
],
dataZoom: [
{
show: true,
start: 04,
end: 100
},
{
type: 'inside',
start: 44,
end: 100
},
{
show: true,
yAxisIndex: 0,
filterMode: 'empty',
width: 30,
height: '80%',
showDataShadow: false,
left: '93%'
}
],
series: [
{
name: "test",
type: 'bar',
data: BarDBData,
//data: [2.0, 4.9, 4, 9, 4],
itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#83bff6' },
{ offset: 0.5, color: '#188df0' },
{ offset: 1, color: '#188df0' }
])
},
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' }
]
}
}
]
};
option && myChart.setOption(option);
}
you can just map through array and extract values into another array
const result = {}
const arr = [{"name":"ERP Developer","value":2},{"name":"Software Engineer","value":2},{"name":"Dot Net Developer","value":2},{"name":"Apex Developer","value":0},{"name":"test","value":1}]
arr.forEach(row => {
for (let i in row) {
if (result[i]) {
result[i].push(row[i])
} else {
result[i] = [row[i]]
}
}
})
console.log(result)
Just reduce() it into the desired shape:
const response = [
{"name":"ERP Developer","value":2},
{"name":"Software Engineer","value":2},
{"name":"Dot Net Developer","value":2},
{"name":"Apex Developer","value":0},
{"name":"test","value":1}
];
const mapped = response.reduce(
(acc,x) => {
acc.name.push( x.name );
acc.Value.push( x.value );
return acc;
},
{ name: [], Value: [] }
);
var array= [{ name: "LTNS", id: 1, percentage: 60, price: 900000 },
{ name: "NPCS", id: 2, percentage: 30, price: 342000 },
{ name: "MARCOS", id: 3, percentage: 10, price: 600000 }]
Using above array i need build stacked bar chart in angular-highchart and result should be like below.
I am using angular-highchart 7.2.0 version.
I have seen lots reference but nothing is same as above.
I think that you can start from this approach:
var array = [{
name: "LTNS",
id: 1,
percentage: 60,
price: 900000
},
{
name: "NPCS",
id: 2,
percentage: 30,
price: 342000
},
{
name: "MARCOS",
id: 3,
percentage: 10,
price: 600000
}
].reverse();
array.forEach(obj => {
obj.data = [obj.percentage]
})
Highcharts.chart('container', {
chart: {
type: 'bar'
},
plotOptions: {
bar: {
stacking: 'normal',
groupPadding: 0.2
}
},
series: array
});
Demo: https://jsfiddle.net/BlackLabel/d9xrgeka/
If you will face an issue implementing other features, please ask a specific question.
I want to create a tree map using Highcharts that has 4 levels. Building a tree map with 3 levels works fine. This is the fiddle: https://jsfiddle.net/khsemucx/2/ and the snipped:
var data = {
"Species1": {
"Organ1": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ2": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ3": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ4": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
},
"Species2": {
"Organ1": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ2": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ3": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
},
"Species3": {
"Organ1": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
"Organ2": {
"Tissue1": 3,
"Tissue2": 3,
"Tissue3": 3,
},
},
}
var points = [],
speciesP,
speciesVal,
speciesI = 0,
sampleP,
sampleI,
causeP,
causeI,
species,
sample,
cause
for (species in data) {
if (data.hasOwnProperty(species)) {
speciesVal = 0;
speciesP = {
id: 'id_' + speciesI,
name: species,
color: Highcharts.getOptions().colors[speciesI]
};
sampleI = 0;
for (sample in data[species]) {
if (data[species].hasOwnProperty(sample)) {
sampleP = {
id: speciesP.id + '_' + sampleI,
name: sample,
parent: speciesP.id
};
points.push(sampleP);
causeI = 0;
for (cause in data[species][sample]) {
if (data[species][sample].hasOwnProperty(cause)) {
causeP = {
id: sampleP.id + '_' + causeI,
name: cause,
parent: sampleP.id,
value: Math.round(+data[species][sample][cause])
};
speciesVal += causeP.value;
points.push(causeP);
causeI = causeI + 1;
}
}
sampleI = sampleI + 1;
}
}
speciesP.value = Math.round(speciesVal);
points.push(speciesP);
speciesI = speciesI + 1;
}
}
Highcharts.chart('container', {
exporting: {
sourceWidth: 600,
sourceHeight: 480,
// scale: 2 (default)
chartOptions: {
subtitle: null
},
fallbackToExportServer: false,
buttons: { // specific options for the export button
contextButton: {
menuItems: ['downloadPNG', 'downloadJPEG', 'downloadSVG'],
},
},
},
tooltip: {
formatter: function () {
//console.log(this)
var value = this.point.value;
if (value > 1) {
return value + (' samples');
} else {
return false;
}
},
style: {
fontWeight: 'bold'
},
shared: false,
animation: false,
hideDelay: 200,
delayForDisplay: 200,
useHTML: true
},
series: [{
type: 'treemap',
layoutAlgorithm: 'stripes',
layoutStartingDirection: 'vertical',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
layoutAlgorithm: 'squarified',
layoutStartingDirection: 'vertical',
level: 1,
dataLabels: {
enabled: true,
format: '{point.name}',
style: {
fontSize: '14px',
}
},
borderWidth: 3
},
{
level: 2,
layoutAlgorithm: 'squarified',
layoutStartingDirection: 'horizontal',
},
{
level: 3,
layoutAlgorithm: 'squarified',
layoutStartingDirection: 'horizontal',
},
{
level: 4,
layoutAlgorithm: 'squarified',
layoutStartingDirection: 'horizontal',
}],
data: points,
}],
subtitle: {
text: 'Click points to drill down.'
},
title: {
text: 'Treemap with 3 levels'
},
chart: {
animation: {
duration: 350
}
},
credits: {
enabled: false
},
});
#container {
min-width: 300px;
max-width: 600px;
margin: 0 auto;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/data.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<script src="https://code.highcharts.com/modules/treemap.js"></script>
<div id="container"></div>
Now I want to add another level to this tree map, which does not work: https://jsfiddle.net/36fwztsq/2/
There is no error shown in the browser console, but I can trace back the error to this piece of code:
for (species in data) {
if (data.hasOwnProperty(species)) {
speciesVal = 0;
speciesP = {
id: 'id_' + speciesI,
name: species,
color: Highcharts.getOptions().colors[speciesI]
};
sampleI = 0;
for (sample in data[species]) {
if (data[species].hasOwnProperty(sample)) {
sampleP = {
id: speciesP.id + '_' + sampleI,
name: sample,
parent: speciesP.id
};
points.push(sampleP);
causeI = 0;
for (cause in data[species][sample]) {
if (data[species][sample].hasOwnProperty(cause)) {
causeP = {
id: sampleP.id + '_' + causeI,
name: cause,
parent: sampleP.id,
value: Math.round(+data[species][sample][cause])
};
speciesVal += causeP.value;
points.push(causeP);
# Something may be wrong here --->
replI = 0;
for (repl in data[species][sample][cause]) {
if (data[species][sample][cause].hasOwnProperty(repl)) {
replP = {
id: causeP.id + '_' + replI,
name: repl,
parent: causeP.id,
value: Math.round(+data[species][sample][cause][repl])
};
speciesVal += replP.value;
points.push(replP);
replI = replI + 1;
}
}
# <---
causeI = causeI + 1;
}
}
sampleI = sampleI + 1;
}
}
speciesP.value = Math.round(speciesVal);
points.push(speciesP);
speciesI = speciesI + 1;
}
}
Any idea what could be wrong?
There is a problem with a piece of code that prepares points array.
The result of this line will be NaN -> value: Math.round(+data[species][sample][cause][]). Just remove it:
causeP = {
id: sampleP.id + '_' + causeI,
name: cause,
parent: sampleP.id,
// value: Math.round(+data[species][sample][cause][]) - remove it
};
// speciesVal += causeP.value; - remove it
points.push(causeP);
replI = 0;
Demo:
https://jsfiddle.net/BlackLabel/mb9ogyaw/