scotthmurray / d3-book Goto Github PK
View Code? Open in Web Editor NEWCode examples for “Interactive Data Visualization for the Web”
Home Page: http://d3book.com
License: Other
Code examples for “Interactive Data Visualization for the Web”
Home Page: http://d3book.com
License: Other
Hey! Thanks for the great work with the book - making my way through it now. Similar to Issue #34 , a change needs to be made when making a json request.
On line 29, instead of
d3.json("us-states.json", function(json) {
Should instead now be
d3.json("us-states.json")
.then(function(json){
Cheers!
In Chapter 16, in data transform the following needs to be updated:
From:
dataset[i-3] = {
date: parseTime(rows[i][0]) // make a new Data obj for each year + month
};
To:
dataset[i-3] = {
date: d3.timeParse(rows[i][0]) // make a new Data obj for each year + month
};
The link to the MDN CSS Selectors docs doesn't work in the second edition on O'Reilly:
For details on additional selectors, see the Mozilla Developer Network.
The shortlink http://mzl.la/V27Mcr has a 301 to https://developer.mozilla.org/en-US/CSS/CSS_Reference#Selectors (which no longer exists but redirects to itself).
I think the current CSS Selector docs are at: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference#selectors
P.S. Thanks for making such a great resource! 🤩
复活复活你
The code for tooltips seems to have changed between d3 versions.
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.bandwidth() / 2;
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + h / 2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#value")
.text(d);
Returns "Object Mouse Event" in the tooltip rather than the actual number.
I got it to work by changing function(d) to function(e,d)
Original code:
var dragging = function(d) {
//Log out d3.event, so you can see all the goodies inside
//console.log(d3.event);
It should be function(e,d)
and console.log(e)
and using e
(event) to get access to dx
and dy
.
Also I have a question:
svg.selectAll("path") .attr("d", path);
Paths and circles in this example (p.301) are updated on svg
instead of map
which contains the group. Should it be map
instead or it shouldn't matter here?
Thanks a lot!
I've enjoyed the book and the examples, thanks very much for the thorough work. However I'm stumped as to what is causing an apparent bug in the bar chart examples you provided that add and remove bars. It appears to work correctly until you add and remove enough bars so that the yScale has to expand upward.
Once that happens, all of the existing labels are now in the incorrect position on the chart and not shifting with their bars. I can't seem to find how to correct this. I'm mostly curious from a learning perspective at this point, but I'd love to see a correctly working example as well as to know the cause of the inconsistency.
I'm attempting to attach a screen shot of the bar chart in the state to which I'm referring. The labels on the middle bars are only visible when I select them with the mouse.
overriden
should be overridden
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/02_drawing_divs_height.html#L12
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/03_drawing_divs_spaced.html#L12
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/04_power_of_data.html#L12
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/05_power_of_data_more_points.html#L12
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/06_power_of_data_random.html#L12
https://github.com/alignedleft/d3-book/blob/78deb23662a69de4379a4d9753fb30a45ef9bf2f/chapter_06/07_power_of_data_rounded.html#L12
Line 36 - in d3 v5 it has changed to:
d3.csv("mauna_loa_co2_monthly_averages.csv", rowConverter).then(function(data) {...} ;
Working through the section on time-based axes, but the sample files (08 and 09) draw 31 sets of x and y axes (without any data points) instead of one set with 31 data points.
The JSON file has both, but there is no CSV data for Alaska and Hawaii. If you show me where you got this data, I can give you a pull request.
Nice work Scott!
I noticed you don't use Mike's indentation style for method chaining. Was that a deliberate choice? I've always found this style very useful and educational. It makes it very clear on which selection the methods are operating.
And maybe even more importantly; when you store the results of a chain in a variable, this indentation style makes it very clear what selection you are actually storing. With complex chains that for example involve enter() and several child appends, it very quickly can get confusing and therefore it is better to be very explicit.
In short, I think this indentation style makes the code much more readable and understandable; especially for beginners.
See the the selections chapter in Mike's workshop:
With method chaining, I normally use four spaces to indent. However, I use two spaces for operations that change the selection, such as append. This causes operations that change the context to stick out.
In this snippet, the entire expression evaluates to the appended h1 elements, even though we started by selectingelements.
var h1 = d3.selectAll("section")
.style("background", "steelblue")
.append("h1")
.text("Hello!")
Use caution with method chaining: append returns a new selection!
In Chapter 16, in data transform the following needs to be updated:
From:
dataset[i-3] = {
date: parseTime(rows[i][0]) // make a new Data obj for each year + month
};
To:
dataset[i-3] = {
date: d3.timeParse(rows[i][0]) // make a new Data obj for each year + month
};
I had to change:
d3.csv("time_scale_data.csv", rowConverter, function(data) {...})
to:
d3.csv("time_scale_data.csv", rowConverter).then(function(data) {...})
to get it to work.
http://alignedleft.com/tutorials/d3/fundamentals lists <html>
, <head>
and <body>
tags in simplest HTML page, but these are in fact unnecessary, so simplest page can be reduced to:
<title>Page Title</title>
<h1>Page Title</h1>
<p>This is a really interesting paragraph.</p>
Regarding global variable dataset, I found I had to define var dataset = [], and use dataset.push(data). If I did the same as the book, the dataset can only have the last element in the imported csv file.
The code does not work with the latest version of d3(5.5.0), you must use an older version.
I think I'm missing something, sorry if this is a dumb question:
In chapter 9 (page 179 in the 2nd edition) you say "When storing the results of these selection methods, the most specific result....is the reference handed off to the variable" and provide the following example saying that paragraphs contains a selection of all p elements in the DOM.
var paragraphs = d3.select("body").selectAll("p");
However, chapter 12 (page 236) you provide the following example saying that it will store a selection of all the circle elements on the page contained within g elements:
var allCirclesInGroups = d3.selectAll("g").selectAll("circle")
What's the difference between these two examples? I imagine I'm just misunderstanding something.
Also thank you for writing this book, it's great!
Line 142 - D3 eliminated d3.schemeCategory20 it will work with d3.schemeCategory10.
The original code for freakout()
has:
var colors = d3.schemeCategory20;
var colorIndex = Math.round(Math.random() *20);
D3 no longer provides the d3.schemeCategory20* categorical color schemes. These twenty-color schemes were flawed because their grouped design could falsely imply relationships in the data: a shared hue can imply that the encoded data are part of a group (a super-category), while relative lightness can imply order
To get it to work, I changed it to:
var colors = d3.schemeCategory10;
var colorIndex = Math.round(Math.random() *10);
If you click 20 x 'Remove a data value' (hence dataset is total empty), then click 'Add a new data value', ...
01_enter_merge_exit.html:136 Uncaught TypeError: Cannot read property 'key' of undefined
Change 136: var lastKeyValue = dataset[ dataset.length -1 ].key;
to:
var lastKeyValue = (dataset.length)
? dataset[ dataset.length -1 ].key
: -1
Best Wishes,
Wolfgang
first keeping clicking remove a data value and empty the data, and then click add a data value, it will not do work and report a bug for lastKeyValue = dataset[dataset.length - 1].key
without length checking.
All .html files only show the map visualizations when I use FireFox. When I load the same file in Chrome, I can't see any map visualizations, just a blank page. I can't seem to find what setting would cause this.
d3-book/chapter_07/09_time_scale.html
Line 36 in 4cbba7c
The following line of code did not work for me:
d3.csv("time_scale_data.csv", rowConverter, function(data) {
Instead, the following code worked for me what I figured out:
d3.csv("time_scale_data.csv", rowConverter).then( function(data) {
Please check,
Waqas
In,
https://raw.githubusercontent.com/alignedleft/d3-book/master/chapter_12/us-cities.csv
San Francisco and Boston are incorrect.
Chapter 2 of the online version of this book has an issue with the URL for the official D3 website. It is listed as http://www.d3js.org/, which will result in an error if visited, rather than https://d3js.org/, which is the correct URL.
The page in question is https://learning.oreilly.com/library/view/interactive-data-visualization/9781491921296/ch02.html.
Not sure if this is something that has to be corrected by O'Reiley
I'm not sure if this qualifies as an issue, but as I was working through chapter 8, I had some trouble positioning my axes to get the zeroes to intersect as I had used some different padding logic previously. Given that the data and the axes are drawn independently, it might work better to directly transform/translate the axes to xScale(0) and yScale(0), that way they explicitly line up with how the data is drawn.
So currently the code is:
.attr("transform", "translate(0," + (h - padding) + ")"
.attr("transform", "translate( padding + ", 0)"
If it were this instead:
.attr("transform", "translate(0," + yScale(0) + ")"
.attr("transform", "translate(" + xScale(0) + ", 0)"
The first line is positioning the x-axis down to where the y-axis is zero, and the second is shifting the y-axis to where the x-axis is zero. I believe the plots in the book would be visually unaffected, as the padding is accounted for in the scale variables/functions.
Perhaps I am totally misunderstanding things, but just in case this helps anyone else :-)
Hello
I'm rather new here, so let me know if my question comes the wrong way. I'm new to d3.js too and I totally enjoy learning with the book. After reading all the comments and changing to d3.js version 4 I still have some issues with "09_time_scale.html" in Chapter 8 and "09_time_axis_prettier.html" in Chapter 9:
The code in question generates 31 empty svg-elements for "09_time_scale.html" or 31 svg-elements with "naked" x- and y-axis for "09_time_axis_prettier.html".
It's rather confusing as I was going through all the steps in the book but can't find the bug.
Do other people have the same trouble? I'm using Chrome Browser.
Thank you for looking into it.
Mone
Hello, I'n not sure I should post this here, but I've found an error in the book.
Following along with the book at the chapter 6 (about the Scatterplot, page 109 of printed book) I read that the Area of a cirlce is A = pi*r^2
. Then we chose our area to be A = h - d[1]
and I read that as a consequence the radius was supposed to be r = Math.sqrt(h - d[1])
.
Shouldn't it be r = Math.sqrt((h - d[1]) / Math.PI)
?
The "Function-level scope" section of Chapter 3 (second edition, accessed on O'Reilly) mentions the following:
With block-level scope, our
i
would exist only within the context of the for loop, for example, so any attempts to read the value ofi
or changei
outside of the loop would fail. This is nice because you could establish other variables from within your loop and know that they wouldn’t conflict with variables that exist elsewhere.
Because we used var to declare the i
variable in the for loop, i
gets attached to the window (hey! that's the next section! 😄), so we actually could access it outside of the for block:
Compare this with declaring the variable with let:
This is horrible JS minutia that's absolutely outside the scope of this section's objectives, but it's caused me grief in the past, so I figured I'd point it out.
Hi @alignedleft
I enjoy the book so far, and thank you so much for updating everything to v4. It's been a life, and time saver.
However, I think it'd be nice if you wrote a couple of examples using newer standards such as ES6/ES7 and use webpack or yarn as a build tools.
I thought it'd be worth mentioning an example here for the future readers that might find themselves confused, and do a small contribution to the community.
Reason for this is the issue with this
in ES6 module scope , so couple of examples that use d3.select(this)
from your book won't work.
Example:
.on(" end", function()
{
d3. select( this) .transition() // <-- New!
.duration( 1000) // <-- New!
.attr(" fill", "black")
.attr(" r", 2);
});
Murray, Scott. Interactive Data Visualization for the Web: An Introduction to Designing with D3 (p. 173). O'Reilly Media. Kindle Edition.
With ES6, this example would look like
.on(" end", (d, i, node) => // <-- we use a fat arrow function here
{
d3. select( node[i]) .transition() // <-- D3 v4 idiomatic approach which eliminates this inside the module
.duration( 1000) //
.attr(" fill", "black")
.attr(" r", 2);
});
In the box Pointer Events on Overlapping Elements on pages 201–2, Chapter 10 (2nd Edition), one of the blocks of code seems to be misplaced. At the start of page 202, the text reads:
For example, this would apply to all SVG
text
elements:
svg
rect
rect
rect
...
text
text
text
...
But this doesn't make sense in context and looks like it has been mistakenly copied and pasted from exactly the same code block, printed further down the same page, where the section Grouping SVG Elements describes the element hierarchy.
I suspect that the block at the start of page 202 should instead be something like the following.
For example, this would apply to all SVG
text
elements:
text {
pointer-events: none;
}
Or possibly
svg text {
pointer-events: none;
}
In Chapter 16, it's not clear why the anonymous function passed to stack.keys(keys).value()
is given a name. Line 117 reads:
The full block is
//Tell stack function where to find the keys
stack.keys(keys)
.value(function value(d, key) {
return d[key].sales;
});
But this is functionally equivalent (having checked the console.log()
) to
stack.keys(keys)
.value(function (d, key) {
return d[key].sales;
});
(And of course in ES6:)
stack.keys(keys)
.value((d, key) => d[key].sales);
So I'm not sure if this is a mistake, an inconsistency in style, or something subtle that I am missing (but in which case should be documented.)
This appears on page 336 of the 2nd edition of the book.
For some unclear reason the GeoJSON is not being showed properly using the latest d3js version (a black rectangle is shown)
line 77 returns undefined (dataset.columns) which causes line 78 to error out.
This does not seem to be a difference in version of d3 (I am using v5) as I tried using v3 and v4 getting the same results.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.