Can the remove button gap in vis-timelne be suppressed? - javascript

In vis-timeline, if stacking is not enabled (default), there seems to be an enforced gap between two items on the same line, such that two items can never touch. It appears to me, that this gap is enforced to have always enough space for the remove button, which appears right to the item. However, this gap is always enforced, even if editable.remove is set to false in the options for vis.Timeline.
Is there a possibility to avoid having this gap, without having to enable stacking? (I do not want to have overlapping, except for a point in time.)
Here is an example (it's from the github page of vis-timeline, but simplified):
<!doctype html>
<html>
<head>
<title>Timeline</title>
<script type="text/javascript" src="https://unpkg.com/vis-timeline#latest/standalone/umd/vis-timeline-graph2d.min.js"></script>
<link href="https://unpkg.com/vis-timeline#latest/styles/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#visualization {
width: 600px;
height: 400px;
border: 1px solid lightgray;
}
</style>
</head>
<body>
<div id="visualization"></div>
<script type="text/javascript">
// DOM element where the Timeline will be attached
var container = document.getElementById('visualization');
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{id: 1, content: 'item 1', start: '2014-04-14T00:00:00', end: '2014-04-14T00:15:00'},
{id: 2, content: 'item 2', start: '2014-04-14T00:15:00', end: '2014-04-14T00:30:00'},
]);
// Configuration for the Timeline
var options = {editable: true};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
</script>
</body>
</html>
If You runs this snippet, you will see, that the two created items were moved to different lines.
If you try to move the to items to one line, you will discover, that this is only possible with a small gap between them. Notice, that this gap more or less as large as the remove button for the items. However disabling this button either by framework or by css doesn't change the behaviour.

You can adjust the horizontal item margin in vis-timeline using the margin.item.horizontal option described in the documentation at https://visjs.github.io/vis-timeline/docs/timeline/#Configuration_Options. The default value is 10, setting it to 0 will allow the items to be placed side by side.
Example updated options object:
var options = {
editable: true,
margin : {
item: {
horizontal:0
}
}
};
Example updated snippet:
<!doctype html>
<html>
<head>
<title>Timeline</title>
<script type="text/javascript" src="https://unpkg.com/vis-timeline#latest/standalone/umd/vis-timeline-graph2d.min.js"></script>
<link href="https://unpkg.com/vis-timeline#latest/styles/vis-timeline-graph2d.min.css" rel="stylesheet" type="text/css" />
<style type="text/css">
#visualization {
width: 600px;
height: 400px;
border: 1px solid lightgray;
}
</style>
</head>
<body>
<div id="visualization"></div>
<script type="text/javascript">
// DOM element where the Timeline will be attached
var container = document.getElementById('visualization');
// Create a DataSet (allows two way data-binding)
var items = new vis.DataSet([
{id: 1, content: 'item 1', start: '2014-04-14T00:00:00', end: '2014-04-14T00:15:00'},
{id: 2, content: 'item 2', start: '2014-04-14T00:15:00', end: '2014-04-14T00:30:00'},
]);
// Configuration for the Timeline
var options = {
editable: true,
margin : {
item: {
horizontal:0
}
}
};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
</script>
</body>
</html>

Related

Anychart Gantt time in seconds which resets to zero

