Browse Source

Merge branch 'develop' of https://github.com/almende/vis into develop

Conflicts:
	dist/vis.js
	docs/graph2d.html
v3_develop
Alex de Mulder 10 years ago
parent
commit
8dd36d1fa3
22 changed files with 25748 additions and 25204 deletions
  1. +3
    -1
      HISTORY.md
  2. +24177
    -24086
      dist/vis.js
  3. +1
    -1
      dist/vis.map
  4. +12
    -12
      dist/vis.min.js
  5. +69
    -174
      docs/graph2d.html
  6. +907
    -866
      docs/network.html
  7. +74
    -2
      docs/timeline.html
  8. +16
    -16
      examples/graph2d/01_basic.html
  9. +65
    -0
      examples/graph2d/13_localization.html
  10. +1
    -0
      examples/graph2d/index.html
  11. +231
    -0
      examples/network/31_localization.html
  12. +1
    -0
      examples/network/index.html
  13. +65
    -0
      examples/timeline/19_localization.html
  14. +1
    -0
      examples/timeline/index.html
  15. +7
    -18
      lib/network/Network.js
  16. +35
    -0
      lib/network/locales.js
  17. +1
    -1
      lib/network/mixins/HierarchicalLayoutMixin.js
  18. +31
    -21
      lib/network/mixins/ManipulationMixin.js
  19. +12
    -3
      lib/timeline/component/CurrentTime.js
  20. +11
    -3
      lib/timeline/component/CustomTime.js
  21. +13
    -0
      lib/timeline/component/TimeAxis.js
  22. +15
    -0
      lib/timeline/locales.js

+ 3
- 1
HISTORY.md View File

@ -9,18 +9,20 @@ http://visjs.org
- Fixed the `change` event sometimes being fired twice on IE10.
- Fixed canceling moving an item to another group did not move the item
back to the original group.
- Added localization support.
### Network
- A fix in reading group properties for a node.
- Fixed physics solving stopping when a support node was not moving.
- Added localization support.
### Graph2D
- Added 'allowOverlap' option for barCharts.
- Added two examples showing the two additions above.
- Added 'customRange' for the Y axis and an example showing how it works.
- Added localization support.
## 2014-08-14, version 3.2.0

+ 24177
- 24086
dist/vis.js
File diff suppressed because it is too large
View File


+ 1
- 1
dist/vis.map
File diff suppressed because it is too large
View File


+ 12
- 12
dist/vis.min.js
File diff suppressed because it is too large
View File


+ 69
- 174
docs/graph2d.html View File

