Vis js network - align label with one letter in node - javascript

I have to align label with one letter (number) inside node using vis js network. As documentation says, there is font.align property inside node option and by default it's set to center. It looks nice when there are more than one letter in label:
However with one letter it looks like labels are aligned to the left:
Is it a bug or am I doing something wrong? If it's a bug, how can I get around it?
My full code (i'm using react-graph-vis version 1.0.5):
import React from 'react';
import Graph from "react-graph-vis";
import 'vis-network/styles/vis-network.min.css';
const ExecutionPathGraph = ({issueTraces}) => {
const graph = {
nodes: [
{ id: 1, label: "1"},
{ id: 2, label: "2"},
{ id: 3, label: "3"},
{ id: 4, label: "4"},
{ id: 5, label: "5"}
],
edges: [
{ from: 1, to: 2 },
{ from: 1, to: 3 },
{ from: 2, to: 4 },
{ from: 2, to: 5 }
]
};
const options = {
height: '500px',
nodes: {
shape: 'circle',
borderWidth: 0,
color: '#000',
font: {
color: '#fff',
size: 18,
align: 'center'
},
shadow: true,
},
edges: {
color: {
color: '#F98323'
},
width: 1.5
},
layout: {
hierarchical: {
sortMethod: 'directed',
shakeTowards: 'roots',
direction: 'UD'
}
},
interaction: {
dragNodes: false,
dragView: false,
selectable: false,
selectConnectedEdges: false,
hover: false,
hoverConnectedEdges: false,
zoomView: false,
},
physics: false
};
return (
<Graph
graph={graph}
options={options}
/>
);
};
export default ExecutionPathGraph;

I ran into this same issue and have a really dumb solution: add an empty space before and after your number.
nodes: [
{ id: 1, label: " 1 "},
{ id: 2, label: " 2 "},
{ id: 3, label: " 3 "},
{ id: 4, label: " 4 "},
{ id: 5, label: " 5 "}

Related

How to minimize the space between the text and subtext in the Doughnut Chart of ECharts?

I am using ECharts to create a Doughnut chart and I would like to display static text in the center of the chart. However, there is a space between the text and subtext that I am unable to reduce. Can somebody please assist me in resolving this issue? The code is provided below with screenshot.
https://echarts.apache.org/examples/en/editor.html?c=pie-doughnut
option = {
title: {
text: `51`,
subtext: 'INSTANCES',
x: 'center',
y: 'center',
textStyle:{
color: '#111111',
fontFamily: 'Montserrat',
fontWeight: 'bolder',
fontSize: 70,
},
subtextStyle:{
fontSize: 16,
color: '#888888',
}
},
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: ['55%', '70%'],
avoidLabelOverlap: false,
label: {
show: false,
position: 'center'
},
labelLine: {
show: false
},
data: [
{ value: 36, name: 'Standard' },
{ value: 12, name: 'High Memory' },
{ value: 3, name: 'High CPU' },
{ value: 3, name: 'Other' },
]
}
]
};

cytoscape.js and dagre result in one node positioned awkwardly

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>

How to change the nodes location by direction of arrow in VIsJS Network

