7 Great Utility Libraries for Data Visualization With JavaScript

JavaScript runs the web. You can use it in a browser, you can use it on a server, and you can use it for mobile applications.
Today’s ecosystem is full of great libraries and frameworks helping engineers build powerful, user-centric applications for any platform.
Data visualization has been one of the hottest topics in the world right now, even before the Covid-19 pandemic. Companies sit on massive amounts of data and need to find ways to analyze, interpret, and visualize that data.
Whether you’re a data scientist or a programmer that has to deal with data visualization, here are seven great JavaScript frameworks to help you create stunning solutions.

  1. D3
    https://github.com/d3/d3
    D3 currently has 90,000 stars on GitHub, making it one of the most popular JavaScript libraries available. It’s an amazing library for visualizing data with JavaScript using web standards (SVG, Canvas, HTML). It combines powerful interaction and visualization techniques to manipulate the DOM with a data-driven approach.
    It allows for binding arbitrary data to the DOM and then applying transformations to the document.
    Key features are:
    Full capabilities of web standards
    Extremely fast and supports large datasets
    Official and community-developed modules available
  2. three.js
    https://github.com/mrdoob/three.js
    three.js is another great JavaScript library for data visualization that currently has about 60,000 GitHub stars. It wants to create an easy-to-use, simple, and lightweight 3D library with a default WebGL renderer.
    Key features are:
    Default WebGL renderer
    Supports renderer for Canvas 2D, SVG, and CSS3D
    Good documentation
  3. Chart.js

Chart.js is a simple but flexible JavaScript-charting library for designers and developers that has about 50,000 stars on GitHub at the moment. It has great documentation, and it’s pretty easy to get started.
Key features:
Mixed chart types
Out-of-the-box stunning transitions
Open-source project
Supports eight chart types
Responsive

  1. Paper.js

Paper.js is an open-source vector graphic–scripting framework running on the top of HTML5 Canvas. It offers a lot of powerful functionality to create and work with Bézier curves and vector graphics. It’s based on Scriptographer, a scripting environment for Adobe Illustrator. Paper.js is easy to learn for beginners but also has a lot of advanced features for advanced users.
Key features:
Easy to get started with
Well-designed and battle-hardened API
Based on Scriptographer, using HTML5 standards
It offers nested layers, groups, paths, compound paths, rasters, symbols, etc.

  1. Fabric.js

Fabric.js is a great JavaScript framework for working with HTML canvas elements easily. It has both an interactive object model on top of the canvas element and an SVG-to-canvas parser.
With Fabric, one can easily create simple shapes, like circles, triangles, rectangles, or other polygons, using JavaScript.
Key features:
Unit tested
Modular architecture
Cross-browser functionality
It’s fast and follows semantic versioning

  1. ECharts

ECharts is a powerful visualization and charting library for JavaScript that offers easy ways of adding interactive, intuitive, and highly customizable charts to applications and currently has about 40,000 stars on GitHub. It’s based on ZRender and written in pure JavaScript.
Key features:
Incubator project of the Apache Software Foundation
Free to use
Supports multidimensional data analysis
Active community
Charts for all sizes of devices

  1. Two.js

Two.js is a small API for two-dimensional drawing in modern browsers. It’s renderer-agnostic, enabling rendering in multiple contexts, such as WebGL, Canvas2D, or SVG, with the same API.
Key features:
Focus on vector shapes
Relies on scene graphs
Built-in animation loop
Features a scalable vector-graphics interpreter

WAS8.5 add a new DS timestampPrecisionReporting custom properties

cmd:
./wsadmin.sh -lang jython -f ds2.py TEST_CL

cluster = sys.argv[0]
ds =  AdminConfig.getid('/ServerCluster:'+cluster+'/JDBCProvider:DB2 Universal JDBC Driver Provider/DataSource:web DataSource')
propSet = AdminConfig.showAttribute( ds, 'propertySet' )
print propSet
print AdminConfig.required('J2EEResourceProperty')
url_attr = [ [ 'name', 'timestampPrecisionReporting'  ], [ 'value', 2 ], [ 'type', 'java.lang.String' ], [ 'required', 'false' ] ]
print AdminConfig.create('J2EEResourceProperty', propSet, url_attr)
AdminConfig.save()

