Ticket #6: chart-rotate-label.diff

File chart-rotate-label.diff, 7.2 kB (added by jae@…, 4 years ago)

patch to chart.py

  • chart.py

     
    1717 
    1818import copy 
    1919import cairo 
     20import math 
    2021 
    2122from pycha.color import (defaultColorscheme, getColorscheme, hex2rgb, 
    2223                         DEFAULT_COLOR) 
     
    302303        cx.set_source_rgb(*hex2rgb(self.options.axis.lineColor)) 
    303304        cx.set_line_width(self.options.axis.lineWidth) 
    304305 
     306        cx.select_font_face(self.options.axis.labelFont, 
     307                    cairo.FONT_SLANT_NORMAL, 
     308                    cairo.FONT_WEIGHT_NORMAL) 
     309        cx.set_font_size(self.options.axis.labelFontSize) 
     310 
    305311        if not self.options.axis.y.hide: 
    306312            if self.yticks: 
    307313                def drawYLabel(tick): 
     
    321327                    extents = cx.text_extents(label) 
    322328                    labelWidth = extents[2] 
    323329                    labelHeight = extents[3] 
    324                     cx.move_to(x - self.options.axis.tickSize - labelWidth - 5, 
    325                                y + labelHeight / 2.0) 
    326                     cx.show_text(label) 
    327330 
     331                    if self.options.axis.y.rotate: 
     332                        radians = math.radians(self.options.axis.y.rotate) 
     333                        cx.move_to( 
     334                                x   - self.options.axis.tickSize 
     335                                    - (labelWidth * math.cos(radians)) 
     336                                    - 4, 
     337                                y   + (labelWidth * math.sin(radians)) 
     338                                    + labelHeight / (2.0/math.cos(radians)) 
     339                                ) 
     340                        cx.rotate(-radians) 
     341                        cx.show_text(label) 
     342                        cx.rotate(radians) 
     343                    else: 
     344                        cx.move_to( 
     345                                x - self.options.axis.tickSize - labelWidth - 5, 
     346                                y + labelHeight / 2.0) 
     347                        cx.show_text(label) 
    328348                    return label 
     349 
    329350                for tick in self.yticks: 
    330351                    drawYLabel(tick) 
    331352 
     353            if self.options.axis.y.label: 
     354                tickExtents = [cx.text_extents(unicode(tick[1]))[2:4] 
     355                        for tick in self.yticks] 
     356                tickWidth = 0.0 
     357                if tickExtents: 
     358                    tickWidth = self.options.axis.tickSize + 4.0 
     359                    tickExtents.sort() 
     360                    max_width, height = tickExtents[-1] 
     361                    if self.options.axis.y.rotate: 
     362                        radians = math.radians(self.options.axis.y.rotate) 
     363                        max_width = ( 
     364                                (max_width * math.cos(radians)) 
     365                                + (height * math.sin(radians)) ) 
     366                    tickWidth += max_width 
     367 
     368                cx.new_path() 
     369                label = unicode(self.options.axis.y.label) 
     370                labelWidth, labelHeight = cx.text_extents(label)[2:4] 
     371                x = self.area.x - tickWidth - 4.0 
     372                y = self.area.y + .5 * self.area.h + labelWidth / 2 
     373                cx.move_to(x, y) 
     374                cx.select_font_face(self.options.axis.labelFont, 
     375                            cairo.FONT_SLANT_NORMAL, 
     376                            cairo.FONT_WEIGHT_BOLD) 
     377                radians = math.radians(90) 
     378                cx.rotate(-radians) 
     379                cx.show_text(label) 
     380                cx.rotate(radians) 
     381                cx.select_font_face(self.options.axis.labelFont, 
     382                            cairo.FONT_SLANT_NORMAL, 
     383                            cairo.FONT_WEIGHT_NORMAL) 
     384 
    332385            cx.new_path() 
    333386            cx.move_to(self.area.x, self.area.y) 
    334387            cx.line_to(self.area.x, self.area.y + self.area.h) 
     
    349402                    cx.line_to(x, y + self.options.axis.tickSize) 
    350403                    cx.close_path() 
    351404                    cx.stroke() 
     405                    cx.fill() 
    352406 
     407                    cx.new_path() 
    353408                    label = unicode(tick[1]) 
    354409                    extents = cx.text_extents(label) 
    355410                    labelWidth = extents[2] 
    356411                    labelHeight = extents[3] 
    357                     cx.move_to(x - labelWidth / 2.0, 
    358                                y + self.options.axis.tickSize + 10) 
    359                     cx.show_text(label) 
     412                    if self.options.axis.x.rotate: 
     413                        radians = math.radians(self.options.axis.x.rotate) 
     414                        cx.move_to( 
     415                                x   - (labelHeight * math.cos(radians)), 
     416                                y   + self.options.axis.tickSize 
     417                                    + (labelHeight * math.cos(radians)) 
     418                                    + 2) 
     419                        cx.rotate(radians) 
     420                        cx.show_text(label) 
     421                        cx.rotate(-radians) 
     422                    else: 
     423                        cx.move_to(x - labelWidth / 2.0, 
     424                               y + self.options.axis.tickSize + labelHeight + 2) 
     425                        cx.show_text(label) 
    360426                    return label 
     427 
    361428                for tick in self.xticks: 
    362429                    drawXLabel(tick) 
    363430 
     431            if self.options.axis.x.label: 
     432                tickExtents = [cx.text_extents(unicode(tick[1]))[2:4] 
     433                        for tick in self.xticks] 
     434                tickHeight = 0.0 
     435                if tickExtents: 
     436                    tickHeight = self.options.axis.tickSize + 4.0 
     437                    tickExtents.sort() 
     438                    max_width, height = tickExtents[-1] 
     439                    if self.options.axis.x.rotate: 
     440                        radians = math.radians(self.options.axis.x.rotate) 
     441                        height = ((max_width * math.sin(radians)) 
     442                                  + (height * math.cos(radians)) ) 
     443                    tickHeight += height 
     444 
     445                cx.new_path() 
     446                label = unicode(self.options.axis.x.label) 
     447                cx.select_font_face(self.options.axis.labelFont, 
     448                            cairo.FONT_SLANT_NORMAL, 
     449                            cairo.FONT_WEIGHT_BOLD) 
     450                labelWidth, labelHeight = cx.text_extents(label)[2:4] 
     451                x = self.area.x + self.area.w / 2.0 - labelWidth / 2.0 
     452                y = self.area.y + self.area.h + tickHeight + labelHeight + 4.0 
     453                cx.move_to(x, y) 
     454                cx.show_text(label) 
     455                cx.select_font_face(self.options.axis.labelFont, 
     456                            cairo.FONT_SLANT_NORMAL, 
     457                            cairo.FONT_WEIGHT_NORMAL) 
     458 
    364459            cx.new_path() 
    365460            cx.move_to(self.area.x, self.area.y + self.area.h) 
    366461            cx.line_to(self.area.x + self.area.w, self.area.y + self.area.h) 
     
    456551            tickCount=10, 
    457552            tickPrecision=1, 
    458553            range=None, 
     554            rotate=None, 
     555            label=None, 
    459556        ), 
    460557        y=Option( 
    461558            hide=False, 
     
    463560            tickCount=10, 
    464561            tickPrecision=1, 
    465562            range=None, 
     563            rotate=None, 
     564            label=None, 
    466565        ), 
    467566    ), 
    468567    background=Option(