Creating Organization Charts for IBM Connections using JavaScript and Google Charts

Similar documents
Jquery Ajax Json Php Mysql Data Entry Example

Overview... 4 JavaScript Charting and Metric Insights... 5

Jquery Manually Set Checkbox Checked Or Not

Using Development Tools to Examine Webpages

Copyright Descriptor Systems, Course materials may not be reproduced in whole or in part without prior written consent of Joel Barnum

Jquery.ajax Call Returns Status Code Of 200 But Fires Jquery Error

Creating an Online Catalogue Search for CD Collection with AJAX, XML, and PHP Using a Relational Database Server on WAMP/LAMP Server

Sparrow Client (Front-end) API

HTML Advanced Portlets. Your Guides: Ben Rimmasch, Rahul Agrawal

Using the Visualization API with GWT and Other Advanced Topics. Itai Raz May 27, 2009

WebGL Seminar: O3D. Alexander Lokhman Tampere University of Technology

NWTL17 - Get your hands on IBM Connections Engagement Center Lab

Akumina Digital Workplace

Manual Html A Href Javascript Window Open In Same

Web API Lab. The next two deliverables you shall write yourself.

Utilising the data attribute. adding client side behaviour in Oracle APEX

Elementary! Incorporating BlueMix, Node-RED and Watson in Domino applications

django-baton Documentation

Lab 1: Getting Started with IBM Worklight Lab Exercise

JavaScript CS 4640 Programming Languages for Web Applications

Developing Apps for the BlackBerry PlayBook

PyBossa.JS JavaScript library for PyBossa

Marketo Forms Integration Guide

User Interaction: jquery

Getting Started with the Aloha Community Template for Salesforce Identity

jquery and AJAX

Client Side JavaScript and AJAX

Easy Authcache documentation

AngularJS Intro Homework

INFO216: Advanced Modelling

Google Maps Manually Place Marker On Click V3 Remove

Unifer Documentation. Release V1.0. Matthew S

Design Document V2 ThingLink Startup

CSCE 120: Learning To Code

Here are a few easy steps to create a simple timeline. Open up your favorite text or HTML editor and start creating an HTML file.

for Lukas Renggli ESUG 2009, Brest

AJAX: From the Client-side with JavaScript, Back to the Server

XPages development practices: developing a common Tree View Cust...

Reports and Documents Generator for SharePoint ver.: 2.1

Tutorials Php Y Jquery Mysql Database Without Refreshing Code

django-baton Documentation

Table of contents. Ajax AutoComplete Manual DMXzone.com

If looking for a ebook XML Programming Success in a Day: Beginner's Guide to Fast, Easy, and Efficient Learning of XML Programming (XML, XML

MAX 2006 Beyond Boundaries

WELCOME TO JQUERY PROGRAMMING LANGUAGE ONLINE TUTORIAL

jquery UI Widget Factory

(Simple) JavaScript Framework Homework

Human-Computer Interaction Design

JavaScript: the language of browser interactions. Claudia Hauff TI1506: Web and Database Technology

JavaScript CS 4640 Programming Languages for Web Applications

Web applications Developing Android/Iphone Applications using WebGUI

Web Applications. Software Engineering 2017 Alessio Gambi - Saarland University

Paul Withers Intec Systems Ltd By Kind Permission of Matt White and Tim Clark

KonaKart Shopping Widgets. 3rd January DS Data Systems (UK) Ltd., 9 Little Meadow Loughton, Milton Keynes Bucks MK5 8EH UK

JavaScript Web Applications: JQuery Developers' Guide To Moving State To The Client By Alex MacCaw READ ONLINE

Adding a RSS Feed Custom Widget to your Homepage

JQuery WHY DIDN T WE LEARN THIS EARLIER??!

CIS 3308 Logon Homework

PDF Exporter Xpages Custom Control Documentation

SSJS Server-Side JavaScript WAF Wakanda Ajax Framework

Best Practices Chapter 5

FolderView DMXzone.com Folder View 2 Manual

KWizCom Corporation. Data View Plus App. User Guide

AD406: What s New in Digital Experience Development with IBM Web Experience Factory

Overview

AJAX Programming Chris Seddon

Multimedia im Netz Online Multimedia Winter semester 2015/16

DATABASE SYSTEMS. Introduction to web programming. Database Systems Course, 2016