@ -47,6 +47,8 @@
</li>
<li><a href="#Methods">Methods</a></li>
<li><a href="#Events">Events</a></li>
<li><a href="#Localization">Localization</a></li>
<li><a href="#Styles">Styles</a></li>
<li><a href="#Data_Policy">Data Policy</a></li>
</ul>
@ -90,7 +92,7 @@
start: '2014-06-10',
end: '2014-06-18'
};
var graph2d = new vis.Graph2d(container, dataset, options);
var Graph2d = new vis.Graph2d(container, dataset, options);
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
@ -278,7 +280,7 @@ The options colored in green can also be used as options for the groups. All opt
<td class="greenField">yAxisOrientation</td>
<td>String</td>
<td>'left'</td>
<td>This defines with which axis, left or right, the graph is coupled. <a href="../examples/graph2d/05_bothAxis.html">Example 5</a> shows groups with different Y axis. If no groups are coupled
<td>This defines with which axis, left or right, the graph is coupled. <a href="../examples/Graph2d/05_bothAxis.html">Example 5</a> shows groups with different Y axis. If no groups are coupled
with an axis, it will not be shown.</td>
</tr>
<tr>
@ -298,7 +300,7 @@ The options colored in green can also be used as options for the groups. All opt
<td class="greenField">sampling</td>
<td>Boolean</td>
<td>true</td>
<td>If sampling is enabled, graph2D will automatically determine the amount of points per pixel.
<td>If sampling is enabled, Graph2d will automatically determine the amount of points per pixel.
If there are more than 1 point per pixel, not all points will be drawn. Disabling sampling will cause a decrease in performance.</td>
</tr>
<tr>
@ -371,7 +373,7 @@ The options colored in green can also be used as options for the groups. All opt
<td class="greenField">catmullRom.parametrization</td>
<td>String</td>
<td>'centripetal'</td>
<td>Define the type of parametrizaion. <a href="../examples/graph2d/07_scrollingAndSorting.html">Example 7</a> shows the different methods. The options are 'centripetal' (best results), 'chordal' and 'uniform'. Uniform is the computationally cheapest variant.
<td>Define the type of parametrizaion. <a href="../examples/Graph2d/07_scrollingAndSorting.html">Example 7</a> shows the different methods. The options are 'centripetal' (best results), 'chordal' and 'uniform'. Uniform is the computationally cheapest variant.
If catmullRom is disabled, linear interpolation is used.</td>
</tr>
<tr>
@ -475,174 +477,11 @@ The options colored in green can also be used as options for the groups. All opt
<h3 id="timelineOptions">Timeline Options</h3>
<p>
Graph2d is built upon the framework of the timeline. These options from the timeline can be used with graph2D.
All options are optional.
Graph2d is built upon the framework of the Timeline. All options from the Timeline can be used with Graph2d. The options available for the Timeline are listed here:
</p>
<p>
<a href="timeline.html#Configuration_Options">timeline.html#Configuration_options</a>
</p>
<table>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th>Description</th>
</tr>
<tr>
<td>autoResize</td>
<td>boolean</td>
<td>true</td>
<td>If true, the Timeline will automatically detect when its container is resized, and redraw itself accordingly. If false, the Timeline can be forced to repaint after its container has been resized using the function <code>redraw()</code>.</td>
</tr>
<tr>
<td>end</td>
<td>Date | Number | String</td>
<td>none</td>
<td>The initial end date for the axis of the timeline.
If not provided, the latest date present in the items set is taken as
end date.</td>
</tr>
<tr>
<td>height</td>
<td>Number | String</td>
<td>none</td>
<td>The height of the timeline in pixels or as a percentage.
When height is undefined or null, the height of the timeline is automatically
adjusted to fit the contents.
It is possible to set a maximum height using option <code>maxHeight</code>
to prevent the timeline from getting too high in case of automatically
calculated height.
</td>
</tr>
<tr>
<td>margin.axis</td>
<td>Number</td>
<td>20</td>
<td>The minimal margin in pixels between items and the time axis.</td>
</tr>
<tr>
<td>margin.item</td>
<td>Number</td>
<td>10</td>
<td>The minimal margin in pixels between items.</td>
</tr>
<tr>
<td>max</td>
<td>Date | Number | String</td>
<td>none</td>
<td>Set a maximum Date for the visible range.
It will not be possible to move beyond this maximum.
</td>
</tr>
<tr>
<td>maxHeight</td>
<td>Number | String</td>
<td>none</td>
<td>Specifies the maximum height for the Timeline. Can be a number in pixels or a string like "300px".</td>
</tr>
<tr>
<td>min</td>
<td>Date | Number | String</td>
<td>none</td>
<td>Set a minimum Date for the visible range.
It will not be possible to move beyond this minimum.
</td>
</tr>
<tr>
<td>minHeight</td>
<td>Number | String</td>
<td>none</td>
<td>Specifies the minimum height for the Timeline. Can be a number in pixels or a string like "300px".</td>
</tr>
<tr>
<td>orientation</td>
<td>String</td>
<td>'bottom'</td>
<td>Orientation of the timeline: 'top' or 'bottom' (default). If orientation is 'bottom', the time axis is drawn at the bottom, and if 'top', the axis is drawn on top.</td>
</tr>
<tr>
<td>showCurrentTime</td>
<td>boolean</td>
<td>true</td>
<td>Show a vertical bar at the current time.</td>
</tr>
<tr>
<td>showCustomTime</td>
<td>boolean</td>
<td>false</td>
<td>Show a vertical bar displaying a custom time. This line can be dragged by the user. The custom time can be utilized to show a state in the past or in the future. When the custom time bar is dragged by the user, the event <code>timechange</code> is fired repeatedly. After the bar is dragged, the event <code>timechanged</code> is fired once.</td>
</tr>
<tr>
<td>showMajorLabels</td>
<td>boolean</td>
<td>true</td>
<td>By default, the timeline shows both minor and major date labels on the
time axis.
For example the minor labels show minutes and the major labels show hours.
When <code>showMajorLabels</code> is <code>false</code>, no major labels
are shown.</td>
</tr>
<tr>
<td>showMinorLabels</td>
<td>boolean</td>
<td>true</td>
<td>By default, the timeline shows both minor and major date labels on the
time axis.
For example the minor labels show minutes and the major labels show hours.
When <code>showMinorLabels</code> is <code>false</code>, no minor labels
are shown. When both <code>showMajorLabels</code> and
<code>showMinorLabels</code> are false, no horizontal axis will be
visible.</td>
</tr>
<tr>
<td>start</td>
<td>Date | Number | String</td>
<td>none</td>
<td>The initial start date for the axis of the timeline.
If not provided, the earliest date present in the events is taken as start date.</td>
</tr>
<tr>
<td>width</td>
<td>String</td>
<td>'100%'</td>
<td>The width of the timeline in pixels or as a percentage.</td>
</tr>
<tr>
<td>zoomMax</td>
<td>Number</td>
<td>315360000000000</td>
<td>Set a maximum zoom interval for the visible range in milliseconds.
It will not be possible to zoom out further than this maximum.
Default value equals about 10000 years.
</td>
</tr>
<tr>
<td>zoomMin</td>
<td>Number</td>
<td>10</td>
<td>Set a minimum zoom interval for the visible range in milliseconds.
It will not be possible to zoom in further than this minimum.
</td>
</tr>
</table>
<h2 id="Methods">Methods</h2>
@ -880,16 +719,72 @@ Graph2d.off('rangechanged', onChange);
</table>
<h2 id="Localization">Localization</h2>
<p>
Graph2d can be localized. For localization, Graph2d depends largely on the localization of <a href="http://momentjs.com">moment.js</a>. Locales are not included in vis.js by default. To enable localization, moment.js must be loaded with locales. Moment.js offers a bundle named "moment-with-locales.min.js" for this and there are various alternative ways to load locales.
</p>
<p>
To set a locale for the Graph2d, specify the option <code>locale</code>:
</p>
<pre class="prettyprint lang-js">var options = {
locale: 'nl'
};
</pre>
<h3>Create a new locale</h3>
To load a locale into the Graph2d not supported by default, one can add a new locale to the option <code>locales</code>:
<pre class="prettyprint lang-js">var options = {
locales: {
// create a new locale
mylocale: {
current: 'current',
time: 'time',
}
},
// use the new locale
locale: 'mylocale'
};
</pre>
<h3 id="available-locales">Available locales</h3>
Graph2d comes with support for the following locales:
<table>
<tr><th>Language</th><th>Code</th></tr>
<tr>
<td>English</td>
<td>
<code>en</code><br>
<code>en_EN</code><br>
<code>en_US</code>
</td>
</tr>
<tr>
<td>Dutch</td>
<td>
<code>nl</code><br>
<code>nl_NL</code><br>
<code>nl_BE</code>
</td>
</tr>
</table>
<h2 id="Styles">Styles</h2>
<p>
All parts of the Graph2d have a class name and a default css style just like the Timeline.
All parts of the Graph2d have a class name and a default css style just like the Graph2d.
The styles can be overwritten, which enables full customization of the layout
of the Graph2d.
</p>
<p>
Additionally, Graph2d has 10 preset styles for graphs, which are cycled through when loading groups. These styles can be overwritten
as well, along with defining your own classes to style the graphs! <a href="../examples/graph2d/04_rightAxis.html">Example 4</a> and
<a href="../examples/graph2d/05_bothAxis.html">example 5</a> show the usage of custom styles.
as well, along with defining your own classes to style the graphs! <a href="../examples/Graph2d/04_rightAxis.html">Example 4</a> and
<a href="../examples/Graph2d/05_bothAxis.html">example 5</a> show the usage of custom styles.
</p>
<h2 id="Data_Policy">Data Policy</h2>

