D3 in Angular, Angular in D3

D3 in Angular, Angular in D3

0 0


On Github timruffles / ng-d3-angularconnect

D3 in Angular, Angular in D3

@timruffles @sidekicksrc

My year

The proposition

You built what?!

I was blown away

Of course I said yes

I wanted to build cool things

Then I saw the code

A quest!

To unite mutual friend, and a new face

Big ideas

Enables cool things

Has big ideas too

Meet d3

d3 ≃ jQuery + data


  • select elements
  • affect those elements via chaining API


<svg id="meetD3" width="600" height="220">
  <circle r="50" cx="300" cy="110" fill="black"></circle>

Nothing new so far

One callback API turns jQ into D3

D3's callback

  function(data) {
    return data.risk > 0.9 
      ? "red" : "green";

Data -> visual

  function(data) {
    return data.risk > 0.9 
      ? "red" : "green";

...and where does the data come from?


    {title: "jQuery"},
    {title: "D3"}

The data-join!

Driving the document with data

<svg id="join" width="600" height="220">
  <circle r="50" cx="250" cy="110"></circle>
  <circle r="50" cx="450" cy="110"></circle>

Sync DOM + data

var update = d3.selectAll('circle')
  .attr("r", getRadius)

var enter = update.enter()

var exit = update.exit()

var circleData = [
  {id: 1}, {id: 2}, {id: 3}

// renderCircles




Add el Remove el




Add data Remove data




Big idea


d3 components = functions that sync <DOM> & {data}

Same input, same output

component(elements0, data1) // elements1

component(elements1, data1) // elements1

component(elements1, data2) // elements2

component(elements2, data1) // elements1

So what?


var colData = [
  {id: 1}, {id: 2}, {id: 3}


d3 components = function over 2 data-sets

{data} + <DOM>

Idempotency = DOM is predictable

Idempotency = collaboration via f · g · h

Back to the quest

How to use D3's powers


Or losing benefits of Angular?

I brought 'best practice'

ng view concerns live in?


App-flavoured HTML

<!-- BOOO!! -->
<div class='profile'></div>

<!-- YAAAAY! -->

One directive per chart

Approach lots of libraries have taken


<div ng-controller='ReportCtrl as ctrl'>

Sometimes, great!

1:00 AM Start
  timeCtrl.item.time: 1:00 AM
  timeForm.time.$modelValue: 1:00 AM
<form ng-controller="TimeCtrl as timeCtrl" name="timeForm">
  <clock-input ng-model="timeCtrl.item.time" name="time">

ngModelController FTW!

No giant files!


Our most ambitious plans were thwarted

Web-components selfishly horde <DOM>

Remember collaboration?

A dark night of the soul

How are newbies building cooler apps?

An unsettling realisation

An example

Editable chart

  • x/y plot
  • editable data
  • update on change

Ok, we've done that before

Chart component

Editing component


Users don't care about components

...they don't even see them


Where the ambitious...

...is sacrificed to optimise the average

Users don't care about 'best practice'

'Best practice' should be making things easier

...not limiting you to easy things

Did I want to be an enterprise architect?!

A new quest

No more programmer vision

Direct access

Show don't tell

But <form> + <svg>?

How will you validate?

Are you casting aside ng?

Writing HTML with D3?!

// the horror
var form = d3.select("#form-root")
.on("submit", handleSubmit)

.attr("type", "range")
.attr("required", true)

.attr("type", "number")
.attr("required", true)
// ... and on, and on

I needed ng & d3

Beat the tools into submission!


Flip the hierarchy!

On demand

.angularize(function(d, i) {
  return {
    controller: "ComplexFormCtrl",
    locals: {
      // provide Ctrl a way to hand back to D3
      $edited: edited,
    templateUrl: "editors/complexForm.html",
    controllerAs: "ctrl",
    injector: "app",
    modules: ["app", "someFormModule"],

Coding === enabling

Let's not find excuses

Let's remember why we got into code

Let's find reasons to say...