Deep Dive into Apps for Office with Word

Contents. Demos folder: Demos\14-Ajax. 1. Overview of Ajax. 2. Using Ajax directly. 3. jquery and Ajax. 4. Consuming RESTful services

Website Development Lecture 18: Working with JQuery ================================================================================== JQuery

Widget ID Each user type widget should have a unique identifier within a single controller (ID). Any string can be as ID.

JavaScript, jquery & AJAX

CIW 1D CIW JavaScript Specialist.

Building Collaborative Apps with Wookie

JavaScript Fundamentals_

Package shiny.semantic

HTML5. clicktag implementation

Configuring Anonymous Access to Analysis Files in TIBCO Spotfire 7.5

Web Development. With PHP. Web Development With PHP

Programming with the Finesse API

IBM. BPM Blueprint; IBM WebSphere Lombardi Edition V7.1, Application Development

KWizCom Corporation. List Aggregator App. User Guide

BEST PRACTICES HTML5 SPECIFICATIONS. what's next in data-driven advertising. File Types. HTML5: HTML, JS, CSS, JPG, JPEG, GIF, PNG, and SVG

Aware IM Version 8.2 Aware IM for Mobile Devices

When you don t want to lose your site s existing look and feel, you re

«FitPhoto» Integration

Static Webpage Development

XAP: extensible Ajax Platform

THE PRAGMATIC INTRO TO REACT. Clayton Anderson thebhwgroup.com WEB AND MOBILE APP DEVELOPMENT AUSTIN, TX

Multimedia im Netz Online Multimedia Winter semester 2015/16

A demo Wakanda solution (containing a project) is provided with each chapter. To run a demo:

Table of contents. Pure ASP Upload 3 Manual DMXzone

AJAX: Asynchronous Event Handling Sunnie Chung

Theme System. Wisej Themes 1 OVERVIEW

Eclipse Scout. Release Notes. Scout Team. Version 7.0

AJAX: Introduction CISC 282 November 27, 2018

2015 OSIsoft TechCon. Bring element relative features of your PI PB displays to PI Coresight

Professional Edition Tutorial: Basic Excel

JavaScript By: A. Mousavi & P. Broomhead SERG, School of Engineering Design, Brunel University, UK

Transcription:

Creating Organization Charts for IBM Connections using JavaScript and Google Charts As we all know, IBM Connections has a great report-to-chain widget which shows current user reporting structure. However, sometimes we want to see the whole picture and display the full reporting chart of our organization. And it s quite easy to do since we have all data in IBM Connections. In this document I described how to create nice looking Org Charts based on IBM Connections report-tochain structure and Google Charts JS library. Here is an example of the resulting chart: Using IBM Connections REST API we can get all people managed by specified user as described here: https://www- 10.lotus.com/ldd/lcwiki.nsf/xpAPIViewer.xsp?lookupName=IBM+Connections+6.0+API+Documentation# action=opendocument&res_title=searching_for_a_persons_direct_reports_ic60&content=apicontent Requesting an URL /profiles/atom/peoplemanaged.do?key=<userid> You will get an XML data with all people managed by user as XML entries. <userid> is an internal key generated by Connections for each user. You can also use URL /profiles/atom/peoplemanaged.do?email=<e-mail> if you want. Then, using jquery DOM methods we can get the information we need from that XML and create our chart. We will need a recursive function to walk through all organization tree and get data for each employee. For chart display I used Google Charts Library which have a ready-to-use component for creating Organization Charts https://developers.google.com/chart/interactive/docs/gallery/orgchart

So, we will do it in two steps: 1. Create simple HTML/JS code which can be inserted in ICEC HTML widget on any page. 2. Create custom widget with editable configuration settings. In this document we will work with on-premise version of IBM Connections. There are some differences with IBM Connections Cloud: in URLs of profiles and API calls. However, you can find all the codes for both versions of ICEC widget for Cloud and On-premise as well in zip archive. Let s start! Creating recursive function for retrieving data According to Google Org Chart documentation we need to compose google DataTable object to hold chart data. So we create the object with 2 columns and then add rows with data. // create google data object var data = new google.visualization.datatable(); data.addcolumn('string', 'Name'); data.addcolumn('string', 'Manager'); // add row data.addrow([{v:<userid>,f:<what to display in user box>,<managerid>]); As <userid> we will use IBM Connections user key. You can see user key in the profile link which looks like this In <what to display in user box> section we want to construct nice-looking HTML code with user picture, Name, Title and link to profile. So that s how our table row will look in the code: // add user entry to chart data data.addrow([{v:userkey,f:'<img src="/profiles/photo.do?key='+userkey+'" width="40" height="40"><b><a href="/profiles/html/profileview.do?key='+userkey+'" target="_blank">'+username + '</a></b><br>'+ usertitle, managerid]);

