Comments (6)
Hi Doug,
I am glad you found dc.js useful. I have created this library mainly based
on my own project requirement so some of the chart might not offer exactly
what you expect. Currently bubble chart actually only works on one
dimension with a multi-value group/reduce. It allows you to retrieve 3
different values for x/y/radius respectively. It does not allow you bind
your data to the coloring of the bubble yet (which is an interesting idea).
You can take a look at the source code of my Nasdaq example page to see how
a multi-value group/reduce in crossfilter can be used to render a bubble
chart.
Create crossfilter dimension and a multi-value group/reduce:
var yearlyDimension = ndx.dimension(function(d) {
return d3.time.year(d.dd);
});
var yearlyPerformanceGroup = yearlyDimension.group().reduce(
//add
function(p, v) {
++p.count;
p.absGain += +v.close - +v.open;
p.fluctuation += Math.abs(+v.close - +v.open);
p.sumIndex += (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
//remove
function(p, v) {
--p.count;
p.absGain -= +v.close - +v.open;
p.fluctuation -= Math.abs(+v.close - +v.open);
p.sumIndex -= (+v.open + +v.close) / 2;
p.avgIndex = p.sumIndex / p.count;
p.percentageGain = (p.absGain / p.avgIndex) * 100;
p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100;
return p;
},
//init
function() {
return {count:0, absGain:0, fluctuation:0, fluctuationPercentage:0, sumIndex:0, avgIndex:0, percentageGain:0};
}
);
Char definition:
yearlyBubbleChart.width(990)
.height(250)
.dimension(yearlyDimension)
.group(yearlyPerformanceGroup)
.colors(d3.scale.category20c())
.keyRetriever(function(p) {
return p.value.absGain;
})
.valueRetriever(function(p) {
return p.value.percentageGain;
})
.radiusValueRetriever(function(p) {
return p.value.fluctuationPercentage;
})
.x(d3.scale.linear().domain([-2500, 2500]))
.y(d3.scale.linear().domain([-100, 100]))
.r(d3.scale.linear().domain([0, 4000]))
.renderLabel(true)
.renderTitle(true)
.label(function(p) {
return p.key.getFullYear();
})
.title(function(p) {
return p.key.getFullYear()
+ "\n"
+ "Index Gain: " + numberFormat(p.value.absGain) + "\n"
+ "Index Gain in Percentage: " + numberFormat(p.value.percentageGain) + "%\n"
+ "Fluctuation / Index Ratio: " + numberFormat(p.value.fluctuationPercentage) + "%";
})
.yAxis().tickFormat(function(v) {
return v + "%";
});
Also check out crossfilter's API for more details:
https://github.com/square/crossfilter/wiki/API-Reference
A side note, typically a bubble chart allow you to encode 3 different
information using x/y/radius; adding a fourth dimension, in my personal
opinion, might be a little bit too tricky for your user to decipher. In
that case I would have probably just created a separate chart (a bar chart
or line chart) to highlight this data distribution (which is what dc.js
designed for multi-dimensional representation). I am also currently working
on a concept called renderlet - a sort of hook/callback that you can
register in any chart to inject your own custom logic to render anything
you want using raw d3 api. This capability will be ready in next release
(v0.7). Once that is in place you should be able to set the color for each
of the bubble based on your own calculation.
Cheers,
Nick
from dc.js.
Hi Nick,
Thanks for that response. In my case I'm holding the y-dimension constant
and by my product owner's spec I am trying to map one dimension to color,
another to size (radius) and another to a categorical (ordinal) scale along
x - basically the result is to show a series of clusters discovered in data
(x), their relative representation of the population (r) and (ideally) a
cluster attribute that indicates the degree of "separation" (the important
thing) between this cluster and the entire population. So still within your
recommended max of three dimensions.
It was hoped to represent this separation dimension with a color range that
was like a kind of heat map. And in fact mapping this to y would convey the
same information, so there is a way out. But it does seem a little odd
allow a color range to be specified against your graph without the natural
next step of mapping it to the variation within a dimension. So yeah, I +1
that :-)
In your example, it might be interesting to try to add a dimension that
represented major industries and then show that as color. Blues for tech,
yellows for commodities, reds for financial, etc. I agree that with your
range of years, that could get cluttered pretty quickly, perhaps it would
make more sense over just a couple of years. Anyway, a hypothetical.
I did read a lot of your code including the example below, and in fact I
tribute my deeper understanding of crossfilter to your examples. And being
new to javascript, I found your code organization very illustrative of what
appear to me some really clean idioms. Very helpful.
As long as I have this comment open - I'd also like to advocate allowing
order to be defined on your group. I attempted, with no success, and when I
read bubble-chart.js I saw why. Specifically
var bubbleG = _chart.g().selectAll("g." + NODE_CLASS)
.data(_chart.group().all());
Which according to the API docs "Returns the array of all groups, in
ascending natural order by key." If instead you did something like
var bubbleG = _chart.g().selectAll("g." + NODE_CLASS)
.data(_chart.group().top(Infinity));
You'd allow for grouping order to be added to the chart. This specifically
would have helped me because while I wanted the X-axis to draw my ordinal
names, I wanted to order by the relative size. Anyway the docs acknowledge
that this is slower than .all(), but still, seems like a cost-benefit
tradeoff to be made by the framework client.
Hope this is helpful.
Doug
On Sat, Aug 4, 2012 at 7:59 PM, Nick Zhu <
[email protected]
wrote:
Hi Doug,
I am glad you found dc.js useful. I have created this library mainly based
on my own project requirement so some of the chart might not offer exactly
what you expect. Currently bubble chart actually only works on one
dimension with a multi-value group/reduce. It allows you to retrieve 3
different values for x/y/radius respectively. It does not allow you bind
your data to the coloring of the bubble yet (which is an interesting idea).
You can take a look at the source code of my Nasdaq example page to see how
a multi-value group/reduce in crossfilter can be used to render a bubble
chart.Create crossfilter dimension and a multi-value group/reduce:
var yearlyDimension = ndx.dimension(function(d) { return d3.time.year(d.dd); }); var yearlyPerformanceGroup = yearlyDimension.group().reduce( //add function(p, v) { ++p.count; p.absGain += +v.close - +v.open; p.fluctuation += Math.abs(+v.close - +v.open); p.sumIndex += (+v.open + +v.close) / 2; p.avgIndex = p.sumIndex / p.count; p.percentageGain = (p.absGain / p.avgIndex) * 100; p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100; return p; }, //remove function(p, v) { --p.count; p.absGain -= +v.close - +v.open; p.fluctuation -= Math.abs(+v.close - +v.open); p.sumIndex -= (+v.open + +v.close) / 2; p.avgIndex = p.sumIndex / p.count; p.percentageGain = (p.absGain / p.avgIndex) * 100; p.fluctuationPercentage = (p.fluctuation / p.avgIndex) * 100; return p; }, //init function() { return {count:0, absGain:0, fluctuation:0, fluctuationPercentage:0, sumIndex:0, avgIndex:0, percentageGain:0}; } );Char definition:
yearlyBubbleChart.width(990) .height(250) .dimension(yearlyDimension) .group(yearlyPerformanceGroup) .colors(d3.scale.category20c()) .keyRetriever(function(p) { return p.value.absGain; }) .valueRetriever(function(p) { return p.value.percentageGain; }) .radiusValueRetriever(function(p) { return p.value.fluctuationPercentage; }) .x(d3.scale.linear().domain([-2500, 2500])) .y(d3.scale.linear().domain([-100, 100])) .r(d3.scale.linear().domain([0, 4000])) .renderLabel(true) .renderTitle(true) .label(function(p) { return p.key.getFullYear(); }) .title(function(p) { return p.key.getFullYear() + "\n" + "Index Gain: " + numberFormat(p.value.absGain) + "\n" + "Index Gain in Percentage: " + numberFormat(p.value.percentageGain) + "%\n" + "Fluctuation / Index Ratio: " + numberFormat(p.value.fluctuationPercentage) + "%"; }) .yAxis().tickFormat(function(v) { return v + "%"; });Also check out crossfilter's API for more details:
https://github.com/square/crossfilter/wiki/API-ReferenceA side note, typically a bubble chart allow you to encode 3 different
information using x/y/radius; adding a fourth dimension, in my personal
opinion, might be a little bit too tricky for your user to decipher. In
that case I would have probably just created a separate chart (a bar chart
or line chart) to highlight this data distribution (which is what dc.js
designed for multi-dimensional representation). I am also currently working
on a concept called renderlet - a sort of hook/callback that you can
register in any chart to inject your own custom logic to render anything
you want using raw d3 api. This capability will be ready in next release
(v0.7). Once that is in place you should be able to set the color for each
of the bubble based on your own calculation.Cheers,
Nick
Reply to this email directly or view it on GitHub:
#12 (comment)
from dc.js.
Hi Doug,
Thanks for the detailed explanation of your use case. I am always interested to know how people are using the library. The custom rendering hook being introduced in v0.7 release will allow you to do pretty much everything you want to do. And I am planning to introduce some new API to allow data visualization using color scaling. There is already another issue opened on sorting generally, and I am hoping to tackle it in 0.8 or 0.9 release.
Based on your description, the chart you are creating for business is quite different from a traditional bubble chart, so the generic bubble chart implementation might not suite your need with limited customization though it's API. Another option is to fork my implementation and customize it completely from the ground up or just use it as a reference implementation to create your own. Heat Map is also something that is on my todo list (probably scheduled for v0.8 release)
Cheers,
Nick
from dc.js.
In 0.8 release, now you can use color as an additional data dimension, see example below:
yearlyBubbleChart.colors(["red", "#ccc","steelblue","green"])
.colorDomain([-1750, 1644])
.colorAccessor(function(d){return d.value.absGain;})
...
from dc.js.
Hey Nick,
I may check it out, but I took your suggestion to start coding directly to
d3. I had already had an inkling that that's what I needed to do to
properly learn that framework. Unfortunately the fine line to walk with
these frameworks on top of frameworks is that the one on the top, while
simplifying a very specific use case as you've pointed out, can hide a lot
of the power you'd otherwise like to access. Like this color dimension,
until you just added it.
I appreciate that you're OK with me reading your code for implementation
ideas. I really appreciate it more as much for what appear to me really
crisp examples of sophisticated javascript architectures as for learning
how to wrangle D3 and Crossfilter. I'm slowly wrapping my head around it.
I have a question for you that's not germane to this thread, if you don't
mind I may send you an InMail on LinkedIn - I don't know of another way to
do that without you exposing your email address in this public forum - hope
that's OK.
Doug
On Thu, Aug 16, 2012 at 2:02 PM, Nick Zhu [email protected] wrote:
In 0.8 release, now you can use color as an additional data dimension, see
example below:yearlyBubbleChart.colors(["red", "#ccc","steelblue","green"])
.colorDomain([-1750, 1644])
.colorAccessor(function(d){return d.value.absGain;})...—
Reply to this email directly or view it on GitHubhttps://github.com//issues/12#issuecomment-7799367.
from dc.js.
Yeah, apparently color encoding is more popular than I originally thought; got requests from other users as well =) Building your visualization from scratch is absolutely the best way to learn d3. Feel free to send me a message on linkedin.
from dc.js.
Related Issues (20)
- DataCount issues improper warning HOT 3
- Stacked bar chart legend label alignment is off in Chrome HOT 3
- Bar charts with rangeChart breaks mouse zoom on second render call. HOT 1
- "brushing on ordinal bar chart" example row chart animation is very slow HOT 4
- Line chart can't renderData point and Brush at same time HOT 3
- 2.x support - crossfilter.quicksort removed in [email protected]
- dc sunburst chart -- color of legend and the chart does NOT match HOT 6
- dc built in wordcloud for dc v4 possible?
- array filter feature in dc.js, how to handle when the .dimensions function takes multiple dimensions? HOT 3
- dc sunburst chart - externalLabels not working
- Seeking new maintainers HOT 5
- vulnerability: d3-color:2.0.0: 1084597(10.0)
- High vulnerability found in d3-color
- Line chart- multiple lines with multiple datasets HOT 2
- Error: No d3.js compatbility nester registered, load v5 or v6 compability layer. HOT 3
- Does it support faceted graphics? HOT 1
- Tip: make dataTable.columns accept object path
- Brushing/filtering issue since 4.1.0 - Broken example HOT 6
- Is DC v4 compatible with D3 v7? HOT 4
- I have set the users group to read only
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dc.js.