Leverage the power of EchartsJS and LeafletJS to visualize network topology using the
NetJSON NetworkGraph
format.
Build powerful and interoperable visualizations without losing flexibility!
yarn install
yarn start
netjsongraph.js accepts two arguments.
- url (required, string|array|object): URL(s) to fetch the JSON data from. It supports both NetJSON and GeoJSON data formats. You can also pass a NetJSON or GeoJSON object directly.
NetJSON format used internally is based on networkgraph but with a slight difference as follows:
{
nodes: [{
properties ? : {
// Define node category
category ? : String,
/*
Define the geographic coordinates of the node.
Required when rendering a map.
*/
location ? : {
lng: Float,
lat: Float,
},
// Define node updated time
time ? : String
}
}],
links: [{
properties ? : {
// Define link updated time
time ? : String
}
}]
flatNodes ? : {
<node id>: node Object
}
}
- options (optional, object): custom options described below
-
el
Default:
body
The element which the graph or map is rendered. You can pass any valid element name or class name or id.
-
render
Default:
graph
The rendering mode. You can render the map by setting it as
map
. -
metadata
Default:
true
Whether to show NetJSON NetworkGraph metadata or not. You can also set it
false
to disable it. -
svgRender
Default:
false
Whether to render it as SVG or not. You can also set it
true
to enable it. Canvas is used when it is set tofalse
. -
switchMode
Default:
false
Whether to allow switching between graph and map render or not. You can also set it
true
to enable it. -
showLabelsAtZoomLevel
Default:
7
The zoom level at which the labels are shown. This only works when
render
is set tomap
. In graph mode, the overlapping labels are hidden automatically when zooming. -
maxPointsFetched
Default:
10000
The maximum number of nodes to fetch from the server.
-
loadMoreAtZoomLevel
Default:
9
The zoom level at which more nodes are loaded from the server when the total number of nodes are greater than
maxPointsFetched
. These nodes are loaded based on the geographic extent of the map. -
clustering
Default:
false
Whether to enable clustering of nodes or not. You can also set it
true
to enable it. -
clusteringThreshold
Default:
100
The threshold of clustering. When the number of nodes is greater than this value, the clustering will be enabled.
-
disableClusteringAtLevel
Default:
8
The zoom level at which clustering is disabled. When the zoom level is greater than this value, all the clusters will be expanded.
-
clusterRadius
Default:
80
The maximum radius that a cluster will cover. Decreasing will make more, smaller clusters and vice versa.
-
clusteringAttribute
The property used to cluster the nodes. The nodes with the same properties will be clustered together.
-
dealDataByWorker
The url to the worker file if you want to deal the data by a worker.
-
echartsOption
The global configuration for Echarts. You can pass any valid Echarts options.
-
graphConfig
The configuration for the graph render. It consists of the following properties:
graphConfig:{ series:{ nodeStyle:{ // The style of the nodes }, linkStyle:{ // The style of the links }, nodeSize: string|number, }, baseOptions:{ // The global configuration for Echarts specifically for the graph. } }
You can see the list available options which can be used in the
series
property of thegraphConfig
in the Echarts documentation.The
nodeStyle
andlinkStyle
properties are used to customize the style of the nodes and links. The list of all available style properties can be found in the Echarts documentation.The
nodeSize
property is used to customize the size of the nodes.The
baseOptions
property is used to customize the global configuration for Echarts specifically for the graph. This is useful when you have setswitchMode
totrue
and you have to set separate configuration for the graph and the map. -
mapOptions
The configuration for the map render. It consists of the following properties:
mapOptions:{ nodeConfig:{ nodeStyle:{ // The style of the nodes }, nodeSize: string|number, }, linkConfig:{ linkStyle:{ // The style of the links }, }, clusterConfig:{ // The configuration for the clusters }, baseOptions:{ // The global configuration for Echarts specifically for the map. } }
We use Leaflet to render the map. You can also pass any valid Leaflet options in
mapOptions
.It is mandatory to set
center
inmapOptions
when you are using the map render which is used to set the initial geographic center of the map. You can learn more about it in the Leaflet documentation.nodeConfig
deals with the configuration of the nodes. You can pass any valid Echarts options innodeConfig
.The
nodeStyle
property is used to customize the style of the nodes. The list of all available style properties can be found in the Echarts documentation.The
nodeSize
property is used to customize the size of the nodes.The
clusterConfig
property is used to customize the clusters. You can pass any valid Echarts options inclusterConfig
. If you are using GeoJSON data, you can customize the cluster styles by using the CSS classmarker-cluster
. You can also use property values when clustering based on data properties as class names.linkConfig
deals with the configuration of the links. You can pass any valid Echarts options inlinkConfig
.The
linkStyle
property is used to customize the style of the links. The list of all available style properties can be found in the Echarts documentation. -
mapTileConfig
The configuration for the map tiles. You can use multiple tiles by passing an array of tile configurations.
mapTileConfig:[ ..., { label: string, urlTemplate: string, options:{ minZoom: number, maxZoom: number, attribution: string, } }, ... ]
urlTemplate
is the URL template of the tile provider. You can learn more about the options in the Leaflet documentation. -
nodeCategories
The configuration for different categories of nodes if your data contain nodes of various categories. You can pass an array of categories. Each category is an object with the following properties:
nodeCategories:[ ..., { name: string, nodeStyle: { // The style of the nodes }, nodeSize: string|number, }, ... ]
name
is the name of the category. You can also pass any valid Echarts options innodeStyle
. -
linkCategories
The configuration for different categories of links if your data contain links of various categories. You can pass an array of categories. Each category is an object with the following properties:
linkCategories:[ ..., { name: string, linkStyle: { // The style of the links }, }, ... ]
name
is the name of the category. You can also pass any valid Echarts options inlinkStyle
. -
geoOptions
The configuration for the GeoJSON render. It consists of the following properties:
geoOptions:{ style:{ // The style GeoJSON features }, }
You can customize the style of GeoJSON features using
style
property. The list of all available properties can be found in the Leaflet documentation. -
onInit
The callback function executed on initialization of
NetJSONGraph
instance. -
onRender
The callback function executed at the start of initial render.
-
onUpdate
The callback function executed at the start of update.
-
afterUpdate
The callback function executed after update.
-
onReady
The Callback function executed after initial render.
-
prepareData
The callback function executed after data has been loaded. Used to convert data to NetJSON Data normally. You can also use this function to categorize the data based on certain properties in your dataset.
-
onClickElement
The callback function executed when a node or link is clicked.
netjsongraph.js mainly relies on the Echarts for rendering, so the related configuration is mainly inherited from Echarts.
The library mainly supports two rendering modes -- graph
and map
. You can choose either of these and set it in render
property in options.
In extreme cases, you can also pass your own render function if you don't want Echarts to render. We will pass in the processed netjson data and netjsongraph object.
For graph, you need to configure graphConfig
property. We only support graph and graphGL. The main difference between graph and graphGL is the forceAtlas2
param series in Echarts. The latter is mainly used for big data rendering. You can use graphGL by setting graphConfig.type
to graphGL
. We use graph series and force layout by default. You can modify them freely according to the documentation.
For map, you need to configure mapOptions
. The mapOptions
and mapTileConfig
are required for the map render. You can customize the nodes and links with nodeConfig
and linkConfig
optionally. For map nodes, you can also change the type
to effectScatter
series to enable animation effects.
You can also customize some global properties with echartsOption
in echarts.
-
setConfig
Method to set the configuration of the graph. You can use this function to add, update or modify the configuration of the graph.
-
setUtils
Method to set the utils of the graph. You can use this function to add, update the utils.
-
render
Method to render the graph.
We use socket.io to monitor data changes which supports WebSockets and Polling. You can call JSONDataUpdate
when the data change event occurs and pass the data to update the view.
/**
* @function
* @name JSONDataUpdate
* Callback function executed when data update. Update Information and view.
*
* @param {object|string} Data JSON data or url.
* @param {boolean} override If old data need to be overrided? True defaultly. (Attention: Only 'map' render can set it `false`!)
* @param {boolean} isRaw If the data need to deal with the configuration? True defaultly.
*
* @this {object} NetJSONGraph object
*
*/
const graph = new NetJSONGraph("./data/netjsonmap.json", {
render: "graph",
});
graph.render();
const socket = io("http://localhost:3000/",{ transports : ['websocket'] });
socket.on("connect", function() {
console.log("client connected");
});
socket.on("disconnect", function() {
console.log("client disconnected");
});
// Self-monitoring server, re-render when the data changes.
socket.on("netjsonChange", graph.utils.JSONDataUpdate.bind(graph));
You can see this in action by executing the following commands:
cd examples/realtime_update
yarn install
yarn dev
In this demo the nodes and links change after 5 seconds.
If you want to add search elements function, you just need to pass the url as param to searchElements
, which will return a function searchFunc
.
Then you just need to obtain the value input, and pass it to the searchFunc
.
searchFunc
is similar to JSONDataUpdate, you can also set appendData
and isRaw
params according to different conditions.
/**
* @function
* @name searchElements
* Add search function for new data.
*
* @param {string} url listen url
*
* @this {object} NetJSONGraph object
*
* @return {function} searchFunc
*/
const graph = new NetJSONGraph("./data/netjsonmap.json", {
onLoad: function(){
let searchContainer = document.createElement("div"),
searchInput = document.createElement("input"),
searchBtn = document.createElement("button"),
/*
Pass in the url to listen to, and save the returned function.
Please ensure that the return value of the api is the specified json format.
*/
searchFunc = this.utils.searchElements.call(this, "https://ee3bdf59-d14c-4280-b514-52bd3dfc2c17.mock.pstmn.io/?search=");
searchInput.setAttribute("class", "njg-searchInput");
searchInput.placeholder = "Input value for searching special elements.";
searchBtn.setAttribute("class", "njg-searchBtn");
searchBtn.innerHTML = "search";
searchContainer.setAttribute("class", "njg-searchContainer");
searchContainer.appendChild(searchInput);
searchContainer.appendChild(searchBtn);
this.el.appendChild(searchContainer);
searchInput.onchange = () => {
// do something to deal user input value.
};
searchBtn.onclick = () => {
let inputValue = searchInput.value.trim();
/*
Pass in the relevant search value,
which will re-render automatically according to the request result within the function.
*/
if(inputValue === "appendData"){
// appendData
searchFunc(inputValue, false);
}
else{
searchFunc(inputValue);
}
searchInput.value = "";
}
this.utils.hideLoading();
}
});
graph.render();
Demo is here.
You can input test
(overrideData) or appendData
(appendData) and click the search
button.
The view will change if the value is valid
, and you can also click the back button of browser to go back
.
You can deal with the data asynchronously by dealDataByWorker
.
/**
* @function
* @name dealDataByWorker
* Deal JSONData by WebWorker.
*
* @param {object} JSONData NetJSONData
* @param {string} workerFile url
* @param {function} callback override data and render defaultly.
*
* @this {object} _this NetJSONGraph object
*
*/
Demo is here.
You can simply set the dealDataByWorker
param in config to process the data asynchronously before rendering.
Of course you can also call the function directly.
We provide a function -- dataParse
for parsing the time
field.
We mainly use it to parse the time into the browser's current time zone based on the incoming matching rules.
/**
* @function
* @name dateParse
*
* Parse the time in the browser's current time zone based on the incoming matching rules.
* The exec result must be [date, year, month, day, hour, minute, second, millisecond?]
*
* @param {string} dateString "2000-12-31T23:59:59.999Z"
* @param {object(RegExp)} parseRegular /^([1-9]\d{3})-(\d{1,2})-(\d{1,2})T(\d{1,2}):(\d{1,2}):(\d{1,2})(?:\.(\d{1,3}))?Z$/ defaultly
* @param {number} hourDiffer you can custom time difference, default is the standard time difference
*
* @return {string} Date string
*/
If you provide time
field in node or link's properties, it'll display the parse date in the detail info defaultly.
Demo is here.
You can load more data from the server even when the total number of nodes are greater than maxPointsFetched
using geographic extent.
You can specify the zoom level at which more data is loaded by setting loadMoreDataZoomLevel
in the config.
You can see this in action by executing the following commands:
cd examples/load_data_geo_extent
yarn install
yarn start
-
generateGraphOption
Method to generate graph option in echarts by JSONData.
-
generateMapOption
Method to generate map option in echarts by JSONData.
-
graphRender
Render the final graph view based on JSONData.
-
mapRender
Render the final map view based on JSONData.
-
JSONParamParse
Parse JSONParam (string|object), return Promise object.
-
paginatedDataParse
Parse paginated response from the server. It accepts
JSONParam
as a parameter.
It uses cursor-based pagination by default.
If you want to parse from the server that uses some other pagination logic,
you can override this method usingsetUtils
method.graph.setUtils({ paginatedDataParse: async function(JSONParam){ // Implement your custom logic here } });
You can see the default implementation here.
-
getBBoxData
Load data which is inside the current bounding box of the map from the server. Accepts
JSONParam
andbounds
as the parameter.
If you want to implement your own logic or use a different API, you can override this method usingsetUtils
method.graph.setUtils({ getBBoxData: async function(JSONParam,bounds){ // Implement your custom logic here } });
-
makeCluster
Accepts NetJSONGraph instance as parameter and returns an object containing the cluster nodes, other individual nodes and links.
-
isObject
Check if the param is object.
-
isArray
Check if the param is array.
-
isElement
Check if the param is dom element.
-
deepMergeObj
Merge multiple objects deeply.
-
updateMetadata
Update metadata of JSONData.
-
getMetadata
Get the metadata object from JSONData.
-
nodeInfo
Get the node info object.
-
linkInfo
Get link info object.
-
createTooltipItem
Create tooltip item with a key and value in the tooltip modal.
-
getNodeTooltipInfo
Get node tooltip info html string.
-
getLinkTooltipInfo
Get link tooltip info html string.
-
generateStyle
Generate the style configuration of the node or link.
-
getNodeStyle
Get node style configuration.
-
getLinkStyle
Get link style configuration.
-
showLoading
Show loading animation. Used in onRender by default.
-
hideLoading
Hide loading animation. Used in onLoad defaultly.
-
createEvent
Create an event listener.
<!DOCTYPE html>
<html lang="en">
<head>
<title>netjsongraph.js: basic example</title>
<meta charset="utf-8">
<!-- theme can be easily customized via css -->
<link href="../src/css/netjsongraph-theme.css" rel="stylesheet">
<link href="../src/css/netjsongraph.css" rel="stylesheet">
</head>
<body>
<script type="text/javascript" src="../dist/netjsongraph.min.js"></script>
<script type="text/javascript">
const graph = new NetJSONGraph("../src/data/netjson.json", {
render: "graph",
});
graph.render();
</script>
</body>
</html>
The demo shows default graph
render.
Basic graph demo
The demo shows map
render.
Map demo
The demo shows how to use graphGL
to render big data.
graphGL(bigData) demo
The demo shows how to set custom attributes.
Custom attributes demo
The demo shows the multiple links render.
Currently only supports up to two links.
Multiple links demo
The demo is used to show how to deal with the multiple interfaces
in the NetJSON data.
We provide a work file to process the data before rendering.
This file provides functions to remove dirty data, deduplicate, handle multiple interfaces, add node links, add flatNodes and so on.
You can also define related files yourself.
Multiple interfaces demo
The demo is used to show the use of the dateParse
function.
You can set the node or link property value time
, we will call this function to parse the string in the element details defaultly.
Of course you can also call directly.
dateParse demo
The demo shows how to switch the netjsongraph render mode -- svg
or canvas
.
Switch render mode demo
The demo shows how to switch the netjsongraph render mode -- graph
or map
.
Switch graph mode demo
The demo is used to show the use of the searchElements
function.
For test, you can input test
or appendData
and click the search
button.
Search elements demo
The demo shows how to interact with elements.
Nodes expand or fold demo
The demo is used to show how to use the JSONDataUpdate
function to update data.
See other examples:
netjson-updateData.html: It chooses override data.
netjsonmap-appendData.html: It chooses append data.
JSONDataUpdate using override option demo
The demo shows hwo to set path animation.
Geographic map animated links demo
The demo is used to show how to set indoor map.
Mainly the operation of leaflet.
Indoor map demo
The demo is used to show how to use the leaflet plugins.
Mainly the operation of leaflet.
Leaflet plugins demo
The demo shows the multiple tiles render.
Map with multiple tiles demo
The demo is used to show how to use the JSONDataUpdate
function to update data.
Here we choose to append data by modify the default parameter.
See other examples:
netjson-updateData.html: It chooses override data.
netjsonmap-nodeTiles.html: override data by different zoom value.
JSONDataUpdate using append option demo
Using array files to append data step by step at start.
Similiar to the first method, but easier.
Append data using arrays demo
The demo shows the clustering of nodes.
Clustering demo
We advise all users of netjsongraph.js who are using the 0.1.x version to upgrade to the latest version.
The following steps explain how to upgrade.
- Download the latest version of netjsongraph.js
- Replace the old version of netjsongraph.min.js with the new version
- Replace the old version of netjsongraph-theme.css with the new version
- Replace the old version of netjsongraph.css with the new version
- Replace the deprecated options with the equivalent new options. See the Arguments section for more details.
The following list shows the deprecated options:
defaultStyle
scaleExtent
charge
linkDistance
linkStrength
friction
gravity
theta
chargeDistance
nodeClassProperty
linkClassProperty
circleRadius
labelDx
labelDy
onEnd
linkDistanceFunc
redraw
onClickNode
onClickLink
The function definition for onInit
and onLoad
has been changed:
passing any additional arguments to these functions is not needed anymore.
The option linkDistance
has been renamed to edgeLength
.
Options like edgeLength
, friction
, gravity
are now passed as an object
named force
in series
property of graphConfig
.
Learn more about graphConfig
by looking at the Arguments section.
Refer to the Echarts documentation for more details.
Use label
instead of labelDx
and labelDy
in the series
property of graphConfig
.
Refer to the Arguments section for more details.
You can learn more about label
in the
Echarts documentation.
Use onClickElement
instead of onClickNode
and onClickLink
.
Refer to the Arguments section section for more details.
- Fork it!
- Create your feature branch: git checkout -b my-new-feature
- Commit your changes: git commit -am 'Add some feature'
- Push to the branch: git push origin my-new-feature
- Submit a pull request :D