Using d3 to create views for local objects

d3 is is a JavaScript library for data visualizations in web browsers. In Glamorous Toolkit through web views we can use d3 to create views for local objects.

This page describes details an example.

Initial setup

Currently we rely on a local webserver to pass data to d3 and implement callbacks.

In the future we will also inject the html and data directly into the browser and use IPC handler to implement callbacks from d3 back to GT.

The next snippet initialises the local server used by d3 views

GtD3WebViewServer createDefaultWithNewZnServer.
  
GtD3WebViewServer defaultInstance start
  

Example view

The class GtD3WebViewExampleAnalysis Object subclass: #GtD3WebViewExampleAnalysis instanceVariableNames: 'numberOfClasses' classVariableNames: '' package: 'GToolkit-D3-WebView' uses a d3 view to show an interactive barchart of the top 20 classes with the largest number of methods in the system.

The view is animated and if we click on the bar representing a class, we will open it in a new pane.

GtD3WebViewExampleAnalysis new
	numberOfClasses: 20
  

Implementation

To create these views we need to instantiate a GtD3WebViewPhlowLocalSpecification Object subclass: #GtD3WebViewPhlowLocalSpecification instanceVariableNames: 'id dataProvider viewName sourceProvider' classVariableNames: '' package: 'GToolkit-D3-WebView' that knows how to return the source and data for the view using a source provider and a data provider.

specification := GtD3WebViewPhlowLocalSpecification new 
	viewName: #barchart;
	sourceProvider: (GtD3WebViewSourceProvider 
		forGToolkitVisualiserExamplesFolder);
	dataProvider: (GtD3WebViewCsvDataProvider new 
		objects: [ (Smalltalk allClasses 
			sorted: [ :each | each methods size ] descending)
				first: 20 ];
		rowLabel: [ :each | each name ];
		rowValue: [ :each | each methods size ]).
  

From the specification we can obtain a ohlow wrapper object that knows how to render the view, handles the communication with the server and navigation.

wrapper := specification createPhlowWrapper
  

To make http requests that use this wrapper we need to register it with the local server.

wrapper ensureWrapperIsRegistered
  

Several ways to interact with the wrapper:

wrapper viewSource
  
ZnClient new 
	get: wrapper viewSourceUrl
  
wrapper viewData
  
ZnClient new 
	get: wrapper viewDataUrl
  

The wrapper also holds on to the web view element, and if the element displayed it can use phlow to open the selected object in a new page to the right

wrapper webViewElementForWrapper removeFromParent
  
wrapper navigateToObjectWithId: 3
  
ZnClient new 
	get: (wrapper selectionUrlForObjectId:  3)