I'm using highcharts in vuejs with highcharts-vue but a sankey diagram won't show up at all:
in my main.js I have done all necessary imports
import Highcharts from 'highcharts'
import HighchartsVue from 'highcharts-vue'
import sanKeyInit from 'highcharts/modules/sankey'
sanKeyInit(Highcharts)
import exportingInit from 'highcharts/modules/exporting'
import exportDataInit from 'highcharts/modules/export-data'
import More from 'highcharts/highcharts-more'
exportingInit(Highcharts)
exportDataInit(Highcharts)
import dependencyWheelInit from 'highcharts/modules/dependency-wheel'
dependencyWheelInit(Highcharts)
treemapInit(Highcharts)
More(Highcharts)
in my vue component I can display a treemap but not the sankey diagram
Overview.vue
<template>
<v-container pa-0 ma-0>
<v-layout column>
<v-flex xs12>
<v-container pa-0 ma-0 >
<KeyValue :value="breadCrumb.join('>')" label=""></KeyValue>
</v-container>
</v-flex>
<v-layout row>
<v-flex xs12>
<v-layout row>
<v-flex xs6>
<highcharts :constructor-type="'chart'" :options="treeMap" :callback="initMap" ref="treeMap"></highcharts>
</v-flex>
<v-flex xs6>
<!-- <highcharts :constructor-type="'chart'" :options="arc" :callback="initCircles" ref="circle"></highcharts> -->
<highcharts :constructor-type="'chart'" :options="wheel" :callback="initWheel">
</highcharts>
</v-flex>
</v-layout>
</v-flex>
</v-layout>
</v-layout>
</v-container>
</template>
<script>
import vue from 'vue'
import KeyValue from '#/components/KeyValue'
export default {
name: 'Overview',
components: {
KeyValue
},
data(){
return {
breadCrumb: [this.rootName],
hashTree: {},
charts: {treemap: null, circles: null, wheel: null},
currentGraph: {nodeList: [], linkList: []},
tree: [
{name: 'thesponge', id: '2', value: 12, color: '#aaa'},
{name: 'aa', id: '3', parent: '2', value: 34, color: '#aaa'},
{name: 'ab', id: '4', parent: '2', value: 20, color: '#aaa'},
{name: 'bob ', id: '5', value: 45, color: '#a00'},
{name: 'ba', id: '6', parent: '5', value: 40, color: 'red'},
{name: 'bb', id: '7', parent: '5', value: 56, color: 'red'},
{name: 'bba', id: '8', parent: '5', value: 40, color: 'red'},
{name: 'bbb', id: '9', parent: '5', value: 56, color: 'red'},
{name: 'bba', id: '10', parent: '8', value: 40, color: 'red'},
{name: 'bbb', id: '11', parent: '8', value: 56, color: 'red'},
],
arch: { '2': { nodeList: [{key: 'a', category: 'OfActivity', text: 'hello' },
{key: 'ab', category: 'OfActivity', text: 'goodbye' }],
linkList: [{from: {nodeIdInCurrentGraph: 'a'}, to: {nodeIdInCurrentGraph: 'ab'}},
{from: {nodeIdInCurrentGraph: 'ab'}, to: {nodeIdInCurrentGraph: 'ac'}}
]
},
'': { nodeList: [{key: 'a', category: 'OfActivity', text: 'miles' },
{key: 'ab', category: 'OfActivity', text: 'davis' }],
linkList: [{from: {nodeIdInCurrentGraph: 'a'}, to: {nodeIdInCurrentGraph: 'ab'}},
{from: {nodeIdInCurrentGraph: 'a'}, to: {nodeIdInCurrentGraph: 'ac'}}
]
},
'5': { nodeList: [{key: 'a', category: 'OfActivity', text: 'john' },
{key: 'ab', category: 'OfActivity', text: 'doe' }],
linkList: [{from: {nodeIdInCurrentGraph: 'a'}, to: {nodeIdInCurrentGraph: 'ab'}},
{from: {nodeIdInCurrentGraph: 'a'}, to: {nodeIdInCurrentGraph: 'a'}},
{from: {nodeIdInCurrentGraph: 'ac'}, to: {nodeIdInCurrentGraph: 'ab'}},]
}
}
}
},
computed: {
wheel(){
return {
title: { text: 'Dependencies' },
chart: {
type: 'chart'
},
series: [{
visible: true,
name: 'country deps',
keys: ['from', 'to', 'wheight'],
/* data:[ this.arch[''].linkList.map((l)=>{return {from: l.from.nodeIdInCurrentGraph, to: l.to.nodeIdInCurrentGraph, weight: 1}})
* ],*/
data: [ ['Brazil', 'Portugal', 5],
['Brazil', 'France', 1],
['Brazil', 'Spain', 1],
['Brazil', 'England', 1],
['Canada', 'Portugal', 1],
['Canada', 'France', 5],
['Canada', 'England', 1],
['Mexico', 'Portugal', 1],
['Mexico', 'France', 1],
['Mexico', 'Spain', 5],
['Mexico', 'England', 1],
['USA', 'Portugal', 1],
['USA', 'France', 1],
['USA', 'Spain', 1],
['USA', 'England', 5],
['Portugal', 'Angola', 2],
['Portugal', 'Senegal', 1],
['Portugal', 'Morocco', 1],
['Portugal', 'South Africa', 3],
['France', 'Angola', 1],
['France', 'Senegal', 3]
],
type: 'sankey',
}]
}
},
// ---
treeMap() {
return {
title: { text: 'Navigate' },
chart: {
events: {
load(){
this.__proto__.vue.initTreeSeries()
}
},
},
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 3
}],
events: {
setRootNode(){
this.chart.__proto__.vue.updateCharts(arguments[0])
}
},
data: []
}]
}
},
}
},
props: {
rootName: {type: String, default: 'root'},
width: {type: Number, default: 500},
height: {type: Number, default: 500}
},
methods: {
initWheel(chart){
console.log("init wheel", chart)
chart.__proto__.vue = this
this.charts.wheel = chart
},
initMap(chart){
this.hashTree = this.tree.reduce((mem,n)=>{
n.children = []
if(!n.parent) n.parent = ''
mem[n.id] = n
return mem
},{})
this.tree.forEach((n)=>{
if(n.parent === '') return
if(!this.hashTree[n.parent]) return
this.hashTree[n.parent].children.push(n)
})
chart.__proto__.vue = this
this.charts.treemap = chart
}
}
}
</script>
result of sankey diagram in vuejs
Although the treemap shows properly, the sankey diagram doesn't
I've used the highchart debugger and yet no error.
Please help !!!
thanks
Related
I have an array of objects with dynamic keys and values (so not all objects have category_id, size and so on) but I simplified it to this:
let products_row = [
{
id: 1,
category_id: 11,
options: {
'modelName1': {
size: '2 feet',
colour: 'red',
is_new: true
},
'modelName2': {
size: '4 feet',
colour: 'black',
is_new: true
},
}
},
{
id: 2,
category_id: 21,
options: {
'modelName11': {
size: '2 feet',
colour: 'white',
is_new: false
},
'modelName12': {
size: '4 feet',
colour: 'white',
is_new: false
},
}
},
{
id: 3,
category_id: 31,
options: {
'modelName21': {
size: '8 feet',
colour: 'white',
is_new: false
},
'modelName22': {
size: '4 feet',
colour: 'black',
is_new: true
},
}
},
{
id: 4,
category_id: 41,
options: {
'modelName31': {
size: '8 feet',
colour: 'red',
is_new: true
},
'modelName32': {
size: '8 feet',
colour: 'red',
is_new: true
},
}
}
]
the result data structure needs to be like this:
let resultArray = [
{
id: 1,
category_id: 11,
model: 'modelName1',
size: '2 feet',
colour: 'red',
is_new: true
},
{
id: 1,
category_id: 11,
model: 'modelName2',
size: '4 feet',
colour: 'black',
is_new: true
},
{
id: 2,
category_id: 21,
model: 'modelName11',
size: '2 feet',
colour: 'white',
is_new: false
},
{
id: 2,
category_id: 21,
model: 'modelName12',
size: '4 feet',
colour: 'white',
is_new: false
},
{
id: 3,
category_id: 31,
model: 'modelName21',
size: '8 feet',
colour: 'white',
is_new: false
},
{
id: 3,
category_id: 31,
model: 'modelName22',
size: '4 feet',
colour: 'black',
is_new: true
},
{
id: 4,
category_id: 41,
model: 'modelName31',
size: '8 feet',
colour: 'red',
is_new: true
},
{
id: 4,
category_id: 41,
model: 'modelName32',
size: '8 feet',
colour: 'red',
is_new: true
},
]
This is what I have tried:
let productsData = [];
products_row
.map((product, p) => Object.entries(product.options || {})
.filter((model, i) => {
return productsData.push(
{
model: model[0],
[Object.keys(product).filter(el => delete product.options)[i]]: Object.values(product)[i],
[Object.keys(model[1] || [])[i]]: Object.values(model[1] || [])[i],
}
)
})
)
console.log(productsData)
But it returns not all data, which is expected because I can't figure out how to keep previous key-values:
[
{
model: 'modelName1',
id: 1,
size: '2 feet',
},
{
model: 'modelName2',
category_id: 11,
colour: 'black',
},
{
model: 'modelName11',
id: 2,
size: '2 feet',
},
{
model: 'modelName12',
category_id: 21,
colour: 'white',
},
{
model: 'modelName21',
id: 3,
size: '8 feet',
},
{
model: 'modelName22',
category_id: 31,
colour: 'black',
},
{
model: 'modelName31',
id: 4,
size: '8 feet',
},
{
model: 'modelName32',
category_id: 41,
colour: 'red',
},
]
I am completely stuck, any help is appreciated. Thank you.
you can use flatMap and map
What flatMap does is if the returned array of map looks like
[
[{...1},{...2}],
[{...3},{...4}]
]
it will flatten it and give
[
{...1},{...2},
{...3},{...4}
]
let products_row = [{id: 1,category_id: 11,options: {'modelName1': {size: '2 feet',colour: 'red',is_new: true},'modelName2': {size: '4 feet',colour: 'black',is_new: true},}},{id: 2,category_id: 21,options: {'modelName11': {size: '2 feet',colour: 'white',is_new: false},'modelName12': {size: '4 feet',colour: 'white',is_new: false},}},{id: 3,category_id: 31,options: {'modelName21': {size: '8 feet',colour: 'white',is_new: false},'modelName22': {size: '4 feet',colour: 'black',is_new: true},}},{id: 4,category_id: 41,options: {'modelName31': {size: '8 feet',colour: 'red',is_new: true},'modelName32': {size: '8 feet',colour: 'red',is_new: true},}}]
let x = products_row.flatMap(({options,...rest}) => Object.entries(options).map(([k,v]) => ({...v,...rest,model:k})))
console.log(x)
It is quite hard to analyze your solution and reason about your idea, so I cannot fix your code.
What you want to do is to extract options from each object and attach the rest of object, in other words you want to iterate over each option for each product row.
There are numerous ways to achieve this, you can use flatMap as #cmgchess suggested. Easier to understand is something like this:
let result = [];
products_row.forEach(({ options, ...rest }) =>
Object.values(options).forEach((b) => result.push({ ...rest, ...b })),
);
I am working on a layout in VisJS that involves a lot of nodes. When edges are hovered over, I have text that I want to appear and then hide on leave.
When the nodes are crowded and the edge labels run into it, they are currently displaying so that they are underneath the nodes, instead of above. Is there any way I can set the z-index of the edge label so that they appear on top of the nodes rather than underneath them?
I have read the docs extensively and haven't seen anything that would be likely to change the position in the z index. any hacks or workaround would be welcomed. Thanks!
working JSFiddle
My visjs code:
const root = document.querySelector('#graph');
const nodeData = [
{
type: "A",
name: 'A Node 1',
index: 0,
x: -50,
y: -50
},
{
type: 'A',
name: 'A node 2',
index: 1,
x: -50,
y: 50
},
{
type: 'A',
name: 'A node 3',
index: 2,
x: -150,
y: 50
},
{
type: 'A',
name: 'A Node 4',
index: 3,
x: 50,
y: 50
},
{
type: 'A',
name: 'A Node 5',
index: 4,
x: -50,
y: 150
},
{
type: "B",
name: 'B Node 1',
index: 5
},
{
type: "B",
name: 'B Node 2',
index: 6
},
{
type: 'B',
name: 'B Node ',
index: 7
},
{
type: 'B',
name: 'B Node ',
index: 8
},
{
type: 'B',
name: 'B Node ',
index: 9
},
{
type: 'B',
name: 'B Node ',
index: 10
},
{
type: 'B',
name: 'B Node ',
index: 11
},
{
type: 'B',
name: 'B Node ',
index: 12
}, {
type: 'B',
name: 'B Node ',
index: 13
},
];
const edgeData = [
{from: 0, to: 1},
{from: 1, to: 2},
{from: 1, to: 3},
{from: 1, to: 4},
{from: 2, to: 5},
{from: 3, to: 6},
{from: 4, to: 7},
{from: 4, to: 8},
{from: 4, to: 9},
{from: 4, to: 10},
{from: 4, to: 11},
{from: 4, to: 12},
{from: 4, to: 13},
]
const options = {
physics: {
barnesHut: {
avoidOverlap: 1,
springConstant: 0.3
},
solver: 'hierarchicalRepulsion'
},
layout: {
randomSeed: '0:0'
}
};
const nodes = new vis.DataSet(nodeData.map(d => {
const newNode = {
id: d.index,
label: d.name,
fixed: d.type === 'A'
}
if (typeof d.x === 'number') {
newNode.x = d.x;
}
if (typeof d.y === 'number') {
newNode.y = d.y;
}
if(d.type === 'A') {
newNode.color = 'orange';
newNode.mass = 3;
}
return newNode;
}));
const edges = new vis.DataSet(edgeData.map(e => {
return {...e, smooth: false, label: 'edge from node to node'}
}));
const network = new vis.Network(root, {nodes, edges}, options);
network.on('stabilizationIterationsDone', () => network.setOptions({physics: false}));
This question already has answers here:
sorting object Sunday to Saturday in javascript
(2 answers)
Closed 2 years ago.
I have a array as bellow:
const list = [
{ id: 1, name: 'Product 1', color: 'white'},
{ id: 2, name: 'Product 2', color: 'black'},
{ id: 3, name: 'Product 3', color: 'red'},
{ id: 4, name: 'Product 4', color: 'white'},
{ id: 5, name: 'Product 5', color: 'black'},
]
I want to sort array based on predefined order by color: red -> white -> black and output:
const list = [
{ id: 3, name: 'Product 3', color: 'red'},
{ id: 1, name: 'Product 1', color: 'white'},
{ id: 4, name: 'Product 4', color: 'white'},
{ id: 5, name: 'Product 5', color: 'black'},
{ id: 2, name: 'Product 2', color: 'black'}
]
let colorPriority = ['red', 'white', 'black'];
list = list.sort((obj1, obj2) => colorPriority.indexOf(obj1.color) - colorPriority.indexOf(obj2.color));
this code should work for you.
I have an Array of Objects containing product information where there are categories and colors as fields. Now, I have another array containing which categories and which colors to show.
Main Array:
products: [{
id: 1,
name: 'Product 1',
category: 'Home',
skill: 'Easy',
color: 'blue',
price: 100.00
}, {
id: 2,
name: 'Product 2',
category: 'Home',
skill: 'Intermediate',
color: 'red',
price: 120.00
}, {
id: 3,
name: 'Product 3',
category: 'Office',
skill: 'Intermediate',
color: 'green',
price: 190.00
}, {
id: 4,
name: 'Product 4',
category: 'Office',
skill: 'Advanced',
color: 'blue',
price: 260.00
}, {
id: 5,
name: 'Product 5',
category: 'Warehouse',
skill: 'Advanced',
color: 'white',
price: 321.00
}, {
id: 6,
name: 'Product 6',
category: 'Farm',
skill: 'Intermediate',
color: 'red',
price: 120.00
}, {
id: 7,
name: 'Product 7',
category: 'Space',
skill: 'Advanced',
color: 'green',
price: 150.00
}, {
id: 8,
name: 'Product 8',
category: 'Bathroom',
skill: 'Easy',
color: 'black',
price: 9.00
}],
My another array containing filter options:
selectedFilters: {
categories : ["home", "bathroom"] ,
colors : ["blue", "red"]
}
Now I want my output as:
[{
id: 1,
name: 'Product 1',
category: 'Home',
skill: 'Easy',
color: 'blue',
price: 100.00
}, {
id: 2,
name: 'Product 2',
category: 'Home',
skill: 'Intermediate',
color: 'red',
price: 120.00
}]
I tried the normal array filter method:
this.filteredProducts = this.products.filter(prod => {
// [prod.category, prod.color].some(val => this.selectedFilters.includes(val))
console.log(this.selectedFilters);
for (let i = 0; i < this.selectedFilters.length; i++) {
// console.log('Selected Category : ', this.selectedFilters[i]);
// console.log('Product Category : ', prod.category);
if (prod.category == this.selectedFilters[i]) {
console.log('Called category');
return true;
} else if (prod.color == this.selectedFilters[i]) {
console.log('Called color');
return true;
} else {
console.log('Called else');
continue;
}
}
});
How can I achieve this using array filter functions or Lodash functions?
No need for a library, use the standard .filter method to filter an array, check to see if each object's color and category is included in the selectedFilters object:
const products = [{
id: 1,
name: 'Product 1',
category: 'Home',
skill: 'Easy',
color: 'blue',
price: 100.00
}, {
id: 2,
name: 'Product 2',
category: 'Home',
skill: 'Intermediate',
color: 'red',
price: 120.00
}, {
id: 3,
name: 'Product 3',
category: 'Office',
skill: 'Intermediate',
color: 'green',
price: 190.00
}, {
id: 4,
name: 'Product 4',
category: 'Office',
skill: 'Advanced',
color: 'blue',
price: 260.00
}, {
id: 5,
name: 'Product 5',
category: 'Warehouse',
skill: 'Advanced',
color: 'white',
price: 321.00
}, {
id: 6,
name: 'Product 6',
category: 'Farm',
skill: 'Intermediate',
color: 'red',
price: 120.00
}, {
id: 7,
name: 'Product 7',
category: 'Space',
skill: 'Advanced',
color: 'green',
price: 150.00
}, {
id: 8,
name: 'Product 8',
category: 'Bathroom',
skill: 'Easy',
color: 'black',
price: 9.00
}];
const selectedFilters = {
categories : ["home", "bathroom"] ,
colors : ["blue", "red"]
};
const { categories, colors } = selectedFilters;
const filteredProducts = products.filter(({ category, color }) => (
categories.includes(category.toLowerCase()) && colors.includes(color.toLowerCase())
));
console.log(filteredProducts);
Is there a way to order this highchart chart by total?
https://jsfiddle.net/bsvLnnxv/3/
The final result expected in this case should be:
Name 1 -> 19
Name 4 -> 12
Name 3 -> 10
Name 2 -> 8
Find the code below:
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
type: 'category'
},
yAxis: {
min: 0,
title: {
text: 'Highchart test'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold'
}
}
},
legend: {
enabled: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'AAA',
data: [{
name: 'Name 1',
y: 5,
drilldown: 'Name1AAA'
}, {
name: 'Name 2',
y: 2
}, {
name: 'Name 3',
y: 2
}]
}, {
name: 'BBB',
data: [{
name: 'Name 1',
y: 10,
drilldown: 'Name1BBB'
}, {
name: 'Name 2',
y: 5
}]
}, {
name: 'CCC',
data: [{
name: 'Name 4',
y: 12
}, {
name: 'Name 3',
y: 8
}, {
name: 'Name 1',
y: 4,
drilldown: 'Name1CCC'
}, {
name: 'Name 2',
y: 1
}]
}],
drilldown: {
series: [{
name: 'Name 1 - AAA',
id: 'Name1AAA',
data: [
['Name 1/1', 2],
['Name 1/2', 2],
['Name 1/3', 1],
]
}, {
name: 'Name 1 - BBB',
id: 'Name1BBB',
data: [
['Name 1/1', 7],
['Name 1/2', 2],
['Name 1/3', 1],
]
}, {
name: 'Name 1 - CCC',
id: 'Name1CCC',
data: [
['Name 1/1', 2],
['Name 1/2', 3],
['Name 1/3', 4],
]
}]
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="http://github.highcharts.com/modules/drilldown.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
I found the solution!
Highcharts doesn't have a property to sort the data automatically, so you must fill all series data previously sorted.
Another point of attention: if you don't have a value you will need to set the value as 0 to make sure that all categories have the same quantity of elements.
https://jsfiddle.net/bsvLnnxv/4/
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
type: 'category'
},
yAxis: {
min: 0,
title: {
text: 'Highchart test'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold'
}
}
},
legend: {
enabled: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'AAA',
data: [{
name: 'Name 1',
y: 5,
drilldown: 'Name1AAA'
}, {
name: 'Name 4',
y: 0
}, {
name: 'Name 3',
y: 2
}, {
name: 'Name 2',
y: 2
}]
}, {
name: 'BBB',
data: [{
name: 'Name 1',
y: 10,
drilldown: 'Name1BBB'
}, {
name: 'Name 4',
y: 0
}, {
name: 'Name 3',
y: 0
}, {
name: 'Name 2',
y: 5
}]
}, {
name: 'CCC',
data: [{
name: 'Name 1',
y: 4,
drilldown: 'Name1CCC'
}, {
name: 'Name 4',
y: 12
}, {
name: 'Name 3',
y: 8
}, {
name: 'Name 2',
y: 1
}]
}],
drilldown: {
series: [{
name: 'Name 1 - AAA',
id: 'Name1AAA',
data: [
['Name 1/1', 2],
['Name 1/2', 2],
['Name 1/3', 1],
]
}, {
name: 'Name 1 - BBB',
id: 'Name1BBB',
data: [
['Name 1/1', 7],
['Name 1/2', 2],
['Name 1/3', 1],
]
}, {
name: 'Name 1 - CCC',
id: 'Name1CCC',
data: [
['Name 1/1', 2],
['Name 1/2', 3],
['Name 1/3', 4],
]
}]
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="http://github.highcharts.com/modules/drilldown.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>