+ 907
- 866
docs/network.html
File diff suppressed because it is too large
View File


+ 74
- 2
docs/timeline.html View File

@ -43,6 +43,7 @@
<li><a href="#Methods">Methods</a></li>
<li><a href="#Events">Events</a></li>
<li><a href="#Editing_Items">Editing Items</a></li>
<li><a href="#Localization">Localization</a></li>
<li><a href="#Styles">Styles</a></li>
<li><a href="#Data_Policy">Data Policy</a></li>
</ul>
@ -438,6 +439,20 @@ var options = {
</td>
</tr>
<tr>
<td>locale</td>
<td>String</td>
<td>none</td>
<td>Select a locale for the Timeline. See section <a href="#Localization">Localization</a> for more information.</td>
</tr>
<tr>
<td>locales</td>
<td>Object</td>
<td>none</td>
<td>A map with i18n locales. See section <a href="#Localization">Localization</a> for more information.</td>
</tr>
<tr>
<td>margin.axis</td>
<td>Number</td>
@ -985,11 +1000,69 @@ var options = {
callback(null); // cancel updating the item
}
}
}
};
</pre>
A full example is available here: <a href="../examples/timeline/08_edit_items.html">08_edit_items.html</a>.
<h2 id="Localization">Localization</h2>
<p>
Timeline can be localized. For localization, Timeline depends largely on the localization of <a href="http://momentjs.com">moment.js</a>. Locales are not included in vis.js by default. To enable localization, moment.js must be loaded with locales. Moment.js offers a bundle named "moment-with-locales.min.js" for this and there are various alternative ways to load locales.
</p>
<p>
To set a locale for the Timeline, specify the option <code>locale</code>:
</p>
<pre class="prettyprint lang-js">var options = {
locale: 'nl'
};
</pre>
<h3>Create a new locale</h3>
To load a locale into the Timeline not supported by default, one can add a new locale to the option <code>locales</code>:
<pre class="prettyprint lang-js">var options = {
locales: {
// create a new locale (text strings should be replaced with localized strings)
mylocale: {
current: 'current',
time: 'time',
}
},
// use the new locale
locale: 'mylocale'
};
</pre>
<h3 id="available-locales">Available locales</h3>
<p>
Timeline comes with support for the following locales:
</p>
<table>
<tr><th>Language</th><th>Code</th></tr>
<tr>
<td>English</td>
<td>
<code>en</code><br>
<code>en_EN</code><br>
<code>en_US</code>
</td>
</tr>
<tr>
<td>Dutch</td>
<td>
<code>nl</code><br>
<code>nl_NL</code><br>
<code>nl_BE</code>
</td>
</tr>
</table>
<h2 id="Styles">Styles</h2>
<p>
@ -1008,7 +1081,6 @@ A full example is available here: &lt;/style&gt;
</pre>
<h2 id="Data_Policy">Data Policy</h2>
<p>
All code and data is processed and rendered in the browser.

+ 16
- 16
examples/graph2d/01_basic.html View File