After googling lot of time I decided visjs will fit for my solution to develop network graph. I was able generate network graph with Dataset by Hierarchical Layout Horizontal. I have a small issue in network i.e i want all edges only in one(forward) direction.
I needed B, C and F nodes in this screenshot of network left side of the triangle:
I tried changing different options but not able achieve it.
is there anybody have used this library for network graph, Please help me.
Thanks in advance.
Refrence Example in documentation.
Here is code sample.
const container = document.getElementById("mynetwork");
const nodes = new vis.DataSet([
{
id: 1,
label: "A",
color: {
background: "rgb(76, 195, 217)",
border: "rgb(255, 198, 93)"
}
},
{
id: 2,
label: "B",
color: {
background: "rgb(147, 100, 14)",
border: "rgb(123, 200, 164)"
}
},
{
id: 3,
label: "C",
color: {
background: "rgb(76, 195, 217)",
border: "rgb(241, 103, 69)"
}
},
{
id: 4,
label: "D",
shape: "triangle",
size: 25,
color: { background: "white", border: "rgb(64, 64, 64)" }
},
{
id: 5,
label: "E",
color: {
background: "rgb(238,238,238)",
border: "rgb(241, 103, 69)"
}
},
{
id: 6,
label: "F",
color: {
background: "rgb(147, 100, 14)",
border: "rgb(123, 200, 164)"
}
},
{
id: 7,
label: "G",
shape: "triangle",
size: 25,
color: { background: "white", border: "rgb(64, 64, 64)" }
},
{
id: 8,
label: "H",
color: { background: "rgb(238,238,238)", border: "rgb(64, 64, 64)" }
}
]);
const edges = new vis.DataSet([
{ from: 1, to: 4, label: "70%" },
{ from: 3, to: 4 },
{ from: 2, to: 4 },
{ from: 4, to: 5 },
{ from: 6, to: 7 },
{ from: 5, to: 7 },
{ from: 7, to: 8, label: "50%" }
]);
const data = {
nodes: nodes,
edges: edges
};
const options = {
nodes: {
font: {
size: 22
},
borderWidth: 3
},
edges: {
font: {
align: "top"
},
smooth: {
type: "dynamic",
forceDirection:
directionInputValue === "UD" || directionInputValue === "DU"
? "vertical"
: "horizontal",
roundness: 0.0
},
arrows: {
to: { enabled: true, scaleFactor: 1, type: "arrow" }
}
},
layout: {
hierarchical: {
direction: directionInputValue
}
},
interaction: {
tooltipDelay: 200,
hover: true
},
physics: {
enabled: false
}
};
const network = new vis.Network(container, data, options);
You need to set the option layout.hierarchical.sortMethod to directed for the correct calculation of levels:
Directed adheres to the to and from data of the edges. A --> B so B is
a level lower than A.
http://visjs.org/docs/network/layout.html
layout: {
hierarchical: {
direction: "LR",
sortMethod: "directed"
}
}
https://jsfiddle.net/whhqka68/

Working with multiple axis with highcharts.js

I’m working with highcharts.js and I have a scatter plot example I found, fiddle here. With this example I can break down the X-axis into two categories which is ideal for my situation. However, I would like to rotate the labels for each ‘Vendor’ variable 90 degrees while keeping the ‘date’ variable horizontal. I can’t figure this out, of even know if it’s possible. I know how to rotate both variables but that doesn’t look good. Is it even possible to achieve this effect with highcharts.js?
var cates = [{
name: "1/1/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}, {
name: "1/2/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}, {
name: "1/3/2014",
categories: ["Vendor 1", "Vendor 2", "Vendor 3"]
}];
console.log("here: ", cates);
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: "container",
type: "scatter",
borderWidth: 5,
borderColor: '#e8eaeb',
borderRadius: 0,
backgroundColor: '#f7f7f7'
},
title: {
text: "title"
},
yAxis: [{ // Primary yAxis
labels: {
format: '${value}',
style: {
color: Highcharts.getOptions().colors[0]
}
},
title: {
text: 'Daily Tickets',
style: {
color: Highcharts.getOptions().colors[0]
}
}
}, { // Secondary yAxis
title: {
text: 'Invoices',
style: {
color: Highcharts.getOptions().colors[0]
}
},
labels: {
format: '${value}',
style: {
color: Highcharts.getOptions().colors[0]
}
},
opposite: true
}]
,
series: [{
name: 'Daily',
type: 'scatter',
yAxis: 1,
data: [4, 14, 18, 5, 6, 5, 14, 15, 18],
tooltip: {
valueSuffix: ' mm'
}
}],
xAxis: {
categories: cates,
/** UNCOMMENT BELOW **/
// labels: {
// rotation:-90,
// style: {
// fontSize:'10px',
// fontWeight:'normal',
// color:'#333'
// },
//}
}
});
});
UPDATE: I figured it out, the labels object should look like this
labels: {
groupedOptions: [{
y: 90,
rotation: 0
}],
rotation:-90,
style: {
fontSize:'10px',
fontWeight:'normal',
color:'#333'
},
}

Highcharts pie donut with gradient

