Is there any way to add custom data to a circle dot in a line chart?

49 views
Skip to first unread message

Sofia Rodrigues

unread,
Mar 7, 2017, 5:59:40 AM3/7/17
to dc-js user group

Hey,

As the title states, I'm curious if I can add custom data to a circle dot. I see that it has the following properties when I click it:
- data (Object with x and y)
- hidden (undefined?)
- layer (chart's groupName from what I know)
- x
- y

Thanks!

Gordon Woodhull

unread,
Mar 7, 2017, 8:11:00 AM3/7/17
to dc.js user group
Hi Sofia,

The data member is the data from your crossfilter objects. 

In particular, data.key is the key returned by the function you passed to the dimension constructor or group constructor. data.value is the value produced by the group's reduce function.

So, if you want to pass other data through, you probably want to use a custom reduce function that returns an object. 

Reductio [1] is great for this, or there are plenty of examples on SO.

Cheers,
Gordon


--
You received this message because you are subscribed to the Google Groups "dc-js user group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dc-js-user-gro...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dc-js-user-group/0e03f18b-2fa8-4792-a68b-8415bcf51c65%40googlegroups.com.

Sofia Rodrigues

unread,
Mar 7, 2017, 8:30:39 AM3/7/17
to dc-js user group
I'm looking at reductio, but I'm not quite sure (at all) how to do what you suggested. o.o

Gordon Woodhull

unread,
Mar 7, 2017, 10:15:22 AM3/7/17
to dc.js user group
Okay, so what I meant is that you have a choice what you want the group reduction to return - it looks like you're just reducing numbers for the Y value, but you could also include other information in there to control aesthetics or titles for the dots.

Simple example: aggregate two columns instead of one.

Say your group reduction is currently summing column q:

group.reduceSum(function(d) { return d.q; })

If you wanted to also sum another column r, you could use a custom reduction like this:

group.reduce(
  function(p, v) { // add
    p.q += v.q;
    p.r += v.r;
    return p;
  },
  function(p, v) { // remove
    p.q -= v.q;
    p.r -= v.r;
    return p;
  },
  function() { // init
    return {q: 0, r: 0};
  }
})

That's a bit more complicated, but only because reduceSum and reduceCount are shortcuts that use reduce underneath.

Now instead of returning {key: number, value: number} objects, the group will return objects 
{key: number, value: {q: number, r: number}}

You'll need to specify the chart's valueAccessor because value is not just a number anymore:

chart.valueAccessor(function(kv) { return kv.value.q; })

And if you want to e.g. use r for the color:

chart.colorAccessor(function(kv) { return kv.value.r; })


Sofia Rodrigues

unread,
Mar 7, 2017, 10:41:08 AM3/7/17
to dc-js user group
Is there any way to be able to see this on the data of a dot click though:

- data (Object with x and y)
- hidden (undefined?)
- layer (chart's groupName from what I know)
- x
- y
- newCustomProperty


Or would it have to be in the data associated to a key or a value?

I'm just trying to pass the chart's unique ID to a dot, so I know which chart the dot belongs to. Previously I was doing that through the layer...but now I have layers that aren't unique anymore.

Gordon Woodhull

unread,
Mar 9, 2017, 10:21:42 AM3/9/17
to dc.js user group
Okay, maybe I've provided too much detail. Let's back up.

The data object that is bound to the dots and passed to the dot click, is an object constructed by dc.js. You don't have much control over that.

However, the data member of that object (the first item in the list you provided below) is exactly the key/value pair returned by the group. So if you change the group's reduce function, you can add members to d.data.value.

--

However there may be simpler ways to get the chart ID, since that's static information and not calculated from the data.

If you're creating the click function inline when defining the chart, you could just use data from the environment. I'm not sure how you structured your code, but say you have 

function buildChart(...) {
  var chart = dc.lineChart(...) 
  chart.on('pretransition', function(chart) {
    chart.selectAll('circle.dot').on('click', function(d) {
    })
  });
}

You could just pass another argument to buildChart and access it inside the click handler.


Sofia Rodrigues

unread,
Mar 28, 2017, 6:08:54 AM3/28/17
to dc-js user group
I didn't know that could be done, I simply went around it through its groupName. Good to know though, thanks!
Reply all
Reply to author
Forward
0 new messages