@ -2,8 +2,8 @@
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Graph2d | Basic Example</title>
<style type="text/css">
@ -18,13 +18,13 @@
<body>
<h2>Graph2d | Basic Example</h2>
<div style="width:700px; font-size:14px; text-align: justify;">
This example shows the most basic functionality of the vis.js Graph2d module. An array or a vis.Dataset can be used as input.
In the following examples we'll explore the options Graph2d offest for customization. This example uses all default settings.
There are 10 predefined styles that will be cycled through automatically when you add different groups. Alternatively you can
create your own styling.
<br /><br />
This example shows the most basic functionality of the vis.js Graph2d module. An array or a vis.Dataset can be used as input.
In the following examples we'll explore the options Graph2d offest for customization. This example uses all default settings.
There are 10 predefined styles that will be cycled through automatically when you add different groups. Alternatively you can
create your own styling.
<br /><br />
Graph2d is built upon the framework of the newly refactored timeline. A lot of the timeline options will also apply to Graph2d.
In these examples however, we will focus on what's new in Graph2d!
In these examples however, we will focus on what's new in Graph2d!
</div>
<br />
<div id="visualization"></div>
@ -33,18 +33,18 @@
var container = document.getElementById('visualization');
var items = [
{x: '2014-06-11', y: 10},
{x: '2014-06-12', y: 25},
{x: '2014-06-13', y: 30},
{x: '2014-06-14', y: 10},
{x: '2014-06-15', y: 15},
{x: '2014-06-16', y: 30}
{x: '2014-06-11', y: 10},
{x: '2014-06-12', y: 25},
{x: '2014-06-13', y: 30},
{x: '2014-06-14', y: 10},
{x: '2014-06-15', y: 15},
{x: '2014-06-16', y: 30}
];
var dataset = new vis.DataSet(items);
var options = {
start: '2014-06-10',
end: '2014-06-18'
start: '2014-06-10',
end: '2014-06-18'
};
var graph2d = new vis.Graph2d(container, dataset, options);

+ 65
- 0
examples/graph2d/13_localization.html View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Graph2d | Localization</title>
<style type="text/css">
body, html, select {
font-family: sans-serif;
font-size: 11pt;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment-with-langs.min.js"></script>
<script src="../../dist/vis.js"></script>
<link href="../../dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h2>Graph2d | Localization</h2>
<p>
To localize Graph2d, one has to load a version of moment.js including locales. To set a locale, specify option <code>{locale: STRING}</code>.
</p>
<p>
<label for="locale">Select a locale:</label>
<select id="locale">
<option value="en" selected>en</option>
<option value="nl">nl</option>
</select>
</p>
<div id="visualization"></div>
<script type="text/javascript">
var container = document.getElementById('visualization');
var items = [
{x: '2014-06-11', y: 10},
{x: '2014-06-12', y: 25},
{x: '2014-06-13', y: 30},
{x: '2014-06-14', y: 10},
{x: '2014-06-15', y: 15},
{x: '2014-06-16', y: 30}
];
var dataset = new vis.DataSet(items);
var options = {
start: '2014-06-10',
end: '2014-06-18'
};
var graph2d = new vis.Graph2d(container, dataset, options);
// update the locale when changing the select box value
var select = document.getElementById('locale');
select.onchange = function () {
graph2d.setOptions({
locale: this.value
});
};
select.onchange();
</script>
</body>
</html>

+ 1
- 0
examples/graph2d/index.html View File

@ -19,6 +19,7 @@
<p><a href="10_barsSideBySide.html">10_barsSideBySide.html</a></p>
<p><a href="11_barsSideBySideGroups.html">11_barsSideBySideGroups.html</a></p>
<p><a href="12_customRange.html">12_customRange.html</a></p>
<p><a href="13_localization.html">13_localization.html</a></p>
</div>
</body>

+ 231
- 0
examples/network/31_localization.html View File

@ -0,0 +1,231 @@
<!doctype html>
<html>
<head>
<title>Network | Localization</title>
<style type="text/css">
body, select {
font: 10pt sans;
}
#mynetwork {
position:relative;
width: 600px;
height: 600px;
border: 1px solid lightgray;
}
table.legend_table {
font-size: 11px;
border-width:1px;
border-color:#d3d3d3;
border-style:solid;
}
table.legend_table,td {
border-width:1px;
border-color:#d3d3d3;
border-style:solid;
padding: 2px;
}
div.table_content {
width:80px;
text-align:center;
}
div.table_description {
width:100px;
}
#operation {
font-size:28px;
}
#network-popUp {
display:none;
position:absolute;
top:350px;
left:170px;
z-index:299;
width:250px;
height:120px;
background-color: #f9f9f9;
border-style:solid;
border-width:3px;
border-color: #5394ed;
padding:10px;
text-align: center;
}
</style>
<script type="text/javascript" src="../../dist/vis.js"></script>
<link type="text/css" rel="stylesheet" href="../../dist/vis.css">
<script type="text/javascript">
var nodes = null;
var edges = null;
var network = null;
function draw() {
nodes = [];
edges = [];
var connectionCount = [];
// randomly create some nodes and edges
var nodeCount = 25;
for (var i = 0; i < nodeCount; i++) {
nodes.push({
id: i,
label: String(i)
});
connectionCount[i] = 0;
// create edges in a scale-free-network way
if (i == 1) {
var from = i;
var to = 0;
edges.push({
from: from,
to: to
});
connectionCount[from]++;
connectionCount[to]++;
}
else if (i > 1) {
var conn = edges.length * 2;
var rand = Math.floor(Math.random() * conn);
var cum = 0;
var j = 0;
while (j < connectionCount.length && cum < rand) {
cum += connectionCount[j];
j++;
}
var from = i;
var to = j;
edges.push({
from: from,
to: to
});
connectionCount[from]++;
connectionCount[to]++;
}
}
// create a network
var container = document.getElementById('mynetwork');
var data = {
nodes: nodes,
edges: edges
};
var options = {
stabilize: false,
dataManipulation: true,
onAdd: function(data,callback) {
var span = document.getElementById('operation');
var idInput = document.getElementById('node-id');
var labelInput = document.getElementById('node-label');
var saveButton = document.getElementById('saveButton');
var cancelButton = document.getElementById('cancelButton');
var div = document.getElementById('network-popUp');
span.innerHTML = "Add Node";
idInput.value = data.id;
labelInput.value = data.label;
saveButton.onclick = saveData.bind(this,data,callback);
cancelButton.onclick = clearPopUp.bind();
div.style.display = 'block';
},
onEdit: function(data,callback) {
var span = document.getElementById('operation');
var idInput = document.getElementById('node-id');
var labelInput = document.getElementById('node-label');
var saveButton = document.getElementById('saveButton');
var cancelButton = document.getElementById('cancelButton');
var div = document.getElementById('network-popUp');
span.innerHTML = "Edit Node";
idInput.value = data.id;
labelInput.value = data.label;
saveButton.onclick = saveData.bind(this,data,callback);
cancelButton.onclick = clearPopUp.bind();
div.style.display = 'block';
},
onConnect: function(data,callback) {
if (data.from == data.to) {
var r=confirm("Do you want to connect the node to itself?");
if (r==true) {
callback(data);
}
}
else {
callback(data);
}
}
};
network = new vis.Network(container, data, options);
// add event listeners
network.on('select', function(params) {
document.getElementById('selection').innerHTML = 'Selection: ' + params.nodes;
});
network.on("resize", function(params) {console.log(params.width,params.height)});
function clearPopUp() {
var saveButton = document.getElementById('saveButton');
var cancelButton = document.getElementById('cancelButton');
saveButton.onclick = null;
cancelButton.onclick = null;
var div = document.getElementById('network-popUp');
div.style.display = 'none';
}
function saveData(data,callback) {
var idInput = document.getElementById('node-id');
var labelInput = document.getElementById('node-label');
var div = document.getElementById('network-popUp');
data.id = idInput.value;
data.label = labelInput.value;
clearPopUp();
callback(data);
}
// update the locale when changing the select box value
var select = document.getElementById('locale');
select.onchange = function () {
network.setOptions({
locale: this.value
});
};
select.onchange();
}
</script>
</head>
<body onload="draw();">
<h2>Editing the dataset (localized)</h2>
<p style="width: 700px; font-size:14px; text-align: justify;">
This is the same example as <a href="21_data_manipulation.html">21_data_manipulation.html</a>, except that there is a select box added which allows to switch locale. The localization is only relevant to the manipulation buttons.
</p>
<p>
<label for="locale">Select a locale:</label>
<select id="locale">
<option value="en" selected>en</option>
<option value="nl">nl</option>
</select>
</p>
<div id="network-popUp">
<span id="operation">node</span> <br>
<table style="margin:auto;"><tr>
<td>id</td><td><input id="node-id" value="new value"></td>
</tr>
<tr>
<td>label</td><td><input id="node-label" value="new value"> </td>
</tr></table>
<input type="button" value="save" id="saveButton"></button>
<input type="button" value="cancel" id="cancelButton"></button>
</div>
<br />
<div id="mynetwork"></div>
<p id="selection"></p>
</body>
</html>

