summaryrefslogtreecommitdiffstats
path: root/vstf/vstf/controller/reporters/report/pdf/element.py
diff options
context:
space:
mode:
Diffstat (limited to 'vstf/vstf/controller/reporters/report/pdf/element.py')
-rwxr-xr-xvstf/vstf/controller/reporters/report/pdf/element.py781
1 files changed, 781 insertions, 0 deletions
diff --git a/vstf/vstf/controller/reporters/report/pdf/element.py b/vstf/vstf/controller/reporters/report/pdf/element.py
new file mode 100755
index 00000000..2528f2c5
--- /dev/null
+++ b/vstf/vstf/controller/reporters/report/pdf/element.py
@@ -0,0 +1,781 @@
+#!/usr/bin/python
+# -*- coding: utf8 -*-
+# author: wly
+# date: 2015-05-04
+# see license for license details
+__version__ = ''' '''
+__doc__ = """
+it contains the base element for pdf
+eImage is used to draw picture on the pdf document
+eDataTable is used to draw table on the pdf document
+eGraphicsTable is used to draw plot on the pdf document
+eParagraph is used to draw text on the pdf document
+"""
+from reportlab.platypus import Image, Table
+from reportlab.graphics.shapes import Drawing
+from reportlab.graphics.charts.lineplots import LinePlot
+from reportlab.graphics.charts.linecharts import HorizontalLineChart
+from reportlab.platypus.paragraph import Paragraph
+from reportlab.graphics.widgets.markers import makeMarker
+from reportlab.graphics.charts.legends import Legend
+from reportlab.graphics.charts.textlabels import Label
+from reportlab.graphics.charts.axes import XValueAxis
+from reportlab.graphics.shapes import Group
+from reportlab.graphics.charts.barcharts import VerticalBarChart
+from vstf.controller.reporters.report.pdf.styles import *
+
+
+class eImage(Image):
+ """ an image(digital picture)which contains the function of auto zoom picture """
+
+ def __init__(self, filename, width=None, height=None, kind='direct', mask="auto", lazy=1, hAlign='CENTRE',
+ vAlign='BOTTOM'):
+ Image.__init__(self, filename, None, None, kind, mask, lazy)
+ print height, width
+ print self.drawHeight, self.drawWidth
+ if self.drawWidth * height > self.drawHeight * width:
+ self.drawHeight = width * self.drawHeight / self.drawWidth
+ self.drawWidth = width
+ else:
+ self.drawWidth = height * self.drawWidth / self.drawHeight
+ self.drawHeight = height
+ self.hAlign = hAlign
+ self.vAlign = vAlign
+ print self.drawHeight, self.drawWidth
+
+
+class eTable(object):
+ """ an abstract table class, which is contains the base functions to create table """
+
+ def __init__(self, data, style=TableStyle(name="default")):
+ self._tablestyle = style
+ self._table = []
+ self._spin = False
+ self._colWidths = None
+ self._data = self.analysisData(data)
+ if self._data:
+ self.create()
+
+ def analysisData(self, data):
+ raise NotImplementedError("abstract eTable")
+
+ def create(self):
+ self._table = Table(self._data, style=self._style, splitByRow=1)
+ self._table.hAlign = self._tablestyle.table_hAlign
+ self._table.vAlign = self._tablestyle.table_vAlign
+ self._table.colWidths = self._tablestyle.table_colWidths
+ if self._spin or self._colWidths:
+ self._table.colWidths = self._colWidths
+ self._table.rowHeights = self._tablestyle.table_rowHeights
+
+ @property
+ def table(self):
+ return self._table
+
+
+class eCommonTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1.2, colors.black)
+ ]
+ return data
+
+
+class eConfigTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('SPAN', (2, 0), (3, 0)),
+ ('SPAN', (2, 1), (3, 1)),
+ ('SPAN', (2, 8), (3, 8)),
+ ('SPAN', (2, 9), (3, 9)),
+ ('SPAN', (2, 10), (3, 10)),
+ ('SPAN', (0, 0), (0, 7)),
+ ('SPAN', (0, 8), (0, 10)),
+ ('SPAN', (0, 11), (0, 19)),
+ ('SPAN', (1, 2), (1, 6)),
+ ('SPAN', (1, 12), (1, 13)),
+ ('SPAN', (1, 14), (1, 16)),
+ ('SPAN', (1, 17), (1, 19)),
+ ('SPAN', (2, 3), (2, 6))
+ ]
+ return data
+
+
+class eSummaryTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('SPAN', (0, 0), (0, 1)),
+ ('SPAN', (1, 0), (4, 0)),
+ ('SPAN', (5, 0), (-1, 0))
+ ]
+ return data
+
+
+class eGitInfoTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('SPAN', (0, 0), (0, 2)),
+ ('SPAN', (0, 3), (0, 5)),
+ ('SPAN', (0, 6), (0, 8))
+ ]
+ return data
+
+
+class eScenarioTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('ALIGN', (2, 1), (-1, -1), 'LEFT'),
+ ('SPAN', (0, 1), (0, 6)),
+ ('SPAN', (0, 7), (0, 12)),
+ ('SPAN', (0, 13), (0, 16)),
+ ('SPAN', (0, 17), (0, 20))
+ ]
+ return data
+
+
+class eOptionsTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('SPAN', (2, 0), (4, 0)),
+ ('SPAN', (2, 1), (4, 1)),
+ ('SPAN', (0, 0), (0, -1)),
+ ('SPAN', (1, 2), (1, 16)),
+ ('SPAN', (1, 17), (1, 19)),
+ ('SPAN', (1, 20), (1, 22)),
+ ('SPAN', (1, 23), (1, 24)),
+ ('SPAN', (2, 2), (2, 4)),
+ ('SPAN', (2, 5), (2, 12)),
+ ('SPAN', (2, 13), (2, 16)),
+ ('SPAN', (2, 17), (2, 19)),
+ ('SPAN', (2, 20), (2, 22)),
+ ('SPAN', (2, 23), (2, 24))
+ ]
+ return data
+
+
+class eProfileTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('SPAN', (0, 1), (0, -1)),
+ ('SPAN', (1, 0), (2, 0)),
+ ]
+ return data
+
+
+class eDataTable(eTable):
+ def analysisData(self, data):
+ result = data
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
+ ('LEADING', (0, 0), (-1, -1), 18),
+ ('GRID', (0, 0), (-1, -1), 0.5, colors.grey),
+ ('BOX', (0, 0), (-1, -1), 1, colors.black),
+ ('LINEBEFORE', (1, 0), (1, -1), 0.8, colors.black),
+ # ('LINEBEFORE', (3, 0), (3, -1), 1, colors.black),
+ # ('LINEBEFORE', (5, 0), (5, -1), 1, colors.black),
+ ('LINEBELOW', (0, 0), (-1, 0), 0.8, colors.black),
+ # ('SPAN', (0, 0), (0, 1)),
+ # ('SPAN', (1, 0), (2, 0)),
+ # ('SPAN', (3, 0), (4, 0))
+ ]
+ if self._spin is True:
+ print "start spin"
+ result = map(list, zip(*result))
+ style = []
+ for value in self._style:
+ value = list(value)
+ value[1] = (value[1][1], value[1][0])
+ value[2] = (value[2][1], value[2][0])
+ if value[0] == 'LINEBELOW':
+ value[0] = 'LINEAFTER'
+ elif value[0] == 'LINEBEFORE':
+ value[0] = 'LINEABOVE'
+ value = tuple(value)
+ style.append(value)
+ self._style = style
+ return result
+
+
+class eGraphicsTable(eTable):
+ def analysisData(self, data):
+ self._style = [
+ ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
+ ('VALIGN', (0, 0), (-1, -1), 'MIDDLE')
+ ]
+ return data
+
+
+class noScaleXValueAxis(XValueAxis):
+ def __init__(self):
+ XValueAxis.__init__(self)
+
+ def makeTickLabels(self):
+ g = Group()
+ if not self.visibleLabels: return g
+
+ f = self._labelTextFormat # perhaps someone already set it
+ if f is None:
+ f = self.labelTextFormat or (self._allIntTicks() and '%.0f' or str)
+ elif f is str and self._allIntTicks():
+ f = '%.0f'
+ elif hasattr(f, 'calcPlaces'):
+ f.calcPlaces(self._tickValues)
+ post = self.labelTextPostFormat
+ scl = self.labelTextScale
+ pos = [self._x, self._y]
+ d = self._dataIndex
+ pos[1 - d] = self._labelAxisPos()
+ labels = self.labels
+ if self.skipEndL != 'none':
+ if self.isXAxis:
+ sk = self._x
+ else:
+ sk = self._y
+ if self.skipEndL == 'start':
+ sk = [sk]
+ else:
+ sk = [sk, sk + self._length]
+ if self.skipEndL == 'end':
+ del sk[0]
+ else:
+ sk = []
+
+ nticks = len(self._tickValues)
+ nticks1 = nticks - 1
+ for i, tick in enumerate(self._tickValues):
+ label = i - nticks
+ if label in labels:
+ label = labels[label]
+ else:
+ label = labels[i]
+ if f and label.visible:
+ v = self.scale(i)
+ if sk:
+ for skv in sk:
+ if abs(skv - v) < 1e-6:
+ v = None
+ break
+ if v is not None:
+ if scl is not None:
+ t = tick * scl
+ else:
+ t = tick
+ if isinstance(f, str):
+ txt = f % t
+ elif isSeq(f):
+ # it's a list, use as many items as we get
+ if i < len(f):
+ txt = f[i]
+ else:
+ txt = ''
+ elif hasattr(f, '__call__'):
+ if isinstance(f, TickLabeller):
+ txt = f(self, t)
+ else:
+ txt = f(t)
+ else:
+ raise ValueError('Invalid labelTextFormat %s' % f)
+ if post: txt = post % txt
+ pos[d] = v
+ label.setOrigin(*pos)
+ label.setText(txt)
+
+ # special property to ensure a label doesn't project beyond the bounds of an x-axis
+ if self.keepTickLabelsInside:
+ if isinstance(self, XValueAxis): # not done yet for y axes
+ a_x = self._x
+ if not i: # first one
+ x0, y0, x1, y1 = label.getBounds()
+ if x0 < a_x:
+ label = label.clone(dx=label.dx + a_x - x0)
+ if i == nticks1: # final one
+ a_x1 = a_x + self._length
+ x0, y0, x1, y1 = label.getBounds()
+ if x1 > a_x1:
+ label = label.clone(dx=label.dx - x1 + a_x1)
+ g.add(label)
+
+ return g
+
+ def ___calcScaleFactor(self):
+ """Calculate the axis' scale factor.
+ This should be called only *after* the axis' range is set.
+ Returns a number.
+ """
+ self._scaleFactor = self._length / (len(self._tickValues) + 1)
+ return self._scaleFactor
+
+ def scale(self, value):
+ """Converts a numeric value to a plotarea position.
+ The chart first configures the axis, then asks it to
+ """
+ assert self._configured, "Axis cannot scale numbers before it is configured"
+ if value is None: value = 0
+ # this could be made more efficient by moving the definition of org and sf into the configuration
+ org = (self._x, self._y)[self._dataIndex]
+ sf = self._length / (len(self._tickValues) + 1)
+ if self.reverseDirection:
+ sf = -sf
+ org += self._length
+ return org + sf * (value + 1)
+
+
+class noScaleLinePlot(LinePlot):
+ def __init__(self):
+ LinePlot.__init__(self)
+ self.xValueAxis = noScaleXValueAxis()
+
+ def calcPositions(self):
+ """Works out where they go.
+
+ Sets an attribute _positions which is a list of
+ lists of (x, y) matching the data.
+ """
+ self._seriesCount = len(self.data)
+ self._rowLength = max(map(len, self.data))
+
+ self._positions = []
+ for rowNo in range(len(self.data)):
+ line = []
+ len_row = len(self.data[rowNo])
+ for colNo in range(len_row):
+ datum = self.data[rowNo][colNo] # x, y value
+ x = self.x + self.width / (len_row + 1) * (colNo + 1)
+ self.xValueAxis.labels[colNo].x = self.x + self.width / (len_row + 1) * (colNo + 1)
+ y = self.yValueAxis.scale(datum[1])
+ # print self.width, " ", x
+ line.append((x, y))
+ self._positions.append(line)
+
+
+# def _innerDrawLabel(self, rowNo, colNo, x, y):
+# return None
+class eLinePlot(object):
+ def __init__(self, data, style):
+ self._lpstyle = style
+ self._linename = data[0]
+ self._data = self.analysisData(data[1:])
+ if self._data:
+ self.create()
+
+ @property
+ def draw(self):
+ return self._draw
+
+ def analysisData(self, data):
+ columns = len(data)
+ # print data
+ data = map(list, zip(*data))
+ rows = len(data)
+
+ for i in range(rows):
+ for j in range(columns):
+ data[i][j] = float(data[i][j])
+ self._linename = self._linename[1:]
+ """
+ delcnt = 0
+ delrows = []
+ for i in range(columns):
+ delrows.append(0.0)
+ del_line = [self._linename[0]]
+ for i in range(rows):
+ for j in range(columns):
+ data[i][j] = float(data[i][j])
+ if data[i] == delrows:
+ delcnt += 1
+ del_line.append(self._linename[i])
+ for i in range(delcnt):
+ data.remove(delrows)
+ for name in del_line:
+ self._linename.remove(name)
+
+ rows = len(data)
+ """
+ # print rows
+ # print data
+ xvalueSteps = data[0]
+ xvalueMin = data[0][0]
+ xvalueMax = data[0][0]
+ yvalueMin = data[1][0]
+ yvalueMax = data[1][0]
+ yvalueSteps = []
+ result = []
+ for j in range(columns):
+ if xvalueMin > data[0][j]:
+ xvalueMin = data[0][j]
+ if xvalueMax < data[0][j]:
+ xvalueMax = data[0][j]
+
+ for i in range(rows - 1):
+ lst = []
+ for j in range(columns):
+ lst.append((data[0][j], data[i + 1][j]))
+ if yvalueMin > data[i + 1][j]:
+ yvalueMin = data[i + 1][j]
+ if yvalueMax < data[i + 1][j]:
+ yvalueMax = data[i + 1][j]
+ yvalueSteps.append(int(data[i + 1][j] * 2.5) / 2.5)
+ result.append(tuple(lst))
+ xvalueMin = int(xvalueMin) / 100 * 100
+ xvalueMax = int(xvalueMax) / 100 * 100 + 200
+ yvalueMin = int(yvalueMin) * 1.0 - 1
+ if yvalueMin < 0:
+ yvalueMin = 0.0
+ yvalueMax = int(yvalueMax) + 2.0
+ yvalueSteps.append(yvalueMin)
+ yvalueSteps.append(yvalueMax)
+ yvalueSteps = {}.fromkeys(yvalueSteps).keys()
+
+ self._xvalue = (xvalueMin, xvalueMax, xvalueSteps)
+ self._yvalue = (yvalueMin, yvalueMax, yvalueSteps)
+ print result
+ return result
+
+ def create(self):
+ lpw = self._lpstyle.width
+ lph = self._lpstyle.height
+ draw = Drawing(lpw, lph)
+ line_cnts = len(self._linename)
+ # lp = noScaleLinePlot()
+ lp = LinePlot()
+ lg_line = (line_cnts + 3) / 4
+ lp.x = self._lpstyle.left
+ lp.y = self._lpstyle.bottom
+
+ lp.height = lph - self._lpstyle.bottom * (lg_line + 1.5)
+ lp.width = lpw - lp.x * 2
+ lp.data = self._data
+ lp.joinedLines = 1
+ lp.strokeWidth = self._lpstyle.strokeWidth
+ line_cnts = len(self._data)
+ sytle_cnts = len(self._lpstyle.linestyle)
+ color_paris = []
+ for i in range(line_cnts):
+ styleIndex = i % sytle_cnts
+ lp.lines[i].strokeColor = self._lpstyle.linestyle[styleIndex][0]
+ lp.lines[i].symbol = makeMarker(self._lpstyle.linestyle[styleIndex][1])
+ lp.lines[i].strokeWidth = self._lpstyle.linestyle[styleIndex][2]
+ color_paris.append((self._lpstyle.linestyle[styleIndex][0], self._linename[i]))
+ # lp.lineLabels[i].strokeColor = self._lpstyle.linestyle[styleIndex][0]
+
+ lp.lineLabelFormat = self._lpstyle.format[0]
+
+ lp.strokeColor = self._lpstyle.strokeColor
+
+ lp.xValueAxis.valueMin, lp.xValueAxis.valueMax, lp.xValueAxis.valueSteps = self._xvalue
+ # valueMin, valueMax, xvalueSteps = self._xvalue
+ # lp.xValueAxis.valueStep = (lp.xValueAxis.valueMax - lp.xValueAxis.valueMin)/len(xvalueSteps)
+ # lp.xValueAxis.valueSteps = map(lambda x: str(x), xvalueSteps)
+
+ lp.yValueAxis.valueMin, lp.yValueAxis.valueMax, lp.yValueAxis.valueSteps = self._yvalue
+
+
+
+ # lp.xValueAxis.forceZero = 0
+ # lp.xValueAxis.avoidBoundFrac = 1
+ # lp.xValueAxis.tickDown = 3
+ # lp.xValueAxis.visibleGrid = 1
+ # lp.xValueAxis.categoryNames = '64 256 512 1400 1500 4096'.split(' ')
+
+ lp.xValueAxis.labelTextFormat = self._lpstyle.format[1]
+ lp.yValueAxis.labelTextFormat = self._lpstyle.format[2]
+
+ delsize = int(lp.xValueAxis.valueMax / 2000)
+ lp.xValueAxis.labels.fontSize = self._lpstyle.labelsfont
+ lp.xValueAxis.labels.angle = 25
+
+ lp.yValueAxis.labels.fontSize = self._lpstyle.labelsfont
+ lp.lineLabels.fontSize = self._lpstyle.labelsfont - delsize
+ draw.add(lp)
+
+ lg = Legend()
+ lg.colorNamePairs = color_paris
+ lg.fontName = 'Helvetica'
+ lg.fontSize = 7
+
+ lg.x = self._lpstyle.left * 3
+ lg.y = self._lpstyle.bottom * (1 + lg_line) + lp.height
+
+ lg.dxTextSpace = 5
+ lg.dy = 5
+ lg.dx = 20
+ lg.deltax = 60
+ lg.deltay = 0
+ lg.columnMaximum = 1
+ lg.alignment = 'right'
+ draw.add(lg)
+ self._draw = draw
+
+
+class eHorizontalLineChart(object):
+ def __init__(self, data, style):
+ self._lcstyle = style
+ if len(data) < 1:
+ return
+ self._linename = data[0]
+ self._data = self.analysisData(data[1:])
+ if self._data:
+ self.create()
+
+ @property
+ def draw(self):
+ return self._draw
+
+ def analysisData(self, data):
+ columns = len(data)
+ data = map(list, zip(*data))
+ self._catNames = data[0]
+ self._linename = self._linename[1:]
+ data = data[1:]
+ rows = len(data)
+
+ yvalueMin = float(data[0][0])
+ yvalueMax = float(data[0][0])
+ yvalueSteps = []
+ result = []
+
+ for rowNo in range(rows):
+ for columnNo in range(columns):
+ data[rowNo][columnNo] = float(data[rowNo][columnNo])
+ if yvalueMin > data[rowNo][columnNo]:
+ yvalueMin = data[rowNo][columnNo]
+ if yvalueMax < data[rowNo][columnNo]:
+ yvalueMax = data[rowNo][columnNo]
+ yvalueSteps.append(int(data[rowNo][columnNo] * 1.0) / 1.0)
+ result.append(tuple(data[rowNo]))
+
+ yvalueMin = int(yvalueMin) * 1.0 - 1
+ if yvalueMin < 0:
+ yvalueMin = 0.0
+ yvalueMax = int(yvalueMax) + 2.0
+ yvalueSteps.append(yvalueMin)
+ yvalueSteps.append(yvalueMax)
+ yvalueSteps = {}.fromkeys(yvalueSteps).keys()
+
+ self._value = (yvalueMin, yvalueMax, yvalueSteps)
+ print result
+ return result
+
+ def create(self):
+ dw = self._lcstyle.width
+ dh = self._lcstyle.height
+ draw = Drawing(dw, dh)
+
+ lc = HorizontalLineChart()
+ line_cnts = len(self._linename)
+
+ lg_line = (line_cnts + 3) / 4
+ lc.height = dh - self._lcstyle.bottom * (lg_line + 1.5)
+ lc.width = dw - lc.x * 2
+ lc.x = self._lcstyle.left
+ lc.y = self._lcstyle.bottom
+
+ lc.data = self._data
+
+ lc.strokeColor = self._lcstyle.strokeColor
+ lc.strokeWidth = self._lcstyle.strokeWidth
+ lc.useAbsolute = 1
+ lc.groupSpacing = lc.width * 2.0 / len(self._catNames)
+ lc.joinedLines = 1
+ lc.lineLabelFormat = self._lcstyle.format[0]
+
+ lc.valueAxis.valueMin, lc.valueAxis.valueMax, lc.valueAxis.valueSteps = self._value
+ lc.valueAxis.labelTextFormat = self._lcstyle.format[1]
+ lc.valueAxis.labels.fontSize = self._lcstyle.labelsfont
+
+ lc.categoryAxis.categoryNames = self._catNames
+ lc.categoryAxis.labels.boxAnchor = 'ne'
+ lc.categoryAxis.labels.dx = lc.width / 2.0 / len(self._catNames)
+ lc.categoryAxis.labels.dy = -6
+ lc.categoryAxis.labels.angle = 10
+ lc.categoryAxis.labels.fontSize = self._lcstyle.labelsfont
+ # lc.categoryAxis.visibleGrid = 1
+ # lc.categoryAxis.tickUp = 100
+ # lc.categoryAxis.tickDown = 50
+ # lc.categoryAxis.gridEnd = dh
+ sytle_cnts = len(self._lcstyle.linestyle)
+ color_paris = []
+ for i in range(line_cnts):
+ styleIndex = i % sytle_cnts
+ lc.lines[i].strokeColor = self._lcstyle.linestyle[styleIndex][0]
+ lc.lines[i].symbol = makeMarker(self._lcstyle.linestyle[styleIndex][1])
+ lc.lines[i].strokeWidth = self._lcstyle.linestyle[styleIndex][2]
+ color_paris.append((self._lcstyle.linestyle[styleIndex][0], self._linename[i]))
+
+ lc.lineLabels.fontSize = self._lcstyle.labelsfont - 2
+
+ draw.add(lc)
+
+ lg = Legend()
+ lg.colorNamePairs = color_paris
+ lg.fontName = 'Helvetica'
+ lg.fontSize = 7
+ # lg.x = dw /2
+ # lg.y = self._lcstyle.bottom *(1.5 + lg_line)
+
+ lg.x = self._lcstyle.left * 3
+ lg.y = self._lcstyle.bottom * (1 + lg_line) + lc.height
+
+ lg.dxTextSpace = 5
+ lg.dy = 5
+ lg.dx = 20
+ lg.deltax = 60
+ lg.deltay = 0
+ lg.columnMaximum = 1
+ lg.alignment = 'right'
+ draw.add(lg)
+ self._draw = draw
+
+
+class eBarChartColumn(object):
+ def __init__(self, data, style):
+ self._bcstyle = style
+ if len(data) < 4:
+ return
+ self._data = self.analysisData(data)
+ if self._data:
+ self.create()
+
+ @property
+ def draw(self):
+ return self._draw
+
+ def analysisData(self, data):
+ self._ytitle = data[0]
+ self._name = data[1]
+ self._bar = data[2]
+ bar_data = data[3]
+ result = []
+ for bar in bar_data:
+ bar = map(lambda x: float(x), bar)
+ result.append(tuple(bar))
+ return result
+
+ def create(self):
+ dw = self._bcstyle.width
+ dh = self._bcstyle.height
+ draw = Drawing(dw, dh)
+
+ bc = VerticalBarChart()
+ bar_cnt = len(self._bar)
+ lg_line = (bar_cnt + 3) / 4
+
+ bc.width = dw - self._bcstyle.left - self._bcstyle.right
+ bc.height = dh - self._bcstyle.top - self._bcstyle.bottom
+ if bar_cnt > 1:
+ bc.height -= lg_line * 15
+
+ bc.x = self._bcstyle.left
+ bc.y = self._bcstyle.bottom
+ color_paris = []
+ for i in range(bar_cnt):
+ bc.bars[i].fillColor = self._bcstyle.pillarstyle[self._bar[i]][0]
+ color_paris.append((self._bcstyle.pillarstyle[self._bar[i]][0], self._bar[i]))
+
+ bc.fillColor = self._bcstyle.background
+ bc.barLabels.fontName = 'Helvetica'
+ bc.barLabelFormat = self._bcstyle.pillarstyle[self._bar[0]][1]
+ bc.barLabels.fontSize = self._bcstyle.labelsfont
+ bc.barLabels.dy = self._bcstyle.labelsfont
+ bc.valueAxis.labels.fontName = 'Helvetica'
+ bc.valueAxis.labels.fontSize = self._bcstyle.labelsfont
+ bc.valueAxis.forceZero = 1
+ bc.valueAxis.valueMin = 0
+
+ bc.data = self._data
+ bc.barSpacing = self._bcstyle.barSpacing
+ bc.groupSpacing = self._bcstyle.groupSpacing / bar_cnt
+ bc.valueAxis.avoidBoundFrac = 1
+ bc.valueAxis.gridEnd = dw - self._bcstyle.right
+ bc.valueAxis.tickLeft = self._bcstyle.tick
+ bc.valueAxis.visibleGrid = 1
+ bc.categoryAxis.categoryNames = self._name
+ bc.categoryAxis.tickDown = self._bcstyle.tick
+ bc.categoryAxis.labels.fontName = 'Helvetica'
+ bc.categoryAxis.labels.fontSize = self._bcstyle.labelsfont
+ bc.categoryAxis.labels.dy = -27
+ bc.categoryAxis.labels.angle = -90
+ draw.add(bc)
+ lb = Label()
+ lb.fontName = 'Helvetica'
+ lb.fontSize = 7
+ lb.x = 12
+ lb.y = 80
+ lb.angle = 90
+ lb.textAnchor = 'middle'
+ lb.maxWidth = 100
+ lb.height = 20
+ lb._text = self._ytitle
+ draw.add(lb)
+ if bar_cnt > 1:
+ lg = Legend()
+ lg.colorNamePairs = color_paris
+ lg.fontName = 'Helvetica'
+ lg.fontSize = 7
+
+ lg.x = self._bcstyle.left + bc.width / (bar_cnt + 1)
+ lg.y = dh - self._bcstyle.top - lg_line * 5
+
+ lg.dxTextSpace = 5
+ lg.dy = 5
+ lg.dx = 25
+ lg.deltax = 80
+ lg.deltay = 0
+ lg.columnMaximum = 1
+ lg.alignment = 'right'
+ draw.add(lg)
+
+ self._draw = draw
+
+
+class eParagraph(object):
+ def __init__(self, data, style):
+ self._pstyle = style
+ self._data = self.analysisData(data)
+ self.create()
+
+ def analysisData(self, data):
+ result = ""
+ for dstr in data:
+ if self._pstyle.name == 'ps_body':
+ # dstr = "<i>" + dstr + "</i><br/>"
+ dstr = dstr + "<br/>"
+ else:
+ dstr = dstr + "<br/>"
+ result += dstr
+ return result
+
+ def create(self):
+ self._para = Paragraph(self._data, self._pstyle)
+
+ @property
+ def para(self):
+ return self._para