How to show label when mouse over bar - javascript

I made a Bar chart by chartist.js.
Now I want to add some listening event on the bars.
How can I do to let label show up when mouse over the bar?

You have 2 options -
Option 1
There is a tooltip plugin that you could use. You can find it here - https://github.com/Globegitter/chartist-plugin-tooltip
Once you add the CSS and JS files, you should be able to call the plugin like this - Chartist.plugins.tooltip()
Here is an example from their Plugins page -
var chart = new Chartist.Line('.ct-chart', {
labels: [1, 2, 3],
series: [
[
{meta: 'description', value: 1 },
{meta: 'description', value: 5},
{meta: 'description', value: 3}
],
[
{meta: 'other description', value: 2},
{meta: 'other description', value: 4},
{meta: 'other description', value: 2}
]
]
}, {
low: 0,
high: 8,
fullWidth: true,
plugins: [
Chartist.plugins.tooltip()
]
});
This will be the easier and the better option.
Option 2
If you want to do something by yourself, you can bind mouseover and mouseout events on draw event's callback -
var data = {
labels: ['W1', 'W2', 'W3', 'W4', 'W5', 'W6', 'W7', 'W8', 'W9', 'W10'],
series: [
[1, 2, 4, 8, 6, -2, -1, -4, -6, -2]
]
};
var options = {
high: 10,
low: -10,
axisX: {
labelInterpolationFnc: function(value, index) {
return index % 2 === 0 ? value : null;
}
}
};
var chart = new Chartist.Bar('.ct-chart', data, options);
// Based on ty's comment
chart.on('created', function(bar) {
$('.ct-bar').on('mouseover', function() {
$('#tooltip').html('<b>Selected Value: </b>' + $(this).attr('ct:value'));
});
$('.ct-bar').on('mouseout', function() {
$('#tooltip').html('<b>Selected Value:</b>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/chartist.js/0.9.5/chartist.min.js"></script>
<link href="https://cdn.jsdelivr.net/chartist.js/0.9.5/chartist.min.css" rel="stylesheet" />
<div id="tooltip"><b>Selected Value:</b>
</div>
<div class="ct-chart"></div>
UPDATE: Updated the code as per ty's comment

Related

Disable the overlap of nodes

I have created visualisation using vis-network, the problem is that the nodes are overlapping one on top of the other.
I have tried changing different values of nodeSpacing till 1000, that didn't help
Also i have tried setting barnesHut.avoidOverlap to 1 and that didn't help either,
any suggestions to fix this will be highly appreciated.
Updated options object
var options = {
interaction: {
hover: true
},
manipulation: {
enabled: true,
},
layout: {
hierarchical: {
direction: "LR",
shakeTowards: "leaves",
nodeSpacing: 1000,
treeSpacing: 300,
},
},
physics: {
stabilization: {
enabled: true, // <------ Disables animation.
iterations: 4000
},
barnesHut: {
avoidOverlap: 1
}
}
};
As mentioned in the documentation here for the layout.hierarchical.nodeSpacing option:
This is only for the initial layout. If you enable physics, the node distance there will be the effective node distance.
Therefore nodeSpacing isn't the final distance when physics is enabled. Two possible options are described below with examples.
nodeSpacing with Physics Disabled
The nodeSpacing option could be used with physics disabled. With physics disabled edges will likely overlap nodes when there are a large number of nodes. An example of this can be seen at https://jsfiddle.net/pbx8m9sk/.
nodeDistance with Hierarchical Repulsion Solver
As mentioned in the solver section of the documentation here the hierarchical repulsion solver is used by default when using a hierarchical layout. When the hierarchicalRepulsion solver is used the nodeDistance option can be used to control the distance between the nodes.
For example:
var options = {
physics: {
hierarchicalRepulsion: {
nodeDistance: 300,
}
}
};
Snippet using hierarchical repulsion solver with node distance set is below. You would likely want to adjust the nodeDistance and could adjust other hierarchicalRepulsion options, depending on the data.
// Setup initial nodes / edges
const nodes = [
{id: 1, label: '1'},
{id: 2, label: '2'},
{id: 3, label: '3'},
{id: 4, label: '4'},
{id: 5, label: '5'},
{id: 6, label: '6'},
{id: 7, label: '7'},
{id: 8, label: '8'},
{id: 9, label: '9'},
{id: 10, label: '10'},
{id: 11, label: '11'},
];
const edges = [
{from: 1, to: 2},
{from: 2, to: 3},
{from: 2, to: 4},
{from: 2, to: 5},
{from: 2, to: 6},
{from: 2, to: 7},
{from: 2, to: 8},
{from: 2, to: 9},
{from: 2, to: 10},
{from: 2, to: 11},
];
// Add a number nodes / edges
const nodesToAdd = 200;
for (let i = 12; i < 12 + nodesToAdd; i++){
nodes.push({id: i, label: `${i}`});
edges.push({from: 11, to: i});
}
var data = {
nodes: nodes,
edges: edges,
};
// create a network
var container = document.getElementById("mynetwork");
var options = {
interaction: {
hover: true
},
manipulation: {
enabled: true
},
nodes: {
shape: 'dot',
},
layout: {
hierarchical: { },
},
physics: {
hierarchicalRepulsion: {
nodeDistance: 300,
}
},
};
var network = new vis.Network(container, data, options);
#mynetwork {
width: 100%;
height: 170px;
border: 1px solid lightgray;
}
<script src="https://visjs.github.io/vis-network/standalone/umd/vis-network.min.js"></script>
<div id="mynetwork"></div>

Can I have a grid as background on a Vis.js Network

I'm implementing a network chart using Vis.js, and I'd like to have a grid as background
Do you have any idea how can I achieve that and if I can achieve that?
Example using beforeDrawing (per this example):
// create an array with nodes
var nodes = new vis.DataSet([
{ id: 1, value: 2, label: "Algie" },
{ id: 2, value: 31, label: "Alston" },
{ id: 3, value: 12, label: "Barney" },
{ id: 4, value: 16, label: "Coley" },
{ id: 5, value: 17, label: "Grant" },
{ id: 6, value: 15, label: "Langdon" },
{ id: 7, value: 6, label: "Lee" },
{ id: 8, value: 5, label: "Merlin" },
{ id: 9, value: 30, label: "Mick" },
{ id: 10, value: 18, label: "Tod" },
]);
// create an array with edges
var edges = new vis.DataSet([
{ from: 2, to: 8, value: 3, title: "3 emails per week" },
{ from: 2, to: 9, value: 5, title: "5 emails per week" },
{ from: 2, to: 10, value: 1, title: "1 emails per week" },
{ from: 4, to: 6, value: 8, title: "8 emails per week" },
{ from: 5, to: 7, value: 2, title: "2 emails per week" },
{ from: 4, to: 5, value: 1, title: "1 emails per week" },
{ from: 9, to: 10, value: 2, title: "2 emails per week" },
{ from: 2, to: 3, value: 6, title: "6 emails per week" },
{ from: 3, to: 9, value: 4, title: "4 emails per week" },
{ from: 5, to: 3, value: 1, title: "1 emails per week" },
{ from: 2, to: 7, value: 4, title: "4 emails per week" },
]);
// create a network
var container = document.getElementById("mynetwork");
var data = {
nodes: nodes,
edges: edges,
};
var options = {
nodes: {
shape: "dot",
},
};
var network = new vis.Network(container, data, options);
network.on("beforeDrawing", function(ctx) {
var width = ctx.canvas.clientWidth;
var height = ctx.canvas.clientHeight;
var spacing = 40;
var gridExtentFactor = 4;
ctx.strokeStyle = "lightgrey";
// draw grid
ctx.beginPath();
for (var x = -width * gridExtentFactor; x <= width * gridExtentFactor; x += spacing) {
ctx.moveTo(x, height * gridExtentFactor);
ctx.lineTo(x, -height * gridExtentFactor);
}
for (var y = -height * gridExtentFactor; y <= height * gridExtentFactor; y += spacing) {
ctx.moveTo(width * gridExtentFactor, y);
ctx.lineTo(-width * gridExtentFactor, y);
}
ctx.stroke();
});
#mynetwork {
width: 600px;
height: 200px;
border: 1px solid lightgray;
background-color: none;
}
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<div id="mynetwork"></div>
vis-network uses a html5 canvas to draw the chart. You could draw the grid yourself using the beforeDrawing event. To support interactivity like zooming and panning you would also need to listen to the dragStart, dragging and dragEnd events as well as zoom. With these events it should be possible to implement a fully interactive background.
Have a look at the renderEvents example and the interactionEvents example.

Adjusting dates in X Axis Plotly

I was wondering how can you achieve the following:
I'm using a Date format of year and month ( i.e 2022-01), but Plotly is not providing an option to have a simple date value for the x Axis, Chart.JS actually allows you to define the date by month, so what is happening is that if you zoom in to one month, then you can see days and even hours, so how do I change that?
Secondly, is there a way to control how the X-axis is displayed?, for example perhaps when you have more than one year is better to show quarters, but as you zoom in for a 1-year period, then I would like to see every month display?, but I don't want to have more granularity, I would like to have only the month display in the graph
https://jsfiddle.net/60ucqz8w/
var Deals = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 234021, 26544, 28856, 70463, 28856, 155019],
name: 'Deals',
type: 'bar',
marker: {
color: 'rgb(0,131,117)',
}
};
var Leads = {
x: ['2022-03', '2022-04', '2022-05', '2022-06', '2022-07', '2022-08', '2022-11', '2023-01', '2023-02'],
y: [7255, 5155, 61950, 63000, 5155, 19845, 20905, 5155, 15750],
name: 'Leads',
type: 'bar',
marker: {
color: 'rgb(160,220,210)',
}
};
var Cumulative = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 245262, 271806, 300662, 371125, 399981, 555000],
name: 'Cumulative Deals',
type: 'line',
marker: {
color: 'rgb(0,131,117)',
}
};
var data = [Deals,Leads,Cumulative];
var layout = {
title: "Sales Forecast",
barmode: 'stack',
xaxis: {
autorange: true,
rangeselector: {
buttons: [{
step: 'all'
},
{
count: 1,
label: 'YTD',
step: 'year',
stepmode: 'todate'
},
{
count: 6,
label: '6m',
step: 'month',
stepmode: 'todate'
}]},
rangeslider: { },
type: 'date',
tickfont:{
size: 14
},
},
yaxis: {
tickfont:{size: 14}
}
};
Plotly.newPlot('DivBarChart', data,layout);```
You code was mostly right the only thing that needed fixing is the scrollZoom: true. The code won't work unless you put scrollZoom: true because the function won't be active unless specified. You need this so you can enable it for your graph. You need to select the timeframe using you mouse. Click and drag to see your timeframe.
var Deals = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 234021, 26544, 28856, 70463, 28856, 155019],
name: 'Deals',
type: 'bar',
marker: {
color: 'rgb(0,131,117)',
}
};
var Leads = {
x: ['2022-03', '2022-04', '2022-05', '2022-06', '2022-07', '2022-08', '2022-11', '2023-01', '2023-02'],
y: [7255, 5155, 61950, 63000, 5155, 19845, 20905, 5155, 15750],
name: 'Leads',
type: 'bar',
marker: {
color: 'rgb(160,220,210)',
}
};
var Cumulative = {
x: ['2021-10', '2022-01', '2022-03', '2022-04', '2022-05', '2022-07', '2022-09'],
y: [11241, 245262, 271806, 300662, 371125, 399981, 555000],
name: 'Cumulative Deals',
type: 'line',
marker: {
color: 'rgb(0,131,117)',
}
};
var data = [Deals, Leads, Cumulative];
var layout = {
title: "Sales Forecast",
barmode: 'stack',
};
Plotly.newPlot('DivBarChart', data, layout, {
scrollZoom: true
});
<div class="col-sm-4">
<div id='DivBarChart' class="container"></div>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</div>
See scroll and zoom in or plotly.js docs for more information.

JavaScript, HTML, CSS to Class diagram

I been searching around for a tool that can help me generate class diagram for my web development project.
I have one plugin for eclipse but it only works for the JavaScript and does not link the HTML and CSS - http://jsuml.org/.
Found another that does sort of what I want but it requires me to use npm, however, since I didnt use this in my project from start its quite difficult for me to change the structure now - https://www.npmjs.org/package/wavi
I am using visual code to write my code but am happy to move my code to another editor if it gets the job done (as long as its windows) :)
The result I am looking for is something like below:
Please let me know if I have posted this in the wrong section and I be happy to move it.
I found some plugins for visual code but there all seem to be for sequence diagram and none for class diagram.
Here is an example using vis js:
// create an array with nodes
var nodes = new vis.DataSet([{
id: 1,
label: 'Node 1'
},
{
id: 2,
label: 'Node 2'
},
{
id: 3,
label: 'Node 3'
},
{
id: 4,
label: 'Node 4'
},
{
id: 5,
label: 'Node 5'
},
{
id: 6,
label: 'Node 6'
},
{
id: 7,
label: 'Node 7'
},
{
id: 8,
label: 'Node 8'
}
]);
// create an array with edges
var edges = new vis.DataSet([{
from: 1,
to: 8,
arrows: 'to',
dashes: true
},
{
from: 1,
to: 3,
arrows: 'to'
},
{
from: 1,
to: 2,
arrows: 'to, from'
},
{
from: 2,
to: 4,
arrows: 'to, middle'
},
{
from: 2,
to: 5,
arrows: 'to, middle, from'
},
{
from: 5,
to: 6,
arrows: {
to: {
scaleFactor: 2
}
}
},
{
from: 6,
to: 7,
arrows: {
middle: {
scaleFactor: 0.5
},
from: true
}
}
]);
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {};
var network = new vis.Network(container, data, options);
#myNetwork {
width: 400px;
height: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<div id='mynetwork'></div>
More example can be found here

vis.js large nodes overlapping in hierarchical mode

Is it possible to have nodes in vis.js in hierarchical layout without overlaping on X axis?
I tried to add options:
var options = {
layout: {
hierarchical: {
direction: "UD",
sortMethod: "directed"
},
physics: {
solver: "barnesHut"
,barnesHut: {
avoidOverlap: 1
}
}
}
};
You can increase layout.hierarchical.nodeSpacing for the initial layout.
// create an array with nodes
var nodes = new vis.DataSet([
{id: 1, label: 'Node 1 with lage text'},
{id: 2, label: 'Node 2 with lage text'},
{id: 3, label: 'Node 3 with lage text'},
{id: 4, label: 'Node 4 with lage text'},
{id: 5, label: 'Node 5 with lage text'}
]);
// create an array with edges
var edges = new vis.DataSet([
{from: 1, to: 3},
{from: 1, to: 2},
{from: 2, to: 4},
{from: 2, to: 5}
]);
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
layout: {
hierarchical: {
direction: "UD",
sortMethod: "directed",
nodeSpacing: 200 // <-- !!!!!!!
}
},
physics: false
};
var network = new vis.Network(container, data, options);
#mynetwork {
width: 100%;
height: 100%;
border: 1px solid lightgray;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.17.0/vis.min.js" type="text/javascript"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.17.0/vis.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="mynetwork"></div>
</body>
</html>
Another solution might be
myVisOptions = {
layout: {
hierarchical: {
direction: "UD",
sortMethod: "directed",
shakeTowards: 'roots'
}
},
physics: {
// https://visjs.github.io/vis-network/docs/network/physics.html
enabled: true,
hierarchicalRepulsion: {
avoidOverlap: 0.99
},
stabilization: {
iterations: 2000,
updateInterval: 100
},
solver: 'hierarchicalRepulsion'
},
nodes: {
margin: 8,
shape: 'box',
font: {size: 20},
color: {
background: 'white',
border: '#ffc468',
hover: '#ffc468',
highlight: '#ffc468'//, '#bd6500'
},
}
};

Categories