+ 1
- 0
examples/network/index.html View File

@ -42,6 +42,7 @@
<p><a href="28_world_cup_network_performance.html">28_world_cup_network_performance.html</a></p>
<p><a href="29_neighbourhood_highlight.html">29_neighbourhood_highlight.html</a></p>
<p><a href="30_importing_from_gephi.html">30_importing_from_gephi.html</a></p>
<p><a href="31_localization.html">31_localization.html</a></p>
<p><a href="graphviz/graphviz_gallery.html">graphviz_gallery.html</a></p>
</div>

+ 65
- 0
examples/timeline/19_localization.html View File

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Timeline | Localization</title>
<style type="text/css">
body, html, select {
font-family: sans-serif;
font-size: 11pt;
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.7.0/moment-with-langs.min.js"></script>
<script src="../../dist/vis.js"></script>
<link href="../../dist/vis.css" rel="stylesheet" type="text/css" />
</head>
<body>
<p>
To localize the Timeline, one has to load a version of moment.js including locales. To set a locale, specify option <code>{locale: STRING}</code>.
</p>
<p>
<label for="locale">Select a locale:</label>
<select id="locale">
<option value="en" selected>en</option>
<option value="nl">nl</option>
</select>
</p>
<div id="visualization"></div>
<script type="text/javascript">
var DAY = 24 * 60 * 60 * 1000;
// 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: new Date(new Date().valueOf() - DAY)},
{id: 2, content: 'item 2', start: new Date(new Date().valueOf() + 2 * DAY)}
]);
// Configuration for the Timeline
var options = {
showCurrentTime: true,
showCustomTime: true
};
// Create a Timeline
var timeline = new vis.Timeline(container, items, options);
timeline.setCustomTime(new Date(new Date().valueOf() + DAY));
// update the locale when changing the select box value
var select = document.getElementById('locale');
select.onchange = function () {
timeline.setOptions({
locale: this.value
});
};
select.onchange();
</script>
</body>
</html>

+ 1
- 0
examples/timeline/index.html View File

