简体   繁体   中英

Making a calendar with d3

i am trying to build a plugin to display a year view of the events on a google calendar account, i am trying to build this view using D3 and fetching the data from the google calendar API (this part sounds easy so far), but i'm stuck trying to actually build the view in d3, here is what i have so far:

My code :

var margin = {top: 40, right: 40, bottom: 40, left: 40},
    width = 960,
    height = 500;

var x = d3.time.scale()
.domain([new Date(2013, 0, 1), new Date(2014, 0, 1)])
.range([0, width])

var y = d3.time.scale()
.domain([new Date(2013,0,1), new Date(2013, 0,31)])
.range([0, height])

var xAxis = d3.svg.axis()
.scale(x)
.orient("top")

var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(d3.time.days, 1)
.tickFormat(d3.time.format('%e'))

 var svg = d3.select(".container").append("svg")
 .attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
 .append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

function makeXaxis() {
return d3.svg.axis()
.scale(x)
.orient("top")
}

function makeYaxis() {
return d3.svg.axis()
.scale(y)
.orient("left")
.ticks(d3.time.days, 1)
.tickFormat(d3.time.format('%e'))
 }

 svg.append("g")
  .attr("class", "x axis")
  // .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(0,0)")
.call(yAxis);

 svg.append("g")
 .attr("class", "grid")
.call(makeYaxis()
  .tickSize(-width, 0, 0)
  .tickFormat("")
  .tickPadding(8)
  )

svg.append("g")
.attr("class", "grid")
.call(makeXaxis()
  .tickSize(-height, 0, 0)
  .tickFormat("")
  )

What it renders: actual view calendar

在此处输入图片说明

What i want to achieve: goal calendar

在此处输入图片说明

There are a few problem with my code,

  • the first being that my y domain is an arbitrary month of 31 days, i don't know if my data will place itself on the graph well if it is a time scale, should i use a linear scale of 31 ?

  • How can i just render January...December without the 2013 and 2014

  • How can i display the months in the middle top of each row instead of displaying them on every tick ?

  • Well , i am not going to ask for more considering i am already asking for alot.

Thanks everyone, i am totally new to d3, i have read lots of tuts tho.

My approach (not the only way):

Use linear numerical domains for both axes. In other words:

x.domain( [0, 11] );    // months, zero-indexed
y.domain( [1, 31] );    // days of month

To render the months properly, you will then have to do something kooky like:

var monthFormatter = d3.time.format( "%B" );  // %B = Month name
function makeYaxis() {
    return d3.svg.axis()
    .scale(y)
    .orient("left")
    .tickFormat( function(d) { return monthFormatter( d.date ) } )
 }

As for alignment of these values, this https://groups.google.com/forum/?fromgroups=#!topic/d3-js/1gCrn0taKw8 describes how it's a non-trivial problem. You may be best to tinker with adjusting the x-values manually.

I don't see the code used to render the data on screen, but you can use something like:

svg.selectAll( rect ).data( myData ).append( "rect" )
  .attr( "x", function(d) { return x( d.date.getMonth() ); } )
  .attr( "y", function(d) { return x( d.date.getDate() ); } )

I imagine that having 'stacked' data (side-by-side) will be problematic, but we'll deal with that later.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM