Related
Given the cytoscape.js snippet below, using the dagre layout, can anyone explain why node number 2 positions itself to the bottom right instead of in order like the rest of them?
var cy = cytoscape({
container: document.getElementById('cy'),
elements: [{
data: {
id: 1477,
label: "Heading",
},
},
{
data: {
id: 1483,
label: "Number 2",
parent: 1479,
},
},
{
data: {
id: 1479,
label: "Group",
},
},
{
data: {
id: 1478,
label: "Number 0",
parent: 1479,
},
},
{
data: {
id: 1480,
source: 1477,
target: 1478,
minLen: 1,
},
},
{
data: {
id: 1484,
source: 1481,
target: 1483,
minLen: 1,
},
},
{
data: {
id: 1481,
label: "Number 1",
parent: 1479,
},
},
{
data: {
id: 1482,
source: 1478,
target: 1481,
minLen: 1,
},
},
{
data: {
id: 1487,
label: "Number 4",
parent: 1479,
},
},
{
data: {
id: 1485,
label: "Number 3",
parent: 1479,
},
},
{
data: {
id: 1486,
source: 1483,
target: 1485,
minLen: 1,
},
},
{
data: {
id: 1488,
source: 1485,
target: 1487,
minLen: 1,
},
},
{
data: {
id: 1490,
source: 1487,
target: 1489,
minLen: 1,
},
},
{
data: {
id: 1489,
label: "Number 5",
parent: 1479,
},
},
{
data: {
id: 1491,
label: "Final",
},
},
{
data: {
id: 1492,
source: 1489,
target: 1491,
minLen: 1,
},
},
],
layout: {
name: 'dagre',
'nodeSep': 25,
'rankSep': 10,
},
style: [{
selector: 'node',
style: {
label: 'data(label)',
'text-valign': 'center',
'text-halign': 'right',
'text-margin-x': '-155',
'text-wrap': 'wrap',
'text-max-width': 150,
'width': 180,
'background-fit': 'contain',
'shape': 'roundrectangle',
'background-opacity': 0,
'background-position-x': 0,
'height': 24,
'border-width': 1,
'padding-right': 5,
'padding-left': 5,
'padding-top': 5,
'padding-bottom': 5,
'text-events': 'yes',
'font-size': 12,
}
},
{
selector: 'edge',
style: {
'width': 1,
'curve-style': 'bezier',
'line-color': 'black',
'line-style': 'solid',
'target-arrow-shape': 'triangle-backcurve',
'target-arrow-color': 'black',
'text-rotation': 'autorotate',
'label': 'data(label)',
}
},
{
selector: '$node > node',
style: {
'text-rotation': '-90deg',
'text-halign': 'left',
'text-margin-x': -10,
'text-margin-y': -40,
}
},
{
selector: '.Badge',
style: {
'border-width': 3,
}
},
],
minZoom: 0.5,
maxZoom: 1.5,
zoomingEnabled: true,
userZoomingEnabled: false,
autoungrabify: false,
autounselectify: true,
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.5/cytoscape.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre#2.2.2/cytoscape-dagre.min.js"></script>
<div id="cy"></div>
With a little re-arragement, you can easily get this to work. Generally, it is better to group the elements by nodes and edges, also in a ascending order. This improves readability and, in this case, prevents inconsistent layouts.
I think that the issue here stemms from the edges being added to the graph before the corresponding node (node Number 2) is present.
Here is the working code:
var cy = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: [{
data: {
id: 1477,
label: "Heading",
},
},
{
data: {
id: 1479,
label: "Group",
},
},
{
data: {
id: 1478,
label: "Number 0",
parent: 1479,
},
},
{
data: {
id: 1481,
label: "Number 1",
parent: 1479,
},
},
{
data: {
id: 1483,
label: "Number 2",
parent: 1479,
},
},
{
data: {
id: 1485,
label: "Number 3",
parent: 1479,
},
},
{
data: {
id: 1487,
label: "Number 4",
parent: 1479,
},
},
{
data: {
id: 1489,
label: "Number 5",
parent: 1479,
},
},
{
data: {
id: 1491,
label: "Final",
},
},
],
edges: [{
data: {
id: 1480,
source: 1477,
target: 1478,
minLen: 1,
},
},
{
data: {
id: 1482,
source: 1478,
target: 1481,
minLen: 1,
},
},
{
data: {
id: 1484,
source: 1481,
target: 1483,
minLen: 1,
},
},
{
data: {
id: 1486,
source: 1483,
target: 1485,
minLen: 1,
},
},
{
data: {
id: 1488,
source: 1485,
target: 1487,
minLen: 1,
},
},
{
data: {
id: 1490,
source: 1487,
target: 1489,
minLen: 1,
},
},
{
data: {
id: 1492,
source: 1489,
target: 1491,
minLen: 1,
},
}
]
},
layout: {
name: 'dagre',
'nodeSep': 25,
'rankSep': 10,
},
style: [{
selector: 'node',
style: {
label: 'data(label)',
'text-valign': 'center',
'text-halign': 'right',
'text-margin-x': '-155',
'text-wrap': 'wrap',
'text-max-width': 150,
'width': 180,
'background-fit': 'contain',
'shape': 'roundrectangle',
'background-opacity': 0,
'background-position-x': 0,
'height': 24,
'border-width': 1,
'padding-right': 5,
'padding-left': 5,
'padding-top': 5,
'padding-bottom': 5,
'text-events': 'yes',
'font-size': 12,
}
},
{
selector: 'edge',
style: {
'width': 1,
'curve-style': 'bezier',
'line-color': 'black',
'line-style': 'solid',
'target-arrow-shape': 'triangle-backcurve',
'target-arrow-color': 'black',
'text-rotation': 'autorotate',
'label': 'data(label)',
}
},
{
selector: '$node > node',
style: {
'text-rotation': '-90deg',
'text-halign': 'left',
'text-margin-x': -10,
'text-margin-y': -40,
}
},
{
selector: '.Badge',
style: {
'border-width': 3,
}
},
],
minZoom: 0.5,
maxZoom: 1.5,
zoomingEnabled: true,
userZoomingEnabled: false,
autoungrabify: false,
autounselectify: true,
});
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.5/cytoscape.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dagre/0.8.5/dagre.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-dagre#2.2.2/cytoscape-dagre.min.js"></script>
<div id="cy"></div>
I have an array of objects that need to be filtered through, and displayed depending on which checkbox is selected. I can get it to work with a one dimension array, when I nest deeper I don't understand how to get everything working again.
This is the initial function that filters the array:
computed: {
selectedFilters: function() {
let filters = [];
let checkedFilters = this.shopFilters.filter(obj => obj.checked);
checkedFilters.forEach(element => {
filters.push(element.value);
});
return filters;
}
}
Tis is the data it pulls from:
shopFilters: [
{
name: 'price',
categories: [
{
checked: false,
value: 'Under $50'
},
{
checked: false,
value: '$50 to $100'
},
{
checked: false,
value: '$100 to $150'
},
{
checked: false,
value: '$150 to $200'
},
{
checked: false,
value: 'Over $200'
},
]
},
{
name: 'sports',
categories: [
{
checked: false,
value: 'lifestyle'
},
{
checked: false,
value: 'running'
},
{
checked: false,
value: 'basketball'
},
{
checked: false,
value: 'football'
},
{
checked: false,
value: 'soccer'
},
{
checked: false,
value: 'training & gym'
},
{
checked: false,
value: 'skateboarding'
},
{
checked: false,
value: 'baseball / softball'
},
{
checked: false,
value: 'golf'
}
]
}
]
This is the function that filters through the product data in another file to display on the page:
methods: {
getfilteredData: function() {
this.filteredData = data;
let filteredDataByfilters = [];
// first check if filters where selected
if (this.selectedFilters.length > 0) {
filteredDataByfilters= this.filteredData.filter(obj => this.selectedFilters.every(val => obj.indexOf(val) >= 0));
this.filteredData = filteredDataByfilters;
}
}
}
What the data looks like:
const data = [
{
name: 'SNKR 001',
gender: 'Men',
price: 100,
sport: 'running',
width: 'Wide',
colors: ['black', 'white', 'green', 'pink'],
sizes: [3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 14, 15],
image: '../assets/images/shoe-1.png'
},
{
name: 'SNKR 002',
gender: 'Men',
price: 100,
sport: 'running',
width: 'Wide',
colors: ['black', 'white', 'green', 'pink'],
sizes: [3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 14, 15],
image: '../assets/images/shoe-1.png'
},
{
name: 'SNKR 003',
gender: 'Men',
price: 100,
sport: 'training & gym',
width: 'Wide',
colors: ['black', 'white', 'green', 'pink'],
sizes: [3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 14, 15],
image: '../assets/images/shoe-1.png'
},
{
name: 'SNKR 004',
gender: 'Men',
price: 100,
sport: 'lifestyle',
width: 'Wide',
colors: ['black', 'white', 'green', 'pink'],
sizes: [3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7, 7.5, 8, 8.5, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 14, 15],
image: '../assets/images/shoe-1.png'
}
];
export default data;
You can merge all filter into 1 array:
const categories = this.shopFilters.map(item => item.categories)
const flatFilters = [].concat.apply([], categories)
then the filter will become flat:
flatFilters: [{
checked: false,
value: 'Under $50'
},
{
checked: false,
value: '$50 to $100'
},
{
checked: false,
value: '$100 to $150'
},
{
checked: false,
value: '$150 to $200'
},
{
checked: false,
value: 'Over $200'
},
{
checked: false,
value: 'lifestyle'
},
{
checked: false,
value: 'running'
},
{
checked: false,
value: 'basketball'
},
{
checked: false,
value: 'football'
},
{
checked: false,
value: 'soccer'
},
{
checked: false,
value: 'training & gym'
},
{
checked: false,
value: 'skateboarding'
},
{
checked: false,
value: 'baseball / softball'
},
{
checked: false,
value: 'golf'
}
]
then use can apply old logic
computed: {
selectedFilters: function() {
let filters = [];
const categories = this.shopFilters.map(item => item.categories)
const flatFilters = [].concat.apply([], categories)
let checkedFilters = flatFilters.filter(obj => obj.checked);
checkedFilters.forEach(element => {
filters.push(element.value);
});
return filters;
}
I want to create a node in the jstree grid, when clicking create i want to popup a jquery dialog box in which i want to enter the node name and save it. How to implement jquery dialog popup with create click event?
any contribution or suggestions are welcome
// tree data
var data;
data = [{
text: "Products",
data: {},
children: [{
text: "Fruit",
data: {},
children:[
{text: "Apple", data: {price: 0.1, quantity: 20}},
{text: "Banana", data: {price: 0.2, quantity: 31}},
{text: "Grapes", data: {price: 1.99, quantity: 34}},
{text: "Mango", data: {price: 0.5, quantity: 8}},
{text: "Melon", data: {price: 0.8, quantity: 4}},
{text: "Pear", data: {price: 0.1, quantity: 30}},
{text: "Strawberry", data: {price: 0.15, quantity: 32}}
],
'state': {'opened': true}
}, {
text: "Vegetables",
data: {},
children:[
{text: "Aubergine", data: {price: 0.5, quantity: 8}},
{text: "Broccoli", data: {price: 0.4, quantity: 22}},
{text: "Carrot", data: {price: 0.1, quantity: 32}},
{text: "Cauliflower", data: {price: 0.45, quantity: 18}},
{text: "Potato", data: {price: 0.2, quantity: 38}}
]
}],
'state': {'opened': true}
}];
// load jstree
$("div#jstree").jstree({
plugins: ["table","dnd","contextmenu","sort"],
core: {
data: data,
'check_callback': true
},
// configure tree table
table: {
columns: [
{width: 200, header: "Name"},
{width: 150, value: "price", header: "Price", format: function(v) {if (v){ return '$'+v.toFixed(2) }}},
{width: 150, value: "quantity", header: "Qty"}
],
resizable: true,
draggable: true,
contextmenu: true,
width: 500,
height: 300
}
});
JS Fiddle sample
The function create object will do the job, once one node is selected on the tree, we will have the parent
function create_node(name, display, type) {
var ref = $("#data").jstree(),
sel = ref.get_selected(),
parent = $("#data").jstree('get_selected');
if (!sel.length) {
return false;
}
sel = sel[0];
var newNode = {
text: name,
state: "open",
type: type
};
sel = ref.create_node(parent, newNode);
if (sel) {
ref.edit(sel);
}
};
Button on dialog:
<button onclick="create_node(document.getElementById('name').value, document.getElementById('name').value, document.getElementById('type').value)"></button>
I would like to create an external button named 'Export to PDF' outside the highcharts and hide the default buttons "Export" & "Print" in highchart export options.
I am using localhost for my project and have to export the highcharts to PDF offline. I have created an example at jsfiddle below.
jsfiddle
$(function () {
window.chart = new Highcharts.Chart('container', {
chart: {marginLeft: 400},
title: {
text: 'Report',
x: 50,
y: 130,
margin: 150
}, plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter: function() {
var val = this.y;
if (val < 1) {
return '';
}
return val;
},
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
}, exporting:{
enabled: false,
}, xAxis: {
categories: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30']
},
labels: {
items: [{
//html: 'Total fruit consumption',
style: {
left: '50px',
top: '18px',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
}]
},
series: [{
type: 'column',
name: 'Jane',
data: [3, 2, 1, 3, 4, 3, 2, 1, 3, 4, 3, 2, 1, 3, 4, 3, 2, 1, 3, 4, 3, 2, 1, 3, 4, 3, 2, 1, 3, 4]
}, {
type: 'column',
name: 'John',
data: [2, 3, 5, 7, 6, 2, 3, 5, 7, 6, 2, 3, 5, 7, 6, 2, 3, 5, 7, 6, 2, 3, 5, 7, 6, 2, 3, 5, 7, 6],
center: [0, 100],
}, {
type: 'pie',
name: 'Total Visit',
data: [{
name: 'Jane',
y: 13,
color: Highcharts.getOptions().colors[0] // Jane's color
}, {
name: 'John',
y: 23,
color: Highcharts.getOptions().colors[1] // John's color
}],
center: [-250, 250],
size: 150,
showInLegend: false,
dataLabels: {
enabled: true
}
}]
}, function (chart) {
chart.renderer.text('Total Visit', 120, 320)
.css({
color: '#4572A7',
fontSize: '16px'
})
.add();
});
$('#export_PDF').click(function () {
chart.exportChart({
type: 'application/pdf',
sourceWidth: 1700,
sourceHeight: 600,
});
});
});
Can I know how to export the highcharts to PDF offline by clicking the external button that I have created?
If you need to have the pdf export to work offline, you need to setup the highcharts render on the server side.
Render charts on the server
Just edit your code for button on click with this,
$('#export_PDF').click(function () {
chart.exportChartLocal({
type: 'application/pdf',
sourceWidth: 1700,
sourceHeight: 600,
});
});
I am creating pie chart with multiple data in one pie chart. In my case (don't know why) I have a problems with each series line height. My code looks that (http://jsfiddle.net/yATYL/):
$('#container2').highcharts({
chart: {
type: 'pie',
center : [50, 50]
},
title: {
text: 'Bla bla bla',
},
series: [
{
name: 'optionzz1',
innerSize: '40%',
startAngle: -120,
data: [
{
name: 'optionzz 1',
y: 25,
color: '#f26522'
},{
name: '',
y: 75,
color: 'white'
}
]
},{
name: 'optionzz2',
innerSize: '60%',
startAngle: -120,
data: [
{
name: 'optionzz 2',
y: 15,
color: '#2babe2'
},{
name: '',
y: 85,
color: 'white'
}
]
},{
name: 'optionz3',
innerSize: '80%',
startAngle: -120,
data: [
{
name: 'optionzz 3',
y: 60,
color: '#bedbf3'
},{
name: '',
y: 40,
color: 'white'
}]
}]
});