Is there a way using Highcharts, to achieve that kind of gradients?
Here is some jsfiddle boilerplate
var chart = new Highcharts.Chart({
chart: {
renderTo: 'chart',
type: 'pie'
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
title: {
text: null
},
tooltip: {
enabled: false
},
plotOptions: {
pie: {
animation: false,
enableMouseTracking: false,
borderColor: 'transparent',
colors: ['#fdc81c', '#eee'],
borderWidth: 0,
innerSize: '60%',
dataLabels: {
enabled: false
}
}
},
series: [{ data: [80, 20] }]
})
Thanks!
you can use radial gradient for highcharts, but I'm afraid you would not get the filling of color as per the value.
highcharts have provided in their documentation here that radial and linear gradients can be used with highcharts.
Highcharts only have two types of gradients, linear and radial, so you cannot solve your problem using them. That is why I start thinking how to do it and after wasting a lot of time, I decided to implement it by dividing the chart in small slices with different colors.
Then I have a donut/pie chart with 100 little slices and each one has a different color.
Gradient color degraded from 0 to 100%
Gradient color degraded from 0 to 60%
I am developing a react-native application, so I post you the code here:
gradientColors.js
export default ['#41E500','#44E500','#47E500','#4AE500','#4DE600','#50E601','#53E601','#56E601','#59E701','#5CE702','#5FE702','#62E702','#65E802','#68E803','#6BE803','#6EE903','#71E903','#74E904','#77E904','#7AEA04','#7DEA04','#80EA05','#83EA05','#86EB05','#89EB05','#8CEB05','#8FEC06','#92EC06','#95EC06','#98EC06','#9BED07','#9EED07','#A1ED07','#A4ED07','#A7EE08','#AAEE08','#ADEE08','#B0EE08','#B3EF09','#B6EF09','#B9EF09','#BCF009','#BFF00A','#C2F00A','#C5F00A','#C8F10A','#CBF10A','#CEF10B','#D1F10B','#D4F20B','#D7F20B','#DAF20C','#DDF30C','#E0F30C','#E3F30C','#E6F30D','#E9F40D','#ECF40D','#EFF40D','#F2F40E','#F5F50E','#F8F50E','#FBF50E','#FFF60F','#FFF60F','#FFF20E','#FFEF0E','#FFEC0D','#FFE80D','#FFE50C','#FFE20C','#FFDE0C','#FFDB0B','#FFD80B','#FFD50A','#FFD10A','#FFCE0A','#FFCB09','#FFC709','#FFC408','#FFC108','#FFBE07','#FFBA07','#FFB707','#FFB406','#FFB006','#FFAD05','#FFAA05','#FFA705','#FFA705','#FF9805','#FF8906','#FF7B06','#FF6C07','#FF5D07','#FF4F08','#FF4008','#FF3109','#FF230A','#FF230A'];
ProgressChart.js
'use strict';
const Highcharts = 'Highcharts';
import { COLORS } from '#theme';
import gradientColors from './gradientColors';
const fakeData = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
const data = [{
y: 100,
color: COLORS.dark_red,
drilldown: {
name: 'Categories',
categories: ['A', 'B', 'C', 'D', 'E', 'F'],
data: fakeData,
color: COLORS.dark_red
}
}];
const donutData = [];
const donutDataOuter = [];
const dataLen = data.length;
// Build the data arrays
for (let i = 0; i < dataLen; i += 1) {
// add data
const drillDataLen = data[i].drilldown.data.length;
for (let j = 0; j < drillDataLen; j += 1) {
if (j > 60) {
donutData.push({
y: data[i].drilldown.data[j],
color: 'white',
borderColor: 'white'
});
donutDataOuter.push({
y: data[i].drilldown.data[j],
color: 'white',
borderColor: 'white'
});
} else {
donutData.push({
y: data[i].drilldown.data[j],
color: gradientColors[j],
borderColor: gradientColors[j]
});
donutDataOuter.push({
y: data[i].drilldown.data[j],
color: gradientColors[j],
borderColor: gradientColors[j]
});
}
}
}
const donutConf = {
chart: {
type: 'pie',
animation: Highcharts.svg
},
title: {
text: 'Equipment types (%)',
align: 'center',
verticalAlign: 'middle',
floating: true,
style: {
color: COLORS.light_grey_2,
fontWeight: 'bold',
fontSize: 38
}
},
plotOptions: {
pie: {
shadow: false,
center: ['50%', '50%']
},
showCheckbox: true
},
tooltip: {
formatter() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' %';
}
},
legend: {
enabled: true
},
exporting: {
enabled: false
},
series: [
{
name: 'Categories',
data: donutData,
size: '93%',
innerSize: '58%',
dataLabels: {
enabled: false
},
id: 'inner'
},
{
name: 'Categories2',
data: donutDataOuter,
size: '100%',
innerSize: '97%',
dataLabels: {
enabled: false
},
id: 'outer'
}],
};
export default donutConf;
I have developed it very fast. So the example code above is for the 60% chart. In my final version I won't include this dirty if-else clauses I will solve it
Then in your case I recommend you to use this webpage http://www.perbang.dk/rgbgradient/ and use the number of steps that you need. For instance you can simply chose 2 from green to blue as I show you in this image. After copying the hex codes to the gradientColors variable you will be able to solve your problem.

Categories

Resources