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
-
elDefault:
bodyThe element which the graph or map is rendered. You can pass any valid element name or class name or id.
-
renderDefault:
graphThe rendering mode. You can render the map by setting it as
map. -
metadataDefault:
trueWhether to show NetJSON NetworkGraph metadata or not. You can also set it
falseto disable it. -
svgRenderDefault:
falseWhether to render it as SVG or not. You can also set it
trueto enable it. Canvas is used when it is set tofalse. -
switchModeDefault:
falseWhether to allow switching between graph and map render or not. You can also set it
trueto enable it. -
showLabelsAtZoomLevelDefault:
7The zoom level at which the labels are shown. This only works when
renderis set tomap. In graph mode, the overlapping labels are hidden automatically when zooming. -
maxPointsFetchedDefault:
10000The maximum number of nodes to fetch from the server.
-
loadMoreAtZoomLevelDefault:
9The 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. -
clusteringDefault:
falseWhether to enable clustering of nodes or not. You can also set it
trueto enable it. -
clusteringThresholdDefault:
100The threshold of clustering. When the number of nodes is greater than this value, the clustering will be enabled.
-
disableClusteringAtLevelDefault:
8The zoom level at which clustering is disabled. When the zoom level is greater than this value, all the clusters will be expanded.
-
clusterRadiusDefault:
80The maximum radius that a cluster will cover. Decreasing will make more, smaller clusters and vice versa.
-
clusteringAttributeThe property used to cluster the nodes. The nodes with the same properties will be clustered together.
-
dealDataByWorkerThe url to the worker file if you want to deal the data by a worker.
-
echartsOptionThe global configuration for Echarts. You can pass any valid Echarts options.
-
graphConfigThe 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
seriesproperty of thegraphConfigin the Echarts documentation.The
nodeStyleandlinkStyleproperties 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
nodeSizeproperty is used to customize the size of the nodes.The
baseOptionsproperty is used to customize the global configuration for Echarts specifically for the graph. This is useful when you have setswitchModetotrueand you have to set separate configuration for the graph and the map. -
mapOptionsThe 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
centerinmapOptionswhen 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.nodeConfigdeals with the configuration of the nodes. You can pass any valid Echarts options innodeConfig.The
nodeStyleproperty is used to customize the style of the nodes. The list of all available style properties can be found in the Echarts documentation.The
nodeSizeproperty is used to customize the size of the nodes.The
clusterConfigproperty 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.linkConfigdeals with the configuration of the links. You can pass any valid Echarts options inlinkConfig.The
linkStyleproperty is used to customize the style of the links. The list of all available style properties can be found in the Echarts documentation. -
mapTileConfigThe 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, } }, ... ]
urlTemplateis the URL template of the tile provider. You can learn more about the options in the Leaflet documentation. -
nodeCategoriesThe 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, }, ... ]
nameis the name of the category. You can also pass any valid Echarts options innodeStyle. -
linkCategoriesThe 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 }, }, ... ]
nameis the name of the category. You can also pass any valid Echarts options inlinkStyle. -
geoOptionsThe 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
styleproperty. The list of all available properties can be found in the Leaflet documentation. -
onInitThe callback function executed on initialization of
NetJSONGraphinstance. -
onRenderThe callback function executed at the start of initial render.
-
onUpdateThe callback function executed at the start of update.
-
afterUpdateThe callback function executed after update.
-
onReadyThe Callback function executed after initial render.
-
prepareDataThe 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.
-
onClickElementThe 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.
-
setConfigMethod to set the configuration of the graph. You can use this function to add, update or modify the configuration of the graph.
-
setUtilsMethod to set the utils of the graph. You can use this function to add, update the utils.
-
renderMethod 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
-
generateGraphOptionMethod to generate graph option in echarts by JSONData.
-
generateMapOptionMethod to generate map option in echarts by JSONData.
-
graphRenderRender the final graph view based on JSONData.
-
mapRenderRender the final map view based on JSONData.
-
JSONParamParseParse JSONParam (string|object), return Promise object.
-
paginatedDataParseParse paginated response from the server. It accepts
JSONParamas 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 usingsetUtilsmethod.graph.setUtils({ paginatedDataParse: async function(JSONParam){ // Implement your custom logic here } });
You can see the default implementation here.
-
getBBoxDataLoad data which is inside the current bounding box of the map from the server. Accepts
JSONParamandboundsas the parameter.
If you want to implement your own logic or use a different API, you can override this method usingsetUtilsmethod.graph.setUtils({ getBBoxData: async function(JSONParam,bounds){ // Implement your custom logic here } });
-
makeClusterAccepts NetJSONGraph instance as parameter and returns an object containing the cluster nodes, other individual nodes and links.
-
isObjectCheck if the param is object.
-
isArrayCheck if the param is array.
-
isElementCheck if the param is dom element.
-
deepMergeObjMerge multiple objects deeply.
-
updateMetadataUpdate metadata of JSONData.
-
getMetadataGet the metadata object from JSONData.
-
nodeInfoGet the node info object.
-
linkInfoGet link info object.
-
createTooltipItemCreate tooltip item with a key and value in the tooltip modal.
-
getNodeTooltipInfoGet node tooltip info html string.
-
getLinkTooltipInfoGet link tooltip info html string.
-
generateStyleGenerate the style configuration of the node or link.
-
getNodeStyleGet node style configuration.
-
getLinkStyleGet link style configuration.
-
showLoadingShow loading animation. Used in onRender by default.
-
hideLoadingHide loading animation. Used in onLoad defaultly.
-
createEventCreate 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:
defaultStylescaleExtentchargelinkDistancelinkStrengthfrictiongravitythetachargeDistancenodeClassPropertylinkClassPropertycircleRadiuslabelDxlabelDyonEndlinkDistanceFuncredrawonClickNodeonClickLink
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