Now we are ready to make a recursive function to get data from connections and put it in chart table. * recursively get data for chart with AJAX calls to Connections API * @param data {google.visualization.datatable hierarchy data * @param id {String parent user ID * @param name {String parent user name function getchartdata(data, id, name) { $.ajax({ type: "GET", async:false, datatype: "xml", url: "/profiles/atom/peoplemanaged.do?key="+id, success: function(xml){ $(xml).find("entry").each(function(){ // get current user data from xml userkey = $(this).find('div.x-profile-key').text(); username = $(this).find('name').text(); usertitle = $(this).find('div.title').text(); // add user entry to chart data data.addrow([{v:userkey,f:'\ <img src="/profiles/photo.do?key='+userkey+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+userkey+'" target="_blank">\ '+username + '</a></b><br>'+ usertitle,id]); // get data for people managed by current user getchartdata(data, userkey, username); ); ); We used AJAX calls to IBM Connections API, got user data from XML and then added it to google table row. We used async:false calls to traverse all tree consequentially.

Creating main function According to Google documentation example we ll wrap the call of our function in another function drawchart: * Main function to call for Chart Draw function drawchart() { // create google data object var data = new google.visualization.datatable(); data.addcolumn('string', 'Name'); data.addcolumn('string', 'Manager'); // add top row data.addrow([{v:topuserid,f:'\ <img src="/profiles/photo.do?key='+topuserid+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+topuserid+'" target="_blank">\ '+topusername+'</a></b><br>'+topusertitle,'']); // create google chart object with chart div var chart = new google.visualization.orgchart(document.getelementbyid('chart_div')); // Start recursive data retrieval getchartdata(data, topuserid, topusername); // Draw the chart, setting the allowhtml option to true for the pictures. chart.draw(data, {allowhtml:true, allowcollapse:true); You can add more options in chart.draw method to use your own colors etc. Now we need only to set root user ID (topuserid variable) and create final HTML for our code. And, of course, we need to include google chart library. <script type="text/javascript" src="//www.gstatic.com/charts/loader.js"></script> <div id="chart_div">retrieving data...</div> <script type="text/javascript"> // Connections ID for root user. // Get it from user profile URL /profiles/html/profileview.do?key=<id> var topuserid = 'cecfe489-4033-48ca-b0b7-df93da53db47'; // well Im lazy so I just set boss name and title right here. // But you can try to get it via Connections API by ID var topusername = 'Dennis Michaels'; var topusertitle = 'CEO'; * recursively get data for chart with AJAX calls to Connections API * @param data {google.visualization.datatable hierarchy data * @param id {String parent user ID * @param name {String parent user name function getchartdata(data, id, name) {

$.ajax({ type: "GET", async:false, datatype: "xml", url: "/profiles/atom/peoplemanaged.do?key="+id, success: function(xml){ $(xml).find("entry").each(function(){ // get current user data from xml userkey = $(this).find('div.x-profile-key').text(); username = $(this).find('name').text(); usertitle = $(this).find('div.title').text(); // add user entry to chart data data.addrow([{v:userkey,f:'\ <img src="/profiles/photo.do?key='+userkey+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+userkey+'" target="_blank">\ '+username + '</a></b><br>'+ usertitle,id]); // get data for people managed by current user getchartdata(data, userkey, username); ); ); * Main function to call for Chart Draw function drawchart() { // create google data object var data = new google.visualization.datatable(); data.addcolumn('string', 'Name'); data.addcolumn('string', 'Manager'); // add top row data.addrow([{v:topuserid,f:'\ <img src="/profiles/photo.do?key='+topuserid+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+topuserid+'" target="_blank">\ '+topusername+'</a></b><br>'+topusertitle,'']); // create google chart object with chart div var chart = new google.visualization.orgchart(document.getelementbyid('chart_div')); // Start recursive data retrieval getchartdata(data, topuserid, topusername); // Draw the chart, setting the allowhtml option to true for the pictures. chart.draw(data, {allowhtml:true, allowcollapse:true); * Theres a problem with loading google library when using the code * inside ICEC HTML widget even using $(document).ready * so this small workaround just to be sure that google chart library is fully loaded. function LoadGoogle() { if(typeof google!= 'undefined')

{ google.charts.load('current', {packages:["orgchart"]); google.charts.setonloadcallback(drawchart); else { // Retry later... settimeout(loadgoogle, 30); LoadGoogle(); </script> The code is ready and we are to insert it in ICEC HTML widget. You can also use this code in classic IBM Connections iwidget or Portlet or any other application. But don t forget to manually set your own top user ID.

And here s the result!

Creating custom ICEC widget Now let s transform our code into custom ICEC widget. Use ICEC documentation and tutorial to better understand ICEC widget API: https://www.ibm.com/support/knowledgecenter/en/ssl3jx/icec/cec-custom-widget-api.html https://www.ibm.com/developerworks/collaboration/library/icec-widget-lab/index.html To make custom widget we will split our code into 2 parts: 1. org_chart_onpremise.html HTML code with div container. Actually, we can put chart content directly into widget container but having our own HTML will give us more control. 2. org_chart_onpremise.js JS code We also need to add some code to custom.js ICEC built-in file to define our custom widget. org_chart_onpremise.html <div id="chart_div">retrieving data...</div> org_chart_onpremise.js (function ($, W) { // get or create and expose the XCC Object var X = (function () {W.XCC = W.XCC {; return W.XCC; ()); // Connections ID for root user. // Get it from user profile URL /profiles/html/profileview.do?key=<id> var topuserid = ''; // well Im lazy so I just set boss name and title right here. // But you can try to get it via Connections API by ID var topusername = ''; var topusertitle = ''; var targetdiv = null; var p = W.XCC.P.getProfile(); * recursively get data for chart with AJAX calls to Connections API * @param data {google.visualization.datatable hierarchy data * @param id {String parent user ID * @param name {String parent user name function getchartdata(data, id, name) { $.ajax({ type: "GET", async:false, datatype: "xml", url: "/profiles/atom/peoplemanaged.do?key="+id, success: function(xml){

$(xml).find("entry").each(function(){ // get current user data from xml userkey = $(this).find('div.x-profile-key').text(); username = $(this).find('name').text(); usertitle = $(this).find('div.title').text(); console.log(username); // add user entry to chart data data.addrow([{v:userkey,f:'\ <img src="/profiles/photo.do?key='+userkey+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+userkey+'" target="_blank">\ '+username + '</a></b><br>'+ usertitle,id]); // get data for people managed by current user getchartdata(data, userkey, username); ); ); * Main function to call for Chart Draw function drawchart() { // create google data object var data = new google.visualization.datatable(); data.addcolumn('string', 'Name'); data.addcolumn('string', 'Manager'); // add top row data.addrow([{v:topuserid,f:'\ <img src="/profiles/photo.do?key='+topuserid+'" width="40" height="40"><b>\ <a href="/profiles/html/profileview.do?key='+topuserid+'" target="_blank">\ '+topusername+'</a></b><br>'+topusertitle,'']); // create google chart object with chart div var chart = new google.visualization.orgchart(targetdiv.find("#chart_div")[0]); // Start recursive data retrieval getchartdata(data, topuserid, topusername); // Draw the chart, setting the allowhtml option to true for the pictures. chart.draw(data, {allowhtml:true, allowcollapse:true); * Callback function for ICEC widget * @param container$ {Jquery-Object the HTML-container in the Widget.. * @param widgetdata {Object The widget data object with widget settings function LoadChart(container$, widgetdata) { targetdiv = container$; topuserid = X.T.getCustomPropertyValue("OrgChartWidgetTopID", widgetdata); topusername = X.T.getCustomPropertyValue("OrgChartWidgetTopName", widgetdata); topusertitle = X.T.getCustomPropertyValue("OrgChartWidgetTopTitle", widgetdata);

if(!topuserid) { topuserid = p.getprofilekey(); topusername = p.getname(); topusertitle = p.gettitle(); google.charts.load('current', {packages:["orgchart"]); google.charts.setonloadcallback(drawchart); // define this function in dependency of nothing X.define([], function () { return LoadChart; ); // END X.define // END X.define (XCC.jQuery jquery, window)); We upload our files in ICEC Customization Files.

Now we need to define our custom widget for ICEC in custom.js file. Open it in editor

and add the following code inside init() function. ********* START: INSERT THIS SECTION INTO CUSTOM.JS init() FUNCTION ********* * ORG CHART widget function. Includes HTML code, google charts JS library * and widget JS code. * @param {[Jquery-Object] container$ [the HTML-container in the Widget.. ] * @param {[Object] widgetdata [The widget data] * function orgchartwidget(container$, widgetdata) { $.get("/xcc/rest/files/custom/org_chart_onpremise.html",function(data) { container$.html(data); ); widgetdata.contenttype = widgetdata.contenttype.trim(); // require google charts JS, widget JS code, and call LoadChart XCC.require(["profiles"], function () { XCC.require(["//www.gstatic.com/charts/loader.js"], function () { XCC.require(["/xcc/rest/public/custom/org_chart_onpremise.js"], function(loadchart) { LoadChart(container$, widgetdata); ); ); ); * ORG CHART edit settings: widget title, and custom properties: * topid, topname, toptitle * @param container$ {jquery the parent node that will hold the editor * @param widgetdata {Object the widget object to work on * * @return a HTML-String, Jquery-Object or an array of Jquery-Objects! * function orgcharteditor(container$, widgetdata) { return [XCC.U.createTextInputOnTheFly("Widget Title", widgetdata.title, "title"),

XCC.U.createTextInputOnTheFly("Top user ID", XCC.T.getCustomPropertyValue("OrgChartWidgetTopID", widgetdata), "orgchartwidgettopid"), XCC.U.createTextInputOnTheFly("Top user Name", XCC.T.getCustomPropertyValue("OrgChartWidgetTopName", widgetdata), "orgchartwidgettopname"), XCC.U.createTextInputOnTheFly("Top user Title", XCC.T.getCustomPropertyValue("OrgChartWidgetTopTitle", widgetdata), "orgchartwidgettoptitle") ]; * ORG CHART save settings to custom properties. * @param {[type] container$ [the Editor as a Jquery-Object] * @param {[type] widgetdata [the widget data] function orgchartsave(container$, widgetdata) { widgetdata.title = container$.find("input[name=title]").val(); XCC.T.setXccPropertyString(widgetData,"OrgChartWidgetTopID", container$.find("input[name=orgchartwidgettopid]").val()); XCC.T.setXccPropertyString(widgetData,"OrgChartWidgetTopName", container$.find("input[name=orgchartwidgettopname]").val()); XCC.T.setXccPropertyString(widgetData,"OrgChartWidgetTopTitle", container$.find("input[name=orgchartwidgettoptitle]").val()); * ORG CHART register a Custom Widget * @param name {String Name of the Custom Widget, * @param icon {String name of the icon. Without the "fa-" at the beginning. * @param createcustomwidget {function Function which should be called when rendering * @param CreateCustomEditor {function optional: Use an own Editor instance! * @param synchuitowidgetdataobject {function optional: Synch your Data * from the UI into the Widget. * @param dontshowin {String optional XCC.W.registerCustomWidget("Org Chart","flag",orgChartWidget,orgChartEditor, orgchartsave ); ********* END: INSERT THIS SECTION INTO CUSTOM.JS init() FUNCTION ********* Following the example of Custom Widget which already placed in init() we created 3 functions: orgchartwidget which invokes the code of our widget. Here we use require module predefined in ICEC to load our google library instead of <script> tag. orgcharteditor to edit our custom settings. orgchartsave to save settings into XCC custom properties Then we registered our widget with registercustomwidget method. Now let s test how it works!

First added our widget shows hierarchy down from current user. Let s define the head of our Organization.

Codes You can find all the codes used in this document here in archive file: https://ibm.box.com/s/d4j46yyfyfut4xh5hr70l45q7lhdk108 Ivan Mikhalychev IBM Collaboration Solutions Technical professional ivan.mikhalychev@ru.ibm.com Special thanks to Stefano Pogliani, IBM Technical Sales Collaboration for useful materials and demo!