1 # -*- coding: iso-8859-1 -*-
   2 """
   3     MoinMoin - SvgPlot Macro
   4 
   5     This macro is a mockup for svg graphics by svgfig, http://code.google.com/p/svgfig/
   6 
   7     @copyright: 2008 MoinMoin:ReimarBauer
   8     @license: GNU GPL, see COPYING for details.
   9 """
  10 import re, svgfig, time
  11 from MoinMoin import wikiutil
  12 from MoinMoin.Page import Page
  13 from MoinMoin.action import cache
  14 from MoinMoin.macro import EmbedObject
  15 
  16 svgfig._canvas_defaults["width"] = '400px'
  17 svgfig._canvas_defaults["height"] = '400px'
  18 
  19 
  20 class DictBase(dict):
  21     """ Base class for wiki dicts
  22 
  23     To use this class, subclass it and override regex and initFromText.
  24     """
  25     def __init__(self, request=None, pagename=None, rev=0):
  26         dict.__init__(self)
  27         self.name = None
  28         if request is not None and pagename is not None:
  29             self.loadFromPage(request, pagename, rev=rev)
  30 
  31     # Regular expression used to parse text - subclass must override this
  32     regex = None  # re.compile(u'...', re.MULTILINE | re.UNICODE)
  33 
  34     def loadFromPage(self, request, name, rev=0):
  35         """ load the dict from wiki page <name>'s content """
  36         self.name = name
  37         text = Page(request, name, rev=rev).get_raw_body()
  38         self.initFromText(text)
  39 
  40     def initFromText(self, text):
  41         """ parse the wiki page text and init the dict from it """
  42         raise NotImplementedError('subclasses should override this')
  43 
  44 
  45 class Dict(DictBase):
  46     """ Mapping of keys to values in a wiki page.
  47 
  48        How a Dict definition page should look like:
  49 
  50        any text ignored
  51         key1:: value1
  52         * ignored, too
  53         key2:: value2 containing spaces
  54         ...
  55         keyn:: ....
  56        any text ignored
  57     """
  58     # Key:: Value - ignore all but key:: value pairs, strip whitespace, exactly one space after the :: is required
  59     regex = re.compile(ur'^ (?P<key>.+?):: (?P<val>.*?) *$', re.MULTILINE | re.UNICODE)
  60 
  61     def initFromText(self, text):
  62         for match in self.regex.finditer(text):
  63             key, val = match.groups()
  64             self[key] = val
  65 
  66     def __repr__(self):
  67         return "<Dict name=%r items=%r>" % (self.name, self.items())
  68 
  69 def macro_SvgPlot(macro,
  70                   width=u'400px',
  71                   height=u'400px',
  72                   parameter=u'cpu MHz'
  73                   ):
  74 
  75     
  76     request = macro.request
  77     pagename = request.page.page_name
  78     cache_arena = 'sendcache'
  79     cache_scope = 'wiki'
  80     content_type = 'image/svg+xml'
  81     do_locking = False
  82     current_rev = Page(request, pagename).current_rev()
  83 
  84     # example data
  85     y = []
  86     for rev in range(current_rev):
  87         try:
  88             page_dict = Dict(request, pagename, rev=rev)
  89             y.append(float(page_dict[parameter].split()[0]))
  90         except:
  91             y.append(0)
  92 
  93     x = range(current_rev) 
  94     if current_rev < 10:
  95         xrange = (0, 10)
  96     else:
  97         xrange = (0, max(x))
  98     
  99     points1 = svgfig.Dots(zip(x, y), svgfig.make_symbol("data1", stroke="black", fill="red", stroke_width="0.25pt"))
 100     #points2 = svgfig.Dots(zip(x, y2), svgfig.make_symbol("data2", stroke="black", fill="blue", stroke_width="0.25pt"))
 101     # define scientific plot 
 102     svgfig.Frame.text_ytitle_offset = 16
 103     myFrame = svgfig.Frame(xrange[0], xrange[1], 0, max(y) + 0.05 * max(y), points1, xtitle='~days (%s)' % (pagename.split('/')[1]), ytitle=parameter).SVG()
 104     # create complete svg xml 
 105     data = myFrame.standalone_xml()
 106     # create key
 107     key = cache.key(request, itemname=pagename, content=data)
 108     size_str = "%s_%s" % (svgfig._canvas_defaults["width"].replace('px', ''), svgfig._canvas_defaults["height"].replace('px', ''))
 109     key = '%s_%s_%s' % (wikiutil.escape(content_type.replace('/', '_')), size_str, key)
 110     # check caching status
 111     if not cache.exists(request, key):
 112         cache.put(request, key, data, content_type=content_type)
 113     # create url to cache file
 114     url = "%s%s%s" % (request.getQualifiedURL(), Page(request, pagename).url(request), cache.url(request, key))
 115     from MoinMoin import macro
 116     from MoinMoin.parser.text import Parser
 117     macro.request = request
 118     macro.formatter = request.html_formatter
 119     p = Parser("##\n", request)
 120     m = macro.Macro(p)
 121     return m.execute('EmbedObject', u'width=%s, height=%s, target=%s, url_mimetype=%s' % (width, height, url, content_type))

Current configuration does not allow embedding of the file example.svg because of its mimetype image/svg+xml.: example.svg

Discussion

I install this macro. System moinmoin 1.8.4, FreeBSD 6.3, Python 2.6, py26-SVGFig-1.1.6. Not drawing SVG on wiki, error "list index out of range". Consol make SVG on phyton, working.

Try it with a page Example/TestPage?action=raw

 cpu MHz:: 4


<<SvgPlot>>

and create different revisions of this page by changing the value. This macro is currently only a mockup to show how one could interact with svgfig. Also it show how to use data from old revisions. And how to call a macro from another macro (or some other code). And how to use the action cache. Probably later I will add it to MoinAPI/Beispiele

MoinMoin: MacroMarket/SvgPlot-1.8 (last edited 2009-08-22 08:01:58 by ReimarBauer)