@ -30,6 +30,7 @@
<p><a href="16_navigation_menu.html">16_navigation_menu.html</a></p>
<p><a href="17_data_serialization.html">17_data_serialization.html</a></p>
<p><a href="18_range_overflow.html">18_range_overflow.html</a></p>
<p><a href="19_localization.html">19_localization.html</a></p>
<p><a href="requirejs/requirejs_example.html">requirejs_example.html</a></p>

+ 7
- 18
lib/network/Network.js View File

@ -13,6 +13,7 @@ var Node = require('./Node');
var Edge = require('./Edge');
var Popup = require('./Popup');
var MixinLoader = require('./mixins/MixinLoader');
var locales = require('./locales');
// Load custom shapes into CanvasRenderingContext2D
require('./shapes');
@ -188,24 +189,8 @@ function Network (container, data, options) {
minVelocity: 0.1, // px/s
stabilize: true, // stabilize before displaying the network
stabilizationIterations: 1000, // maximum number of iteration to stabilize
labels:{
add:"Add Node",
edit:"Edit",
link:"Add Link",
del:"Delete selected",
editNode:"Edit Node",
editEdge:"Edit Edge",
back:"Back",
addDescription:"Click in an empty space to place a new node.",
linkDescription:"Click on a node and drag the edge to another node to connect them.",
editEdgeDescription:"Click on the control points and drag them to a node to connect to it.",
addError:"The function for add does not support two arguments (data,callback).",
linkError:"The function for connect does not support two arguments (data,callback).",
editError:"The function for edit does not support two arguments (data, callback).",
editBoundError:"No edit function has been bound to this button.",
deleteError:"The function for delete does not support two arguments (data, callback).",
deleteClusterError:"Clusters cannot be deleted."
},
locale: 'en',
locales: locales,
tooltip: {
delay: 300,
fontColor: 'black',
@ -662,6 +647,10 @@ Network.prototype.setOptions = function (options) {
this.constants.tooltip.color = util.parseColor(options.tooltip.color);
}
}
if (options.labels) {
throw new Error('Option "labels" is deprecated. Use options "locale" and "locales" instead.');
}
}
// (Re)loading the mixins that can be enabled or disabled in the options.

+ 35
- 0
lib/network/locales.js View File

@ -0,0 +1,35 @@
// English
exports['en'] = {
add: 'Add Node',
edit: 'Edit',
link: 'Add Link',
del: 'Delete selected',
editNode: 'Edit Node',
editEdge: 'Edit Edge',
back: 'Back',
addDescription: 'Click in an empty space to place a new node.',
linkDescription: 'Click on a node and drag the edge to another node to connect them.',
editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.',
createEdgeError: 'Cannot link edges to a cluster.',
deleteClusterError: 'Clusters cannot be deleted.'
};
exports['en_EN'] = exports['en'];
exports['en_US'] = exports['en'];
// Dutch
exports['nl'] = {
add: 'Node',
edit: 'Wijzigen',
link: 'Link toevoegen',
del: 'Selectie verwijderen',
editNode: 'Node wijzigen',
editEdge: 'Link wijzigen',
back: 'Terug',
addDescription: 'Klik op een leeg gebied om een nieuwe node te maken.',
linkDescription: 'Klik op een node en sleep de link naar een andere node om ze te verbinden.',
editEdgeDescription: 'Klik op de verbindingspunten en sleep ze naar een node om daarmee te verbinden.',
createEdgeError: 'Kan geen link maken naar een cluster.',
deleteClusterError: 'Clusters kunnen niet worden verwijderd.'
};
exports['nl_NL'] = exports['nl'];
exports['nl_BE'] = exports['nl'];

+ 1
- 1
lib/network/mixins/HierarchicalLayoutMixin.js View File

