Reputation:
I have a d3 calendar inspired by:
http://bl.ocks.org/KathyZ/c2d4694c953419e0509b
which works as it is now, but I can't figure out where or how to add text to display the day of the month, meaning, the number (1, 2, ... 31, etc) on each of the days. I have to somehow append a text element to the day rectangles and I don't know how to do that.
function normal_cal(dom, data, clk_fn, scp){
var width = 900,
height = 259,
cellSize = 12; // cell size
var no_months_in_a_row = Math.floor(width / (cellSize * 7 + 50));
var shift_up = cellSize * 1;
var day = d3.time.format("%w"), // day of the week
day_of_month = d3.time.format("%e") // day of the month
day_of_year = d3.time.format("%j")
week = d3.time.format("%U"), // week number of the year
month = d3.time.format("%m"), // month number
year = d3.time.format("%Y"),
percent = d3.format(".1%"),
format = d3.time.format("%Y-%m-%d"),
parseDate = d3.time.format("%Y-%m-%d").parse,
year_getter = d3.time.format("%Y%"),
day_getter=d3.time.format("%a, %e");
var color = d3.scale.quantize()
.domain([-.05, .05])
.range(d3.range(11).map(function(d) { return "q" + d + "-11"; }));
// range?
var years = [d3.extent(data, function(d) { return year_getter(parseDate(d.Date)); })];
var start_year = parseInt(years[0][0]);
var end_year = parseInt(years[0][1]);
var svg = d3.select(dom.get(0)).selectAll("svg")
.data(d3.range(start_year, end_year + 1))
.enter().append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "RdYlGn")
.append("g")
var rect = svg.selectAll(".day")
.data(function(d) {
return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
})
.enter().append("rect")
.attr("class", "day")
.attr("width", cellSize)
.attr("height", cellSize)
.attr("x", function(d) {
var month_padding = 1.2 * cellSize*7 * ((month(d)-1) % (no_months_in_a_row));
return day(d) * cellSize + month_padding;
})
.attr("y", function(d) {
var week_diff = week(d) - week(new Date(year(d), month(d)-1, 1) );
var row_level = Math.ceil(month(d) / (no_months_in_a_row));
return (week_diff*cellSize) + row_level*cellSize*8 - cellSize/2 - shift_up;
})
.datum(format);
var month_titles = svg.selectAll(".month-title") // Jan, Feb, Mar and the whatnot
.data(function(d) {
return d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
.enter().append("text")
.text(monthTitle)
.attr("x", function(d, i) {
var month_padding = 1.2 * cellSize*7* ((month(d)-1) % (no_months_in_a_row));
return month_padding;
})
.attr("y", function(d, i) {
var week_diff = week(d) - week(new Date(year(d), month(d)-1, 1) );
var row_level = Math.ceil(month(d) / (no_months_in_a_row));
return (week_diff*cellSize) + row_level*cellSize*8 - cellSize - shift_up;
})
.attr("class", "month-title")
.attr("d", monthTitle);
var year_titles = svg.selectAll(".year-title") // Jan, Feb, Mar and the whatnot
.data(function(d) {
return d3.time.years(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
.enter().append("text")
.text(yearTitle)
.attr("x", function(d, i) { return width/2 - 100; })
.attr("y", function(d, i) { return cellSize*3 - shift_up; })
.attr("class", "year-title")
.attr("d", yearTitle);
// Tooltip Object
var tooltip = d3.select("body")
.append("div").attr("id", "tooltip")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
//==================================================================================PROCESS DATA
//==================================================================================PROCESS DATA
//==================================================================================PROCESS DATA
var data = d3.nest()
.key(function(d) { return d.Date; })
.rollup(function(d) {
return {"value": -5,
"comment": d[0].comment,
"key": d[0].key
};
})
.map(data);
rect.filter(function(d) { return d in data; })
.attr("class", function(d) { return "day " + color(data[d].value); })
.select("title")
.text(function(d) {
return d + ": " +data[d].comment;
});
// Tooltip
rect.on("mouseover", mouseover);
rect.on("mouseout", mouseout);
rect.on("click", function(d){
clk_fn(d, data, scp);
});
function mouseover(d) {
console.log(data[d]);
tooltip.style("visibility", "visible");
var purchase_text = (data[d] !== undefined) ? day_getter(parseDate(d)) + " : " + data[d].comment : day_getter(parseDate(d));
tooltip.transition()
.duration(200)
.style("opacity", .9);
tooltip.html(purchase_text)
.style("left", (d3.event.pageX)+30 + "px")
.style("top", (d3.event.pageY) + "px");
}
function mouseout (d) {
tooltip.transition()
.duration(500)
.style("opacity", 0);
var $tooltip = $("#tooltip");
$tooltip.empty();
}
function dayTitle (t0) {
return t0.toString().split(" ")[2];
}
function monthTitle (t0) {
return t0.toLocaleString("en-us", { month: "long" });
}
function yearTitle (t0) {
return t0.toString().split(" ")[3];
}
//});
}
How can I append the day of the month (number) on the squares?
Upvotes: 1
Views: 646
Reputation: 61666
Based on the link you provided:
http://bl.ocks.org/KathyZ/c2d4694c953419e0509b
I have modified the rect
definition this way (just replace the block defining rect (var rect = svg.selectAll(".day")...)
with the following to try it out):
var rectContainer = svg.selectAll(".day")
.data(function(d) {
return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
})
.enter().append("g")
.attr("transform", function(d) {
var month_padding = 1.2 * cellSize*7 * ((month(d)-1) % (no_months_in_a_row));
var x = day(d) * cellSize + month_padding;
var week_diff = week(d) - week(new Date(year(d), month(d)-1, 1) );
var row_level = Math.ceil(month(d) / (no_months_in_a_row));
var y = (week_diff*cellSize) + row_level*cellSize*8 - cellSize/2 - shift_up;
return "translate(" + x + "," + y + ")";
});
var rect = rectContainer.append("rect")
.attr("class", "day")
.attr("width", cellSize)
.attr("height", cellSize)
.datum(format);
rectContainer.append("text")
.attr("x", cellSize / 2)
.attr("y", cellSize / 2)
.attr("dy", ".35em")
.text(function(d) {
return day_of_month(d);
})
.style("font-size", "10px");
As you can't add text
inside a rect
(details here), you'll have to create a container which will contain both the rect and the text.
As the location of the rect is now handled by the location of the container, the coordinates of the container have to be set. This is done using the transform
attribute by translating the container instead of setting x and y of the rect.
The day_of_month() formatter is defined at the top of link in Kathy Zhou's code.
I'll let you manage the style (font size, putting the text exactly in the center, ...)
Upvotes: 1