Hello I am creating a gantt chart in seconds to calculate the time of a robot line.
I use the Anychart library. When I get to 60 seconds it goes back to zero and resets my tooltip.
I retrieve the values ​​using a JSON file and I use this file to write the diagram
<html>
<head>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-bundle.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
<style type="text/css">
html,
body,
#container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
anychart.onDocumentReady(function() {
anychart.data.loadJsonFile("data.php", function(data) {
// create a data tree
var treeData = anychart.data.tree(data, "as-tree", null, {
children: "children"
});
// map the data
var mapping = treeData.mapAs({
actualStart: "start",
actualEnd: "end",
name: "nom"
});
// create a data tree
// var mapping = anychart.data.tree(data, "as-tree");
anychart.format.outputDateTimeFormat("ss'sec'");
// create a chartec
var chart = anychart.ganttProject();
// set the data
chart.data(mapping);
// set the container id
chart.container("container");
// set the data
chart.dataGrid().fixedColumns(true);
// chart.splitterPosition().hide();
chart.dataGrid().column().enabled(false);
chart.dataGrid().column(0).enabled(false);
chart.getTimeline().elements().labels(false);
chart.rowHoverFill("#ffd54f 0.3");
chart.rowSelectedFill("#ffd54f 0.3");
chart.rowStroke("0.5 #64b5f6");
chart.columnStroke("0.5 #64b5f6");
chart.dataGrid().column(0).enabled(false);
var title = chart.title();
title.enabled(true);
title.text("Gantt Chart");
title.fontColor("#64b5f6");
title.fontSize(18);
title.fontWeight(600);
title.padding(5);
scale = chart.xScale();
// Set zoom levels.
scale.zoomLevels([
[{
unit: 'millisecond',
count: 0
},
{
unit: 'second',
count: 1
}
]
]);
// configure the levels of the timeline header
var header = chart.getTimeline().header();
header.level(0).format("{%tickValue}{dateTimeFormat:ss} sec");
header.level(1).enabled(false);
header.level(2).enabled(false);
chart.headerHeight(50);
// initiate drawing the chart
chart.draw();
// fit elements to the width of the timeline
chart.fitAll();
});
});
</script>
</body>
</html>
I would like to know if it is possible not to reset the time so that the number of seconds can exceed 60.

How to drag and drop items between 2 columns with "Konva.JS"?

I'm looking for a way to drag and drop items between 2 columns with Konva.JS.
Since I found a sample code using Sortable.JS, I ported it and wrote the following code. With this code, I expected there were two vertical independent scroll bars, such as in this example image:
However, there aren't, as shown in this image from running my code:
.
My code:
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva#5.0.2/konva.min.js"></script>
<meta charset="utf-8" />
<style>
body {
margin: 0;
padding: 0;
background-color: #f0f0f0;
height:100%;
overflow: hidden;
}
#Leftcontainer {
overflow: auto;
}
#Rightcontainer {
overflow: auto;
}
</style>
</head>
<body>
<div id="container">
<div id="Leftcontainer"></div> <!-- Left Column -->
<div id="Rightcontainer"></div> <!-- Right Column -->
</div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;
var stage = new Konva.Stage({
container: 'container',
width: width,
height: 60*1090,
});
//Layer 1
var layer = new Konva.Layer();
stage.add(layer);
//Layer 2
var tempLayer = new Konva.Layer();
stage.add(tempLayer);
//Load Image (Group of Left Column)
var leftGroup = new Konva.Group({
id: 'Leftcontainer',
});
layer.add(leftGroup);
for (let i = 0; i < 100; i++) {
var imageObj = new Image();
imageObj.src = './assets/apple.jpg';
imageObj.addEventListener('load', function() {
var dragImage = new Konva.Image({
x: 5,
y: 20+(5+100)*i,
image: imageObj,
width: 100,
height: 100,
draggable: false,
});
leftGroup.add(dragImage);
layer.draw();
});
};
//Load Text (Group of Right Column)
var rightGroup = new Konva.Group({
id: 'Rightcontainer',
});
layer.add(rightGroup);
for (var i = 0; i < 100; i++) {
var WordLabel = new Konva.Label({
x: 300,
y: 18+60*i,
opacity: 0.75,
draggable: true,
fill: 'green',
});
WordLabel.add(
new Konva.Tag({
fill: 'green',
lineJoin: 'round'
})
);
WordLabel.add(
new Konva.Text({
text: "Apple",
fontFamily: 'Calibri',
fontSize: 18,
padding: 5,
fill: 'white',
})
);
rightGroup.add(WordLabel);
};
layer.draw();
</script>
</body>
</html>
It would appear that you are intending there to be two columns on your page since you have the HTML for the container, Leftcontainer and Rightcontainer. You then appear to be setting a Konva stage in the 'container' div but later creating Konva groups to co-relate to left + right containers. You then make these groups long and expect there to be vertical scrollbars.
You are making a false assumption regarding the relationship between the HTML5 canvas (for which Konva is a wrapper) and its interaction with HTML elements. The basic principle is that an HTML5 canvas 'lives' inside a single HTML element. You cannot 'share' bits of it between HTML elements in the way that you are attempting.
[Aside: Under the covers, Konva DOES create a stage per layer, but that still does not allow placing those layers into other host containers than the main stage.]
Options:
1 - you do not specifically require a canvas-based solution to provide an image-based drag & drop. You would already have found this with sortable.js. But if you are simply using this as a learning activity to understand the canvas then well done you!
2 - continuing this the canvas approach, your basic architecture of a stage and a group per column is reasonable. But you have to take care of producing the scroll bars since in the world of canvas there are no such handy UI shortcuts.
3 - again following a canvas solution, ignore the main 'container' element, and create a stage in EACH of the left and right container elements to represent your left and right columns. Draw the content, then approach the problem as one of dragging an element from one canvas to another.

