Modifying calendar to show only one month?

1,663 views
Skip to first unread message

retro

unread,
May 3, 2012, 3:56:48 PM5/3/12
to d3-js
Hi,
Can someone help me understanding the calendar example. I need to
modify it to show data in particular date range only and possibly show
only 1 or 3 months. What needs to be changed?

Also, as far as reading the data is concerned, i have a json string
with key and values
2008-01-01,16

How can i modify the csv code to read this data as json?

Jason Davies

unread,
May 4, 2012, 4:04:21 AM5/4/12
to d3...@googlegroups.com
On Thu, May 03, 2012 at 12:56:48PM -0700, retro wrote:
> Can someone help me understanding the calendar example. I need to
> modify it to show data in particular date range only and possibly show
> only 1 or 3 months. What needs to be changed?

I assume you mean http://mbostock.github.com/d3/ex/calendar.html

On line 16, you can see it creates a separate <svg> element for each
year:

.data(d3.range(1990, 2011))

So if you only wanted to show a few months for a single year, you could
change this to the year in question:

.data([2012])

Since you know there's only one year, you could also simply append the
<svg> element without using data binding:

var svg = d3.select("#chart").append("svg")

The months are chosen on line 30:

.data(function(d) {
return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
})

Here, d3.time.days is used to generate all the days between two given
years. The starting year is retrieved from the data bound on line 16.

So if you only wanted to show a few months, you would simply modify
these two dates appropriately.

> Also, as far as reading the data is concerned, i have a json string
> with key and values
> 2008-01-01,16
>
> How can i modify the csv code to read this data as json?

I'm not sure I understand the question. You may want to read up on
d3.csv to see how CSV parsing works:

https://github.com/mbostock/d3/wiki/CSV

If you want to load the data from a JSON file, you can use d3.json:

https://github.com/mbostock/d3/wiki/Requests#wiki-d3_json

--
Jason Davies, http://www.jasondavies.com/

retro

unread,
May 4, 2012, 11:05:21 AM5/4/12
to d3-js
Thanks for the clarification. I am still not clear what is happening
in this snippet?

.data(function(d) {
return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
})


I assume it is automatically picking up number of days between d and d
+1 where d is the start year?

In that case if we just want one month will the above change to ?

.data(function(d) {
return d3.time.days(new Date(d, 0, 1), new Date(d, 1, 1));
})


On May 4, 4:04 am, Jason Davies <ja...@jasondavies.com> wrote:
> On Thu, May 03, 2012 at 12:56:48PM -0700, retro wrote:
> > Can someone help me understanding the calendar example. I need to
> > modify it to show data in particular date range only and possibly show
> > only 1 or 3 months. What needs to be changed?
>
> I assume you meanhttp://mbostock.github.com/d3/ex/calendar.html

Ger Hobbelt

unread,
May 4, 2012, 11:47:30 AM5/4/12
to d3...@googlegroups.com
On Fri, May 4, 2012 at 5:05 PM, retro <retrofi...@gmail.com> wrote:
Thanks for the clarification. I am still not clear what is happening
in this snippet?

 .data(function(d) {
   return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
 })


I assume it is automatically picking up number of days between d and d
+1 where d is the start year?

That is correct. To be precise, it's doing it for each year in the 
.data(d3.range(1990, 2011))
data range as
svg.selectAll("path.month")
43     .data(function(d) { return d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
will be feeding each of the items in said 1990-2011 range in turn to the function as argument 'd' (as the parent data set was set up here and thus known to the 'svg' instance by the time svg.selectAll.data(function()...) is invoked:
svg = d3.select("#chart").selectAll("svg")
16     .data(d3.range(1990, 2011))
 

In that case if we just want one month will the above change to ?

.data(function(d) {
   return d3.time.days(new Date(d, 0, 1), new Date(d, 1, 1));
 })

Yes, but for that code you MUST still specify the single year for the svg as per Jason's suggestion:
  .data([2012])
The d3.time.days(...) code above WON'T work as is when you follow Jason's hint that you might go and 'simply append the svg element without using data binding', which is a good idea but has some consequences. In that case, it goes something like this:
svg.selectAll("path.month")
43     .data(d3.time.months(new Date(2012, 0, 1), new Date(2012, 1, 1)))

Also be aware that you need to adapt the days range setup accordingly: the month and day shapes (polygon outline and rect respectively) are rendered independently.




Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------



retro

unread,
May 4, 2012, 4:32:29 PM5/4/12
to d3-js
Thanks!!

One more question, how can we handle click event on rects? Current
code shows the data on mouse hover, but on a tablet i need people to
click on it?


On May 4, 11:47 am, Ger Hobbelt <g...@hobbelt.com> wrote:
> On Fri, May 4, 2012 at 5:05 PM, retro <retrofit.br...@gmail.com> wrote:
> > Thanks for the clarification. I am still not clear what is happening
> > in this snippet?
>
> >  .data(function(d) {
> >    return d3.time.days(new Date(d, 0, 1), new Date(d + 1, 0, 1));
> >  })
>
> > I assume it is automatically picking up number of days between d and d
> > +1 where d is the start year?
>
> That is correct. To be precise, it's doing it for each year in the
> .data(d3.range(1990, 2011))
> data range as
>
> svg.selectAll("path.month")43     .data(function(d) { return
> d3.time.months(new Date(d, 0, 1), new Date(d + 1, 0, 1)); })
>
> will be feeding each of the items in said 1990-2011 range in turn to the
> function as argument 'd' (as the parent data set was set up here and thus
> known to the 'svg' instance by the time svg.selectAll.data(function()...)
> is invoked:
>
> svg = d3.select("#chart").selectAll("svg")16     .data(d3.range(1990, 2011))
>
>
>
> > In that case if we just want one month will the above change to ?
>
> > .data(function(d) {
> >    return d3.time.days(new Date(d, 0, 1), new Date(d, 1, 1));
> >  })
>
> Yes, but for that code you MUST still specify the single year for the svg
> as per Jason's suggestion:
>   .data([2012])
> The d3.time.days(...) code above WON'T work as is when you follow Jason's
> hint that you might go and 'simply append the svg element without using
> data binding', which is a good idea but has some consequences. In that
> case, it goes something like this:
>
> svg.selectAll("path.month")43     .data(d3.time.months(new Date(2012,

Ger Hobbelt

unread,
May 4, 2012, 10:11:12 PM5/4/12
to d3...@googlegroups.com
On Fri, May 4, 2012 at 10:32 PM, retro <retrofi...@gmail.com> wrote:
One more question, how can we handle click event on rects? Current
code shows the data on mouse hover, but on a tablet i need people to
click on it?

Haven't tested this on tablets, but the usual event for this is 'click' -->

  .on('click', function(...){....})
Reply all
Reply to author
Forward
0 new messages