1import calendar 2from pyx import * 3 4class daystyle(graph.style._style): 5 6 def columnnames(self, privatedata, sharedata, graph, columnnames, dataaxisnames): 7 # register the new column names 8 usecolumnnames = ["day", "month", "weekday", "note"] 9 for columnname in usecolumnnames: 10 if columnname not in columnnames: 11 raise ValueError("column '%s' missing" % columnname) 12 return usecolumnnames 13 14 def adjustaxis(self, privatedata, sharedata, graph, plotitem, columnname, data): 15 # adjust axes ranges 16 if columnname == "month": 17 graph.axes["x"].adjustaxis([(x, 0) for x in data]) 18 graph.axes["x"].adjustaxis([(x, 1) for x in data]) 19 if columnname == "day": 20 graph.axes["y"].adjustaxis([(x, 0) for x in data]) 21 graph.axes["y"].adjustaxis([(x, 1) for x in data]) 22 23 def drawpoint(self, privatedata, sharedata, graph, point): 24 # draw a single day 25 x1_pt, y1_pt = graph.pos_pt((point["month"], 0), (point["day"], 0)) 26 x2_pt, y2_pt = graph.pos_pt((point["month"], 1), (point["day"], 1)) 27 p = path.rect_pt(x1_pt, y1_pt, x2_pt - x1_pt, y2_pt - y1_pt) 28 if point["weekday"] == calendar.day_abbr[-1]: 29 graph.stroke(p, [deco.filled([color.gray(0.8)])]) 30 else: 31 graph.stroke(p) 32 graph.text_pt(x1_pt+3, y2_pt-3, 33 "%i %s" % (point["day"], point["weekday"]), 34 [text.valign.top]) 35 if point["note"]: 36 graph.text_pt(x1_pt+3, y1_pt+3, point["note"], [text.size.tiny]) 37 38# create calendar data 39year = 2015 40notes = {1: {17: r"\PyX{} 0.2 (2003)", 20: r"\PyX{} 0.5 (2004)", 22: r"\PyX{} 0.5.1 (2004)"}, 41 3: {30: r"\PyX{} 0.6 (2004)", 31: r"\PyX{} 0.3 ('03), \PyX{} 0.6.1 ('04)"}, 42 4: {4: r"\PyX{} 0.3.1 (2003)", 7: r"\PyX{} 0.6.2 (2004)", 27: r"\PyX{} 0.6.3 (2004)", 30: r"\PyX{} 0.14 (2015)"}, 43 5: {5: r"\PyX{} 0.11 (2011)", 20: r"\PyX{} 0.11.1 (2011)", 24: r"\PyX{} 0.9 (2006)"}, 44 7: {13: r"\PyX{} 0.8 (2005)", 14: r"\PyX{} 0.15 (2019)"}, 45 8: {13: r"\PyX{} 0.8.1 (2005)", 22: r"\PyX{} 0.4 (2003)"}, 46 9: {17: r"\PyX{} 0.4.1 (2003)"}, 47 10: {3: r"\PyX{} 0.10 (2007)", 7: r"\PyX{} 0.1 (2002)", 12: r"\PyX{} 0.12 (2012)", 48 21: r"\PyX{} 0.7 (2004)", 26: r"\PyX{} 0.12.1 (2012)"}, 49 11: {2: r"\PyX{} 0.14.1 (2015)"}, 50 12: {15: r"\PyX{} 0.7.1 (2004)", 20: r"\PyX{} 0.13 (2013)"}} 51d = graph.data.points([(day, 52 calendar.month_name[month], 53 calendar.day_abbr[calendar.weekday(year, month, day)], 54 notes.get(month, {}).get(day)) 55 for month in range(1, 13) 56 for day in range(1, calendar.monthrange(year, month)[1]+1)], 57 day=1, month=2, weekday=3, note=4) 58 59# create the calendar 60g = graph.graphxy(width=40, x2=graph.axis.bar(dist=0, linkpainter=None), 61 y=graph.axis.bar(dist=0, reverse=1, painter=None)) 62g.plot(d, [daystyle()]) 63 64# we could write the full calendar by 65# g.writeEPSfile("cal", paperformat=document.paperformat.A3, rotated=1) 66 67# instead we clip the result to show only a small part 68clip = canvas.clip(g.bbox().enlarged(0.1, bottom=-17, right=-25).path()) 69gc = canvas.canvas([clip]) 70gc.insert(g) 71# and add some dots at the clipped parts 72gcbb = gc.bbox() 73c = canvas.canvas() 74c.insert(gc) 75c.text(gcbb.right()+0.5, gcbb.center()[1], r"\dots") 76c.text(gcbb.center()[0], gcbb.bottom()-0.5, r"\dots") 77c.writeEPSfile("cal") 78c.writePDFfile("cal") 79c.writeSVGfile("cal") 80