How to implement a vertical scrollbar?

Does anyone know how to implement a vertical scrollbar for a vis.js timeline? I have read the visjs.org documentation, other threads here on stack overflow and on GitHub, but I still can't implement the scrollbar.
Should it be enough to write verticalScroll: true in the configuration for a vis.js timeline? This is what I have as configuration at the moment. Do I need to write it in some other way? Or do I need to implement the vertical scroll in a totally different way?
// Configuration for the Timeline
var options = {
width: '100%',
height: '100%',
minHeight: '300px',
padding: '0px',
orientation: 'top',
max: futureDate,
min: pastDate,
groupOrder: 'start',
zoomMin: '86400000',
margin: {item: {horizontal: 0, vertical: 5}, axis: 5},
verticalScroll: true,
zoomKey: 'ctrlKey'
};
A priori the options taken are good, It would be enough to reduce the height of the timeline directly in the options rather than to use "minHeight" in this case. Normally, this should bring up the scroll bar.
To check this, reduce the timeline height to 150 px in the options (e.g)
You can also generate a large number of groups so that they exceed the vertical left pannel capacity of timeline so that the vertical scrollbar displays.
UPDATED with minimal example adapted from "vis.js examples"
See also the timeline documentation on website for configuring options...
<html>
<head>
<title>Timeline | Vertical Scroll Option</title>
<!-- note: moment.js must be loaded before vis.js, else vis.js uses its embedded version of moment.js -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.21.0/vis.min.css" />
</head>
<body>
<h1>Timeline vertical scroll option</h1>
<h2>With <code>
verticalScroll: true,
zoomKey: 'ctrlKey'</code>
</h2>
<div id="mytimeline1"></div>
<script>
// create groups
var numberOfGroups = 25;
var groups = new vis.DataSet()
for (var i = 0; i < numberOfGroups; i++) {
groups.add({
id: i,
content: 'Truck ' + i
})
}
// create items
var numberOfItems = 1000;
var items = new vis.DataSet();
var itemsPerGroup = Math.round(numberOfItems/numberOfGroups);
for (var truck = 0; truck < numberOfGroups; truck++) {
var date = new Date();
for (var order = 0; order < itemsPerGroup; order++) {
date.setHours(date.getHours() + 4 * (Math.random() < 0.2));
var start = new Date(date);
date.setHours(date.getHours() + 2 + Math.floor(Math.random()*4));
var end = new Date(date);
var orderIndex = order + itemsPerGroup * truck
items.add({
id: orderIndex,
group: truck,
start: start,
end: end,
content: 'Order ' + orderIndex
});
}
}
// specify options
var options = {
stack: true,
verticalScroll: true,
zoomKey: 'ctrlKey',
height: 200, // you can use also "300px"
start: new Date(),
end: new Date(1000*60*60*24 + (new Date()).valueOf()),
};
// create a Timeline
var container1 = document.getElementById('mytimeline1');
timeline1 = new vis.Timeline(container1, items, groups, options);
</script>
</body>
</html>
It sounds like you can get a scrollbar using overflow-y: scroll. Also, height: 100% will most likely never cause this to kick in (unless this element is contained within another element that has a set height) as the element that you are editing will keep growing in height rather than staying a certain height and have a scrollbar. So I would recommend removing height: 100% and using max-height instead (if your element isn't contained within another element), so if the element content grows to something larger than your max-height, it will begin to scroll. If you're looking to style that scrollbar, that's a whole different story.
https://www.w3schools.com/cssref/css3_pr_overflow-y.asp

Cytoscape.js cxtmenu doesn't fire event on entry select

When I use the cxtmenu extension for Cytoscape.cs, the context menu doesn't fire its event immediately after I select an option but only after I select another node. How can I have it fire the event immediately after selecting the option? My plan is to offer way finding similar to Google Maps, where a source node is already selected and the context menu on right click on a node offers "route to here".
I use jquery 3.1.0 (only because it is stated as a requirement for cxtmenu), cytoscape.js 2.75 and the newest cytoscape-cxtmenu.
See the minimal working example for the problem:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js"></script><!--2.7.5-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/cytoscape/cytoscape.js-cxtmenu/master/cytoscape-cxtmenu.js"></script>
</head>
<body>
<div id="cy" style="width:100%;height:100vh;"></div>
<script>
var cy = cytoscape({
container: document.getElementById('cy'),
elements:
[
{data: {id: 'n1'}},
{data: {id: 'n2'}},
]
});
var added = false;
var defaults = {
menuRadius: 100, // the radius of the circular menu in pixels
selector: 'node', // elements matching this Cytoscape.js selector will trigger cxtmenus
commands: [
{
content: 'test',
select: function(node)
{
if(!added)
{
console.log('adding edge');
cy.add({group:"edges", data: {id: 'e1', source: 'n1', target: 'n2'}});
added=true;
}
}
},
],
openMenuEvents: 'cxttap', // cytoscape events that will open the menu (space separated)
};
var cxtmenuApi = cy.cxtmenu(defaults);
var selectedNode;
cy.on('select',"node",function(event) {selectedNode = event.cyTarget;});
</script>
</body>
</html>
P.S.: I managed to get an event to fire directly by using openMenuEvents: 'cxttapstart taphold' but then the menu activates on releasing the mouse press that intitially activated the menu.

CellView.highlight() breaking change?

My application uses Jointjs.
I recently upgraded from Jointjs v0.9.7 to v0.9.10 and since I did that cell highlighting does not seem to work. I simplified everything down to a test app and I can see that the highlight() function is called but the highlighted class is not set.
I put a simplified test page into a gist and a fiddle. It is also reproduced below in case it helps.
Has there been a breaking change? How is highlighting supposed to work in v0.9.10?
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.10/joint.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.10/joint.core.css" />
</head>
<body>
<div id="paper" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/0.9.10/joint.js"></script>
<script>
//there is a problem with jointjs in the latest version of Chrome. This fixes it
SVGElement.prototype.getTransformToElement =
SVGElement.prototype.getTransformToElement || function (toElement) {
return toElement.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
var highlighted = false;
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#paper'),
width: 400,
height: 400,
model: graph,
gridSize: 1,
interactive: false
});
paper.on('cell:pointerclick', function (cellView) {
if (highlighted) {
cellView.unhighlight();
} else {
cellView.highlight();
}
highlighted = !highlighted
});
var element = new joint.shapes.basic.Rect({
position: { x: 100, y: 30 },
attrs: { text: { text: 'my shape' } },
size: { height: 92.7051, width: 150 }
});
graph.addCell(element);
</script>
</body>
</html>
The default highlighter has changed in JointJS v0.9.10. When you highlight an element - an SVGPathElement with the joint-highlight-stroke class name that mimics the element shape is appended directly to the ElementView. This solves differences across the browsers with CSS property outline mostly unsupported for SVG Elements.
Available highlighters resides in the joint.highlighters namespace (stroke default, opacity, addClass for backwards compatibility).
In order to restore the original behaviour, please use the following.
// a highlighter definition
var myHighlighter = {
name: 'addClass',
options: {
className: 'highlighted'
}
}
// add `myHighlighter` to an `el` (`null` for the entire cellView) DOM element.
cellView.highlight(el, myHighlighter);
// remove `myHighlighter` from an `el` DOM element.
cellView.unhighlight(el, myHighlighter);
Note that the new changes allow highlighting cellViews with multiple highlighters.
Demo
Sorry for inconveniences. The actual documentation for highlighters will appear in the JointJS repository ASAP.

Categories