Teach Yourself D3.js

D3 is a JavaScript framework used for data visualization.
Learning how to work with D3.js is very easy. If you begin with the basics, you’ll see how easy it is to use D3, because:

  • the DOM function names are much shorter than those in the legacy DOM library.
  • the same functions are used for both setting and getting values.
  • setters return a value, so you can keep working with the same element without repeating its name.

If you already know some framework, you probably feel that there’s nothing new under the sun, which is good because it makes learning the new stuff easier.

So, What’s New?

In D3, you can:
* add and remove SVG and HTML elements using the setters and getter.
* set and get the element’s properties, attributes, styles, text and… data

Getting Started

First, download the framework from http://d3js.org
After you include it in your script, you can use selections, that is wrappers for elements.
To get a selection, use one of the functions:

  • d3.select(selector) – to select the first element matching selector.
  • d3.selectAll(selector) – to select the all elements matching selector.

Like the d3 object, selections has their select and selectAll methods to select descendant.

If selection is a selection, it’s easy to understand what selection.text(), selection.attribute(), selection.style(), selection.insert(), and selection.append() do. But, what does selection.data() do?

Data And Update Selection

The selection’s method data() helps you use the HTML DOM as a database.
selection.data() returns an array of all data that belongs to the elements of the selectionץ The data is held in the property __data__ of the element.
selection.data(arr, func) – defines an update selection and distribute the elements of array arr to the elements of selection.
func(d,i)is a function that:

  • receives d an element of arr and its index i.
  • returns a record key.

If func is not passed, the key is the element’s index.

A recommended way to create an update selection is:
var updSelection = selection1.selectAll(selector).data(arr)

Now, updSelection is a selection of existing elements whose data has been changed.
In addition, updSelection has to methods:

  • updSelection.enter() – returns place holders for elements to be created under selection1.
  • updSelection.exit()– returns elements that have lost their data, and are usually to be removed.

Using the data

The methods attr, style, property, text and data can accept a function as a value to set. The function will be called for each element of the selection’s data. And its arguments will be the array element and its index.

Now, let us see it in an example.
The following code arranges data in a donut layout:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Testing Pie Chart</title>
<script type="text/javascript" src="d3.min.js"></script>

<style type="text/css">
.slice text {
font-size: 12pt;
font-family: Arial;
}
</style>
</head>
<body>
<script type="text/javascript">
var width = 300, 
    height = 300, 
    radius = 100, 
    color = d3.scale.category20c(); //builtin range of colors


// Step 1: creating a container for the donut chart, and attach raw data to it.
var vis = d3.select("body")
            .append("svg")     //create the SVG element inside the <body>
            .datum([{"label":"first", "value":20},
                    {"label":"second", "value":10},
                    {"label":"third", "value":30},
                    {"label":"fourth", "value":25}])       
            .attr({"width": width, "height": height})  
            .append("g")
            .attr("transform", "translate(" + radius + "," + radius + ")") //move the center of the pie chart from 0, 0 to r, r



// Step two: defining the accessors of the layour function. 
//           The function 'pie' will use the 'value' accessor to compute the arc's length.
var pie = d3.layout.pie() 
            .value(function(d) { return d.value; })
            .sort(function(a,b){return a.label<b.label?-1:a.label==b.label?0:1;});

// Step 3: Create the update selection. 
var updateSelection = vis.selectAll("g") 
                         .data(pie);    // This will use the function 'pie' to create arc data from the row data attached to the visualisation element.


// Step 4: Using the data in the update selection to create shape elements.
var arc = d3.svg.arc() 
            .outerRadius(radius)
            .innerRadius(radius / 2)
;
updateSelection.enter()
               .append('g')
               .attr('class','slice')
               .append("path")
               .style("fill", function(d, i) { return color(i); } ) //set the color for each slice to be chosen from the color function defined above
               .attr("d", arc);                                     // Create the arc from the arc data attached to each element.

updateSelection.append("text") 
               .attr("transform", 
                     function(d) { 
                       return "translate(" + arc.centroid(d) + ")"; 
                     })
               .attr("text-anchor", "middle")                  
               .text(function(d, i) { return d.data.label; }); 


</script>
</body>
</html> 

And following is the chart:
enter image description here

For more funcions, see the API Reference.

