This is part of a tutorial series on creating extension components for Design Studio.
Edit: This instalment has been updated to reflect a D3 best practice with regard to data handling. See the last section.
So far, we’ve taken our first steps towards getting Eclipse set up for developing Design Studio components and we’ve taken a look at getting a component project set up. If we’re going to build a full featured, dynamic, gauge component for Design Studio, we’re going to have to come to grips with drawing things in the browser; and we’re going to have to come to grips with it quite early. Generally speaking, if you want to draw something in HTML5, there are two approaches; canvas and scalable vector graphics (SVG).
Canvas uses an eponymous html element. You select your canvas element via ID and then use javascript to draw in it. SVG also uses an eponymous html element. You can either attach SVG drawings from external files, or draw in it, again, using Javascript. SVG also uses the document’s document object model (DOM); with the drawing elements added to the DOM tree. For the developer, the main difference is that canvas is pixel based and svg is vector based. Use canvas when you have a lot of things to draw (and all the DOM nodes would bog the browser down) and don’t need to keep track of individual drawing elements. Use svg when you do need to keep track of individual elements.
As gauges involve things that might turn, grow or shrink, being able to keep track of those things and manipulate them is handy. Therefore, we’ll be using svg through this tutorial. Since we’re using svg, we’ll probably want to use D3.js as our visualization manipulation library. Firstly, D3 is the go-to library for manipulating svg in HTML5. Secondly, it’s built into Design Studio’s SDK framework.
Step 2a.1 -
Let’s start by creating a barebones HTML document. It won’t actually show anything when we open it in a browser, yet. The document needs to have a header element and a body element.
The header needs to have a script element, with the reference to the D3 library. This will import the D3 library when the document is opened in the browser and make it available.
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
In the body, we’ll add a div element and give it the id, ‘content’.
Also in the body, we’ll as a script element. Leave it empty for now, as that will be where we write our code.
The HTML file should look like this:
<!DOCTYPE html>
<html>
<head>
<title>My First D3 Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
</head>
<body>
<div id='content'></div>
<script>
</script>
</body>
</html>
If you open it in a browser, should see a blank page.
Step 2a.2 –
Since gauges tend to be radial in nature, we're going to be working with arcs. Therefore, we'll be frequently using Pi. Fortunately, we don't need to define it ourselves, but we can instead use the constant maintained in JavaScript's Math library. Add the following line of code:
var pi = Math.PI;
Step 2a.3 –
We need attach an svg container to our content div. To do this, we write the following:
var vis = d3.select("#content")
.append("svg:svg")
.attr("width", "100%")
.attr("height", "100%");
select() is a method on the D3 object. It returns a selection. The rest of the command acts on the thing selected in the first part. This is called method chaining.
Tangential Exposition: Method Chaining (skip this part if you already know how method chaining works)
In the code above, we wanted to do a few things:
We wanted to select the div, with the id of “content”.
Then, we wanted to append an svg element to the selection.
Then we wanted to set a couple of attributes on the selection.
In most languages – and indeed in vanilla Javascript as well, I’d need to write code that looked something like the following:
var vis = d3.select("#content");
vis.append("svg:svg")
vis.attr("width", "100%")
vis.attr("height", "100%");
Three of the four lines are single actions on the thing returned by the first. The D3 library (and JQuery as well) adds a trick called method chaining. This allows me to concatenate several steps into a single statement, as long as each new step is executing on the results of the last, or if the previous method did not return anything, whatever was still the last “target”.
In the case of the chained command set, above, it flows as follows:
Step 2a.4 –
As svg is vector based, we'll be drawing lines using paths. DashingD3 has an excellent overview of using D3 path generators. In short, there are simple path generator commands for commonly used path primitives. In this tutorial series, we'll be working mostly with lines and arcs.
Let's define a path for a simple arc:
var arcDef = d3.svg.arc()
.innerRadius(0)
.outerRadius(70)
.startAngle(45 * (pi/180)) //converting from degs to radians
.endAngle(3) //just radians
*D3's paths actually use radians, so if you want to use degrees, you'll need to convert, as we did in the code snippet, above.
Step 2a.5 –
Now we're ready to actually draw an arc in our svg element:
var guageArc = vis
.attr("width", "400").attr("height", "400") // Added height and width so arc is visible
.append("path")
.style("fill", "red")
.attr("transform", "translate(200,200)")
.attr("d", arcDef);
Step 2a.6 –
Our completed html file should now look as follows:
<!DOCTYPE html>
<html>
<head>
<title>My First D3 Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
</head>
<body>
<div id='content'></div>
<script>
var vis = d3.select("#content")
.append("svg:svg")
.attr("width", "100%")
.attr("height", "100%");
var pi = Math.PI;
var arcDef = d3.svg.arc()
.innerRadius(0)
.outerRadius(70)
.startAngle(45 * (pi/180)) //converting from degs to radians
.endAngle(3) //just radians
var guageArc = vis
.attr("width", "400").attr("height", "400") // Added height and width so arc is visible
.append("path")
.style("fill", "red")
.attr("transform", "translate(200,200)")
.attr("d", arcDef);
</script>
</body>
</html>
Step 2a.7 –
When you run it, you should see a red pie fragment:
As always, the completed extension (as of part 2) is available as a Github repository.
I'd like to point something out here. In the above code, we defined starAngle and endAngle for the arc directly. This is *not* a D3 best practice. If you are learning D3 along with Design Studio extension creation, then you may want to take a side trip to Part 10a, where we discuss using data, instead of directly defining properties. For the time being (until part 10), we'll stick with the "wrong" way, that we defined above. It will work just fine, though we'll have to make the change when delving into animating our gauge in part 10.
Next time, we'll get our arc into a Design Studio extension!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
25 | |
11 | |
11 | |
7 | |
7 | |
7 | |
6 | |
6 | |
6 | |
5 |