def getCaptcha(n=5,fontName='Courier',fontSize=14,text=None,fillColor=None): '''return n random chars in a string and in a byte string structured as a GIF image''' from reportlab.graphics.shapes import Drawing, Group, String, \ rotate, skewX, skewY, mmult, translate, Rect if not text: from random import randint, uniform text=''.join([_allowed[randint(0,_mx)] for i in range(n)]) else: uniform = lambda l,h: 0.5*(l+h) n = len(text) baseline = 0 x = 0 G0 = Group() for c in text: x += 1 A = translate(x,uniform(baseline-5,baseline+5)) A = mmult(A,rotate(uniform(-15,15))) A = mmult(A,skewX(uniform(-8,8))) A = mmult(A,skewY(uniform(-8,8))) G = Group(transform=A) G.add(String(0,0,c,fontname=fontName,fontSize=fontSize)) G0.add(G) x0,y0,x1,y1 = G0.getBounds() x = 1+x1 G0.transform=translate(2-x0,2-y0) W = 4+x1-x0 H = 4+y1-y0 D = Drawing(W,H) if fillColor: from reportlab.lib.colors import toColor D.add(Rect(0,0,W,H, fillColor = toColor(fillColor),strokeColor=None)) D.add(G0) return text, D.asString('gif')
def get_actual_status_img(request, output_format='png', width=600, height=600): if reportlab is None: messages.error(request, _("Module") + " reportlab " + _("is not available")) try: redirect_to = request.META['HTTP_REFERER'] except KeyError: redirect_to = '/' return HttpResponseRedirect(redirect_to) status_list = Status.objects.all() drawing = Drawing(width, height) pie = Pie3d() pie.x = 100 pie.y = 100 pie.width = width / 2 pie.height = height / 2 pie.labels = [ s.name for s in status_list ] pie.data = [ s.task_set.count() for s in status_list ] pie.slices[3].fontColor = colors.red pie.slices[0].fillColor = colors.darkcyan pie.slices[1].fillColor = colors.blueviolet pie.slices[2].fillColor = colors.blue pie.slices[3].fillColor = colors.cyan pie.slices[4].fillColor = colors.aquamarine pie.slices[5].fillColor = colors.cadetblue pie.slices[6].fillColor = colors.lightcoral drawing.add(pie) image = drawing.asString(output_format) response = HttpResponse(image, mimetype='image/%s' % output_format.lower()) return response
def createBarcodeImageInMemory(code_name, value, width=None, height=None, human_readable=False, lines=LINES_MIN): if len(value) != VALUE_LEN: raise ValueError('Illegal value for value') if lines < LINES_MIN or lines > LINES_MAX: raise ValueError('Illegal number of lines') bc_col = [] if lines > LINES_MIN: i = 1 lin = lines == int(LINES_FOUR) and LINES_FOUR or '' size = VALUE_LEN / lines while i < lines: x = LINES_FOUR + lin + str(i) + value[:size] value = value[size:] bc_col.append(CODES[code_name](value=x, human_readable=human_readable)) i += 1 value = LINES_FOUR + lin + str(i) + value bc = CODES[code_name](value=value, human_readable=human_readable) bc_col.append(bc) x1, y1, x2, y2 = bc.getBounds() w = float(x2 - x1) h = float(y2 - y1) orig_h = h sx = width not in ('auto', None) sy = height not in ('auto', None) if sx or sy: sx = sx and width / w or 1.0 sy = sy and height / h or 1.0 w *= sx h *= sy else: sx = sy = 1 d = Drawing(width=w, height=lines * h, transform=[sx, 0, 0, sy, -sx * x1, -sy * y1]) bc_col.reverse() for i, b in enumerate(bc_col): # XXX: Not sure if this is the right way to set the position. It also # doesn't work for QR or any future supported codes for that matter. b.y = ((i + 1) * orig_h) - orig_h d.add(b, '_bc' + str(i)) return d.asString('png')
def img(code, value, scale): try: dr = createBarcodeDrawing(code, value=str(value), humanReadable=True) dr.renderScale = scale d = Drawing(dr.width*scale, dr.height*scale) d.add(dr) d.renderScale = scale response = make_response(d.asString('png')) response.mimetype = 'image/png' return response except: return send_from_directory(os.path.join(app.root_path, 'static'), 'error.png', mimetype='image/png')
def img(code, value, scale): try: dr = createBarcodeDrawing(code, value=str(value), humanReadable=True) dr.renderScale = scale d = Drawing(dr.width * scale, dr.height * scale) d.add(dr) d.renderScale = scale response = make_response(d.asString('png')) response.mimetype = 'image/png' return response except: return send_from_directory(os.path.join(app.root_path, 'static'), 'error.png', mimetype='image/png')
def run(self, include_sub_survey=False, dimensions=[]): # Build data set averages = [] category_names = [] for dimension in self.getDimensions(): averages.append(self.get_average_score_for_dimension( include_sub_survey=include_sub_survey, dimension=dimension)) category_names.append(dimension) drawing = Drawing(600, 300) bc = VerticalBarChart() bc.x = 20 bc.y = 20 bc.height = 260 bc.width = 580 bc.data = [averages] bc.categoryAxis.categoryNames = category_names bc.categoryAxis.labels.fontName = 'Helvetica' bc.categoryAxis.labels.fontSize = 10 bc.categoryAxis.labels.textAnchor = 'middle' bc.categoryAxis.visibleTicks = 0 bc.valueAxis.valueMax = 100.0 bc.valueAxis.valueMin = min(averages, 0) bc.valueAxis.labels.fontName = 'Helvetica' bc.valueAxis.labels.fontSize = 10 bc.valueAxis.labels.textAnchor = 'middle' bc.barLabelFormat = '%.0f' bc.barLabels.dy = 8 bc.barLabels.fontName = 'Helvetica' bc.barLabels.fontSize = 10 bc.barWidth = len(averages) bc.fillColor = None drawing.add(bc) # Write out data = drawing.asString('png') request = self.REQUEST response = request.RESPONSE response.setHeader('Content-Type', 'image/png') response.setHeader('Content-Disposition','inline; filename=%s.png' % self.getId()) response.setHeader('Content-Length', len(data)) response.setHeader('Cache-Control', 's-maxage=0') return data
def render_graph(self, request_opts, graph_opts): def label_fmt(x): print "@@@", x return str(x) ld = len(graph_opts["data"]) palette = [Color(*x) for x in get_float_pallete(ld)] w = graph_opts["width"] h = graph_opts["height"] drawing = Drawing(w, h) # Legend legend = LineLegend() legend.colorNamePairs = [ (palette[i], graph_opts["data"][i].name) for i in range(ld) ] legend.boxAnchor = "sw" legend.columnMaximum = 2 legend.alignment = "right" drawing.add(legend) lh = legend._calcHeight() + self.X_PADDING / 2 # Plot lp = LinePlot() lfs = lp.xValueAxis.labels.fontSize lp.x = self.X_PADDING lp.y = self.Y_PADDING + lh + lfs lp.width = w - 2 * self.X_PADDING lp.height = h - self.Y_PADDING - lp.y lp.data = [ [(t, v) for v, t in ts] for ts in graph_opts["data"] ] for i in range(ld): lp.lines[i].strokeColor = palette[i] drawing.add(lp) # Render cdata = drawing.asString(format="png") response = self.render_plain_text( cdata, mimetype="image/png" ) if not request_opts["noCache"]: cache.set(request_opts["requestKey"], response, request_opts["cacheTimeout"]) return response
def test(): "Make a conference event for day 1 of UP Python 2003" d = Drawing(400,200) cal = EventCalendar() cal.x = 50 cal.y = 25 cal.data = [ # these might be better as objects instead of tuples, since I # predict a large number of "optionsl" variables to affect # formatting in future. #title, speaker, track id, day, start time (hrs), duration (hrs) # track ID is 1-based not zero-based! ('Keynote: Why design another programming language?', 'Guido van Rossum', None, 1, 9.0, 1.0), ('Siena Web Service Architecture', 'Marc-Andre Lemburg', 1, 1, 10.5, 1.5), ('Extreme Programming in Python', 'Chris Withers', 2, 1, 10.5, 1.5), ('Pattern Experiences in C++', 'Mark Radford', 3, 1, 10.5, 1.5), ('What is the Type of std::toupper()', 'Gabriel Dos Reis', 4, 1, 10.5, 1.5), ('Linguistic Variables: Clear Thinking with Fuzzy Logic ', 'Walter Banks', 5, 1, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 1, 12.0, 2.0), ("CORBA? Isn't that obsolete", 'Duncan Grisby', 1, 1, 14.0, 1.5), ("Python Design Patterns", 'Duncan Booth', 2, 1, 14.0, 1.5), ("Inside Security Checks and Safe Exceptions", 'Brandon Bray', 3, 1, 14.0, 1.5), ("Studying at a Distance", 'Panel Discussion, Panel to include Alan Lenton & Francis Glassborow', 4, 1, 14.0, 1.5), ("Coding Standards - Given the ANSI C Standard why do I still need a coding Standard", 'Randy Marques', 5, 1, 14.0, 1.5), ("RESTful Python", 'Hamish Lawson', 1, 1, 16.0, 1.5), ("Parsing made easier - a radical old idea", 'Andrew Koenig', 2, 1, 16.0, 1.5), ("C++ & Multimethods", 'Julian Smith', 3, 1, 16.0, 1.5), ("C++ Threading", 'Kevlin Henney', 4, 1, 16.0, 1.5), ("The Organisation Strikes Back", 'Alan Griffiths & Sarah Lees', 5, 1, 16.0, 1.5), ('Birds of a Feather meeting', '', None, 1, 17.5, 2.0), ('Keynote: In the Spirit of C', 'Greg Colvin', None, 2, 9.0, 1.0), ('The Infinite Filing Cabinet - object storage in Python', 'Jacob Hallen', 1, 2, 10.5, 1.5), ('Introduction to Python and Jython for C++ and Java Programmers', 'Alex Martelli', 2, 2, 10.5, 1.5), ('Template metaprogramming in Haskell', 'Simon Peyton Jones', 3, 2, 10.5, 1.5), ('Plenty People Programming: C++ Programming in a Group, Workshop with a difference', 'Nico Josuttis', 4, 2, 10.5, 1.5), ('Design and Implementation of the Boost Graph Library', 'Jeremy Siek', 5, 2, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 2, 12.0, 2.0), ("Building GUI Applications with PythonCard and PyCrust", 'Andy Todd', 1, 2, 14.0, 1.5), ("Integrating Python, C and C++", 'Duncan Booth', 2, 2, 14.0, 1.5), ("Secrets and Pitfalls of Templates", 'Nicolai Josuttis & David Vandevoorde', 3, 2, 14.0, 1.5), ("Being a Mentor", 'Panel Discussion, Panel to include Alan Lenton & Francis Glassborow', 4, 2, 14.0, 1.5), ("The Embedded C Extensions to C", 'Willem Wakker', 5, 2, 14.0, 1.5), ("Lightning Talks", 'Paul Brian', 1, 2, 16.0, 1.5), ("Scripting Java Applications with Jython", 'Anthony Eden', 2, 2, 16.0, 1.5), ("Metaprogramming and the Boost Metaprogramming Library", 'David Abrahams', 3, 2, 16.0, 1.5), ("A Common Vendor ABI for C++ -- GCC's why, what and not", 'Nathan Sidwell & Gabriel Dos Reis', 4, 2, 16.0, 1.5), ("The Timing and Cost of Choices", 'Hubert Matthews', 5, 2, 16.0, 1.5), ('Birds of a Feather meeting', '', None, 2, 17.5, 2.0), ('Keynote: The Cost of C & C++ Compatibility', 'Andy Koenig', None, 3, 9.0, 1.0), ('Prying Eyes: Generic Observer Implementations in C++', 'Andrei Alexandrescu', 1, 2, 10.5, 1.5), ('The Roadmap to Generative Programming With C++', 'Ulrich Eisenecker', 2, 2, 10.5, 1.5), ('Design Patterns in C++ and C# for the Common Language Runtime', 'Brandon Bray', 3, 2, 10.5, 1.5), ('Extreme Hour (XH): (workshop) - Jutta Eckstein and Nico Josuttis', 'Jutta Ecstein', 4, 2, 10.5, 1.5), ('The Lambda Library : Unnamed Functions for C++', 'Jaako Jarvi', 5, 2, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 3, 12.0, 2.0), ('Reflective Metaprogramming', 'Daveed Vandevoorde', 1, 3, 14.0, 1.5), ('Advanced Template Issues and Solutions (double session)', 'Herb Sutter',2, 3, 14.0, 3), ('Concurrent Programming in Java (double session)', 'Angelika Langer', 3, 3, 14.0, 3), ('What can MISRA-C (2nd Edition) do for us?', 'Chris Hills', 4, 3, 14.0, 1.5), ('C++ Metaprogramming Concepts and Results', 'Walter E Brown', 5, 3, 14.0, 1.5), ('Binding C++ to Python with the Boost Python Library', 'David Abrahams', 1, 3, 16.0, 1.5), ('Using Aspect Oriented Programming for Enterprise Application Integration', 'Arno Schmidmeier', 4, 3, 16.0, 1.5), ('Defective C++', 'Marc Paterno', 5, 3, 16.0, 1.5), ("Speakers' Banquet & Birds of a Feather meeting", '', None, 3, 17.5, 2.0), ('Keynote: The Internet, Software and Computers - A Report Card', 'Alan Lenton', None, 4, 9.0, 1.0), ('Multi-Platform Software Development; Lessons from the Boost libraries', 'Beman Dawes', 1, 5, 10.5, 1.5), ('The Stability of the C++ ABI', 'Steve Clamage', 2, 5, 10.5, 1.5), ('Generic Build Support - A Pragmatic Approach to the Software Build Process', 'Randy Marques', 3, 5, 10.5, 1.5), ('How to Handle Project Managers: a survival guide', 'Barb Byro', 4, 5, 10.5, 1.5), ('lunch, ACCU AGM', '', None, 5, 12.0, 2.0), ('Sauce: An OO recursive descent parser; its design and implementation.', 'Jon Jagger', 1, 5, 14.0, 1.5), ('GNIRTS ESAC REWOL - Bringing the UNIX filters to the C++ iostream library.', 'JC van Winkel', 2, 5, 14.0, 1.5), ('Pattern Writing: Live and Direct', 'Frank Buschmann & Kevlin Henney', 3, 5, 14.0, 3.0), ('The Future of Programming Languages - A Goldfish Bowl', 'Francis Glassborow and friends', 3, 5, 14.0, 1.5), ('Honey, I Shrunk the Threads: Compile-time checked multithreaded transactions in C++', 'Andrei Alexandrescu', 1, 5, 16.0, 1.5), ('Fun and Functionality with Functors', 'Lois Goldthwaite', 2, 5, 16.0, 1.5), ('Agile Enough?', 'Alan Griffiths', 4, 5, 16.0, 1.5), ("Conference Closure: A brief plenary session", '', None, 5, 17.5, 0.5), ] #return cal cal.day = 1 d.add(cal) for format in ['pdf']:#,'gif','png']: out = d.asString(format) open('eventcal.%s' % format, 'wb').write(out) print 'saved eventcal.%s' % format
def test(): "Make a conference event for day 1 of UP Python 2003" d = Drawing(400, 200) cal = EventCalendar() cal.x = 50 cal.y = 25 cal.data = [ # these might be better as objects instead of tuples, since I # predict a large number of "optionsl" variables to affect # formatting in future. #title, speaker, track id, day, start time (hrs), duration (hrs) # track ID is 1-based not zero-based! ('Keynote: Why design another programming language?', 'Guido van Rossum', None, 1, 9.0, 1.0), ('Siena Web Service Architecture', 'Marc-Andre Lemburg', 1, 1, 10.5, 1.5), ('Extreme Programming in Python', 'Chris Withers', 2, 1, 10.5, 1.5), ('Pattern Experiences in C++', 'Mark Radford', 3, 1, 10.5, 1.5), ('What is the Type of std::toupper()', 'Gabriel Dos Reis', 4, 1, 10.5, 1.5), ('Linguistic Variables: Clear Thinking with Fuzzy Logic ', 'Walter Banks', 5, 1, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 1, 12.0, 2.0), ("CORBA? Isn't that obsolete", 'Duncan Grisby', 1, 1, 14.0, 1.5), ("Python Design Patterns", 'Duncan Booth', 2, 1, 14.0, 1.5), ("Inside Security Checks and Safe Exceptions", 'Brandon Bray', 3, 1, 14.0, 1.5), ("Studying at a Distance", 'Panel Discussion, Panel to include Alan Lenton & Francis Glassborow', 4, 1, 14.0, 1.5), ("Coding Standards - Given the ANSI C Standard why do I still need a coding Standard", 'Randy Marques', 5, 1, 14.0, 1.5), ("RESTful Python", 'Hamish Lawson', 1, 1, 16.0, 1.5), ("Parsing made easier - a radical old idea", 'Andrew Koenig', 2, 1, 16.0, 1.5), ("C++ & Multimethods", 'Julian Smith', 3, 1, 16.0, 1.5), ("C++ Threading", 'Kevlin Henney', 4, 1, 16.0, 1.5), ("The Organisation Strikes Back", 'Alan Griffiths & Sarah Lees', 5, 1, 16.0, 1.5), ('Birds of a Feather meeting', '', None, 1, 17.5, 2.0), ('Keynote: In the Spirit of C', 'Greg Colvin', None, 2, 9.0, 1.0), ('The Infinite Filing Cabinet - object storage in Python', 'Jacob Hallen', 1, 2, 10.5, 1.5), ('Introduction to Python and Jython for C++ and Java Programmers', 'Alex Martelli', 2, 2, 10.5, 1.5), ('Template metaprogramming in Haskell', 'Simon Peyton Jones', 3, 2, 10.5, 1.5), ('Plenty People Programming: C++ Programming in a Group, Workshop with a difference', 'Nico Josuttis', 4, 2, 10.5, 1.5), ('Design and Implementation of the Boost Graph Library', 'Jeremy Siek', 5, 2, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 2, 12.0, 2.0), ("Building GUI Applications with PythonCard and PyCrust", 'Andy Todd', 1, 2, 14.0, 1.5), ("Integrating Python, C and C++", 'Duncan Booth', 2, 2, 14.0, 1.5), ("Secrets and Pitfalls of Templates", 'Nicolai Josuttis & David Vandevoorde', 3, 2, 14.0, 1.5), ("Being a Mentor", 'Panel Discussion, Panel to include Alan Lenton & Francis Glassborow', 4, 2, 14.0, 1.5), ("The Embedded C Extensions to C", 'Willem Wakker', 5, 2, 14.0, 1.5), ("Lightning Talks", 'Paul Brian', 1, 2, 16.0, 1.5), ("Scripting Java Applications with Jython", 'Anthony Eden', 2, 2, 16.0, 1.5), ("Metaprogramming and the Boost Metaprogramming Library", 'David Abrahams', 3, 2, 16.0, 1.5), ("A Common Vendor ABI for C++ -- GCC's why, what and not", 'Nathan Sidwell & Gabriel Dos Reis', 4, 2, 16.0, 1.5), ("The Timing and Cost of Choices", 'Hubert Matthews', 5, 2, 16.0, 1.5), ('Birds of a Feather meeting', '', None, 2, 17.5, 2.0), ('Keynote: The Cost of C & C++ Compatibility', 'Andy Koenig', None, 3, 9.0, 1.0), ('Prying Eyes: Generic Observer Implementations in C++', 'Andrei Alexandrescu', 1, 2, 10.5, 1.5), ('The Roadmap to Generative Programming With C++', 'Ulrich Eisenecker', 2, 2, 10.5, 1.5), ('Design Patterns in C++ and C# for the Common Language Runtime', 'Brandon Bray', 3, 2, 10.5, 1.5), ('Extreme Hour (XH): (workshop) - Jutta Eckstein and Nico Josuttis', 'Jutta Ecstein', 4, 2, 10.5, 1.5), ('The Lambda Library : Unnamed Functions for C++', 'Jaako Jarvi', 5, 2, 10.5, 1.5), ('lunch, short presentations, vendor presentations', '', None, 3, 12.0, 2.0), ('Reflective Metaprogramming', 'Daveed Vandevoorde', 1, 3, 14.0, 1.5), ('Advanced Template Issues and Solutions (double session)', 'Herb Sutter', 2, 3, 14.0, 3), ('Concurrent Programming in Java (double session)', 'Angelika Langer', 3, 3, 14.0, 3), ('What can MISRA-C (2nd Edition) do for us?', 'Chris Hills', 4, 3, 14.0, 1.5), ('C++ Metaprogramming Concepts and Results', 'Walter E Brown', 5, 3, 14.0, 1.5), ('Binding C++ to Python with the Boost Python Library', 'David Abrahams', 1, 3, 16.0, 1.5), ('Using Aspect Oriented Programming for Enterprise Application Integration', 'Arno Schmidmeier', 4, 3, 16.0, 1.5), ('Defective C++', 'Marc Paterno', 5, 3, 16.0, 1.5), ("Speakers' Banquet & Birds of a Feather meeting", '', None, 3, 17.5, 2.0), ('Keynote: The Internet, Software and Computers - A Report Card', 'Alan Lenton', None, 4, 9.0, 1.0), ('Multi-Platform Software Development; Lessons from the Boost libraries', 'Beman Dawes', 1, 5, 10.5, 1.5), ('The Stability of the C++ ABI', 'Steve Clamage', 2, 5, 10.5, 1.5), ('Generic Build Support - A Pragmatic Approach to the Software Build Process', 'Randy Marques', 3, 5, 10.5, 1.5), ('How to Handle Project Managers: a survival guide', 'Barb Byro', 4, 5, 10.5, 1.5), ('lunch, ACCU AGM', '', None, 5, 12.0, 2.0), ('Sauce: An OO recursive descent parser; its design and implementation.', 'Jon Jagger', 1, 5, 14.0, 1.5), ('GNIRTS ESAC REWOL - Bringing the UNIX filters to the C++ iostream library.', 'JC van Winkel', 2, 5, 14.0, 1.5), ('Pattern Writing: Live and Direct', 'Frank Buschmann & Kevlin Henney', 3, 5, 14.0, 3.0), ('The Future of Programming Languages - A Goldfish Bowl', 'Francis Glassborow and friends', 3, 5, 14.0, 1.5), ('Honey, I Shrunk the Threads: Compile-time checked multithreaded transactions in C++', 'Andrei Alexandrescu', 1, 5, 16.0, 1.5), ('Fun and Functionality with Functors', 'Lois Goldthwaite', 2, 5, 16.0, 1.5), ('Agile Enough?', 'Alan Griffiths', 4, 5, 16.0, 1.5), ("Conference Closure: A brief plenary session", '', None, 5, 17.5, 0.5), ] #return cal cal.day = 1 d.add(cal) for format in ['pdf']: #,'gif','png']: out = d.asString(format) open('eventcal.%s' % format, 'wb').write(out) print 'saved eventcal.%s' % format
def run(self): def weight_sort(a, b): return cmp(a.getWeight(), b.getWeight()) drawing = Drawing(600, 300) lc = LinePlot() # Determine axis dimensions and create data set maxval = 0 minval = 0 dimension_one_values = [] dimension_two_values = [] dimension_one_answeroptions_as_objects = [] dimension_two_answeroptions_as_objects = [] counter = 0 for question in self.getQuestions(): weights = [int(weight) for weight in question.getAnswerOptionsWeights()] answeroptions = list(question.getAnswerOptions()) # This is used by the legend. Sort on weight. if counter == 0: dimension_one_answeroptions_as_objects = question.getAnswerOptionsAsObjects() dimension_one_answeroptions_as_objects.sort(weight_sort) else: dimension_two_answeroptions_as_objects = question.getAnswerOptionsAsObjects() dimension_two_answeroptions_as_objects.sort(weight_sort) # Minmax lmin = min(weights) lmax = max(weights) if lmin < minval: minval = lmin if lmax > maxval: maxval = lmax # Data for user, answer in question.answers.items(): value = answer.get('value', None) weight = None if value is not None: # Lookup the integer weight of this answer if value in answeroptions: index = answeroptions.index(value) weight = weights[index] # Always add to the list. ReportLab deals with None. if counter == 0: dimension_one_values.append(weight) else: dimension_two_values.append(weight) counter += 1 # Set minmax absmax = max(abs(minval), abs(maxval)) * 1.1 lc.xValueAxis.valueMin = -absmax lc.xValueAxis.valueMax = absmax lc.yValueAxis.valueMin = -absmax lc.yValueAxis.valueMax = absmax # Zip to create data data = [zip(dimension_one_values, dimension_two_values)] if not len(data[0]): return lc.x = 0 lc.y = 0 # Misc setup lc.height = 300 lc.width = 300 lc.data = data lc.joinedLines = 0 lc.fillColor = None lc.lines[0].strokeColor = colors.red lc.lines[0].symbol = makeMarker('FilledCircle') # Add a grid grid = DoubleGrid() lc.background = grid setupGrid(lc) lc.background = None # Finetune the grid grid.grid0.strokeWidth = 0.2 grid.grid1.strokeWidth = 0.2 # Add to drawing else it overwrites the center Y axis drawing.add(grid) # Add a Y axis to pass through the origin yaxis = YValueAxis() yaxis.setPosition(lc.width/2, 0, lc.height) yaxis.configure([(0,-absmax),(0,absmax)]) yaxis.strokeColor = colors.blue drawing.add(yaxis) # Color X-Axis lc.xValueAxis.strokeColor = colors.green drawing.add(lc) # Legend for Dimension One drawing.add(String(lc.width+20, lc.height-12, 'Dimension One (X-Axis):', fontName='Helvetica', fontSize=12, fillColor=colors.green)) legend = Legend() legend.alignment = 'right' legend.x = lc.width + 20 legend.y = lc.height - 20 legend.fontName = 'Helvetica' legend.fontSize = 12 legend.columnMaximum = 7 items = [] for ob in dimension_one_answeroptions_as_objects: items.append( ( StringWidget(ob.getWeight()), ob() ) ) legend.colorNamePairs = items drawing.add(legend, 'legend1') # Legend for Dimension Two drawing.add(String(lc.width+20, lc.height/2-12, 'Dimension Two (Y-Axis):', fontName='Helvetica', fontSize=12, fillColor=colors.blue)) legend = Legend() legend.alignment = 'right' legend.x = lc.width + 20 legend.y = lc.height/2 - 20 legend.fontName = 'Helvetica' legend.fontSize = 12 legend.columnMaximum = 7 items = [] for ob in dimension_two_answeroptions_as_objects: items.append( ( StringWidget(ob.getWeight()), ob() ) ) legend.colorNamePairs = items drawing.add(legend, 'legend2') # Write out data = drawing.asString('png') request = self.REQUEST response = request.RESPONSE response.setHeader('Content-Type', 'image/png') response.setHeader('Content-Disposition','inline; filename=%s.png' % self.getId()) response.setHeader('Content-Length', len(data)) response.setHeader('Cache-Control', 's-maxage=0') return data
class Barcode: """Model of a barcode object. This class handles the generation and parsing of barcodes to image strings.""" unit_mapping = {'inch': units.inch, 'mm': units.mm} DEFAULT_WIDTH_CODE128 = 200 DEFAULT_WIDTH_QR = 100 def __init__(self, type, text_value, width=None, height=None, unit=None): """ Initialize the barcode. This creates the actual barcode and sets it up for further action. """ # Set class variables self.type = type self.text_value = text_value # Create the barcode barcode = createBarcodeDrawing(type, value=text_value, humanReadable=True) width, height, scale = self._determine_dimensions( barcode, width, height, unit) # Create the drawing self.drawing = Drawing(width, height) self.drawing.scale(scale, scale) self.drawing.add(barcode, name='barcode') def _determine_dimensions(self, barcode, width, height, unit): """Determine the dimensions and scale of the barcode.""" # Determine the width if width: width = float(width) * self.unit_mapping.get(unit, units.mm) else: width = self.DEFAULT_WIDTH_CODE128 if self.type == 'Code128' \ else self.DEFAULT_WIDTH_QR width *= self.unit_mapping.get(unit, units.mm) # Determine the scale scale = width / barcode.width # Determine the height if height: height = float(height) * self.unit_mapping.get(unit, units.mm) else: # Determine the barcode height automatically. # Based on code found here: # http://stackoverflow.com/a/13350788 height = barcode.height * scale return (width, height, scale) def save(self, location, filename, formats): """ Save the barcode """ self.drawing.save(formats, location, fnRoot=filename) def as_string(self, format): """Return the barcode as a string in the specified format.""" return self.drawing.asString(format) def as_image(self, format): """Return the barcode as an image in the specified format.""" image_string = self.drawing.asString(format) return base64.b64encode(image_string).decode('ascii') @property def width(self): """Get the width of the barcode drawing.""" return self.drawing.width @property def height(self): """Get the height of the barcode drawing.""" return self.drawing.height