@ -57,7 +57,7 @@ exports._setupHierarchicalLayout = function() {
// if the user defined some levels but not all, alert and run without hierarchical layout
if (undefinedLevel == true && definedLevel == true) {
alert("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");
throw new Error("To use the hierarchical layout, nodes require either no predefined levels or levels have to be defined for all nodes.");
this.zoomExtent(true,this.constants.clustering.enabled);
if (!this.constants.clustering.enabled) {
this.start();

+ 31
- 21
lib/network/mixins/ManipulationMixin.js View File

@ -64,6 +64,8 @@ exports._createManipulatorBar = function() {
this.off('select', this.boundFunction);
}
var locale = this.constants.locales[this.constants.locale];
if (this.edgeBeingEdited !== undefined) {
this.edgeBeingEdited._disableControlNodes();
this.edgeBeingEdited = undefined;
@ -85,30 +87,31 @@ exports._createManipulatorBar = function() {
while (this.manipulationDiv.hasChildNodes()) {
this.manipulationDiv.removeChild(this.manipulationDiv.firstChild);
}
// add the icons to the manipulator div
this.manipulationDiv.innerHTML = "" +
"<span class='network-manipulationUI add' id='network-manipulate-addNode'>" +
"<span class='network-manipulationLabel'>"+this.constants.labels['add'] +"</span></span>" +
"<span class='network-manipulationLabel'>"+locale['add'] +"</span></span>" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI connect' id='network-manipulate-connectNode'>" +
"<span class='network-manipulationLabel'>"+this.constants.labels['link'] +"</span></span>";
"<span class='network-manipulationLabel'>"+locale['link'] +"</span></span>";
if (this._getSelectedNodeCount() == 1 && this.triggerFunctions.edit) {
this.manipulationDiv.innerHTML += "" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI edit' id='network-manipulate-editNode'>" +
"<span class='network-manipulationLabel'>"+this.constants.labels['editNode'] +"</span></span>";
"<span class='network-manipulationLabel'>"+locale['editNode'] +"</span></span>";
}
else if (this._getSelectedEdgeCount() == 1 && this._getSelectedNodeCount() == 0) {
this.manipulationDiv.innerHTML += "" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI edit' id='network-manipulate-editEdge'>" +
"<span class='network-manipulationLabel'>"+this.constants.labels['editEdge'] +"</span></span>";
"<span class='network-manipulationLabel'>"+locale['editEdge'] +"</span></span>";
}
if (this._selectionIsEmpty() == false) {
this.manipulationDiv.innerHTML += "" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI delete' id='network-manipulate-delete'>" +
"<span class='network-manipulationLabel'>"+this.constants.labels['del'] +"</span></span>";
"<span class='network-manipulationLabel'>"+locale['del'] +"</span></span>";
}
@ -138,7 +141,7 @@ exports._createManipulatorBar = function() {
else {
this.editModeDiv.innerHTML = "" +
"<span class='network-manipulationUI edit editmode' id='network-manipulate-editModeButton'>" +
"<span class='network-manipulationLabel'>" + this.constants.labels['edit'] + "</span></span>";
"<span class='network-manipulationLabel'>" + locale['edit'] + "</span></span>";
var editModeButton = document.getElementById("network-manipulate-editModeButton");
editModeButton.onclick = this._toggleEditMode.bind(this);
}
@ -158,13 +161,15 @@ exports._createAddNodeToolbar = function() {
this.off('select', this.boundFunction);
}
var locale = this.constants.locales[this.constants.locale];
// create the toolbar contents
this.manipulationDiv.innerHTML = "" +
"<span class='network-manipulationUI back' id='network-manipulate-back'>" +
"<span class='network-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
"<span class='network-manipulationLabel'>" + locale['back'] + " </span></span>" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI none' id='network-manipulate-back'>" +
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + this.constants.labels['addDescription'] + "</span></span>";
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + locale['addDescription'] + "</span></span>";
// bind the icon
var backButton = document.getElementById("network-manipulate-back");
@ -187,6 +192,8 @@ exports._createAddEdgeToolbar = function() {
this._unselectAll(true);
this.freezeSimulation = true;
var locale = this.constants.locales[this.constants.locale];
if (this.boundFunction) {
this.off('select', this.boundFunction);
}
@ -197,10 +204,10 @@ exports._createAddEdgeToolbar = function() {
this.manipulationDiv.innerHTML = "" +
"<span class='network-manipulationUI back' id='network-manipulate-back'>" +
"<span class='network-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
"<span class='network-manipulationLabel'>" + locale['back'] + " </span></span>" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI none' id='network-manipulate-back'>" +
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + this.constants.labels['linkDescription'] + "</span></span>";
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + locale['linkDescription'] + "</span></span>";
// bind the icon
var backButton = document.getElementById("network-manipulate-back");
@ -237,12 +244,14 @@ exports._createEditEdgeToolbar = function() {
this.edgeBeingEdited = this._getSelectedEdge();
this.edgeBeingEdited._enableControlNodes();
var locale = this.constants.locales[this.constants.locale];
this.manipulationDiv.innerHTML = "" +
"<span class='network-manipulationUI back' id='network-manipulate-back'>" +
"<span class='network-manipulationLabel'>" + this.constants.labels['back'] + " </span></span>" +
"<span class='network-manipulationLabel'>" + locale['back'] + " </span></span>" +
"<div class='network-seperatorLine'></div>" +
"<span class='network-manipulationUI none' id='network-manipulate-back'>" +
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + this.constants.labels['editEdgeDescription'] + "</span></span>";
"<span id='network-manipulatorLabel' class='network-manipulationLabel'>" + locale['editEdgeDescription'] + "</span></span>";
// bind the icon
var backButton = document.getElementById("network-manipulate-back");
@ -328,9 +337,10 @@ exports._releaseControlNode = function(pointer) {
exports._handleConnect = function(pointer) {
if (this._getSelectedNodeCount() == 0) {
var node = this._getNodeAt(pointer);
if (node != null) {
if (node.clusterSize > 1) {
alert("Cannot create edges to a cluster.")
alert(this.constants.locales[this.constants.locale]['createEdgeError'])
}
else {
this._selectObject(node,false);
@ -386,7 +396,7 @@ exports._finishConnect = function(pointer) {
var node = this._getNodeAt(pointer);
if (node != null) {
if (node.clusterSize > 1) {
alert("Cannot create edges to a cluster.")
alert(this.constants.locales[this.constants.locale]["createEdgeError"])
}
else {
this._createEdge(connectFromId,node.id);
@ -416,7 +426,7 @@ exports._addNode = function() {
});
}
else {
alert(this.constants.labels['addError']);
throw new Error('The function for add does not support two arguments (data,callback)');
this._createManipulatorBar();
this.moving = true;
this.start();
@ -450,7 +460,7 @@ exports._createEdge = function(sourceNodeId,targetNodeId) {
});
}
else {
alert(this.constants.labels["linkError"]);
throw new Error('The function for connect does not support two arguments (data,callback)');
this.moving = true;
this.start();
}
@ -481,7 +491,7 @@ exports._editEdge = function(sourceNodeId,targetNodeId) {
});
}
else {
alert(this.constants.labels["linkError"]);
throw new Error('The function for edit does not support two arguments (data, callback)');
this.moving = true;
this.start();
}
@ -524,11 +534,11 @@ exports._editNode = function() {
});
}
else {
alert(this.constants.labels["editError"]);
throw new Error('The function for edit does not support two arguments (data, callback)');
}
}
else {
alert(this.constants.labels["editBoundError"]);
throw new Error('No edit function has been bound to this button');
}
};
@ -558,7 +568,7 @@ exports._deleteSelected = function() {
});
}
else {
alert(this.constants.labels["deleteError"])
throw new Error('The function for delete does not support two arguments (data, callback)')
}
}
else {
@ -570,7 +580,7 @@ exports._deleteSelected = function() {
}
}
else {
alert(this.constants.labels["deleteClusterError"]);
alert(this.constants.locales[this.constants.locale]["deleteClusterError"]);
}
}
};

+ 12
- 3
lib/timeline/component/CurrentTime.js View File

@ -1,5 +1,7 @@
var util = require('../../util');
var Component = require('./Component');
var moment = require('../../module/moment');
var locales = require('../locales');
/**
* A current time bar
@ -14,7 +16,10 @@ function CurrentTime (body, options) {
// default options
this.defaultOptions = {
showCurrentTime: true
showCurrentTime: true,
locales: locales,
locale: 'en'
};
this.options = util.extend({}, this.defaultOptions);
@ -57,7 +62,7 @@ CurrentTime.prototype.destroy = function () {
CurrentTime.prototype.setOptions = function(options) {
if (options) {
// copy all options that we know
util.selectiveExtend(['showCurrentTime'], this.options, options);
util.selectiveExtend(['showCurrentTime', 'locale', 'locales'], this.options, options);
}
};
@ -81,8 +86,12 @@ CurrentTime.prototype.redraw = function() {
var now = new Date();
var x = this.body.util.toScreen(now);
var locale = this.options.locales[this.options.locale];
var title = locale.current + ' ' + locale.time + ': ' + moment(now).format('dddd, MMMM Do YYYY, H:mm:ss');
title = title.charAt(0).toUpperCase() + title.substring(1);
this.bar.style.left = x + 'px';
this.bar.title = 'Current time: ' + now;
this.bar.title = title;
}
else {
// remove the line from the DOM

+ 11
- 3
lib/timeline/component/CustomTime.js View File

@ -1,6 +1,8 @@
var Hammer = require('../../module/hammer');
var util = require('../../util');
var Component = require('./Component');
var moment = require('../../module/moment');
var locales = require('../locales');
/**
* A custom time bar
@ -16,7 +18,9 @@ function CustomTime (body, options) {
// default options
this.defaultOptions = {
showCustomTime: false
showCustomTime: false,
locales: locales,
locale: 'en'
};
this.options = util.extend({}, this.defaultOptions);
@ -39,7 +43,7 @@ CustomTime.prototype = new Component();
CustomTime.prototype.setOptions = function(options) {
if (options) {
// copy all options that we know
util.selectiveExtend(['showCustomTime'], this.options, options);
util.selectiveExtend(['showCustomTime', 'locale', 'locales'], this.options, options);
}
};
@ -102,8 +106,12 @@ CustomTime.prototype.redraw = function () {
var x = this.body.util.toScreen(this.customTime);
var locale = this.options.locales[this.options.locale];
var title = locale.time + ': ' + moment(this.customTime).format('dddd, MMMM Do YYYY, H:mm:ss');
title = title.charAt(0).toUpperCase() + title.substring(1);
this.bar.style.left = x + 'px';
this.bar.title = 'Time: ' + this.customTime;
this.bar.title = title;
}
else {
// remove the line from the DOM

+ 13
- 0
lib/timeline/component/TimeAxis.js View File

@ -1,6 +1,7 @@
var util = require('../../util');
var Component = require('./Component');
var TimeStep = require('../TimeStep');
var moment = require('../../module/moment');
/**
* A horizontal time axis
@ -63,6 +64,18 @@ TimeAxis.prototype.setOptions = function(options) {
if (options) {
// copy all options that we know
util.selectiveExtend(['orientation', 'showMinorLabels', 'showMajorLabels'], this.options, options);
// apply locale to moment.js
// TODO: not so nice, this is applied globally to moment.js
if ('locale' in options) {
if (typeof moment.locale === 'function') {
// moment.js 2.8.1+
moment.locale(options.locale);
}
else {
moment.lang(options.locale);
}
}
}
};

+ 15
- 0
lib/timeline/locales.js View File

@ -0,0 +1,15 @@
// English
exports['en'] = {
current: 'current',
time: 'time'
};
exports['en_EN'] = exports['en'];
exports['en_US'] = exports['en'];
// Dutch
exports['nl'] = {
custom: 'aangepaste',
time: 'tijd'
};
exports['nl_NL'] = exports['nl'];
exports['nl_BE'] = exports['nl'];

Loading…
Cancel
Save