WAS8.5 change DS webSphereDefaultIsolationLevel

in DMGR bin dir:
for i in cat tt; do ./wsadmin.sh -lang jython -f ds.py $i;done

tt:
Web1_CL
Web2_CL
Web3_CL

cluster = sys.argv[0]
ds =  AdminConfig.getid('/ServerCluster:'+cluster+'/JDBCProvider:DB2 Universal JDBC Driver Provider/DataSource:webDataSource')
propSet = AdminConfig.showAttribute( ds, 'propertySet' )
resProps = AdminConfig.showAttribute( propSet, 'resourceProperties' )
rsPropList = resProps[ 1:-1 ].split()
for prop in rsPropList :
    if ( prop.find( 'webSphereDefaultIsolationLevel' ) > -1 ) :
      urlValue = AdminConfig.showall( prop, 'value' )
      url_attr = [ [ 'name', 'webSphereDefaultIsolationLevel'  ], [ 'value', 2 ], [ 'type', 'java.lang.String' ], [ 'required', 'false' ] ]
      AdminConfig.modify( prop, url_attr )
      AdminConfig.save()

WAS8.5 add or modify JVM custom property

Usage: wsadmin -f addJvmProperty.py server property value [description]

# Usage: wsadmin -f addJvmProperty.py server property value [description]
# Usage: ./wsadmin.sh -f addJvmProperty.py jvm_name org.oasis.open.docs.wsn_HOSTNAME soa.sys.com

server = sys.argv[0]
property = sys.argv[1]
value = sys.argv[2]
if (len(sys.argv) == 4):
    descr = sys.argv[3]
else :
    descr = None

# Convert a list of items separated by linefeeds into an array
def getListArray(l):
    return l.splitlines()

# Obtain the "simple" server name
def getServerName(s):
    return AdminConfig.showAttribute(s, 'name')

# Add common attr list to specified Server's JVM
def addPropertiesToServer(s):
    jvm = AdminConfig.list('JavaVirtualMachine', s)

    # Look for existing property so we can replace it (by removing it first)
    currentProps = getListArray(AdminConfig.list("Property", jvm))
    for prop in currentProps:
        if property == AdminConfig.showAttribute(prop, "name"):
            print "Removing existing property from Server %s" % getServerName(s)
            AdminConfig.remove(prop)

    # Store new property in 'systemProperties' object
    print "Adding property to Server %s" % getServerName(s)
    AdminConfig.modify(jvm,[['systemProperties',attr]])

# Construct list with new property name and value
attr = []

if (descr is None):
    print "Adding property %s=%s" % (property,value)
    attr.append([['name',property],['value',value]])
else:
    print "Adding property %s=%s,%s" % (property,value,descr)
    attr.append([['name',property],['value',value],['description',descr]])

# Locate all Application Servers if server is 'all'
if (server == 'all'):
    servers = AdminConfig.list('Server')
    for aServer in getListArray(servers):
        type = AdminConfig.showAttribute(aServer,'serverType')
        if (type == 'APPLICATION_SERVER'):
            addPropertiesToServer(aServer)

# TODO: support comma-separated list of servers

else:
    # Locate specified Server and its JVM
    server = AdminConfig.getid('/Server:'+server+'/')
    addPropertiesToServer(server)

# Save changes
if (AdminConfig.hasChanges()):
    AdminConfig.save()

WAS 8.5 Administration using Jython