Advertisement

LibreOffice Javascript

There are other languages in which you can write LibreOffice macros. One of them is Javascript. If you’ve installed the package “libreoffice-script-provider-js”, you can write Javascript macros. In Linux’ you can use apt-get or rpm to install it.

Javascript macros can be edited from LibreOffice, and is ready to run without compilation.

.In the Developer Guide, you will find how to write macros in Java. Those example can be easily translated to Javascript. You can even implement interfaces and extend classes. For example, you can override an “actionPerformed” method of a button, as shown in the previous postLibreOffice – The Kakuro Cell Macro.

LibreOffice provides you with a friendlier way to create dialogs:

1. Tools=>Macros=>Organize Dialogs.

2. Edit an existing dialog or a new one.

3. If you added a control, such as a button, double-click it. a window is opened. In the General Tab, you can get or change information such as the name (important if you want to use it in the macro), color, type (“Ok” button, for example), etc. In the Event tab, you can assign macros to events.

The dialog can be created and executed by a macro. Following is an example in LibreOffice Basic:

Sub kakuro_cell
DialogLibraries.LoadLibrary( “Standard” )

oDialog1 = CreateUnoDialog( DialogLibraries.Standard.kakuro )

oDialog1.Execute()
End Sub

This will show the following dialog:

Clicking “Submit” will run another macro with the event details, and the “Button type” selected in the general tab was “OK”. We can also start our macro by pressing the “tab” key until our button gains focus and then pressing the Enter key, thus the event starting the macro is “Item status change”.

Now, what does event handling look like in a Javascript macro:

 event=ARGUMENTS[0];      // Because this macro is a callback, it has the event for first argument.
 evtSource=event.Source;       // The control that fired the event.
 xControl=UnoRuntime.queryInterface(XControl, evtSource);
 xControlModel = xControl.getModel();
 xPropertySet = UnoRuntime.queryInterface(XPropertySet, xControlModel);
 peer=xControl.getPeer();       // The dialog window.
 ctx=xControl.getContext();
 ctxControlContainer=UnoRuntime.queryInterface(XControlContainer, ctx);  // Yes, the window is a control container that contains the button and input fields.
 lowerPartControl = ctxControlContainer.getControl("lowerPart");
 lowerPartModel=lowerPartControl.getModel();
 lowerPartPropertySet=UnoRuntime.queryInterface(XPropertySet,
                                                lowerPartModel);
 upperPartControl = ctxControlContainer.getControl("upperPart");
 upperPartModel=upperPartControl.getModel();
 upperPartPropertySet=UnoRuntime.queryInterface(XPropertySet,
                                                upperPartModel);

How to Translate from Java to Javascript?

The interpreter used by the script provider is named Rhino, an interpreter developed by Mozilla.  Rhino is written entirely in Java, and allows developers to embed Java objects within their code.

Importing

To embed a Java object, you should first import it using the command “importClass(Packages.<class-name>);”.

For example:

importClass(Packages.com.sun.star.sheet.XSpreadsheetDocument);

XSCRIPTCONTEXT

In Javascript, the first command executed is not found inside a function, so instead of an argument of class XScriptContext, a variable named XSCRIPT CONTEXT is supplied upon invocation of a Javascript macro.

Java Objects

Java objects are accessed the same way in both Java and Javascript, but without the casting in the latter because Javascript is loosely type. The “new” command in Javascript has the same syntax as in Java, except for instantiating a Java array.

Instantiating a Java Array

A Javascript array containing Java objects is not a Java array. To instantiate a Java array, you should use class “java.lang.reflect.Array”. This class and other classes from the “reflect” package should not be imported.

To instantiate an array use the function “newInstance(<class>, <integer array>);”. For example:
points = java.lang.reflect.Array.newInstance(Point, [1, 3]);
Will create a bi-dimensional array with one row and 3 columns of Point objects.

Implementing an Interface or Extending a Class

Use the syntax:

<var> = new <class or interface>(<args>){
      <func-name>: function(<args>){
     }
}

For example:

xButton.addActionListener(new XActionListener() {
                    
     disposing: function(evtObj) {
        // TODO Auto-generated method stub
                        
     }
      
     actionPerformed: function(evt){
        // Javascript code
        .
        .
        .
     }
}