C:\WASClient> wsadmin -lang jython -host 192.168.1.5 -port 8879
WASX7209I: Connected to process "dmgr" on node serverCellManager01 using SOAP connector;
The type of process is: DeploymentManager
WASX7031I: For help, enter: "print Help.help()"
wsadmin> execfile("C:\WASClient\scripts\was_scripts.py")
wsadmin> addJVMProperty(‘server1’, ‘myproperty’, ‘value’)
wsadmin> syncNodes()
wsadmin> restartServer(‘server1’)

  1. How to create Application Server?
    wsadmin> createApplicationServer(‘Node01’, ‘MyServer’)
    ‘MyServer(cells/Cell01/nodes/Node01/servers/MyServer|server.xml#Server_1402570244015)’
    wsadmin> AdminConfig.save()

    wsadmin> removeServer(‘Node01’, ‘MyServer’)

    def createApplicationServer (nodeName, serverName, templateName = None):
    if templateName == None:
    templateName = 'default'
    options = '[-name %s -templateName %s -genUniquePorts true]' % (serverName, templateName)
    return AdminTask.createApplicationServer(nodeName, options)
    def removeServer (nodeName, serverName):
    AdminTask.deleteServer('[-serverName %s -nodeName %s]' % (serverName, nodeName))
  2. How to retrieve all Ports used by a Server?

    def getServerPorts (nodeName, serverName): 
    ports = {} 
    serverIndex = AdminConfig.list("ServerIndex", AdminConfig.getid("/Node:" + nodeName + "/")) 
    for serverEntry in AdminConfig.list("ServerEntry", serverIndex).splitlines(): 
      if AdminConfig.showAttribute(serverEntry, "serverName") == serverName: 
         for nep in AdminConfig.list("NamedEndPoint", serverEntry).splitlines(): 
            ports[AdminConfig.showAttribute(nep, "endPointName")] = AdminConfig.showAttribute(AdminConfig.showAttribute(nep, "endPoint"), "port")
    return ports
    def printServerPorts(nodeName, serverName):
    for (name, port) in getServerPorts(nodeName, serverName).items():
      print "%40s - %s" %(name, port) 
  3. How to set Server JVM Classpath
    wsadmin> setClasspath(‘server1’, [‘/app/lib/slf4j.jar’,’/app/lib/logback.jar’])

    def printClasspath(serverName):
    jpd = AdminConfig.list("JavaProcessDef", AdminConfig.getid('/Server:' + serverName))
    jvm = toList(AdminConfig.showAttribute(jpd, "jvmEntries"))[0]
    print "%s" % AdminConfig.showAttribute(jvm, "classpath")
    def setClasspath (serverName, classPaths):
    jpd = AdminConfig.list("JavaProcessDef", AdminConfig.getid('/Server:' + serverName))
    jvm = toList(AdminConfig.showAttribute(jpd, "jvmEntries"))[0]
    for cp in classPaths:
    setObjectProperty(jvm, "classpath", cp)
    def setObjectProperty (objectId, propertyName, propertyValue):
    AdminConfig.modify(objectId, [[propertyName, propertyValue]])
    def removeClasspath (serverName):
    jpd = AdminConfig.list("JavaProcessDef", AdminConfig.getid('/Server:' + serverName))
    jvm = toList(AdminConfig.showAttribute(jpd, "jvmEntries"))[0]
    AdminConfig.unsetAttributes(jvm, "classpath")
  4. How to install Application?
    wsadmin> installApp(‘C:\Sample.war’, ‘node01’, ‘server1’, ‘sample_app’, ‘/sample’, ‘mydomain_vh’)
    wsadmin> installApp(‘C:\Sample.ear’, ‘node01’, ‘server1’, ‘sample_app’, vhName=’mydomain_vh’)

    def installApp(location, nodeName, serverName, appName, ctxRoot=None, vhName=None):
    cellName = AdminConfig.list('Cell')
    options = [ 
        '-nopreCompileJSPs',
        '-distributeApp',
        '-nouseMetaDataFromBinary',
        '-deployejb',
        '-createMBeansForResources',
        '-noreloadEnabled',
        '-deployws',
        '-validateinstall warn',
        '-noprocessEmbeddedConfig',
        '-filepermission .*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755',
        '-noallowDispatchRemoteInclude',
        '-noallowServiceRemoteInclude',
        '-appname', appInfo["appName"],
        '-MapModulesToServers', [
                 ['.*', '.*', 'WebSphere:cell='+cellName+',node='+nodeName+',server='+serverName]
                                ]
              ]
    if vhName != None:
        options.append('-MapWebModToVH')
        options.append([['.*', '.*', vhName]])
    if ctxRoot != None:
        options.append('-contextroot')
        options.append(ctxRoot)
    AdminApp.install(location, options)
  5. How to update JVM logs location?
    wsadmin> configureJVMLogs(‘server1’, ‘/logs/Websphere/server1/’)

    def configureJVMLogs (serverName, logDir):
    logDir = logDir.strip()
    if (logDir[len(logDir) - 1] != '/'):
    logDir = logDir + "/"
    server = AdminConfig.getid('/Server:' + serverName)
    setFile(AdminConfig.showAttribute(server, 'errorStreamRedirect'), logDir, 'SystemErr.log')
    setFile(AdminConfig.showAttribute(server, 'outputStreamRedirect'), logDir, 'SystemOut.log')
    def setFile(streamId, logDir, fileName):
    AdminConfig.modify(streamId, [['fileName', logDir + fileName]])
  6. How to Start/Stop Server
    wsadmin> stopServer(‘Node01’, ‘MyServer’)

    def startServer(nodeName, serverName):
    AdminControl.startServer(serverName, nodeName)
    def stopServer(nodeName, serverName):
    server = AdminControl.completeObjectName('WebSphere:type=Server,name=%s,*' % serverName)
    if len(server) > 0:
    AdminControl.stopServer(serverName, nodeName)
    else:
    print 'Server %s already stopped!' % serverName
    def restartServer(nodeName, serverName):
    stopServer(nodeName, serverName)
    startServer(nodeName, serverName)
  7. How to synchronize the Node?
    wsadmin> syncNodes(‘node01’)

    def syncNodes(nodeName):
    nodeSync = AdminControl.completeObjectName('type=NodeSync,node=' + nodeName + ',*')
    AdminControl.invoke(nodeSync, 'sync')
    def syncAllNodes():
    for node in AdminConfig.list('Node').splitlines():
      syncNodes(AdminConfig.showAttribute(node, 'name'))
  8. How to get the Server State?
    wsadmin> showServerStatus(‘server1’)

    def showServerStatus(serverName):
    serverObj = AdminControl.completeObjectName('WebSphere:type=Server,name=' + serverName + ',*')
    if len(serverObj) > 0:
    serverStatus = AdminControl.getAttribute(serverObj, 'state')
    else:
    serverStatus = 'STOPPED'
    print "%15s %s" %(serverName, serverStatus)
    def showAllServerStatus():
    for server in AdminConfig.list('Server').splitlines():
    showServerStatus(AdminConfig.showAttribute(server, 'name'))
  9. Managing VirtualHost Configuration
    wsadmin> createVirtualHostWithAliases(‘myhost’, [[‘host1.com’, 80], [‘secure.host.com’, 443]])
    wsadmin> AdminConfig.save()
    wsadmin> addVirtualHostAlias(‘myhost’, [[‘host2.com’, 80], [‘secure.host2.com’, 443]])
    wsadmin> AdminConfig.save()
    wsadmin> printVirtualHostAliases(‘myhost’)
    host1.com:80
    secure.host.com:443
    host2.com:80
    secure.host2.com:443
    wsadmin> removeVirtualHostAlias(‘myhost’, ‘host1.com’)
    wsadmin> AdminConfig.save()
    wsadmin> removeVirtualHost(‘myhost’)
    wsadmin> AdminConfig.save()

    def printAllVirtualHosts():
    for vh in toList(AdminConfig.list("VirtualHost")):
    print "%s" %(AdminConfig.showAttribute(vh, "name"))
    def printAllVirtualHostWithAliases():
    for vh in toList(AdminConfig.list("VirtualHost")):
    print "%s" %(AdminConfig.showAttribute(vh, "name"))
    for al in toList(AdminConfig.showAttribute(vh, 'aliases')):
      print "\t%s:%s" %(AdminConfig.showAttribute(al, 'hostname'), AdminConfig.showAttribute(al, 'port'))
    def printVirtualHostAliases(virtualHost):
    vh = AdminConfig.getid("/VirtualHost:" + virtualHost)
    if len(vh) > 0:
    for al in toList(AdminConfig.showAttribute(vh, 'aliases')):
      print "%s:%s" % (AdminConfig.showAttribute(al, 'hostname'), AdminConfig.showAttribute(al, 'port'))
    else:
    print "VirtualHost '%s' not found" % (virtualHost)
    def createVirtualHost (virtualHostName): 
    AdminConfig.create("VirtualHost", AdminConfig.list("Cell"), [["name", virtualHostName]]) 
    def createVirtualHostWithAliases (virtualHostName, aliases): 
    virtualHost = AdminConfig.create("VirtualHost", AdminConfig.list("Cell"), [["name", virtualHostName]]) 
    for alias in aliases:
    AdminConfig.create("HostAlias", virtualHost, [["hostname", alias[0]], ["port", alias[1]]])
    def addVirtualHostAlias(virtualHostName, aliases):
      virtualHost = AdminConfig.getid("/VirtualHost:" + virtualHostName)
      for alias in aliases:
        AdminConfig.create("HostAlias", virtualHost, [["hostname", alias[0]], ["port", alias[1]]])
    def removeVirtualHostAlias(virtualHostName, hostName):
    virtualHost = AdminConfig.getid("/VirtualHost:" + virtualHostName)
    for alias in toList(AdminConfig.showAttribute(vh, 'aliases')):
    if AdminConfig.showAttribute(alias, 'hostname') == hostName:
      AdminConfig.remove(alias)
    def removeVirtualHost(virtualHostName):
    virtualHost = AdminConfig.getid("/VirtualHost:" + virtualHostName)
    if len(virtualHost) > 0:
    AdminConfig.remove(virtualHost)
    else:
    print "VirtualHost '%s' not found" % (virtualHost)    

jython script to add Web container > Custom properties

you can run below CMD to add prop for ALL JVMs:
./wsadmin.sh -f add_prop.py all prop_name prop_value

or add on one JVM with JVM name:
./wsadmin.sh -f add_prop.py my_jvm_name prop_name prop_value

Here is the code:

serverName = sys.argv[0]
propName = sys.argv[1]
propValue = sys.argv[2]
def toList(inStr):
    outList=[]
    if (len(inStr)>0 and inStr[0]=='[' and inStr[-1]==']'):
        inStr = inStr[1:-1]
        tmpList = inStr.split(" ")
    else:
        tmpList = inStr.split("\n")
    for item in tmpList:
        item = item.rstrip();
        if (len(item)>0):
           outList.append(item)
    return outList

def printWebContainerProperty(serverName):
  for p in toList(AdminConfig.showAttribute(getWebContainer(serverName), 'properties')):
    print '%60s - %s' % (AdminConfig.showAttribute(p, 'name'), AdminConfig.showAttribute(p, 'value'))

def updateWebContainerProperty(serverName, propName, propValue):
  wc = getWebContainer(serverName)
  updated = 'N'
  for p in toList(AdminConfig.showAttribute(wc, 'properties')):
    if AdminConfig.showAttribute(p, 'name') == propName:
      AdminConfig.modify(p, [['value', propValue]])
      updated = 'Y'
  if updated == 'N':
    setCustomProperties(wc, 'properties', {propName:propValue})

def removeWebContainerProperty(serverName, propName):
  wc = getWebContainer(serverName)
  for p in toList(AdminConfig.showAttribute(wc, 'properties')):
    if AdminConfig.showAttribute(p, 'name') == propName:
      AdminConfig.remove(p)

def getWebContainer(serverName):
  return AdminConfig.list('WebContainer', AdminConfig.getid('/Server:' + serverName))

def setCustomProperties (objectName, propertyName, propertyMap):
  propVals = []
  for (key, value) in propertyMap.items():
    propVals.append([["name", key], ["value", value]])
  setObjectProperty(objectName, propertyName, propVals)

def setObjectProperty (objectName, propertyName, propertyValue):
  AdminConfig.modify(objectName, [[propertyName, propertyValue]])

# Locate all Application Servers if server is 'all'
if (serverName == 'all'):
    servers = AdminConfig.list('Server')
    for aServer in toList(servers):
        type = AdminConfig.showAttribute(aServer,'serverType')
        if (type == 'APPLICATION_SERVER'):
            serverName = AdminConfig.showAttribute(aServer, 'name')
            print serverName
            updateWebContainerProperty(serverName, propName, propValue)
else:
    # Locate specified Server and its JVM
    serverName = sys.argv[0]
    updateWebContainerProperty(serverName, propName, propValue)

# Save changes
if (AdminConfig.hasChanges()):
    AdminConfig.save()