[MERGE] Remove the embedded pychart library, and use the online version

bzr revid: stw@openerp.com-20120823150546-3pi7gw8oq2elpnt4
This commit is contained in:
Stephane Wirtel 2012-08-23 17:05:46 +02:00
commit b90a483138
105 changed files with 2 additions and 8182 deletions

View File

@ -32,7 +32,6 @@ import modules
import netsvc
import osv
import pooler
import pychart
import release
import report
import run_tests

View File

@ -1,24 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
##############################################################################
__all__ = [ "axis", "area", "basecanvas", "canvas",
"line_plot", "pie_plot", "rose_plot", "tick_mark",
"bar_plot", "chart_data", "arrow", "text_box", "color", "font",
"fill_style", "error_bar", "range_plot", "chart_object",
"line_style", "legend", "pychart_util", "theme", "scaling",
"zap", "coord", "linear_coord", "log_coord",
"category_coord", "afm", "interval_bar_plot" ]

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font AvantGarde-Book (path: /usr/share/fonts/afms/adobe/pagk8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["AvantGarde-Book"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 277, 295, 309, 554, 554, 775, 757, 351, 369, 369, 425, 606, 277, 332, 277, 437, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 277, 277, 606, 606, 606, 591, 867, 740, 574, 813, 744, 536, 485, 872, 683, 226, 482, 591, 462, 919, 740, 869, 592, 871, 607, 498, 426, 655, 702, 960, 609, 592, 480, 351, 605, 351, 606, 500, 351, 683, 682, 647, 685, 650, 314, 673, 610, 200, 203, 502, 200, 938, 610, 655, 682, 682, 301, 388, 339, 608, 554, 831, 480, 536, 425, 351, 672, 351, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 295, 554, 554, 166, 554, 554, 615, 554, 198, 502, 425, 251, 251, 487, 485, 500, 500, 553, 553, 277, 500, 564, 606, 354, 502, 484, 425, 1000, 1174, 500, 591, 500, 378, 375, 502, 439, 485, 453, 222, 369, 500, 332, 324, 500, 552, 302, 502, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 992, 500, 369, 500, 500, 500, 500, 517, 868, 1194, 369, 500, 500, 500, 500, 500, 1157, 500, 500, 500, 200, 500, 500, 300, 653, 1137, 554, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font AvantGarde-BookOblique (path: /usr/share/fonts/afms/adobe/pagko8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["AvantGarde-BookOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 277, 295, 309, 554, 554, 775, 757, 351, 369, 369, 425, 606, 277, 332, 277, 437, 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, 277, 277, 606, 606, 606, 591, 867, 740, 574, 813, 744, 536, 485, 872, 683, 226, 482, 591, 462, 919, 740, 869, 592, 871, 607, 498, 426, 655, 702, 960, 609, 592, 480, 351, 605, 351, 606, 500, 351, 683, 682, 647, 685, 650, 314, 673, 610, 200, 203, 502, 200, 938, 610, 655, 682, 682, 301, 388, 339, 608, 554, 831, 480, 536, 425, 351, 672, 351, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 295, 554, 554, 166, 554, 554, 615, 554, 198, 502, 425, 251, 251, 487, 485, 500, 500, 553, 553, 277, 500, 564, 606, 354, 502, 484, 425, 1000, 1174, 500, 591, 500, 378, 375, 502, 439, 485, 453, 222, 369, 500, 332, 324, 500, 552, 302, 502, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 992, 500, 369, 500, 500, 500, 500, 517, 868, 1194, 369, 500, 500, 500, 500, 500, 1157, 500, 500, 500, 200, 500, 500, 300, 653, 1137, 554, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font AvantGarde-Demi (path: /usr/share/fonts/afms/adobe/pagd8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["AvantGarde-Demi"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 280, 360, 560, 560, 860, 680, 280, 380, 380, 440, 600, 280, 420, 280, 460, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 560, 740, 740, 580, 780, 700, 520, 480, 840, 680, 280, 480, 620, 440, 900, 740, 840, 560, 840, 580, 520, 420, 640, 700, 900, 680, 620, 500, 320, 640, 320, 600, 500, 280, 660, 660, 640, 660, 640, 280, 660, 600, 240, 260, 580, 240, 940, 600, 640, 660, 660, 320, 440, 300, 600, 560, 800, 560, 580, 460, 340, 600, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 560, 560, 160, 560, 560, 560, 560, 220, 480, 460, 240, 240, 520, 520, 500, 500, 560, 560, 280, 500, 600, 600, 280, 480, 480, 460, 1000, 1280, 500, 560, 500, 420, 420, 540, 480, 420, 480, 280, 500, 500, 360, 340, 500, 700, 340, 540, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 900, 500, 360, 500, 500, 500, 500, 480, 840, 1060, 360, 500, 500, 500, 500, 500, 1080, 500, 500, 500, 240, 500, 500, 320, 660, 1080, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font AvantGarde-DemiOblique (path: /usr/share/fonts/afms/adobe/pagdo8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["AvantGarde-DemiOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 280, 360, 560, 560, 860, 680, 280, 380, 380, 440, 600, 280, 420, 280, 460, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 560, 740, 740, 580, 780, 700, 520, 480, 840, 680, 280, 480, 620, 440, 900, 740, 840, 560, 840, 580, 520, 420, 640, 700, 900, 680, 620, 500, 320, 640, 320, 600, 500, 280, 660, 660, 640, 660, 640, 280, 660, 600, 240, 260, 580, 240, 940, 600, 640, 660, 660, 320, 440, 300, 600, 560, 800, 560, 580, 460, 340, 600, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 560, 560, 160, 560, 560, 560, 560, 220, 480, 460, 240, 240, 520, 520, 500, 500, 560, 560, 280, 500, 600, 600, 280, 480, 480, 460, 1000, 1280, 500, 560, 500, 420, 420, 540, 480, 420, 480, 280, 500, 500, 360, 340, 500, 700, 340, 540, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 900, 500, 360, 500, 500, 500, 500, 480, 840, 1060, 360, 500, 500, 500, 500, 500, 1080, 500, 500, 500, 240, 500, 500, 320, 660, 1080, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Bookman-Demi (path: /usr/share/fonts/afms/adobe/pbkd8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Bookman-Demi"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 340, 360, 420, 660, 660, 940, 800, 320, 320, 320, 460, 600, 340, 360, 340, 600, 660, 660, 660, 660, 660, 660, 660, 660, 660, 660, 340, 340, 600, 600, 600, 660, 820, 720, 720, 740, 780, 720, 680, 780, 820, 400, 640, 800, 640, 940, 740, 800, 660, 800, 780, 660, 700, 740, 720, 940, 780, 700, 640, 300, 600, 300, 600, 500, 320, 580, 600, 580, 640, 580, 380, 580, 680, 360, 340, 660, 340, 1000, 680, 620, 640, 620, 460, 520, 460, 660, 600, 800, 600, 620, 560, 320, 600, 320, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 360, 660, 660, 120, 660, 660, 600, 660, 240, 540, 400, 220, 220, 740, 740, 500, 500, 440, 380, 340, 500, 800, 460, 320, 540, 540, 400, 1000, 1360, 500, 660, 500, 400, 400, 500, 480, 460, 500, 320, 500, 500, 340, 360, 500, 440, 320, 500, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1140, 500, 400, 500, 500, 500, 500, 640, 800, 1220, 400, 500, 500, 500, 500, 500, 880, 500, 500, 500, 360, 500, 500, 340, 620, 940, 660, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Bookman-DemiItalic (path: /usr/share/fonts/afms/adobe/pbkdi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Bookman-DemiItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 340, 320, 380, 680, 680, 880, 980, 320, 260, 260, 460, 600, 340, 280, 340, 360, 680, 680, 680, 680, 680, 680, 680, 680, 680, 680, 340, 340, 620, 600, 620, 620, 780, 720, 720, 700, 760, 720, 660, 760, 800, 380, 620, 780, 640, 860, 740, 760, 640, 760, 740, 700, 700, 740, 660, 1000, 740, 660, 680, 260, 580, 260, 620, 500, 320, 680, 600, 560, 680, 560, 420, 620, 700, 380, 320, 700, 380, 960, 680, 600, 660, 620, 500, 540, 440, 680, 540, 860, 620, 600, 560, 300, 620, 300, 620, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 680, 680, 120, 680, 680, 620, 680, 180, 520, 380, 220, 220, 820, 820, 500, 500, 420, 420, 340, 500, 680, 360, 300, 520, 520, 380, 1000, 1360, 500, 620, 500, 380, 340, 480, 480, 480, 460, 380, 520, 500, 360, 360, 500, 560, 320, 480, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1140, 500, 440, 500, 500, 500, 500, 640, 760, 1180, 440, 500, 500, 500, 500, 500, 880, 500, 500, 500, 380, 500, 500, 380, 600, 920, 660, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Bookman-Light (path: /usr/share/fonts/afms/adobe/pbkl8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Bookman-Light"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 300, 380, 620, 620, 900, 800, 220, 300, 300, 440, 600, 320, 400, 320, 600, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 320, 320, 600, 600, 600, 540, 820, 680, 740, 740, 800, 720, 640, 800, 800, 340, 600, 720, 600, 920, 740, 800, 620, 820, 720, 660, 620, 780, 700, 960, 720, 640, 640, 300, 600, 300, 600, 500, 220, 580, 620, 520, 620, 520, 320, 540, 660, 300, 300, 620, 300, 940, 660, 560, 620, 580, 440, 520, 380, 680, 520, 780, 560, 540, 480, 280, 600, 280, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 300, 620, 620, 140, 620, 620, 520, 620, 220, 400, 360, 240, 240, 620, 620, 500, 500, 540, 540, 320, 500, 600, 460, 220, 400, 400, 360, 1000, 1280, 500, 540, 500, 340, 340, 420, 440, 440, 460, 260, 420, 500, 320, 320, 500, 380, 320, 420, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1260, 500, 420, 500, 500, 500, 500, 600, 800, 1240, 420, 500, 500, 500, 500, 500, 860, 500, 500, 500, 300, 500, 500, 320, 560, 900, 660, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Bookman-LightItalic (path: /usr/share/fonts/afms/adobe/pbkli8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Bookman-LightItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 300, 320, 360, 620, 620, 800, 820, 280, 280, 280, 440, 600, 300, 320, 300, 600, 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, 300, 300, 600, 600, 600, 540, 780, 700, 720, 720, 740, 680, 620, 760, 800, 320, 560, 720, 580, 860, 720, 760, 600, 780, 700, 640, 600, 720, 680, 960, 700, 660, 580, 260, 600, 260, 600, 500, 280, 620, 600, 480, 640, 540, 340, 560, 620, 280, 280, 600, 280, 880, 620, 540, 600, 560, 400, 540, 340, 620, 540, 880, 540, 600, 520, 360, 600, 380, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 320, 620, 620, 20, 620, 620, 620, 620, 200, 440, 300, 180, 180, 640, 660, 500, 500, 620, 620, 300, 500, 620, 460, 320, 480, 440, 300, 1000, 1180, 500, 540, 500, 340, 320, 440, 440, 440, 440, 260, 420, 500, 300, 320, 500, 340, 260, 440, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1220, 500, 440, 500, 500, 500, 500, 580, 760, 1180, 400, 500, 500, 500, 500, 500, 880, 500, 500, 500, 280, 500, 500, 340, 540, 900, 620, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Courier (path: /usr/share/fonts/afms/adobe/pcrr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Courier"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Courier-Bold (path: /usr/share/fonts/afms/adobe/pcrb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Courier-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Courier-BoldOblique (path: /usr/share/fonts/afms/adobe/pcrbo8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Courier-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Courier-Oblique (path: /usr/share/fonts/afms/adobe/pcrro8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Courier-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 600, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 500, 600, 600, 600, 600, 600, 600, 600, 600, 500, 600, 600, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 600, 500, 600, 500, 500, 500, 500, 600, 600, 600, 600, 500, 500, 500, 500, 500, 600, 500, 500, 500, 600, 500, 500, 600, 600, 600, 600, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica (path: /usr/share/fonts/afms/adobe/phvr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 500, 556, 556, 556, 278, 500, 537, 350, 222, 333, 333, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 556, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 222, 611, 944, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Bold (path: /usr/share/fonts/afms/adobe/phvb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 500, 556, 556, 556, 278, 500, 556, 350, 278, 500, 500, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 611, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 278, 611, 944, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-BoldOblique (path: /usr/share/fonts/afms/adobe/phvbo8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 474, 556, 556, 889, 722, 278, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 278, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 238, 500, 556, 333, 333, 611, 611, 500, 556, 556, 556, 278, 500, 556, 350, 278, 500, 500, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 611, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 278, 611, 944, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Light (path: /usr/share/fonts/afms/adobe/phvl8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Light"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 278, 556, 556, 889, 667, 222, 333, 333, 389, 660, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 660, 660, 660, 500, 800, 667, 667, 722, 722, 611, 556, 778, 722, 278, 500, 667, 556, 833, 722, 778, 611, 778, 667, 611, 556, 722, 611, 889, 611, 611, 611, 333, 278, 333, 660, 500, 222, 556, 611, 556, 611, 556, 278, 611, 556, 222, 222, 500, 222, 833, 556, 556, 611, 611, 333, 500, 278, 556, 500, 722, 500, 500, 500, 333, 222, 333, 660, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 222, 389, 556, 389, 389, 500, 500, 500, 500, 556, 556, 278, 500, 650, 500, 222, 389, 389, 556, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 556, 778, 1000, 334, 500, 500, 500, 500, 500, 889, 500, 500, 500, 222, 500, 500, 222, 556, 944, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-LightOblique (path: /usr/share/fonts/afms/adobe/phvlo8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-LightOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 278, 556, 556, 889, 667, 222, 333, 333, 389, 660, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 660, 660, 660, 500, 800, 667, 667, 722, 722, 611, 556, 778, 722, 278, 500, 667, 556, 833, 722, 778, 611, 778, 667, 611, 556, 722, 611, 889, 611, 611, 611, 333, 278, 333, 660, 500, 222, 556, 611, 556, 611, 556, 278, 611, 556, 222, 222, 500, 222, 833, 556, 556, 611, 611, 333, 500, 278, 556, 500, 722, 500, 500, 500, 333, 222, 333, 660, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 222, 389, 556, 389, 389, 500, 500, 500, 500, 556, 556, 278, 500, 650, 500, 222, 389, 389, 556, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 556, 778, 1000, 334, 500, 500, 500, 500, 500, 889, 500, 500, 500, 222, 500, 500, 222, 556, 944, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Narrow (path: /usr/share/fonts/afms/adobe/phvr8an.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Narrow"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 228, 291, 456, 456, 729, 547, 182, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 228, 228, 479, 479, 479, 456, 832, 547, 547, 592, 592, 547, 501, 638, 592, 228, 410, 547, 456, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 228, 228, 228, 385, 456, 182, 456, 456, 410, 456, 456, 228, 456, 456, 182, 182, 410, 182, 683, 456, 456, 456, 456, 273, 410, 228, 456, 410, 592, 410, 410, 410, 274, 213, 274, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 157, 273, 456, 273, 273, 410, 410, 500, 456, 456, 456, 228, 500, 440, 287, 182, 273, 273, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 456, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 182, 501, 774, 501, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Narrow-Bold (path: /usr/share/fonts/afms/adobe/phvb8an.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Narrow-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 273, 389, 456, 456, 729, 592, 228, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 273, 273, 479, 479, 479, 501, 800, 592, 592, 592, 592, 547, 501, 638, 592, 228, 456, 592, 501, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 273, 228, 273, 479, 456, 228, 456, 501, 456, 501, 456, 273, 501, 501, 228, 228, 456, 228, 729, 501, 501, 501, 501, 319, 456, 273, 501, 456, 638, 456, 456, 410, 319, 230, 319, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 195, 410, 456, 273, 273, 501, 501, 500, 456, 456, 456, 228, 500, 456, 287, 228, 410, 410, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 501, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 228, 501, 774, 501, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Narrow-BoldOblique (path: /usr/share/fonts/afms/adobe/phvbo8an.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Narrow-BoldOblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 273, 389, 456, 456, 729, 592, 228, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 273, 273, 479, 479, 479, 501, 800, 592, 592, 592, 592, 547, 501, 638, 592, 228, 456, 592, 501, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 273, 228, 273, 479, 456, 228, 456, 501, 456, 501, 456, 273, 501, 501, 228, 228, 456, 228, 729, 501, 501, 501, 501, 319, 456, 273, 501, 456, 638, 456, 456, 410, 319, 230, 319, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 195, 410, 456, 273, 273, 501, 501, 500, 456, 456, 456, 228, 500, 456, 287, 228, 410, 410, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 501, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 228, 501, 774, 501, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Narrow-Oblique (path: /usr/share/fonts/afms/adobe/phvro8an.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Narrow-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 228, 228, 291, 456, 456, 729, 547, 182, 273, 273, 319, 479, 228, 273, 228, 228, 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, 228, 228, 479, 479, 479, 456, 832, 547, 547, 592, 592, 547, 501, 638, 592, 228, 410, 547, 456, 683, 592, 638, 547, 638, 592, 547, 501, 592, 547, 774, 547, 547, 501, 228, 228, 228, 385, 456, 182, 456, 456, 410, 456, 456, 228, 456, 456, 182, 182, 410, 182, 683, 456, 456, 456, 456, 273, 410, 228, 456, 410, 592, 410, 410, 410, 274, 213, 274, 479, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 273, 456, 456, 137, 456, 456, 456, 456, 157, 273, 456, 273, 273, 410, 410, 500, 456, 456, 456, 228, 500, 440, 287, 182, 273, 273, 456, 820, 820, 500, 501, 500, 273, 273, 273, 273, 273, 273, 273, 273, 500, 273, 273, 500, 273, 273, 273, 820, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 820, 500, 303, 500, 500, 500, 500, 456, 638, 820, 299, 500, 500, 500, 500, 500, 729, 500, 500, 500, 228, 500, 500, 182, 501, 774, 501, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Helvetica-Oblique (path: /usr/share/fonts/afms/adobe/phvro8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Helvetica-Oblique"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 355, 556, 556, 889, 667, 222, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 222, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 556, 556, 191, 333, 556, 333, 333, 500, 500, 500, 556, 556, 556, 278, 500, 537, 350, 222, 333, 333, 556, 1000, 1000, 500, 611, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 370, 500, 500, 500, 500, 556, 778, 1000, 365, 500, 500, 500, 500, 500, 889, 500, 500, 500, 278, 500, 500, 222, 611, 944, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font NewCenturySchlbk-Bold (path: /usr/share/fonts/afms/adobe/pncb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["NewCenturySchlbk-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 287, 296, 333, 574, 574, 833, 852, 241, 389, 389, 500, 606, 278, 333, 278, 278, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 278, 278, 606, 606, 606, 500, 747, 759, 778, 778, 833, 759, 722, 833, 870, 444, 648, 815, 722, 981, 833, 833, 759, 833, 815, 667, 722, 833, 759, 981, 722, 722, 667, 389, 606, 389, 606, 500, 241, 611, 648, 556, 667, 574, 389, 611, 685, 370, 352, 667, 352, 963, 685, 611, 667, 648, 519, 500, 426, 685, 611, 889, 611, 611, 537, 389, 606, 389, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 296, 574, 574, 167, 574, 574, 500, 574, 241, 481, 500, 333, 333, 685, 685, 500, 500, 500, 500, 278, 500, 747, 606, 241, 481, 481, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 981, 500, 367, 500, 500, 500, 500, 722, 833, 1000, 367, 500, 500, 500, 500, 500, 870, 500, 500, 500, 370, 500, 500, 352, 611, 907, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font NewCenturySchlbk-BoldItalic (path: /usr/share/fonts/afms/adobe/pncbi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["NewCenturySchlbk-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 287, 333, 400, 574, 574, 889, 889, 259, 407, 407, 500, 606, 287, 333, 287, 278, 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, 287, 287, 606, 606, 606, 481, 747, 741, 759, 759, 833, 741, 704, 815, 870, 444, 667, 778, 704, 944, 852, 833, 741, 833, 796, 685, 722, 833, 741, 944, 741, 704, 704, 407, 606, 407, 606, 500, 259, 667, 611, 537, 667, 519, 389, 611, 685, 389, 370, 648, 389, 944, 685, 574, 648, 630, 519, 481, 407, 685, 556, 833, 574, 519, 519, 407, 606, 407, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 574, 574, 167, 574, 574, 500, 574, 287, 481, 481, 278, 278, 685, 685, 500, 500, 500, 500, 287, 500, 650, 606, 259, 481, 481, 481, 1000, 1167, 500, 481, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 412, 500, 500, 500, 500, 704, 833, 963, 356, 500, 500, 500, 500, 500, 815, 500, 500, 500, 389, 500, 500, 389, 574, 852, 574, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font NewCenturySchlbk-Italic (path: /usr/share/fonts/afms/adobe/pncri8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["NewCenturySchlbk-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 333, 400, 556, 556, 833, 852, 204, 333, 333, 500, 606, 278, 333, 278, 606, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 606, 606, 606, 444, 747, 704, 722, 722, 778, 722, 667, 778, 833, 407, 611, 741, 667, 944, 815, 778, 667, 778, 741, 667, 685, 815, 704, 926, 704, 685, 667, 333, 606, 333, 606, 500, 204, 574, 556, 444, 611, 444, 333, 537, 611, 333, 315, 556, 333, 889, 611, 500, 574, 556, 444, 444, 352, 611, 519, 778, 500, 500, 463, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 556, 556, 167, 556, 556, 500, 556, 278, 389, 426, 333, 333, 611, 611, 500, 500, 500, 500, 278, 500, 650, 606, 204, 389, 389, 426, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 870, 500, 422, 500, 500, 500, 500, 667, 778, 981, 372, 500, 500, 500, 500, 500, 722, 500, 500, 500, 333, 500, 500, 333, 500, 778, 556, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font NewCenturySchlbk-Roman (path: /usr/share/fonts/afms/adobe/pncr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["NewCenturySchlbk-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 296, 389, 556, 556, 833, 815, 204, 333, 333, 500, 606, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 606, 606, 606, 444, 737, 722, 722, 722, 778, 722, 667, 778, 833, 407, 556, 778, 667, 944, 815, 778, 667, 778, 722, 630, 667, 815, 722, 981, 704, 704, 611, 333, 606, 333, 606, 500, 204, 556, 556, 444, 574, 500, 333, 537, 611, 315, 296, 593, 315, 889, 611, 500, 574, 556, 444, 463, 389, 611, 537, 778, 537, 537, 481, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 296, 556, 556, 167, 556, 556, 500, 556, 204, 389, 426, 259, 259, 611, 611, 500, 556, 500, 500, 278, 500, 606, 606, 204, 389, 389, 426, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 334, 500, 500, 500, 500, 667, 778, 1000, 300, 500, 500, 500, 500, 500, 796, 500, 500, 500, 315, 500, 500, 315, 500, 833, 574, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Palatino-Bold (path: /usr/share/fonts/afms/adobe/pplb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Palatino-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 278, 402, 500, 500, 889, 833, 278, 333, 333, 444, 606, 250, 333, 250, 296, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 747, 778, 667, 722, 833, 611, 556, 833, 833, 389, 389, 778, 611, 1000, 833, 833, 611, 833, 722, 611, 667, 778, 778, 1000, 667, 667, 667, 333, 606, 333, 606, 500, 278, 500, 611, 444, 611, 500, 389, 556, 611, 333, 333, 611, 333, 889, 611, 556, 611, 611, 389, 444, 333, 611, 556, 833, 500, 556, 500, 310, 606, 310, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 500, 500, 167, 500, 500, 500, 500, 227, 500, 500, 389, 389, 611, 611, 500, 500, 500, 500, 250, 500, 641, 606, 333, 500, 500, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 438, 500, 500, 500, 500, 611, 833, 1000, 488, 500, 500, 500, 500, 500, 778, 500, 500, 500, 333, 500, 500, 333, 556, 833, 611, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Palatino-BoldItalic (path: /usr/share/fonts/afms/adobe/pplbi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Palatino-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 500, 500, 500, 889, 833, 278, 333, 333, 444, 606, 250, 389, 250, 315, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 833, 722, 667, 685, 778, 611, 556, 778, 778, 389, 389, 722, 611, 944, 778, 833, 667, 833, 722, 556, 611, 778, 667, 1000, 722, 611, 667, 333, 606, 333, 606, 500, 278, 556, 537, 444, 556, 444, 333, 500, 556, 333, 333, 556, 333, 833, 556, 556, 556, 537, 389, 444, 389, 556, 556, 833, 500, 556, 500, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 556, 500, 250, 500, 500, 333, 333, 611, 611, 500, 500, 556, 556, 250, 500, 556, 606, 250, 500, 500, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 556, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 333, 500, 500, 500, 500, 611, 833, 944, 333, 500, 500, 500, 500, 500, 738, 500, 500, 500, 333, 500, 500, 333, 556, 778, 556, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Palatino-Italic (path: /usr/share/fonts/afms/adobe/pplri8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Palatino-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 500, 500, 500, 889, 778, 278, 333, 333, 389, 606, 250, 333, 250, 296, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 500, 747, 722, 611, 667, 778, 611, 556, 722, 778, 333, 333, 667, 556, 944, 778, 778, 611, 778, 667, 556, 611, 778, 722, 944, 722, 667, 667, 333, 606, 333, 606, 500, 278, 444, 463, 407, 500, 389, 278, 500, 500, 278, 278, 444, 278, 778, 556, 444, 500, 463, 389, 389, 333, 556, 500, 722, 500, 500, 444, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 333, 500, 500, 333, 333, 528, 545, 500, 500, 500, 500, 250, 500, 500, 500, 278, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 941, 500, 333, 500, 500, 500, 500, 556, 778, 1028, 333, 500, 500, 500, 500, 500, 638, 500, 500, 500, 278, 500, 500, 278, 444, 669, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Palatino-Roman (path: /usr/share/fonts/afms/adobe/pplr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Palatino-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 278, 371, 500, 500, 840, 778, 278, 333, 333, 389, 606, 250, 333, 250, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 250, 606, 606, 606, 444, 747, 778, 611, 709, 774, 611, 556, 763, 832, 337, 333, 726, 611, 946, 831, 786, 604, 786, 668, 525, 613, 778, 722, 1000, 667, 667, 667, 333, 606, 333, 606, 500, 278, 500, 553, 444, 611, 479, 333, 556, 582, 291, 234, 556, 291, 883, 582, 546, 601, 560, 395, 424, 326, 603, 565, 834, 516, 556, 500, 333, 606, 333, 606, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 500, 500, 167, 500, 500, 500, 500, 208, 500, 500, 331, 331, 605, 608, 500, 500, 500, 500, 250, 500, 628, 606, 278, 500, 500, 500, 1000, 1144, 500, 444, 500, 333, 333, 333, 333, 333, 333, 250, 333, 500, 333, 333, 500, 380, 313, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 333, 500, 500, 500, 500, 611, 833, 998, 333, 500, 500, 500, 500, 500, 758, 500, 500, 500, 287, 500, 500, 291, 556, 827, 556, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Symbol (path: /usr/share/fonts/afms/adobe/psyr.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Symbol"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 713, 500, 549, 833, 778, 439, 333, 333, 500, 549, 250, 549, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 549, 549, 549, 444, 549, 722, 667, 722, 612, 611, 763, 603, 722, 333, 631, 722, 686, 889, 722, 722, 768, 741, 556, 592, 611, 690, 439, 768, 645, 795, 611, 333, 863, 333, 658, 500, 500, 631, 549, 549, 494, 439, 521, 411, 603, 329, 603, 549, 549, 576, 521, 549, 549, 521, 549, 603, 439, 576, 713, 686, 493, 686, 494, 480, 200, 480, 549, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 620, 247, 549, 167, 713, 500, 753, 753, 753, 753, 1042, 987, 603, 987, 603, 400, 549, 411, 549, 549, 713, 494, 460, 549, 549, 549, 549, 1000, 603, 1000, 658, 823, 686, 795, 987, 768, 768, 823, 768, 768, 713, 713, 713, 713, 713, 713, 713, 768, 713, 790, 790, 890, 823, 549, 250, 713, 603, 603, 1042, 987, 603, 987, 603, 494, 329, 790, 790, 786, 713, 384, 384, 384, 384, 384, 384, 494, 494, 494, 494, 500, 329, 274, 686, 686, 686, 384, 384, 384, 384, 384, 384, 494, 494, 494, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Times-Bold (path: /usr/share/fonts/afms/adobe/ptmb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Times-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 555, 500, 500, 1000, 833, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 930, 722, 667, 722, 722, 667, 611, 778, 778, 389, 500, 778, 667, 944, 722, 778, 611, 778, 722, 556, 667, 722, 722, 1000, 722, 722, 667, 333, 278, 333, 581, 500, 333, 500, 556, 444, 556, 444, 333, 500, 556, 278, 333, 556, 278, 833, 556, 500, 556, 556, 444, 389, 333, 556, 500, 722, 500, 500, 444, 394, 220, 394, 520, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 540, 350, 333, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 1000, 500, 300, 500, 500, 500, 500, 667, 778, 1000, 330, 500, 500, 500, 500, 500, 722, 500, 500, 500, 278, 500, 500, 278, 500, 722, 556, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Times-BoldItalic (path: /usr/share/fonts/afms/adobe/ptmbi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Times-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 389, 555, 500, 500, 833, 778, 333, 333, 333, 500, 570, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 570, 570, 570, 500, 832, 667, 667, 667, 722, 667, 667, 722, 778, 389, 500, 667, 611, 889, 722, 722, 611, 722, 667, 556, 611, 722, 667, 889, 667, 611, 611, 333, 278, 333, 570, 500, 333, 500, 500, 444, 500, 444, 333, 500, 556, 278, 278, 500, 278, 778, 556, 500, 500, 500, 389, 389, 278, 556, 444, 667, 500, 444, 389, 348, 220, 348, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 389, 500, 500, 167, 500, 500, 500, 500, 278, 500, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 500, 350, 333, 500, 500, 500, 1000, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 944, 500, 266, 500, 500, 500, 500, 611, 722, 944, 300, 500, 500, 500, 500, 500, 722, 500, 500, 500, 278, 500, 500, 278, 500, 722, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Times-Italic (path: /usr/share/fonts/afms/adobe/ptmri8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Times-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 420, 500, 500, 833, 778, 333, 333, 333, 500, 675, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 333, 675, 675, 675, 500, 920, 611, 611, 667, 722, 611, 611, 722, 722, 333, 444, 667, 556, 833, 667, 722, 611, 722, 611, 500, 556, 722, 611, 833, 611, 556, 556, 389, 278, 389, 422, 500, 333, 500, 500, 444, 500, 444, 278, 500, 500, 278, 278, 444, 278, 722, 500, 500, 500, 500, 389, 389, 278, 500, 444, 667, 444, 444, 389, 400, 275, 400, 541, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 389, 500, 500, 167, 500, 500, 500, 500, 214, 556, 500, 333, 333, 500, 500, 500, 500, 500, 500, 250, 500, 523, 350, 333, 556, 556, 500, 889, 1000, 500, 500, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 889, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 276, 500, 500, 500, 500, 556, 722, 944, 310, 500, 500, 500, 500, 500, 667, 500, 500, 500, 278, 500, 500, 278, 500, 667, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Times-Roman (path: /usr/share/fonts/afms/adobe/ptmr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Times-Roman"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 250, 333, 408, 500, 500, 833, 778, 333, 333, 333, 500, 564, 250, 333, 250, 278, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 278, 564, 564, 564, 444, 921, 722, 667, 667, 722, 611, 556, 722, 722, 333, 389, 722, 611, 889, 722, 722, 556, 722, 667, 556, 611, 722, 722, 944, 722, 722, 611, 333, 278, 333, 469, 500, 333, 444, 500, 444, 500, 444, 333, 500, 500, 278, 278, 500, 278, 778, 500, 500, 500, 500, 333, 389, 278, 500, 500, 722, 500, 500, 444, 480, 200, 480, 541, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 333, 500, 500, 167, 500, 500, 500, 500, 180, 444, 500, 333, 333, 556, 556, 500, 500, 500, 500, 250, 500, 453, 350, 333, 444, 444, 500, 1000, 1000, 500, 444, 500, 333, 333, 333, 333, 333, 333, 333, 333, 500, 333, 333, 500, 333, 333, 333, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 889, 500, 276, 500, 500, 500, 500, 611, 722, 889, 310, 500, 500, 500, 500, 500, 667, 500, 500, 500, 278, 500, 500, 278, 500, 722, 500, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Utopia-Bold (path: /usr/share/fonts/afms/adobe/putb8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Utopia-Bold"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 210, 278, 473, 560, 560, 887, 748, 252, 365, 365, 442, 600, 280, 392, 280, 378, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 456, 833, 644, 683, 689, 777, 629, 593, 726, 807, 384, 386, 707, 585, 918, 739, 768, 650, 768, 684, 561, 624, 786, 645, 933, 634, 617, 614, 335, 379, 335, 600, 500, 252, 544, 605, 494, 605, 519, 342, 533, 631, 316, 316, 582, 309, 948, 638, 585, 615, 597, 440, 446, 370, 629, 520, 774, 522, 524, 483, 365, 284, 365, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 560, 560, 100, 560, 560, 566, 560, 252, 473, 487, 287, 287, 639, 639, 500, 500, 510, 486, 280, 500, 552, 455, 252, 473, 473, 487, 1000, 1289, 500, 456, 500, 430, 430, 430, 430, 430, 430, 430, 430, 500, 430, 430, 500, 430, 430, 430, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 879, 500, 405, 500, 500, 500, 500, 591, 768, 1049, 427, 500, 500, 500, 500, 500, 806, 500, 500, 500, 316, 500, 500, 321, 585, 866, 662, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Utopia-BoldItalic (path: /usr/share/fonts/afms/adobe/putbi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Utopia-BoldItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 210, 285, 455, 560, 560, 896, 752, 246, 350, 350, 500, 600, 280, 392, 280, 260, 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, 280, 280, 600, 600, 600, 454, 828, 634, 680, 672, 774, 622, 585, 726, 800, 386, 388, 688, 586, 921, 741, 761, 660, 761, 681, 551, 616, 776, 630, 920, 630, 622, 618, 350, 460, 350, 600, 500, 246, 596, 586, 456, 609, 476, 348, 522, 629, 339, 333, 570, 327, 914, 635, 562, 606, 584, 440, 417, 359, 634, 518, 795, 516, 489, 466, 340, 265, 340, 600, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 285, 560, 560, 100, 560, 560, 568, 560, 246, 455, 560, 360, 360, 651, 652, 500, 500, 514, 490, 280, 500, 580, 465, 246, 455, 455, 560, 1000, 1297, 500, 454, 500, 400, 400, 400, 400, 400, 400, 402, 400, 500, 400, 400, 500, 400, 350, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 890, 500, 444, 500, 500, 500, 500, 592, 761, 1016, 412, 500, 500, 500, 500, 500, 789, 500, 500, 500, 339, 500, 500, 339, 562, 811, 628, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Utopia-Italic (path: /usr/share/fonts/afms/adobe/putri8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Utopia-Italic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 225, 240, 402, 530, 530, 826, 725, 216, 350, 350, 412, 570, 265, 392, 265, 270, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 265, 265, 570, 570, 570, 425, 794, 624, 632, 661, 763, 596, 571, 709, 775, 345, 352, 650, 565, 920, 763, 753, 614, 753, 640, 533, 606, 794, 637, 946, 632, 591, 622, 330, 390, 330, 570, 500, 216, 561, 559, 441, 587, 453, 315, 499, 607, 317, 309, 545, 306, 912, 618, 537, 590, 559, 402, 389, 341, 618, 510, 785, 516, 468, 468, 340, 270, 340, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 240, 530, 530, 100, 530, 530, 530, 530, 216, 402, 462, 277, 277, 607, 603, 500, 500, 500, 490, 265, 500, 560, 500, 216, 402, 402, 462, 1000, 1200, 500, 425, 500, 400, 400, 400, 400, 400, 400, 402, 400, 500, 400, 400, 500, 400, 350, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 880, 500, 425, 500, 500, 500, 500, 571, 753, 1020, 389, 500, 500, 500, 500, 500, 779, 500, 500, 500, 317, 500, 500, 318, 537, 806, 577, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font Utopia-Regular (path: /usr/share/fonts/afms/adobe/putr8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["Utopia-Regular"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 225, 242, 458, 530, 530, 838, 706, 278, 350, 350, 412, 570, 265, 392, 265, 460, 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, 265, 265, 570, 570, 570, 389, 793, 635, 646, 684, 779, 606, 580, 734, 798, 349, 350, 658, 568, 944, 780, 762, 600, 762, 644, 541, 621, 791, 634, 940, 624, 588, 610, 330, 460, 330, 570, 500, 278, 523, 598, 496, 598, 514, 319, 520, 607, 291, 280, 524, 279, 923, 619, 577, 608, 591, 389, 436, 344, 606, 504, 768, 486, 506, 480, 340, 228, 340, 570, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 242, 530, 530, 150, 530, 530, 554, 530, 278, 458, 442, 257, 257, 610, 610, 500, 500, 504, 488, 265, 500, 555, 409, 278, 458, 458, 442, 1000, 1208, 500, 389, 500, 400, 400, 400, 400, 400, 400, 400, 400, 500, 400, 400, 500, 400, 400, 400, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 876, 500, 390, 500, 500, 500, 500, 574, 762, 1025, 398, 500, 500, 500, 500, 500, 797, 500, 500, 500, 291, 500, 500, 294, 577, 882, 601, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font ZapfChancery-MediumItalic (path: /usr/share/fonts/afms/adobe/pzcmi8a.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["ZapfChancery-MediumItalic"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 220, 280, 220, 440, 440, 680, 780, 240, 260, 220, 420, 520, 220, 280, 220, 340, 440, 440, 440, 440, 440, 440, 440, 440, 440, 440, 260, 240, 520, 520, 520, 380, 700, 620, 600, 520, 700, 620, 580, 620, 680, 380, 400, 660, 580, 840, 700, 600, 540, 600, 600, 460, 500, 740, 640, 880, 560, 560, 620, 240, 480, 320, 520, 500, 240, 420, 420, 340, 440, 340, 320, 400, 440, 240, 220, 440, 240, 620, 460, 400, 440, 400, 300, 320, 320, 460, 440, 680, 420, 400, 440, 240, 520, 240, 520, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 280, 440, 440, 60, 440, 440, 420, 440, 160, 340, 340, 240, 260, 520, 520, 500, 500, 460, 480, 220, 500, 500, 600, 180, 280, 360, 380, 1000, 960, 500, 400, 500, 220, 300, 340, 440, 440, 440, 220, 360, 500, 300, 300, 500, 400, 280, 340, 1000, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 740, 500, 260, 500, 500, 500, 500, 580, 660, 820, 260, 500, 500, 500, 500, 500, 540, 500, 500, 500, 240, 500, 500, 300, 440, 560, 420, )

View File

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
# AFM font ZapfDingbats (path: /usr/share/fonts/afms/adobe/pzdr.afm).
# Derived from Ghostscript distribution.
# Go to www.cs.wisc.edu/~ghost to get the Ghostcript source code.
import dir
dir.afm["ZapfDingbats"] = (500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 278, 974, 961, 974, 980, 719, 789, 790, 791, 690, 960, 939, 549, 855, 911, 933, 911, 945, 974, 755, 846, 762, 761, 571, 677, 763, 760, 759, 754, 494, 552, 537, 577, 692, 786, 788, 788, 790, 793, 794, 816, 823, 789, 841, 823, 833, 816, 831, 923, 744, 723, 749, 790, 792, 695, 776, 768, 792, 759, 707, 708, 682, 701, 826, 815, 789, 789, 707, 687, 696, 689, 786, 787, 713, 791, 785, 791, 873, 761, 762, 762, 759, 759, 892, 892, 788, 784, 438, 138, 277, 415, 392, 392, 668, 668, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 732, 544, 544, 910, 667, 760, 760, 776, 595, 694, 626, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 788, 894, 838, 1016, 458, 748, 924, 748, 918, 927, 928, 928, 834, 873, 828, 924, 924, 917, 930, 931, 463, 883, 836, 836, 867, 867, 696, 696, 874, 500, 874, 760, 946, 771, 865, 771, 888, 967, 888, 831, 873, 927, 970, 918, )

View File

@ -1,22 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
__all__ = ["Courier_Oblique", "AvantGarde_BookOblique", "Times_Italic", "Helvetica_Bold", "NewCenturySchlbk_Roman", "Helvetica", "Helvetica_Narrow", "AvantGarde_Demi", "Times_BoldItalic", "Helvetica_Narrow_Bold", "Helvetica_Light", "Bookman_DemiItalic", "Utopia_Regular", "Times_Roman", "Palatino_Italic", "Courier_Bold", "ZapfChancery_MediumItalic", "NewCenturySchlbk_Italic", "NewCenturySchlbk_BoldItalic", "Helvetica_Narrow_BoldOblique", "Courier", "AvantGarde_DemiOblique", "Courier_BoldOblique", "Bookman_LightItalic", "Symbol", "Utopia_Bold", "Times_Bold", "Helvetica_BoldOblique", "Utopia_BoldItalic", "AvantGarde_Book", "Bookman_Demi", "Palatino_Roman", "Bookman_Light", "Utopia_Italic", "NewCenturySchlbk_Bold", "Helvetica_LightOblique", "ZapfDingbats", "Helvetica_Narrow_Oblique", "Helvetica_Oblique", "Palatino_BoldItalic", "Palatino_Bold", "dir"]

View File

@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
afm = {}

View File

@ -1,250 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import coord
import line_style
import legend
import axis
import pychart_util
import chart_object
import fill_style
import canvas
import area_doc
import linear_coord
import category_coord
import theme
from pychart_types import *
from types import *
_dummy_legend = legend.T()
def range_doc(t):
u = t.upper()
return """Specifies the range of %s values that are displayed in the
chart. IF the value is None, both the values are computed
automatically from the samples. Otherwise, the value must be a
tuple of format (MIN, MAX). MIN and MAX must be either None or a
number. If None, the value is computed automatically from the
samples. For example, if %s_range = (None,5), then the minimum %s
value is computed automatically, but the maximum %s value is fixed
at 5.""" % (u, t, u, u)
_keys = {
"loc" : (CoordType, (0,0),
"""The location of the bottom-left corner of the chart.
@cindex chart location
@cindex location, chart
"""),
"size" : (CoordType, (120,110),
"""The size of the chart-drawing area, excluding axis labels,
legends, tick marks, etc.
@cindex chart size
@cindex size, chart
"""),
"bg_style": (fill_style.T, None, "Background fill-pattern."),
"border_line_style": (line_style.T, None, "Line style of the outer frame of the chart."),
"x_coord":
(coord.T, linear_coord.T(),
"""Set the X coordinate system.""",
"""A linear coordinate system."""),
"y_coord": (coord.T, linear_coord.T(),
"Set the Y coordinate system.",
"""A linear coordinate system."""),
"x_range": (CoordType, None, range_doc("x")),
"y_range": (CoordType, None, range_doc("y")),
"x_axis": (axis.X, None, "The X axis. <<axis>>."),
"x_axis2": (axis.X, None, """The second X axis. This axis should be non-None either when you want to display plots with two distinct domains or when
you just want to display two axes at the top and bottom of the chart.
<<axis>>"""),
"y_axis": (axis.Y, None, "The Y axis. <<axis>>."),
"y_axis2": (axis.Y, None,
"""The second Y axis. This axis should be non-None either when you want to display plots with two distinct ranges or when
you just want to display two axes at the left and right of the chart. <<axis>>"""),
"x_grid_style" : (line_style.T, None,
"""The style of horizontal grid lines.
@cindex grid lines"""),
"y_grid_style" : (line_style.T, line_style.gray70_dash3,
"The style of vertical grid lines."),
"x_grid_interval": (IntervalType, None,
"""The horizontal grid-line interval.
A numeric value
specifies the interval at which
lines are drawn. If value is a function, it
takes two arguments, (MIN, MAX), that tells
the minimum and maximum values found in the
sample data. The function should return a list
of values at which lines are drawn."""),
"y_grid_interval": (IntervalType, None,
"The vertical grid-line interval. See also x_grid_interval"),
"x_grid_over_plot": (IntType, False,
"If True, grid lines are drawn over plots. Otherwise, plots are drawn over grid lines."),
"y_grid_over_plot": (IntType, False, "See x_grid_over_plot."),
"plots": (ListType, pychart_util.new_list,
"""Used only internally by pychart."""),
"legend": (legend.T, _dummy_legend, "The legend of the chart.",
"""a legend is by default displayed
in the right-center of the chart."""),
}
class T(chart_object.T):
keys = _keys
__doc__ = area_doc.doc
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def x_pos(self, xval):
"Return the x position (on the canvas) corresponding to XVAL."
off = self.x_coord.get_canvas_pos(self.size[0], xval,
self.x_range[0], self.x_range[1])
return self.loc[0] + off
def y_pos(self, yval):
"Return the y position (on the canvas) corresponding to YVAL."
off = self.y_coord.get_canvas_pos(self.size[1], yval,
self.y_range[0], self.y_range[1])
return self.loc[1] + off
def x_tic_points(self, interval):
"Return the list of X values for which tick marks and grid lines are drawn."
if type(interval) == FunctionType:
return apply(interval, self.x_range)
return self.x_coord.get_tics(self.x_range[0], self.x_range[1], interval)
def y_tic_points(self, interval):
"Return the list of Y values for which tick marks and grid lines are drawn."
if type(interval) == FunctionType:
return apply(interval, self.y_range)
return self.y_coord.get_tics(self.y_range[0], self.y_range[1], interval)
def __draw_x_grid_and_axis(self, can):
if self.x_grid_style:
for i in self.x_tic_points(self.x_grid_interval):
x = self.x_pos(i)
if x > self.loc[0]:
can.line(self.x_grid_style,
x, self.loc[1], x, self.loc[1]+self.size[1])
if self.x_axis:
self.x_axis.draw(self, can)
if self.x_axis2:
self.x_axis2.draw(self, can)
def __draw_y_grid_and_axis(self, can):
if self.y_grid_style:
for i in self.y_tic_points(self.y_grid_interval):
y = self.y_pos(i)
if y > self.loc[1]:
can.line(self.y_grid_style,
self.loc[0], y,
self.loc[0]+self.size[0], y)
if self.y_axis:
self.y_axis.draw(self, can)
if self.y_axis2:
self.y_axis2.draw(self, can)
def __get_data_range(self, r, which, coord, interval):
if isinstance(coord, category_coord.T):
# This info is unused for the category coord type.
# So I just return a random value.
return ((0,0), 1)
r = r or (None, None)
if len(self.plots) == 0:
raise ValueError, "No chart to draw, and no data range specified.\n";
dmin, dmax = 999999, -999999
for plot in self.plots:
this_min, this_max = plot.get_data_range(which)
dmin = min(this_min, dmin)
dmax = max(this_max, dmax)
if interval and type(interval) == FunctionType:
tics = apply(interval, (dmin, dmax))
dmin = tics[0]
dmax = tics[len(tics)-1]
else:
dmin, dmax, interval = coord.get_min_max(dmin, dmax, interval)
if r[0] != None:
dmin = r[0]
if r[1] != None:
dmax = r[1]
return ((dmin, dmax), interval)
def draw(self, can = None):
"Draw the charts."
if can == None:
can = canvas.default_canvas()
self.type_check()
for plot in self.plots:
plot.check_integrity()
self.x_range, self.x_grid_interval = \
self.__get_data_range(self.x_range, 'X',
self.x_coord,
self.x_grid_interval)
self.y_range, self.y_grid_interval = \
self.__get_data_range(self.y_range, 'Y',
self.y_coord,
self.y_grid_interval)
can.rectangle(self.border_line_style, self.bg_style,
self.loc[0], self.loc[1],
self.loc[0] + self.size[0], self.loc[1] + self.size[1])
if not self.x_grid_over_plot:
self.__draw_x_grid_and_axis(can)
if not self.y_grid_over_plot:
self.__draw_y_grid_and_axis(can)
clipbox = theme.adjust_bounding_box([self.loc[0], self.loc[1],
self.loc[0] + self.size[0],
self.loc[1] + self.size[1]])
can.clip(clipbox[0], clipbox[1],
clipbox[2], clipbox[3])
for plot in self.plots:
plot.draw(self, can)
can.endclip()
if self.x_grid_over_plot:
self.__draw_x_grid_and_axis(can)
if self.y_grid_over_plot:
self.__draw_y_grid_and_axis(can)
if self.legend == _dummy_legend:
self.legend = legend.T()
if self.legend:
legends = []
for plot in self.plots:
entry = plot.get_legend_entry()
if entry == None:
pass
elif type(entry) != ListType:
legends.append(entry)
else:
for e in entry:
legends.append(e)
self.legend.draw(self, legends, can)
def add_plot(self, *plots):
"Add PLOTS... to the area."
self.plots.extend(plots)

View File

@ -1,64 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
plots(type:list) default="Used only internally by pychart.".
loc(type:(x,y)) default="The location of the bottom-left corner of the chart.
@cindex chart location
@cindex location, chart
".
y_grid_style(type:line_style.T) default="The style of vertical grid lines.".
y_grid_interval(type:Number or function) default="The vertical grid-line interval. See also x_grid_interval".
x_grid_over_plot(type:int) default="If True, grid lines are drawn over plots. Otherwise, plots are drawn over grid lines.".
x_range(type:(x,y)) default="Specifies the range of X values that are displayed in the
chart. IF the value is None, both the values are computed
automatically from the samples. Otherwise, the value must be a
tuple of format (MIN, MAX). MIN and MAX must be either None or a
number. If None, the value is computed automatically from the
samples. For example, if x_range = (None,5), then the minimum X
value is computed automatically, but the maximum X value is fixed
at 5.".
y_coord(type:coord.T) default="Set the Y coordinate system.".
A linear coordinate system.
y_range(type:(x,y)) default="Specifies the range of Y values that are displayed in the
chart. IF the value is None, both the values are computed
automatically from the samples. Otherwise, the value must be a
tuple of format (MIN, MAX). MIN and MAX must be either None or a
number. If None, the value is computed automatically from the
samples. For example, if y_range = (None,5), then the minimum Y
value is computed automatically, but the maximum Y value is fixed
at 5.".
x_axis(type:axis.X) default="The X axis. <<axis>>.".
bg_style(type:fill_style.T) default="Background fill-pattern.".
x_coord(type:coord.T) default="Set the X coordinate system.".
A linear coordinate system.
legend(type:legend.T) default="The legend of the chart.".
a legend is by default displayed in the right-center of the
chart.
y_grid_over_plot(type:int) default="See x_grid_over_plot.".
x_axis2(type:axis.X) default="The second X axis. This axis should be non-None either when you want to display plots with two distinct domains or when
you just want to display two axes at the top and bottom of the chart.
<<axis>>".
y_axis2(type:axis.Y) default="The second Y axis. This axis should be non-None either when you want to display plots with two distinct ranges or when
you just want to display two axes at the left and right of the chart. <<axis>>".
x_grid_style(type:line_style.T) default="The style of horizontal grid lines.
@cindex grid lines".
y_axis(type:axis.Y) default="The Y axis. <<axis>>.".
border_line_style(type:line_style.T) default="Line style of the outer frame of the chart.".
x_grid_interval(type:Number or function) default="The horizontal grid-line interval.
A numeric value
specifies the interval at which
lines are drawn. If value is a function, it
takes two arguments, (MIN, MAX), that tells
the minimum and maximum values found in the
sample data. The function should return a list
of values at which lines are drawn.".
size(type:(x,y)) default="The size of the chart-drawing area, excluding axis labels,
legends, tick marks, etc.
@cindex chart size
@cindex size, chart
".
"""

View File

@ -1,185 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import line_style
import color
import chart_object
import object_set
import math
import arrow_doc
import canvas
from pychart_types import *
from types import *
from scaling import *
__doc__ = """
Arrow is an optional component of a chart that draws line segments with
an arrowhead. To draw an arrow, one creates an arrow.T object, and calls
its "draw" method usually after area.draw() is called (otherwise, area.draw()
may overwrite the arrow). For example, the below code draws an arrow
from (10,10) to (20,30).
ar = area.T(...)
a = arrow.T(head_style = 1)
ar.draw()
a.draw([(10,10), (20,30)])
"""
def draw_arrowhead(can, tailx, taily, tipx, tipy, thickness, head_len, style):
can.comment("ARROWHEAD tail=(%d,%d) tip=(%d,%d)\n"
% (tailx, taily, tipx, tipy))
halfthickness = thickness/2.0
dx = tipx - tailx
dy = tipy - taily
arrow_len = math.sqrt(dx*dx + dy*dy)
angle = math.atan2(dy, dx) * 360 / (2*math.pi)
base = arrow_len - head_len
can.push_transformation((tailx, taily), None, angle)
can.newpath()
if style == 0:
can.moveto(base, - halfthickness)
can.lineto(base, halfthickness)
can.lineto(arrow_len, 0)
can.closepath()
elif style == 1:
depth = head_len / 2.5
can.moveto(base - depth, -halfthickness)
can.lineto(base, 0)
can.lineto(base - depth, halfthickness)
can.lineto(arrow_len, 0)
can.closepath()
elif style == 2:
can.moveto(base + head_len/2.0, 0)
can.path_arc(base + head_len / 2.0, 0, head_len / 2.0, 1.0, 0, 400)
elif style == 3:
can.moveto(base, 0)
can.lineto(base + head_len/2.0, -halfthickness)
can.lineto(arrow_len, 0)
can.lineto(base + head_len/2.0, halfthickness)
can.closepath()
else:
raise Exception, "Arrow style must be a number between 0 and 3."
can.fill()
can.pop_transformation()
can.comment("end ARROWHEAD.\n")
def draw_arrowbody(can, tailx, taily, tipx, tipy, head_len):
dx = tipx - tailx
dy = tipy - taily
arrow_len = math.sqrt(dx*dx + dy*dy)
angle = math.atan2(dy, dx) * 360 / (2*math.pi)
base = arrow_len - head_len
can.push_transformation((tailx, taily), None, angle)
can.moveto(0, 0)
can.lineto(base+head_len*0.1, 0)
can.stroke()
can.pop_transformation()
class T(chart_object.T):
__doc__ = arrow_doc.doc
keys = {
"thickness" : (UnitType, 4,
"The width of the arrow head."),
"head_len": (UnitType, 8,
"The length of the arrow head."),
"head_color": (color.T, color.default,
"The color of the arrow head."),
"line_style": (line_style.T, line_style.default,
"Line style."),
"head_style": (IntType, 1,
"The value of 0 draws a triangular arrow head. The value of 1 draws a swallow-tail arrow head. The value of 2 draws a circular head. The value of 3 draws a diamond-shaped head.")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, points, can = None):
"""Parameter <points> specifies the
list of points the arrow traverses through.
It should contain at least two points, i.e.,
the tail and tip. Parameter
<can> is an optional parameter that specifies the output.
<<canvas>>
"""
if can == None: can = canvas.default_canvas()
self.type_check()
xtip = points[-1][0]
ytip = points[-1][1]
xtail = points[-2][0]
ytail = points[-2][1]
can.newpath()
can.set_line_style(self.line_style)
if len(points) > 2:
can.moveto(points[0][0], points[0][1])
for i in range(1, len(points)-1):
can.lineto(points[i][0], points[i][1])
draw_arrowbody(can, xscale(xtail), yscale(ytail),
yscale(xtip), yscale(ytip),
nscale(self.head_len))
can.set_fill_color(self.head_color)
draw_arrowhead(can, xscale(xtail), yscale(ytail),
xscale(xtip), yscale(ytip),
nscale(self.thickness),
nscale(self.head_len),
self.head_style)
can.setbb(xtail, ytail)
can.setbb(xtip, ytip)
standards = object_set.T()
def _intern(a):
global standards
standards.add(a)
return a
a0 = _intern(T(head_style=0))
a1 = _intern(T(head_style=1))
a2 = _intern(T(head_style=2))
a3 = _intern(T(head_style=3))
gray0 = _intern(T(head_style=0, head_color = color.gray50,
line_style=line_style.T(color=color.gray50)))
gray1 = _intern(T(head_style=1, head_color = color.gray50,
line_style=line_style.T(color=color.gray50)))
gray2 = _intern(T(head_style=2, head_color = color.gray50,
line_style=line_style.T(color=color.gray50)))
gray3 = _intern(T(head_style=3, head_color = color.gray50,
line_style=line_style.T(color=color.gray50)))
fat0 = _intern(T(head_style=0, head_len=12, thickness=10, line_style=line_style.T(width=2)))
fat1 = _intern(T(head_style=1, head_len=12, thickness=10, line_style=line_style.T(width=2)))
fat2 = _intern(T(head_style=2, head_len=12, thickness=10, line_style=line_style.T(width=2)))
fat3 = _intern(T(head_style=3, head_len=12, thickness=10, line_style=line_style.T(width=2)))
fatgray0 = _intern(T(head_style=0, head_len=12, thickness=10,
head_color = color.gray50,
line_style=line_style.T(width=2, color=color.gray50)))
fatgray1 = _intern(T(head_style=1, head_len=12, thickness=10,
head_color = color.gray50,
line_style=line_style.T(width=2, color=color.gray50)))
fatgray2 = _intern(T(head_style=2, head_len=12, thickness=10,
head_color = color.gray50,
line_style=line_style.T(width=2, color=color.gray50)))
fatgray3 = _intern(T(head_style=3, head_len=12, thickness=10,
head_color = color.gray50,
line_style=line_style.T(width=2, color=color.gray50)))
default = a1

View File

@ -1,10 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
head_color(type:color.T) default="The color of the arrow head.".
head_style(type:int) default="The value of 0 draws a triangular arrow head. The value of 1 draws a swallow-tail arrow head. The value of 2 draws a circular head. The value of 3 draws a diamond-shaped head.".
head_len(type:length in points (\\xref{unit})) default="The length of the arrow head.".
line_style(type:line_style.T) default="Line style.".
thickness(type:length in points (\\xref{unit})) default="The width of the arrow head.".
"""

View File

@ -1,242 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import font
import pychart_util
import chart_object
import line_style
import math
import theme
import axis_doc
from pychart_types import *
from types import *
class T(chart_object.T):
keys = {
"tic_interval" : (IntervalType, None,
pychart_util.interval_desc("tick marks")),
"tic_len" : (UnitType, 6, """The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis."""),
"minor_tic_interval" : (IntervalType, None,
pychart_util.interval_desc("minor tick marks")),
"minor_tic_len" : (UnitType, 3, """The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis."""),
"line_style": (line_style.T, line_style.default,
"Specifies the style of axis and tick lines."),
"label": (types.StringType, "axis label",
"The descriptive string displayed below (or to the left of) the axis. <<font>>."),
"format": (FormatType, "%s",
"""The format string for tick labels.
It can be a `printf' style format string, or
a single-parameter function that takes an X (or Y) value
and returns a string. """ +
pychart_util.string_desc),
"label_offset": (CoordOrNoneType, (None,None),
"""The location for drawing the axis label,
relative to the middle point of the axis.
If the value is None, the label is displayed
below (or to the left of) of axis at the middle."""),
"tic_label_offset": (CoordType, (0,0),
"""The location for drawing tick labels,
relative to the tip of the tick line."""),
"offset": (UnitType, 0,
"""The location of the axis.
The value of 0 draws the
axis at the left (for the Y axis) or bottom (for the X axis)
edge of the drawing area.
""")
}
class X(T):
keys = pychart_util.union_dict(T.keys,
{"draw_tics_above": (IntType, 0,
"If true, tick lines and labels are drawn above the axis line.")})
__doc__ = axis_doc.doc_x
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw_below(self, ar, can):
self.type_check()
self.tic_interval = self.tic_interval or ar.x_grid_interval
y_base = ar.loc[1] + self.offset
can.line(self.line_style, ar.loc[0], y_base,
ar.loc[0]+ ar.size[0], y_base)
tic_dic = {}
max_tic_height = 0
for i in ar.x_tic_points(self.tic_interval):
tic_dic[i] = 1
ticx = ar.x_pos(i)
str = "/hC" + pychart_util.apply_format(self.format, (i, ), 0)
(total_height, base_height) = font.text_height(str)
max_tic_height = max(max_tic_height, total_height)
can.line(self.line_style, ticx, y_base, ticx, y_base-self.tic_len)
can.show(ticx+self.tic_label_offset[0],
y_base-self.tic_len-base_height+self.tic_label_offset[1],
str)
if self.minor_tic_interval:
for i in ar.x_tic_points(self.minor_tic_interval):
if tic_dic.has_key(i):
# a major tic was drawn already.
pass
else:
ticx = ar.x_pos(i)
can.line(self.line_style, ticx, y_base, ticx,
y_base-self.minor_tic_len)
self.draw_label(ar, can, y_base - self.tic_len - max_tic_height - 10)
def draw_above(self, ar, can):
y_base = ar.loc[1] + self.offset
tic_dic = {}
max_tic_height = 0
for i in ar.x_tic_points(self.tic_interval):
tic_dic[i] = 1
ticx = ar.x_pos(i)
str = "/hC" + pychart_util.apply_format(self.format, (i, ), 0)
(total_height, base_height) = font.text_height(str)
max_tic_height = max(max_tic_height, total_height)
can.line(self.line_style, ticx, y_base, ticx, y_base + self.tic_len)
can.show(ticx+self.tic_label_offset[0],
y_base + self.tic_len + base_height + self.tic_label_offset[1],
str)
if self.minor_tic_interval:
for i in ar.x_tic_points(self.minor_tic_interval):
if tic_dic.has_key(i):
# a major tic was drawn already.
pass
else:
ticx = ar.x_pos(i)
can.line(self.line_style, ticx, y_base, ticx,
y_base + self.minor_tic_len)
self.draw_label(ar, can, y_base + self.tic_len + max_tic_height + 10)
def draw_label(self, ar, can, ylabel):
if self.label == None: return
str = "/hC/vM" + self.label
(label_height, base_height) = font.text_height(str)
xlabel = ar.loc[0] + ar.size[0]/2.0
if self.label_offset[0] != None:
xlabel += self.label_offset[0]
if self.label_offset[1] != None:
ylabel += self.label_offset[1]
can.show(xlabel, ylabel, str)
def draw(self, ar, can):
self.type_check()
self.tic_interval = self.tic_interval or ar.x_grid_interval
y_base = ar.loc[1] + self.offset
can.line(self.line_style, ar.loc[0], y_base,
ar.loc[0]+ ar.size[0], y_base)
if self.draw_tics_above:
self.draw_above(ar, can)
else:
self.draw_below(ar, can)
class Y(T):
__doc__ = axis_doc.doc_y
keys = pychart_util.union_dict(T.keys,
{"draw_tics_right": (IntType, 0,
"If true, tick lines and labels are drawn right of the axis line.")})
def draw_left(self, ar, can):
x_base = ar.loc[0] + self.offset
xmin = 999999
tic_dic = {}
for i in ar.y_tic_points(self.tic_interval):
y_tic = ar.y_pos(i)
tic_dic[i] = 1
can.line(self.line_style, x_base, y_tic,
x_base - self.tic_len, y_tic)
str = pychart_util.apply_format(self.format, (i,), 0)
if self.tic_len > 0: str = "/hR" + str
tic_height, base_height = font.text_height(str)
x = x_base - self.tic_len + self.tic_label_offset[0]
can.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1],
str)
xmin = min(xmin, x - font.text_width(str))
if self.minor_tic_interval:
for i in ar.y_tic_points(self.minor_tic_interval):
if tic_dic.has_key(i):
# a major tic line was drawn already.
pass
else:
y_tic = ar.y_pos(i)
can.line(self.line_style, x_base, y_tic,
x_base - self.minor_tic_len, y_tic)
self.draw_label(ar, can, xmin - theme.default_font_size/2.0)
def draw_right(self, ar, can):
x_base = ar.loc[0] + self.offset
xmax = 0
tic_dic = {}
for i in ar.y_tic_points(self.tic_interval):
y_tic = ar.y_pos(i)
tic_dic[i] = 1
can.line(self.line_style, x_base, y_tic,
x_base + self.tic_len, y_tic)
str = pychart_util.apply_format(self.format, (i,), 0)
if self.tic_len > 0: str = "/hL" + str
tic_height, base_height = font.text_height(str)
x = x_base + self.tic_len + self.tic_label_offset[0]
can.show(x, y_tic - tic_height/2.0 + self.tic_label_offset[1],
str)
xmax = max(xmax, x + font.text_width(str))
if self.minor_tic_interval:
for i in ar.y_tic_points(self.minor_tic_interval):
if tic_dic.has_key(i):
# a major tic line was drawn already.
pass
else:
y_tic = ar.y_pos(i)
can.line(self.line_style, x_base, y_tic,
x_base + self.minor_tic_len, y_tic)
self.draw_label(ar, can, xmax + theme.default_font_size)
def draw_label(self, ar, can, xlabel):
if self.label == None:
return
ylabel = ar.loc[1] + ar.size[1] / 2
if self.label_offset[0] != None:
xlabel += self.label_offset[0]
if self.label_offset[1] != None:
ylabel += self.label_offset[1]
can.show(xlabel, ylabel, "/a90/hC" + self.label)
def draw(self, ar, can):
self.type_check()
self.tic_interval = self.tic_interval or ar.y_grid_interval
x_base = ar.loc[0] + self.offset
can.line(self.line_style, x_base, ar.loc[1], x_base, ar.loc[1]+ar.size[1])
if self.draw_tics_right:
self.draw_right(ar, can)
else:
self.draw_left(ar, can)

View File

@ -1,54 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc_x="""Attributes supported by this class are:
draw_tics_above(type:int) default="If true, tick lines and labels are drawn above the axis line.".
minor_tic_len(type:length in points (\\xref{unit})) default="The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.".
tic_label_offset(type:(x,y)) default="The location for drawing tick labels,
relative to the tip of the tick line.".
format(type:printf format string) default="The format string for tick labels.
It can be a `printf' style format string, or
a single-parameter function that takes an X (or Y) value
and returns a string. The appearance of the string produced here can be
controlled using escape sequences. <<font>>".
label_offset(type:(x,y) or None) default="The location for drawing the axis label,
relative to the middle point of the axis.
If the value is None, the label is displayed
below (or to the left of) of axis at the middle.".
label(type:str) default="The descriptive string displayed below (or to the left of) the axis. <<font>>.".
offset(type:length in points (\\xref{unit})) default="The location of the axis.
The value of 0 draws the
axis at the left (for the Y axis) or bottom (for the X axis)
edge of the drawing area.
".
tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which tick marks are drawn.".
line_style(type:line_style.T) default="Specifies the style of axis and tick lines.".
tic_len(type:length in points (\\xref{unit})) default="The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.".
minor_tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which minor tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which minor tick marks are drawn.".
"""
doc_y="""Attributes supported by this class are:
draw_tics_right(type:int) default="If true, tick lines and labels are drawn right of the axis line.".
minor_tic_len(type:length in points (\\xref{unit})) default="The length of minor tick marks. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.".
tic_label_offset(type:(x,y)) default="The location for drawing tick labels,
relative to the tip of the tick line.".
format(type:printf format string) default="The format string for tick labels.
It can be a `printf' style format string, or
a single-parameter function that takes an X (or Y) value
and returns a string. The appearance of the string produced here can be
controlled using escape sequences. <<font>>".
label_offset(type:(x,y) or None) default="The location for drawing the axis label,
relative to the middle point of the axis.
If the value is None, the label is displayed
below (or to the left of) of axis at the middle.".
label(type:str) default="The descriptive string displayed below (or to the left of) the axis. <<font>>.".
offset(type:length in points (\\xref{unit})) default="The location of the axis.
The value of 0 draws the
axis at the left (for the Y axis) or bottom (for the X axis)
edge of the drawing area.
".
tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which tick marks are drawn.".
line_style(type:line_style.T) default="Specifies the style of axis and tick lines.".
tic_len(type:length in points (\\xref{unit})) default="The length of tick lines. The value can be negative, in which case the tick lines are drawn right of (or above) the axis.".
minor_tic_interval(type:Number or function) default="When the value is a number, it specifies the interval at which minor tick marks are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which minor tick marks are drawn.".
"""

View File

@ -1,66 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
doc="""Attributes supported by this class are:
tic_label_offset(type:(x,y)):
The location where the tick labels is drawn. Relative to the
tip of the tick mark.
default value=(0, 0).
format(type:printf format string):
The format string for tick labels. It can be a `printf' style
format string, or a single-parameter function that returns a
string. See also font.
default value=%s.
minor_tic_len(type:number):
The length of minor tick marks.
default value=3.
label_offset(type:(x,y) or None):
The location where the axis label is drawn. Relative to the
left-bottom corner of the axis.
default value=(None, None).
grid_interval(type:Number or function):
When the value is a number, it specifies the interval with which
grid lines are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where grid lines are drawn.
default value=None.
label(type:str):
The description of the axis. See also font.
default value=axis label.
grid_style(type:line_style.T):
The style of grid lines.
default value=None.
tic_interval(type:Number or function):
When the value is a number, it specifies the interval with which
tick marks are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where tick marks are drawn.
default value=None.
line_style(type:line_style.T):
The style of tick lines.
default value=default.
tic_len(type:number):
The length of tick lines
default value=6.
minor_tic_interval(type:Number or function):
When the value is a number, it specifies the interval with which
minor tick marks are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where minor tick marks are drawn.
default value=None.
first_tic_value(type:number):
The location of the first tick mark. Defaults to the x_range[0]
(or y_range[0]) of the area.
default value=None.
"""

View File

@ -1,66 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
doc="""Attributes supported by this class are:
minor_tic_len(type:number):
The length of minor tick marks.
default value=3.
tic_label_offset(type:(x,y)):
The location where the tick labels is drawn. Relative to the
tip of the tick mark.
default value=(0, 0).
format(type:printf format string):
The format string for tick labels. It can be a `printf' style
format string, or a single-parameter function that returns a
string. See also font.
default value=%s.
label_offset(type:(x,y) or None):
The location where the axis label is drawn. Relative to the
left-bottom corner of the axis.
default value=(None, None).
grid_interval(type:Number or function):
When the value is a number, it specifies the interval with which
grid lines are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where grid lines are drawn.
default value=None.
tic_len(type:number):
The length of tick lines
default value=6.
grid_style(type:line_style.T):
default value=gray70dash3.
tic_interval(type:Number or function):
When the value is a number, it specifies the interval with which
tick marks are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where tick marks are drawn.
default value=None.
line_style(type:line_style.T):
The style of tick lines.
default value=default.
label(type:str):
The description of the axis. See also font.
default value=axis label.
minor_tic_interval(type:Number or function):
When the value is a number, it specifies the interval with which
minor tick marks are drawn. Otherwise, the value must be a function.
It must take no argument and return the list of numbers, which
specifies the X or Y points where minor tick marks are drawn.
default value=None.
first_tic_value(type:number):
The location of the first tick mark. Defaults to the x_range[0]
(or y_range[0]) of the area.
default value=None.
"""

View File

@ -1,269 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import line_style
import fill_style
import pychart_util
import chart_object
import legend
import error_bar
import bar_plot_doc
import theme
from types import *
from pychart_types import *
fill_styles = None
_keys = {
"direction" : (StringType, "vertical",
"""The direction the growth of the bars. The value is either 'horizontal'
or 'vertical'."""),
"data" : (AnyType, None, pychart_util.data_desc),
"data_label_offset": (CoordType, (0, 5),
"The location of data labels relative to the sample point. See also attribute data_label_format."),
"data_label_format": (FormatType, None, """The
format string for the label displayed besides each
bar. It can be a `printf' style format
string, or a two-parameter function that
takes (x,y) values and returns a string. """
+ pychart_util.string_desc),
"label": (StringType, "???", pychart_util.label_desc),
"bcol" : (IntType, 0,
"""Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted.
The
combination of "data", "bcol", and "hcol" attributes defines
the set of boxes drawn by this chart. See the
below example:
@example
d = [[5,10], [7,22], [8,25]]
p = bar_plot.T(data = d, bcol = 1, hcol = 2)
@end example
Here, three bars will be drawn. The X values of the bars
will be 5, 7, and 8. The Y values of the bars will be
10, 22, and 25, respectively. (In practice, because
the values of bcol and hcol defaults to 1 and 2, you can
write the above example just as "p = bar_plot.T(data = d)".
"""),
"hcol": (IntType, 1,
"""The column from which the height of each bar is extracted.
See also the description of the 'bcol' attribute."""),
"line_style": (line_style.T, line_style.default,
"The style of the outer frame of each box."),
"fill_style": (fill_style.T, lambda: fill_styles.next(),
"Defines the fill style of each box.",
"The style is picked from standard styles round-robin."),
"legend_line_style": (line_style.T, None,
"""The line style used to draw a legend entry. Usually, the value is None, meaning that the value of "line_style" attribute is used."""),
"legend_fill_style": (fill_style.T, None,
"""The fill style used to draw a legend entry. Usually, the value is None, meaning that the value of "fill_style" attribute is used."""),
"cluster": (TupleType, (0, 1), """This attribute is used to
cluster multiple bar plots side by side in a single chart.
The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1
(where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example:
@example
a = area.T(...)
p1 = bar_plot.T(data = [[1,20][2,30]], cluster=(0,2))
p2 = bar_plot.T(data = [[1,25],[2,10]], cluster=(1,2))
a.add_plot(p1, p2)
a.draw()
@end example
In this example, one group of bars will be drawn side-by-side at
position x=1, one with height 20, the other with height 25. The
other two bars will be drawn side by side at position x=2, one
with height 30 and the other with height 10.
"""),
"width": (UnitType, 5, """Width of each box.
@cindex width, bar chart
@cindex size, bar chart
"""),
"cluster_sep": (UnitType, 0, """The separation between
clustered boxes."""),
"stack_on": (AnyType, None,
"The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot."),
"error_minus_col": (IntType, -1,
"""Specifies the column from which the depth of the errorbar is extracted. This attribute is meaningful only when
error_bar != None.
"""),
"qerror_minus_col": (IntType, -1,
"""The depth of the "quartile" errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None. """),
"error_plus_col": (IntType, -1,
"""The depth of the errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None."""),
"qerror_plus_col": (IntType, -1,
"""The depth of the "quartile" errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None."""),
"error_bar": (error_bar.T, None,
"Specifies the style of the error bar. <<error_bar>>"),
"_abs_data" : (ListType, None,
"Used only internally."),
}
def find_bar_plot(ar, nth):
"Find the NTH barplot of the cluster in area AR."
for plot in ar.plots:
if isinstance(plot, T) and plot.cluster[0] == nth:
return plot
raise Exception, "The %dth bar plot in the cluster not found." % nth
class T(chart_object.T):
__doc__ = bar_plot_doc.doc
keys = _keys
def check_integrity(self):
self.type_check()
self.compute_abs_data()
def compute_abs_data(self):
if self._abs_data != None:
return
if self.stack_on == None:
self._abs_data = self.data
else:
n = []
for pair in self.data:
self.stack_on.compute_abs_data()
newpair = list(pair[:])
newpair[self.hcol] = self.stack_on.get_value(newpair[self.bcol]) + pair[self.hcol]
n.append(newpair)
self._abs_data = n
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def get_value(self, bval):
for pair in self._abs_data:
if pair[self.bcol] == bval:
return pair[self.hcol]
raise ValueError, str(bval) + ": can't find the xval"
def get_data_range(self, which):
if self.direction == 'vertical':
if which == 'X':
return pychart_util.get_data_range(self._abs_data, self.bcol)
else:
return pychart_util.get_data_range(self._abs_data, self.hcol)
else:
assert self.direction == 'horizontal'
if which == 'Y':
return pychart_util.get_data_range(self._abs_data, self.bcol)
else:
return pychart_util.get_data_range(self._abs_data, self.hcol)
def get_bar_width(self, ar, nth):
off = 0
for i in range(0, nth):
plot = find_bar_plot(ar, i)
off += plot.width + plot.cluster_sep
return off
def draw_vertical(self, ar, can):
for pair in self.data:
xval = pair[self.bcol]
yval = pychart_util.get_sample_val(pair, self.hcol)
if None in (xval, yval): continue
ybot = 0
if self.stack_on:
ybot = self.stack_on.get_value(xval)
yval += ybot
totalWidth = self.get_bar_width(ar, self.cluster[1])
firstX = ar.x_pos(xval) - totalWidth/2.0
thisX = firstX + self.get_bar_width(ar, self.cluster[0])
can.rectangle(self.line_style, self.fill_style,
thisX, ar.y_pos(ybot), thisX+self.width,
ar.y_pos(yval))
if self.error_bar:
plus = pair[self.error_minus_col or self.error_plus_col]
minus = pair[self.error_plus_col or self.error_minus_col]
qplus = 0
qminus = 0
if self.qerror_minus_col or self.qerror_plus_col:
qplus = pair[self.qerror_minus_col or self.qerror_plus_col]
qminus = pair[self.qerror_plus_col or self.qerror_minus_col]
if None not in (plus, minus, qplus, qminus):
self.error_bar.draw(can, (thisX+self.width/2.0, ar.y_pos(yval)),
ar.y_pos(yval - minus),
ar.y_pos(yval + plus),
ar.y_pos(yval - qminus),
ar.y_pos(yval + qplus))
if self.data_label_format:
can.show(thisX + self.width/2.0 + self.data_label_offset[0],
ar.y_pos(yval) + self.data_label_offset[1],
"/hC" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1))
def draw_horizontal(self, ar, can):
for pair in self.data:
yval = pair[self.bcol]
xval = pychart_util.get_sample_val(pair, self.hcol)
if None in (xval, yval): continue
xbot = 0
if self.stack_on:
xbot = self.stack_on.get_value(yval)
xval += xbot
totalWidth = self.get_bar_width(ar, self.cluster[1])
firstY = ar.y_pos(yval) - totalWidth/2.0
thisY = firstY + self.get_bar_width(ar, self.cluster[0])
can.rectangle(self.line_style, self.fill_style,
ar.x_pos(xbot), thisY,
ar.x_pos(xval), thisY+self.width)
if self.data_label_format:
can.show(ar.x_pos(xval) + self.data_label_offset[0],
thisY + self.width/2.0 + self.data_label_offset[1],
"/vM/hL" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1))
def get_legend_entry(self):
if self.label:
return legend.Entry(line_style=(self.legend_line_style or self.line_style),
fill_style=(self.legend_fill_style or self.fill_style),
label=self.label)
return None
def draw(self, ar, can):
self.type_check()
can.clip(ar.loc[0], ar.loc[1],
ar.loc[0] + ar.size[0], ar.loc[1] + ar.size[1])
if self.direction == "vertical":
self.draw_vertical(ar, can)
else:
self.draw_horizontal(ar, can)
can.endclip()
def init():
global fill_styles
fill_styles = fill_style.standards.iterate()
theme.add_reinitialization_hook(init)

View File

@ -1,80 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
cluster_sep(type:length in points (\\xref{unit})) default="The separation between
clustered boxes.".
error_plus_col(type:int) default="The depth of the errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None.".
direction(type:str) default="The direction the growth of the bars. The value is either 'horizontal'
or 'vertical'.".
legend_line_style(type:line_style.T) default="The line style used to draw a legend entry. Usually, the value is None, meaning that the value of "line_style" attribute is used.".
error_bar(type:error_bar.T) default="Specifies the style of the error bar. <<error_bar>>".
data_label_format(type:printf format string) default="The
format string for the label displayed besides each
bar. It can be a `printf' style format
string, or a two-parameter function that
takes (x,y) values and returns a string. The appearance of the string produced here can be
controlled using escape sequences. <<font>>".
width(type:length in points (\\xref{unit})) default="Width of each box.
@cindex width, bar chart
@cindex size, bar chart
".
bcol(type:int) default="Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted.
The
combination of "data", "bcol", and "hcol" attributes defines
the set of boxes drawn by this chart. See the
below example:
@example
d = [[5,10], [7,22], [8,25]]
p = bar_plot.T(data = d, bcol = 1, hcol = 2)
@end example
Here, three bars will be drawn. The X values of the bars
will be 5, 7, and 8. The Y values of the bars will be
10, 22, and 25, respectively. (In practice, because
the values of bcol and hcol defaults to 1 and 2, you can
write the above example just as "p = bar_plot.T(data = d)".
".
qerror_minus_col(type:int) default="The depth of the "quartile" errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None. ".
_abs_data(type:list) default="Used only internally.".
label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>".
cluster(type:tuple) default="This attribute is used to
cluster multiple bar plots side by side in a single chart.
The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1
(where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example:
@example
a = area.T(...)
p1 = bar_plot.T(data = [[1,20][2,30]], cluster=(0,2))
p2 = bar_plot.T(data = [[1,25],[2,10]], cluster=(1,2))
a.add_plot(p1, p2)
a.draw()
@end example
In this example, one group of bars will be drawn side-by-side at
position x=1, one with height 20, the other with height 25. The
other two bars will be drawn side by side at position x=2, one
with height 30 and the other with height 10.
".
hcol(type:int) default="The column from which the height of each bar is extracted.
See also the description of the 'bcol' attribute.".
stack_on(type:any) default="The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot.".
qerror_plus_col(type:int) default="The depth of the "quartile" errorbar is extracted from
this column in data. This attribute is meaningful only
when error_bar != None.".
data_label_offset(type:(x,y)) default="The location of data labels relative to the sample point. See also attribute data_label_format.".
fill_style(type:fill_style.T) default="Defines the fill style of each box.".
The style is picked from standard styles round-robin.
data(type:any) default="Specifies the data points. <<chart_data>>".
line_style(type:line_style.T) default="The style of the outer frame of each box.".
legend_fill_style(type:fill_style.T) default="The fill style used to draw a legend entry. Usually, the value is None, meaning that the value of "fill_style" attribute is used.".
error_minus_col(type:int) default="Specifies the column from which the depth of the errorbar is extracted. This attribute is meaningful only when
error_bar != None.
".
"""

View File

@ -1,506 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import math
import sys
import time
import re
import font
import pychart_util
import version
from scaling import *
def _compute_bounding_box(points):
"""Given the list of coordinates (x,y), this procedure computes
the smallest rectangle that covers all the points."""
(xmin, ymin, xmax, ymax) = (999999, 999999, -999999, -999999)
for p in points:
xmin = min(xmin, p[0])
xmax = max(xmax, p[0])
ymin = min(ymin, p[1])
ymax = max(ymax, p[1])
return (xmin, ymin, xmax, ymax)
def _intersect_box(b1, b2):
xmin = max(b1[0], b2[0])
ymin = max(b1[1], b2[1])
xmax = min(b1[2], b2[2])
ymax = min(b1[3], b2[3])
return (xmin, ymin, xmax, ymax)
def invisible_p(x, y):
"""Return true if the point (X, Y) is visible in the canvas."""
if x < -499999 or y < -499999:
return 1
return 0
def to_radian(deg):
return deg*2*math.pi / 360.0
def midpoint(p1, p2):
return ( (p1[0]+p2[0])/2.0, (p1[1]+p2[1])/2.0 )
active_canvases = []
InvalidCoord = 999999
class T(object):
def __init__(self):
global active_canvases
self.__xmax = -InvalidCoord
self.__xmin = InvalidCoord
self.__ymax = -InvalidCoord
self.__ymin = InvalidCoord
self.__clip_box = (-InvalidCoord, -InvalidCoord, InvalidCoord, InvalidCoord)
self.__clip_stack = []
self.__nr_gsave = 0
self.title = re.sub("(.*)\\.py$", "\\1", sys.argv[0])
self.creator = "pychart %s" % (version.version,)
self.creation_date = time.strftime("(%m/%d/%y) (%I:%M %p)")
self.aux_comments = ""
self.author = None
active_canvases.append(self)
def set_title(self, s):
"""Define the string to shown in EPS/PDF "Title" field. The default value is the name of the script that creates the EPS/PDF file."""
self.title = s
def set_creator(self, tag):
"""Define the string to be shown in EPS %%Creator or PDF Producer field. The default value is "pychart"."""
self.creator = tag
def set_creation_date(self, s):
"""Define the string to shown in EPS/PDF "CreationDate" field. Defalt value of this field is the current time."""
self.creation_date = s
def set_author(self, s):
"""Set the author string. Unless this method is called, the Author field is not output in EPS or PDF."""
self.author = s
def add_aux_comments(self, s):
"""Define an auxiliary comments to be output to the file, just after the required headers"""
self.aux_comments += s
def close(self):
"""This method closes the canvas and writes
contents to the associated file.
Calling this procedure is optional, because
Pychart calls this procedure for every open canvas on normal exit."""
for i in range(0, len(active_canvases)):
if active_canvases[i] == self:
del active_canvases[i]
return
def open_output(self, fname):
"""Open the output file FNAME. Returns tuple (FD, NEED_CLOSE),
where FD is a file (or file-like) object, and NEED_CLOSE is a
boolean flag that tells whether FD.close() should be called
after finishing writing to the file.
FNAME can be one of the three things:
(1) None, in which case (sys.stdout, False) is returned.
(2) A file-like object, in which case (fname, False) is returned.
(3) A string, in which case this procedure opens the file and returns
(fd, True)."""
if not fname:
return (sys.stdout, False)
elif isinstance(fname, str):
return (file(fname, "wb"), True)
else:
if not hasattr(fname, "write"):
raise Exception, "Expecting either a filename or a file-like object, but got %s" % fname
return (fname, False)
def setbb(self, x, y):
"""Call this method when point (X,Y) is to be drawn in the
canvas. This methods expands the bounding box to include
this point."""
self.__xmin = min(self.__xmin, max(x, self.__clip_box[0]))
self.__xmax = max(self.__xmax, min(x, self.__clip_box[2]))
self.__ymin = min(self.__ymin, max(y, self.__clip_box[1]))
self.__ymax = max(self.__ymax, min(y, self.__clip_box[3]))
def fill_with_pattern(self, pat, x1, y1, x2, y2):
if invisible_p(x2, y2): return
self.comment("FILL pat=%s (%d %d)-(%d %d)\n" % (pat, x1, y1, x2, y2))
self.set_fill_color(pat.bgcolor)
self._path_polygon([(x1, y1), (x1, y2), (x2, y2), (x2, y1)])
self.fill()
pat.draw(self, x1, y1, x2, y2)
self.comment("end FILL.\n")
def _path_polygon(self, points):
"Low-level polygon-drawing routine."
(xmin, ymin, xmax, ymax) = _compute_bounding_box(points)
if invisible_p(xmax, ymax):
return
self.setbb(xmin, ymin)
self.setbb(xmax, ymax)
self.newpath()
self.moveto(xscale(points[0][0]), yscale(points[0][1]))
for point in points[1:]:
self.lineto(xscale(point[0]), yscale(point[1]))
self.closepath()
def polygon(self, edge_style, pat, points, shadow = None):
"""Draw a polygon with EDGE_STYLE, fill with PAT, and the edges
POINTS. POINTS is a sequence of coordinates, e.g., ((10,10), (15,5),
(20,8)). SHADOW is either None or a tuple (XDELTA, YDELTA,
fillstyle). If non-null, a shadow of FILLSTYLE is drawn beneath
the polygon at the offset of (XDELTA, YDELTA)."""
if pat:
self.comment("POLYGON points=[%s] pat=[%s]"
% (str(points), str(pat)))
(xmin, ymin, xmax, ymax) = _compute_bounding_box(points)
if shadow:
xoff, yoff, shadow_pat = shadow
self.gsave()
self._path_polygon(map(lambda p, xoff=xoff, yoff=yoff: (p[0]+xoff, p[1]+yoff), points))
self.clip_sub()
self.fill_with_pattern(shadow_pat, xmin+xoff, ymin+yoff,
xmax+xoff, ymax+yoff)
self.grestore()
self.gsave()
self._path_polygon(points)
self.clip_sub()
self.fill_with_pattern(pat, xmin, ymin, xmax, ymax)
self.grestore()
if edge_style:
self.comment("POLYGON points=[%s] edge=[%s]"
% (str(points), str(edge_style)))
self.set_line_style(edge_style)
self._path_polygon(points)
self.stroke()
def set_background(self, pat, x1, y1, x2, y2):
xmax, xmin, ymax, ymin = self.__xmax, self.__xmin, self.__ymax, self.__ymin
self.rectangle(None, pat, x1, y1, x2, y2)
self.__xmax, self.__xmin, self.__ymax, self.__ymin = xmax, xmin, ymax, ymin
def rectangle(self, edge_style, pat, x1, y1, x2, y2, shadow = None):
"""Draw a rectangle with EDGE_STYLE, fill with PAT, and the
bounding box (X1, Y1, X2, Y2). SHADOW is either None or a
tuple (XDELTA, YDELTA, fillstyle). If non-null, a shadow of
FILLSTYLE is drawn beneath the polygon at the offset of
(XDELTA, YDELTA)."""
self.polygon(edge_style, pat, [(x1,y1), (x1,y2), (x2,y2), (x2, y1)],
shadow)
def _path_ellipsis(self, x, y, radius, ratio, start_angle, end_angle):
self.setbb(x - radius, y - radius*ratio)
self.setbb(x + radius, y + radius*ratio)
oradius = nscale(radius)
centerx, centery = xscale(x), yscale(y)
startx, starty = centerx+oradius * math.cos(to_radian(start_angle)), \
centery+oradius * math.sin(to_radian(start_angle))
self.moveto(centerx, centery)
if start_angle % 360 != end_angle % 360:
self.moveto(centerx, centery)
self.lineto(startx, starty)
else:
self.moveto(startx, starty)
self.path_arc(xscale(x), yscale(y), nscale(radius),
ratio, start_angle, end_angle)
self.closepath()
def ellipsis(self, line_style, pattern, x, y, radius, ratio = 1.0,
start_angle=0, end_angle=360, shadow=None):
"""Draw an ellipsis with line_style and fill PATTERN. The center is \
(X, Y), X radius is RADIUS, and Y radius is RADIUS*RATIO, whose \
default value is 1.0. SHADOW is either None or a tuple (XDELTA,
YDELTA, fillstyle). If non-null, a shadow of FILLSTYLE is drawn
beneath the polygon at the offset of (XDELTA, YDELTA)."""
if invisible_p(x + radius, y + radius*ratio):
return
if pattern:
if shadow:
x_off, y_off, shadow_pat = shadow
self.gsave()
self.newpath()
self._path_ellipsis(x+x_off, y+y_off, radius, ratio,
start_angle, end_angle)
self.clip_sub()
self.fill_with_pattern(shadow_pat,
x-radius*2+x_off,
y-radius*ratio*2+y_off,
x+radius*2+x_off,
y+radius*ratio*2+y_off)
self.grestore()
self.gsave()
self.newpath()
self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle)
self.clip_sub()
self.fill_with_pattern(pattern,
(x-radius*2), (y-radius*ratio*2),
(x+radius*2), (y+radius*ratio*2))
self.grestore()
if line_style:
self.set_line_style(line_style)
self.newpath()
self._path_ellipsis(x, y, radius, ratio, start_angle, end_angle)
self.stroke()
def clip_ellipsis(self, x, y, radius, ratio = 1.0):
"""Create an elliptical clip region. You must call endclip() after
you completed drawing. See also the ellipsis method."""
self.gsave()
self.newpath()
self.moveto(xscale(x)+nscale(radius), yscale(y))
self.path_arc(xscale(x), yscale(y), nscale(radius), ratio, 0, 360)
self.closepath()
self.__clip_stack.append(self.__clip_box)
self.clip_sub()
def clip_polygon(self, points):
"""Create a polygonal clip region. You must call endclip() after
you completed drawing. See also the polygon method."""
self.gsave()
self._path_polygon(points)
self.__clip_stack.append(self.__clip_box)
self.__clip_box = _intersect_box(self.__clip_box, _compute_bounding_box(points))
self.clip_sub()
def clip(self, x1, y1, x2, y2):
"""Activate a rectangular clip region, (X1, Y1) - (X2, Y2).
You must call endclip() after you completed drawing.
canvas.clip(x,y,x2,y2)
draw something ...
canvas.endclip()
"""
self.__clip_stack.append(self.__clip_box)
self.__clip_box = _intersect_box(self.__clip_box, (x1, y1, x2, y2))
self.gsave()
self.newpath()
self.moveto(xscale(x1), yscale(y1))
self.lineto(xscale(x1), yscale(y2))
self.lineto(xscale(x2), yscale(y2))
self.lineto(xscale(x2), yscale(y1))
self.closepath()
self.clip_sub()
def endclip(self):
"""End the current clip region. When clip calls are nested, it
ends the most recently created crip region."""
self.__clip_box = self.__clip_stack[-1]
del self.__clip_stack[-1]
self.grestore()
def curve(self, style, points):
for p in points:
self.setbb(p[0], p[1])
self.newpath()
self.set_line_style(style)
self.moveto(xscale(points[0][0]), xscale(points[0][1]))
i = 1
n = 1
while i < len(points):
if n == 1:
x2 = points[i]
n += 1
elif n == 2:
x3 = points[i]
n += 1
elif n == 3:
x4 = midpoint(x3, points[i])
self.curveto(xscale(x2[0]), xscale(x2[1]),
xscale(x3[0]), xscale(x3[1]),
xscale(x4[0]), xscale(x4[1]))
n = 1
i += 1
if n == 1:
pass
if n == 2:
self.lineto(xscale(x2[0]), xscale(x2[1]))
if n == 3:
self.curveto(xscale(x2[0]), xscale(x2[1]),
xscale(x2[0]), xscale(x2[1]),
xscale(x3[0]), xscale(x3[1]))
self.stroke()
def line(self, style, x1, y1, x2, y2):
if not style:
return
if invisible_p(x2, y2) and invisible_p(x1, y1):
return
self.setbb(x1, y1)
self.setbb(x2, y2)
self.newpath()
self.set_line_style(style)
self.moveto(xscale(x1), yscale(y1))
self.lineto(xscale(x2), yscale(y2))
self.stroke()
def lines(self, style, segments):
if not style:
return
(xmin, ymin, xmax, ymax) = _compute_bounding_box(segments)
if invisible_p(xmax, ymax):
return
self.setbb(xmin, ymin)
self.setbb(xmax, ymax)
self.newpath()
self.set_line_style(style)
self.moveto(xscale(segments[0][0]), xscale(segments[0][1]))
for i in range(1, len(segments)):
self.lineto(xscale(segments[i][0]), yscale(segments[i][1]))
self.stroke()
def _path_round_rectangle(self, x1, y1, x2, y2, radius):
self.moveto(xscale(x1 + radius), yscale(y1))
self.lineto(xscale(x2 - radius), yscale(y1))
self.path_arc(xscale(x2-radius), yscale(y1+radius), nscale(radius), 1, 270, 360)
self.lineto(xscale(x2), yscale(y2-radius))
self.path_arc(xscale(x2-radius), yscale(y2-radius), nscale(radius), 1, 0, 90)
self.lineto(xscale(x1+radius), yscale(y2))
self.path_arc(xscale(x1 + radius), yscale(y2 - radius), nscale(radius), 1, 90, 180)
self.lineto(xscale(x1), xscale(y1+radius))
self.path_arc(xscale(x1 + radius), yscale(y1 + radius), nscale(radius), 1, 180, 270)
def round_rectangle(self, style, fill, x1, y1, x2, y2, radius, shadow=None):
"""Draw a rectangle with rounded four corners. Parameter <radius> specifies the radius of each corner."""
if invisible_p(x2, y2):
return
self.setbb(x1, y1)
self.setbb(x2, y2)
if fill:
if shadow:
x_off, y_off, shadow_fill = shadow
self.gsave();
self.newpath()
self._path_round_rectangle(x1+x_off, y1+y_off, x2+x_off, y2+y_off,
radius)
self.closepath()
self.clip_sub()
self.fill_with_pattern(shadow_fill, x1+x_off, y1+y_off,
x2+x_off, y2+y_off)
self.grestore()
self.gsave();
self.newpath()
self._path_round_rectangle(x1, y1, x2, y2, radius)
self.closepath()
self.clip_sub()
self.fill_with_pattern(fill, x1, y1, x2, y2)
self.grestore()
if style:
self.set_line_style(style)
self.newpath()
self._path_round_rectangle(x1, y1, x2, y2, radius)
self.closepath()
self.stroke()
def show(self, x, y, str):
global out
y_org = y
org_str = str
if invisible_p(x, y):
return
(xmin, xmax, ymin, ymax) = font.get_dimension(str)
# rectangle(line_style.default, None, x+xmin, y+ymin, x+xmax, y+ymax)
# ellipsis(line_style.default, None, x, y, 1)
self.setbb(x+xmin, y+ymin)
self.setbb(x+xmax, y+ymax)
(halign, valign, angle) = font.get_align(str)
base_x = x
base_y = y
# Handle vertical alignment
if valign == "B":
y = font.unaligned_text_height(str)
elif valign == "T":
y = 0
elif valign == "M":
y = font.unaligned_text_height(str) / 2.0
(xmin, xmax, ymin, ymax) = font.get_dimension(org_str)
# print org_str, xmin, xmax, ymin, ymax, x, y_org, y
self.setbb(x+xmin, y_org+y+ymin)
self.setbb(x+xmax, y_org+y+ymax)
itr = font.text_iterator(None)
max_width = 0
lines = []
for line in str.split('\n'):
cur_width = 0
cur_height = 0
itr.reset(line)
strs = []
while 1:
elem = itr.next()
if not elem:
break
(font_name, size, line_height, color, _h, _v, _a, str) = elem
cur_width += font.line_width(font_name, size, str)
max_width = max(cur_width, max_width)
cur_height = max(cur_height, line_height)
# replace '(' -> '\(', ')' -> '\)' to make
# Postscript string parser happy.
str = str.replace("(", "\\(")
str = str.replace(")", "\\)")
strs.append((font_name, size, color, str))
lines.append((cur_width, cur_height, strs))
for line in lines:
cur_width, cur_height, strs = line
cur_y = y - cur_height
y = y - cur_height
self.comment("cury: %d hei %d str %s\n" % (cur_y, cur_height, strs))
if halign == 'C':
cur_x = -cur_width/2.0
elif halign == 'R':
cur_x = -cur_width
else:
cur_x = 0
rel_x, rel_y = pychart_util.rotate(cur_x, cur_y, angle)
self.text_begin()
self.text_moveto(xscale(base_x + rel_x),
yscale(base_y + rel_y), angle)
for segment in strs:
font_name, size, color, str = segment
self.text_show(font_name, nscale(size), color, str)
self.text_end()

View File

@ -1,124 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import basecanvas
import pscanvas
import pdfcanvas
import svgcanvas
import pngcanvas
import x11canvas
import theme
import re
invalid_coord = -999999
_oldexitfunc = None
T = basecanvas.T
def init(fname = None, format = None):
"""This is a "factory" procedure that creates a new canvas.T object.
Both parameters, <fname> and
<format>, are optional. Parameter <fname> specifies either the output
file name or a file object. Parameter <format>, if specified, defines the
file's format. Its value must be one of "ps", "pdf", "svg", "x11", or
"png".
When <fname> is omitted or is None, the output is sent to standard
output. When <format> is omitted, it is guessed from the <fname>'s
suffix; failing that, "ps" is selected."""
fname = fname or theme.output_file
format = format or theme.output_format
if format == None:
if not isinstance(fname, str):
format = "ps"
elif re.search("pdf$", fname):
format = "pdf"
elif re.search("png$", fname):
format = "png"
elif re.search("svg$", fname):
format = "svg"
else:
format = "ps"
if format == "ps":
can = pscanvas.T(fname)
elif format == "png":
can = pngcanvas.T(fname)
elif format == "x11":
can = x11canvas.T(fname)
elif format == "svg":
can = svgcanvas.T(fname)
else:
can = pdfcanvas.T(fname, theme.compress_output)
return can
def default_canvas():
if len(basecanvas.active_canvases) > 0:
return basecanvas.active_canvases[0]
else:
return init(None)
def _exit():
global _oldexitfunc, _active_canvases
for can in basecanvas.active_canvases[:]:
can.close()
if _oldexitfunc:
foo = _oldexitfunc
_oldexitfunc = None
foo()
#
# The following procedures are there just for backward compatibility.
#
def line(style, x1, y1, x2, y2):
default_canvas().line(style, x1, y1, x2, y2)
def curve(style, points):
default_canvas().curve(style, points)
def clip(x1, y1, x2, y2):
default_canvas().clip(x1, y1, x2, y2)
def endclip():
default_canvas().endclip()
def clip_polygon(points):
default_canvas().clip_polygon(points)
def clip_ellipsis(x, y, radius, ratio = 1.0):
default_canvas().clip_ellipsis(x, y, radius, ratio)
def ellipsis(line_style, pattern, x, y, radius, ratio = 1.0,
start_angle=0, end_angle=360, shadow=None):
default_canvas().ellipsis(line_style, pattern, x, y, radius, ratio,
start_angle, end_angle, shadow)
def rectangle(edge_style, pat, x1, y1, x2, y2, shadow = None):
default_canvas().rectangle(edge_style, pat, x1, y1, x2, y2, shadow)
def polygon(edge_style, pat, points, shadow = None):
default_canvas().polygon(edge_style, pat, points, shadow = None)
def close():
default_canvas().close()
def round_rectangle(style, fill, x1, y1, x2, y2, radius, shadow=None):
default_canvas().round_rectangle(style, fill, x1, y1, x2, y2, radius, shadow)
def show(x, y, str):
default_canvas().show(x, y, str)
if not vars(sys).has_key("exitfunc"):
sys.exitfunc = _exit
elif sys.exitfunc != _exit:
_oldexitfunc = sys.exitfunc
sys.exitfunc = _exit
#theme.add_reinitialization_hook(lambda: init(None))

View File

@ -1,48 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import coord
import canvas
class T(coord.T):
def __init__(self, data, col):
"""This attribute is meaningful only when x_coord_system ==
'category'. This attribute selects the column of
'x_category_data' from which X values are computed.
Meaningful only when x_coord_system == 'category'. This
attribute specifies the data-set from which the X values are
extracted. See also x_category_col."""
self.data = data
self.col = col
def get_canvas_pos(self, size, val, min, max):
i = 0.5
for v in self.data:
if v[self.col] == val:
return size * i / float(len(self.data))
i += 1
# the drawing area is clipped. So negative offset will make this plot
# invisible.
return canvas.invalid_coord;
def get_tics(self, min, max, interval):
tics = []
if interval == None: interval = 1
for i in range(0, len(self.data), interval):
tics.append(self.data[i][self.col])
return tics
#return map(lambda pair, self = self: pair[self.col], self.data)

View File

@ -1,388 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import pychart_util
import copy
import math
def _convert_item(v, typ, line):
if typ == "a":
try:
i = float(v)
except ValueError: # non-number
i = v
return i
elif typ == "d":
try:
return int(v)
except ValueError:
raise ValueError, "Can't convert %s to int; line=%s" % (v, line)
elif typ == "f":
try:
return float(v)
except ValueError:
raise ValueError, "Can't convert %s to float; line=%s" % (v, line)
elif typ == "s":
return v
else:
raise ValueError, "Unknown conversion type, type=%s; line=%s" % (typ,line)
def parse_line(line, delim):
if delim.find("%") < 0:
return [ _convert_item(item, "a", None) for item in line.split(delim) ]
data = []
idx = 0 # indexes delim
ch = 'f'
sep = ','
while idx < len(delim):
if delim[idx] != '%':
raise ValueError, "bad delimitor: '" + delim + "'"
ch = delim[idx+1]
idx += 2
sep = ""
while idx < len(delim) and delim[idx] != '%':
sep += delim[idx]
idx += 1
xx = line.split(sep, 1)
data.append(_convert_item(xx[0], ch, line))
if len(xx) >= 2:
line = xx[1]
else:
line = ""
break
if line != "":
for item in line.split(sep):
data.append(_convert_item(item, ch, line))
return data
def escape_string(str):
return str.replace("/", "//")
def extract_rows(data, *rows):
"""Extract rows specified in the argument list.
>>> chart_data.extract_rows([[10,20], [30,40], [50,60]], 1, 2)
[[30,40],[50,60]]
"""
try:
# for python 2.2
# return [data[r] for r in rows]
out = []
for r in rows:
out.append(data[r])
return out
except IndexError:
raise IndexError, "data=%s rows=%s" % (data, rows)
return out
def extract_columns(data, *cols):
"""Extract columns specified in the argument list.
>>> chart_data.extract_columns([[10,20], [30,40], [50,60]], 0)
[[10],[30],[50]]
"""
out = []
try:
# for python 2.2:
# return [ [r[c] for c in cols] for r in data]
for r in data:
col = []
for c in cols:
col.append(r[c])
out.append(col)
except IndexError:
raise IndexError, "data=%s col=%s" % (data, col)
return out
def moving_average(data, xcol, ycol, width):
"""Compute the moving average of YCOL'th column of each sample point
in DATA. In particular, for each element I in DATA,
this function extracts up to WIDTH*2+1 elements, consisting of
I itself, WIDTH elements before I, and WIDTH
elements after I. It then computes the mean of the YCOL'th
column of these elements, and it composes a two-element sample
consisting of XCOL'th element and the mean.
>>> data = [[10,20], [20,30], [30,50], [40,70], [50,5]]
... chart_data.moving_average(data, 0, 1, 1)
[(10, 25.0), (20, 33.333333333333336), (30, 50.0), (40, 41.666666666666664), (50, 37.5)]
The above value actually represents:
[(10, (20+30)/2), (20, (20+30+50)/3), (30, (30+50+70)/3),
(40, (50+70+5)/3), (50, (70+5)/2)]
"""
out = []
try:
for i in range(len(data)):
n = 0
total = 0
for j in range(i-width, i+width+1):
if j >= 0 and j < len(data):
total += data[j][ycol]
n += 1
out.append((data[i][xcol], float(total) / n))
except IndexError:
raise IndexError, "bad data: %s,xcol=%d,ycol=%d,width=%d" % (data,xcol,ycol,width)
return out
def filter(func, data):
"""Parameter <func> must be a single-argument
function that takes a sequence (i.e.,
a sample point) and returns a boolean. This procedure calls <func> on
each element in <data> and returns a list comprising elements for
which <func> returns True.
>>> data = [[1,5], [2,10], [3,13], [4,16]]
... chart_data.filter(lambda x: x[1] % 2 == 0, data)
[[2,10], [4,16]].
"""
out = []
for r in data:
if func(r):
out.append(r)
return out
def transform(func, data):
"""Apply <func> on each element in <data> and return the list
consisting of the return values from <func>.
>>> data = [[10,20], [30,40], [50,60]]
... chart_data.transform(lambda x: [x[0], x[1]+1], data)
[[10, 21], [30, 41], [50, 61]]
"""
out = []
for r in data:
out.append(func(r))
return out
def aggregate_rows(data, col):
out = copy.deepcopy(data)
total = 0
for r in out:
total += r[col]
r[col] = total
return out
def empty_line_p(s):
return s.strip() == ""
def fread_csv(fd, delim = ','):
"""This function is similar to read_csv, except that it reads from
an open file handle <fd>, or any object that provides method "readline".
fd = open("foo", "r")
data = chart_data.fread_csv(fd, ",") """
data = []
line = fd.readline()
while line != "":
if line[0] != '#' and not empty_line_p(line):
data.append(parse_line(line, delim))
line = fd.readline()
return data
def read_csv(path, delim = ','):
"""This function reads
comma-separated values from file <path>. Empty lines and lines
beginning with "#" are ignored. Parameter <delim> specifies how
a line is separated into values. If it does not contain the
letter "%", then <delim> marks the end of a value.
Otherwise, this function acts like scanf in C:
chart_data.read_csv("file", "%d,%s:%d")
Paramter <delim> currently supports
only three conversion format specifiers:
"d"(int), "f"(double), and "s"(string)."""
f = open(path)
data = fread_csv(f, delim)
f.close()
return data
def fwrite_csv(fd, data):
"""This function writes comma-separated <data> to <fd>. Parameter <fd> must be a file-like object
that supports the |write()| method."""
for v in data:
fd.write(",".join([str(x) for x in v]))
fd.write("\n")
def write_csv(path, data):
"""This function writes comma-separated values to <path>."""
fd = file(path, "w")
fwrite_csv(fd, data)
fd.close()
def read_str(delim = ',', *lines):
"""This function is similar to read_csv, but it reads data from the
list of <lines>.
fd = open("foo", "r")
data = chart_data.read_str(",", fd.readlines())"""
data = []
for line in lines:
com = parse_line(line, delim)
data.append(com)
return data
def func(f, xmin, xmax, step = None):
"""Create sample points from function <f>, which must be a
single-parameter function that returns a number (e.g., math.sin).
Parameters <xmin> and <xmax> specify the first and last X values, and
<step> specifies the sampling interval.
>>> chart_data.func(math.sin, 0, math.pi * 4, math.pi / 2)
[(0, 0.0), (1.5707963267948966, 1.0), (3.1415926535897931, 1.2246063538223773e-16), (4.7123889803846897, -1.0), (6.2831853071795862, -2.4492127076447545e-16), (7.8539816339744828, 1.0), (9.4247779607693793, 3.6738190614671318e-16), (10.995574287564276, -1.0)]
"""
data = []
x = xmin
if not step:
step = (xmax - xmin) / 100.0
while x < xmax:
data.append((x, f(x)))
x += step
return data
def _nr_data(data, col):
nr_data = 0
for d in data:
nr_data += d[col]
return nr_data
def median(data, freq_col=1):
"""Compute the median of the <freq_col>'th column of the values is <data>.
>>> chart_data.median([(10,20), (20,4), (30,5)], 0)
20
>>> chart_data.median([(10,20), (20,4), (30,5)], 1)
5.
"""
nr_data = _nr_data(data, freq_col)
median_idx = nr_data / 2
i = 0
for d in data:
i += d[freq_col]
if i >= median_idx:
return d
raise Exception, "??? median ???"
def cut_extremes(data, cutoff_percentage, freq_col=1):
nr_data = _nr_data(data, freq_col)
min_idx = nr_data * cutoff_percentage / 100.0
max_idx = nr_data * (100 - cutoff_percentage) / 100.0
r = []
i = 0
for d in data:
if i < min_idx:
if i + d[freq_col] >= min_idx:
x = copy.deepcopy(d)
x[freq_col] = x[freq_col] - (min_idx - i)
r.append(x)
i += d[freq_col]
continue
elif i + d[freq_col] >= max_idx:
if i < max_idx and i + d[freq_col] >= max_idx:
x = copy.deepcopy(d)
x[freq_col] = x[freq_col] - (max_idx - i)
r.append(x)
break
i += d[freq_col]
r.append(d)
return r
def mean(data, val_col, freq_col):
nr_data = 0
sum = 0
for d in data:
sum += d[val_col] * d[freq_col]
nr_data += d[freq_col]
if nr_data == 0:
raise IndexError, "data is empty"
return sum / float(nr_data)
def mean_samples(data, xcol, ycollist):
"""Create a sample list that contains
the mean of the original list.
>>> chart_data.mean_samples([ [1, 10, 15], [2, 5, 10], [3, 8, 33] ], 0, (1, 2))
[(1, 12.5), (2, 7.5), (3, 20.5)]
"""
out = []
numcol = len(ycollist)
try:
for elem in data:
v = 0
for col in ycollist:
v += elem[col]
out.append( (elem[xcol], float(v) / numcol) )
except IndexError:
raise IndexError, "bad data: %s,xcol=%d,ycollist=%s" % (data,xcol,ycollist)
return out
def stddev_samples(data, xcol, ycollist, delta = 1.0):
"""Create a sample list that contains the mean and standard deviation of the original list. Each element in the returned list contains following values: [MEAN, STDDEV, MEAN - STDDEV*delta, MEAN + STDDEV*delta].
>>> chart_data.stddev_samples([ [1, 10, 15, 12, 15], [2, 5, 10, 5, 10], [3, 32, 33, 35, 36], [4,16,66, 67, 68] ], 0, range(1,5))
[(1, 13.0, 2.1213203435596424, 10.878679656440358, 15.121320343559642), (2, 7.5, 2.5, 5.0, 10.0), (3, 34.0, 1.5811388300841898, 32.418861169915807, 35.581138830084193), (4, 54.25, 22.094965489902897, 32.155034510097103, 76.344965489902904)]
"""
out = []
numcol = len(ycollist)
try:
for elem in data:
total = 0
for col in ycollist:
total += elem[col]
mean = float(total) / numcol
variance = 0
for col in ycollist:
variance += (mean - elem[col]) ** 2
stddev = math.sqrt(variance / numcol) * delta
out.append( (elem[xcol], mean, stddev, mean-stddev, mean+stddev) )
except IndexError:
raise IndexError, "bad data: %s,xcol=%d,ycollist=%s" % (data,xcol,ycollist)
return out
def nearest_match(data, col, val):
min_delta = None
match = None
for d in data:
if min_delta == None or abs(d[col] - val) < min_delta:
min_delta = abs(d[col] - val)
match = d
pychart_util.warn("XXX ", match)
return match

View File

@ -1,74 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import pychart_types
import types
def _check_attr_types(obj, keys):
for attr in obj.__dict__.keys():
if not keys.has_key(attr):
raise Exception, "%s: unknown attribute '%s'" % (obj, attr)
typeval, default_value, docstring = keys[attr][0:3]
val = getattr(obj, attr)
if val == None or typeval == pychart_types.AnyType:
pass
elif isinstance(typeval, types.FunctionType):
# user-defined check procedure
error = apply(typeval, (val,))
if error != None:
raise Exception, "%s: %s for attribute '%s', but got '%s'" % (obj, error, attr, val)
elif 1:
try:
if isinstance(val, typeval):
pass
except:
raise Exception, "%s: Expecting type %s, but got %s (attr=%s, %s)" % (obj, typeval, val, attr, keys[attr])
else:
raise Exception, "%s: attribute '%s' expects type %s but found %s" % (obj, attr, typeval, val)
def set_defaults(cls, **dict):
validAttrs = getattr(cls, "keys")
for attr, val in dict.items():
if not validAttrs.has_key(attr):
raise Exception, "%s: unknown attribute %s." % (cls, attr)
tuple = list(validAttrs[attr])
# 0 : type
# 1: defaultValue
# 2: document
# 3: defaultValue document (optional)
tuple[1] = val
validAttrs[attr] = tuple
class T(object):
def init(self, args):
keys = self.keys
for attr, tuple in keys.items():
defaultVal = tuple[1]
if isinstance(defaultVal, types.FunctionType):
# if the value is procedure, use the result of the proc call
# as the default value
defaultVal = apply(defaultVal, ())
setattr(self, attr, defaultVal)
for key, val in args.items():
setattr(self, key, val)
_check_attr_types(self, keys)
def __init__(self, **args):
self.init(args)
def type_check(self):
_check_attr_types(self, self.keys)

View File

@ -1,612 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import chart_object
import object_set
import types
import theme
import pychart_util
import color_doc
from pychart_types import *
blackify_colors = 1
class T(chart_object.T):
__doc__ = color_doc.doc
keys={
"r" : (NumType, 0.0, "The intensity of red. The value is between 0 and 1."),
"g" : (NumType, 0.0, "The intensity of green. The value is between 0 and 1."),
"b" : (NumType, 0.0, "The intensity of blue. The value is between 0 and 1.")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def __str__(self):
s = name_table().lookup(self)
if s:
return s
if self.r == self.g and self.r == self.b:
return "<color:grayscale=%f>" % self.r
else:
return "<color:r=%f,g=%f,b=%f>" % (self.r, self.g, self.b)
standards = object_set.T()
def _intern(r,g,b):
c = T(r = r, g = g, b = b)
standards.add(c)
return c
def gray_scale(g):
"""Generate a grayscale color.T object. G=0 produces white, G=1.0
produces black."""
return T(r=g,g=g,b=g)
# generated automatically from rgb.txt
snow = _intern(r=1.000000,g=0.980392,b=0.980392)
ghostwhite = _intern(r=0.972549,g=0.972549,b=1.000000)
whitesmoke = _intern(r=0.960784,g=0.960784,b=0.960784)
gainsboro = _intern(r=0.862745,g=0.862745,b=0.862745)
floralwhite = _intern(r=1.000000,g=0.980392,b=0.941176)
oldlace = _intern(r=0.992157,g=0.960784,b=0.901961)
linen = _intern(r=0.980392,g=0.941176,b=0.901961)
antiquewhite = _intern(r=0.980392,g=0.921569,b=0.843137)
papayawhip = _intern(r=1.000000,g=0.937255,b=0.835294)
blanchedalmond = _intern(r=1.000000,g=0.921569,b=0.803922)
bisque = _intern(r=1.000000,g=0.894118,b=0.768627)
peachpuff = _intern(r=1.000000,g=0.854902,b=0.725490)
navajowhite = _intern(r=1.000000,g=0.870588,b=0.678431)
moccasin = _intern(r=1.000000,g=0.894118,b=0.709804)
cornsilk = _intern(r=1.000000,g=0.972549,b=0.862745)
ivory = _intern(r=1.000000,g=1.000000,b=0.941176)
lemonchiffon = _intern(r=1.000000,g=0.980392,b=0.803922)
seashell = _intern(r=1.000000,g=0.960784,b=0.933333)
honeydew = _intern(r=0.941176,g=1.000000,b=0.941176)
mintcream = _intern(r=0.960784,g=1.000000,b=0.980392)
azure = _intern(r=0.941176,g=1.000000,b=1.000000)
aliceblue = _intern(r=0.941176,g=0.972549,b=1.000000)
lavender = _intern(r=0.901961,g=0.901961,b=0.980392)
lavenderblush = _intern(r=1.000000,g=0.941176,b=0.960784)
mistyrose = _intern(r=1.000000,g=0.894118,b=0.882353)
white = _intern(r=1.000000,g=1.000000,b=1.000000)
black = _intern(r=0.000000,g=0.000000,b=0.000000)
darkslategray = _intern(r=0.184314,g=0.309804,b=0.309804)
dimgray = _intern(r=0.411765,g=0.411765,b=0.411765)
slategray = _intern(r=0.439216,g=0.501961,b=0.564706)
lightslategray = _intern(r=0.466667,g=0.533333,b=0.600000)
gray = _intern(r=0.745098,g=0.745098,b=0.745098)
lightgray = _intern(r=0.827451,g=0.827451,b=0.827451)
midnightblue = _intern(r=0.098039,g=0.098039,b=0.439216)
navy = _intern(r=0.000000,g=0.000000,b=0.501961)
navyblue = _intern(r=0.000000,g=0.000000,b=0.501961)
cornflowerblue = _intern(r=0.392157,g=0.584314,b=0.929412)
darkslateblue = _intern(r=0.282353,g=0.239216,b=0.545098)
slateblue = _intern(r=0.415686,g=0.352941,b=0.803922)
mediumslateblue = _intern(r=0.482353,g=0.407843,b=0.933333)
lightslateblue = _intern(r=0.517647,g=0.439216,b=1.000000)
mediumblue = _intern(r=0.000000,g=0.000000,b=0.803922)
royalblue = _intern(r=0.254902,g=0.411765,b=0.882353)
blue = _intern(r=0.000000,g=0.000000,b=1.000000)
dodgerblue = _intern(r=0.117647,g=0.564706,b=1.000000)
deepskyblue = _intern(r=0.000000,g=0.749020,b=1.000000)
skyblue = _intern(r=0.529412,g=0.807843,b=0.921569)
lightskyblue = _intern(r=0.529412,g=0.807843,b=0.980392)
steelblue = _intern(r=0.274510,g=0.509804,b=0.705882)
lightsteelblue = _intern(r=0.690196,g=0.768627,b=0.870588)
lightblue = _intern(r=0.678431,g=0.847059,b=0.901961)
powderblue = _intern(r=0.690196,g=0.878431,b=0.901961)
paleturquoise = _intern(r=0.686275,g=0.933333,b=0.933333)
darkturquoise = _intern(r=0.000000,g=0.807843,b=0.819608)
mediumturquoise = _intern(r=0.282353,g=0.819608,b=0.800000)
turquoise = _intern(r=0.250980,g=0.878431,b=0.815686)
cyan = _intern(r=0.000000,g=1.000000,b=1.000000)
lightcyan = _intern(r=0.878431,g=1.000000,b=1.000000)
cadetblue = _intern(r=0.372549,g=0.619608,b=0.627451)
mediumaquamarine = _intern(r=0.400000,g=0.803922,b=0.666667)
aquamarine = _intern(r=0.498039,g=1.000000,b=0.831373)
darkgreen = _intern(r=0.000000,g=0.392157,b=0.000000)
darkolivegreen = _intern(r=0.333333,g=0.419608,b=0.184314)
darkseagreen = _intern(r=0.560784,g=0.737255,b=0.560784)
seagreen = _intern(r=0.180392,g=0.545098,b=0.341176)
mediumseagreen = _intern(r=0.235294,g=0.701961,b=0.443137)
lightseagreen = _intern(r=0.125490,g=0.698039,b=0.666667)
palegreen = _intern(r=0.596078,g=0.984314,b=0.596078)
springgreen = _intern(r=0.000000,g=1.000000,b=0.498039)
lawngreen = _intern(r=0.486275,g=0.988235,b=0.000000)
green = _intern(r=0.000000,g=1.000000,b=0.000000)
chartreuse = _intern(r=0.498039,g=1.000000,b=0.000000)
mediumspringgreen = _intern(r=0.000000,g=0.980392,b=0.603922)
greenyellow = _intern(r=0.678431,g=1.000000,b=0.184314)
limegreen = _intern(r=0.196078,g=0.803922,b=0.196078)
yellowgreen = _intern(r=0.603922,g=0.803922,b=0.196078)
forestgreen = _intern(r=0.133333,g=0.545098,b=0.133333)
olivedrab = _intern(r=0.419608,g=0.556863,b=0.137255)
darkkhaki = _intern(r=0.741176,g=0.717647,b=0.419608)
khaki = _intern(r=0.941176,g=0.901961,b=0.549020)
palegoldenrod = _intern(r=0.933333,g=0.909804,b=0.666667)
lightgoldenrodyellow = _intern(r=0.980392,g=0.980392,b=0.823529)
lightyellow = _intern(r=1.000000,g=1.000000,b=0.878431)
yellow = _intern(r=1.000000,g=1.000000,b=0.000000)
gold = _intern(r=1.000000,g=0.843137,b=0.000000)
lightgoldenrod = _intern(r=0.933333,g=0.866667,b=0.509804)
goldenrod = _intern(r=0.854902,g=0.647059,b=0.125490)
darkgoldenrod = _intern(r=0.721569,g=0.525490,b=0.043137)
rosybrown = _intern(r=0.737255,g=0.560784,b=0.560784)
indianred = _intern(r=0.803922,g=0.360784,b=0.360784)
saddlebrown = _intern(r=0.545098,g=0.270588,b=0.074510)
sienna = _intern(r=0.627451,g=0.321569,b=0.176471)
peru = _intern(r=0.803922,g=0.521569,b=0.247059)
burlywood = _intern(r=0.870588,g=0.721569,b=0.529412)
beige = _intern(r=0.960784,g=0.960784,b=0.862745)
wheat = _intern(r=0.960784,g=0.870588,b=0.701961)
sandybrown = _intern(r=0.956863,g=0.643137,b=0.376471)
tan = _intern(r=0.823529,g=0.705882,b=0.549020)
chocolate = _intern(r=0.823529,g=0.411765,b=0.117647)
firebrick = _intern(r=0.698039,g=0.133333,b=0.133333)
brown = _intern(r=0.647059,g=0.164706,b=0.164706)
darksalmon = _intern(r=0.913725,g=0.588235,b=0.478431)
salmon = _intern(r=0.980392,g=0.501961,b=0.447059)
lightsalmon = _intern(r=1.000000,g=0.627451,b=0.478431)
orange = _intern(r=1.000000,g=0.647059,b=0.000000)
darkorange = _intern(r=1.000000,g=0.549020,b=0.000000)
coral = _intern(r=1.000000,g=0.498039,b=0.313725)
lightcoral = _intern(r=0.941176,g=0.501961,b=0.501961)
tomato = _intern(r=1.000000,g=0.388235,b=0.278431)
orangered = _intern(r=1.000000,g=0.270588,b=0.000000)
red = _intern(r=1.000000,g=0.000000,b=0.000000)
hotpink = _intern(r=1.000000,g=0.411765,b=0.705882)
deeppink = _intern(r=1.000000,g=0.078431,b=0.576471)
pink = _intern(r=1.000000,g=0.752941,b=0.796078)
lightpink = _intern(r=1.000000,g=0.713725,b=0.756863)
palevioletred = _intern(r=0.858824,g=0.439216,b=0.576471)
maroon = _intern(r=0.690196,g=0.188235,b=0.376471)
mediumvioletred = _intern(r=0.780392,g=0.082353,b=0.521569)
violetred = _intern(r=0.815686,g=0.125490,b=0.564706)
magenta = _intern(r=1.000000,g=0.000000,b=1.000000)
violet = _intern(r=0.933333,g=0.509804,b=0.933333)
plum = _intern(r=0.866667,g=0.627451,b=0.866667)
orchid = _intern(r=0.854902,g=0.439216,b=0.839216)
mediumorchid = _intern(r=0.729412,g=0.333333,b=0.827451)
darkorchid = _intern(r=0.600000,g=0.196078,b=0.800000)
darkviolet = _intern(r=0.580392,g=0.000000,b=0.827451)
blueviolet = _intern(r=0.541176,g=0.168627,b=0.886275)
purple = _intern(r=0.627451,g=0.125490,b=0.941176)
mediumpurple = _intern(r=0.576471,g=0.439216,b=0.858824)
thistle = _intern(r=0.847059,g=0.749020,b=0.847059)
snow1 = _intern(r=1.000000,g=0.980392,b=0.980392)
snow2 = _intern(r=0.933333,g=0.913725,b=0.913725)
snow3 = _intern(r=0.803922,g=0.788235,b=0.788235)
snow4 = _intern(r=0.545098,g=0.537255,b=0.537255)
seashell1 = _intern(r=1.000000,g=0.960784,b=0.933333)
seashell2 = _intern(r=0.933333,g=0.898039,b=0.870588)
seashell3 = _intern(r=0.803922,g=0.772549,b=0.749020)
seashell4 = _intern(r=0.545098,g=0.525490,b=0.509804)
antiquewhite1 = _intern(r=1.000000,g=0.937255,b=0.858824)
antiquewhite2 = _intern(r=0.933333,g=0.874510,b=0.800000)
antiquewhite3 = _intern(r=0.803922,g=0.752941,b=0.690196)
antiquewhite4 = _intern(r=0.545098,g=0.513725,b=0.470588)
bisque1 = _intern(r=1.000000,g=0.894118,b=0.768627)
bisque2 = _intern(r=0.933333,g=0.835294,b=0.717647)
bisque3 = _intern(r=0.803922,g=0.717647,b=0.619608)
bisque4 = _intern(r=0.545098,g=0.490196,b=0.419608)
peachpuff1 = _intern(r=1.000000,g=0.854902,b=0.725490)
peachpuff2 = _intern(r=0.933333,g=0.796078,b=0.678431)
peachpuff3 = _intern(r=0.803922,g=0.686275,b=0.584314)
peachpuff4 = _intern(r=0.545098,g=0.466667,b=0.396078)
navajowhite1 = _intern(r=1.000000,g=0.870588,b=0.678431)
navajowhite2 = _intern(r=0.933333,g=0.811765,b=0.631373)
navajowhite3 = _intern(r=0.803922,g=0.701961,b=0.545098)
navajowhite4 = _intern(r=0.545098,g=0.474510,b=0.368627)
lemonchiffon1 = _intern(r=1.000000,g=0.980392,b=0.803922)
lemonchiffon2 = _intern(r=0.933333,g=0.913725,b=0.749020)
lemonchiffon3 = _intern(r=0.803922,g=0.788235,b=0.647059)
lemonchiffon4 = _intern(r=0.545098,g=0.537255,b=0.439216)
cornsilk1 = _intern(r=1.000000,g=0.972549,b=0.862745)
cornsilk2 = _intern(r=0.933333,g=0.909804,b=0.803922)
cornsilk3 = _intern(r=0.803922,g=0.784314,b=0.694118)
cornsilk4 = _intern(r=0.545098,g=0.533333,b=0.470588)
ivory1 = _intern(r=1.000000,g=1.000000,b=0.941176)
ivory2 = _intern(r=0.933333,g=0.933333,b=0.878431)
ivory3 = _intern(r=0.803922,g=0.803922,b=0.756863)
ivory4 = _intern(r=0.545098,g=0.545098,b=0.513725)
honeydew1 = _intern(r=0.941176,g=1.000000,b=0.941176)
honeydew2 = _intern(r=0.878431,g=0.933333,b=0.878431)
honeydew3 = _intern(r=0.756863,g=0.803922,b=0.756863)
honeydew4 = _intern(r=0.513725,g=0.545098,b=0.513725)
lavenderblush1 = _intern(r=1.000000,g=0.941176,b=0.960784)
lavenderblush2 = _intern(r=0.933333,g=0.878431,b=0.898039)
lavenderblush3 = _intern(r=0.803922,g=0.756863,b=0.772549)
lavenderblush4 = _intern(r=0.545098,g=0.513725,b=0.525490)
mistyrose1 = _intern(r=1.000000,g=0.894118,b=0.882353)
mistyrose2 = _intern(r=0.933333,g=0.835294,b=0.823529)
mistyrose3 = _intern(r=0.803922,g=0.717647,b=0.709804)
mistyrose4 = _intern(r=0.545098,g=0.490196,b=0.482353)
azure1 = _intern(r=0.941176,g=1.000000,b=1.000000)
azure2 = _intern(r=0.878431,g=0.933333,b=0.933333)
azure3 = _intern(r=0.756863,g=0.803922,b=0.803922)
azure4 = _intern(r=0.513725,g=0.545098,b=0.545098)
slateblue1 = _intern(r=0.513725,g=0.435294,b=1.000000)
slateblue2 = _intern(r=0.478431,g=0.403922,b=0.933333)
slateblue3 = _intern(r=0.411765,g=0.349020,b=0.803922)
slateblue4 = _intern(r=0.278431,g=0.235294,b=0.545098)
royalblue1 = _intern(r=0.282353,g=0.462745,b=1.000000)
royalblue2 = _intern(r=0.262745,g=0.431373,b=0.933333)
royalblue3 = _intern(r=0.227451,g=0.372549,b=0.803922)
royalblue4 = _intern(r=0.152941,g=0.250980,b=0.545098)
blue1 = _intern(r=0.000000,g=0.000000,b=1.000000)
blue2 = _intern(r=0.000000,g=0.000000,b=0.933333)
blue3 = _intern(r=0.000000,g=0.000000,b=0.803922)
blue4 = _intern(r=0.000000,g=0.000000,b=0.545098)
dodgerblue1 = _intern(r=0.117647,g=0.564706,b=1.000000)
dodgerblue2 = _intern(r=0.109804,g=0.525490,b=0.933333)
dodgerblue3 = _intern(r=0.094118,g=0.454902,b=0.803922)
dodgerblue4 = _intern(r=0.062745,g=0.305882,b=0.545098)
steelblue1 = _intern(r=0.388235,g=0.721569,b=1.000000)
steelblue2 = _intern(r=0.360784,g=0.674510,b=0.933333)
steelblue3 = _intern(r=0.309804,g=0.580392,b=0.803922)
steelblue4 = _intern(r=0.211765,g=0.392157,b=0.545098)
deepskyblue1 = _intern(r=0.000000,g=0.749020,b=1.000000)
deepskyblue2 = _intern(r=0.000000,g=0.698039,b=0.933333)
deepskyblue3 = _intern(r=0.000000,g=0.603922,b=0.803922)
deepskyblue4 = _intern(r=0.000000,g=0.407843,b=0.545098)
skyblue1 = _intern(r=0.529412,g=0.807843,b=1.000000)
skyblue2 = _intern(r=0.494118,g=0.752941,b=0.933333)
skyblue3 = _intern(r=0.423529,g=0.650980,b=0.803922)
skyblue4 = _intern(r=0.290196,g=0.439216,b=0.545098)
lightskyblue1 = _intern(r=0.690196,g=0.886275,b=1.000000)
lightskyblue2 = _intern(r=0.643137,g=0.827451,b=0.933333)
lightskyblue3 = _intern(r=0.552941,g=0.713725,b=0.803922)
lightskyblue4 = _intern(r=0.376471,g=0.482353,b=0.545098)
slategray1 = _intern(r=0.776471,g=0.886275,b=1.000000)
slategray2 = _intern(r=0.725490,g=0.827451,b=0.933333)
slategray3 = _intern(r=0.623529,g=0.713725,b=0.803922)
slategray4 = _intern(r=0.423529,g=0.482353,b=0.545098)
lightsteelblue1 = _intern(r=0.792157,g=0.882353,b=1.000000)
lightsteelblue2 = _intern(r=0.737255,g=0.823529,b=0.933333)
lightsteelblue3 = _intern(r=0.635294,g=0.709804,b=0.803922)
lightsteelblue4 = _intern(r=0.431373,g=0.482353,b=0.545098)
lightblue1 = _intern(r=0.749020,g=0.937255,b=1.000000)
lightblue2 = _intern(r=0.698039,g=0.874510,b=0.933333)
lightblue3 = _intern(r=0.603922,g=0.752941,b=0.803922)
lightblue4 = _intern(r=0.407843,g=0.513725,b=0.545098)
lightcyan1 = _intern(r=0.878431,g=1.000000,b=1.000000)
lightcyan2 = _intern(r=0.819608,g=0.933333,b=0.933333)
lightcyan3 = _intern(r=0.705882,g=0.803922,b=0.803922)
lightcyan4 = _intern(r=0.478431,g=0.545098,b=0.545098)
paleturquoise1 = _intern(r=0.733333,g=1.000000,b=1.000000)
paleturquoise2 = _intern(r=0.682353,g=0.933333,b=0.933333)
paleturquoise3 = _intern(r=0.588235,g=0.803922,b=0.803922)
paleturquoise4 = _intern(r=0.400000,g=0.545098,b=0.545098)
cadetblue1 = _intern(r=0.596078,g=0.960784,b=1.000000)
cadetblue2 = _intern(r=0.556863,g=0.898039,b=0.933333)
cadetblue3 = _intern(r=0.478431,g=0.772549,b=0.803922)
cadetblue4 = _intern(r=0.325490,g=0.525490,b=0.545098)
turquoise1 = _intern(r=0.000000,g=0.960784,b=1.000000)
turquoise2 = _intern(r=0.000000,g=0.898039,b=0.933333)
turquoise3 = _intern(r=0.000000,g=0.772549,b=0.803922)
turquoise4 = _intern(r=0.000000,g=0.525490,b=0.545098)
cyan1 = _intern(r=0.000000,g=1.000000,b=1.000000)
cyan2 = _intern(r=0.000000,g=0.933333,b=0.933333)
cyan3 = _intern(r=0.000000,g=0.803922,b=0.803922)
cyan4 = _intern(r=0.000000,g=0.545098,b=0.545098)
darkslategray1 = _intern(r=0.592157,g=1.000000,b=1.000000)
darkslategray2 = _intern(r=0.552941,g=0.933333,b=0.933333)
darkslategray3 = _intern(r=0.474510,g=0.803922,b=0.803922)
darkslategray4 = _intern(r=0.321569,g=0.545098,b=0.545098)
aquamarine1 = _intern(r=0.498039,g=1.000000,b=0.831373)
aquamarine2 = _intern(r=0.462745,g=0.933333,b=0.776471)
aquamarine3 = _intern(r=0.400000,g=0.803922,b=0.666667)
aquamarine4 = _intern(r=0.270588,g=0.545098,b=0.454902)
darkseagreen1 = _intern(r=0.756863,g=1.000000,b=0.756863)
darkseagreen2 = _intern(r=0.705882,g=0.933333,b=0.705882)
darkseagreen3 = _intern(r=0.607843,g=0.803922,b=0.607843)
darkseagreen4 = _intern(r=0.411765,g=0.545098,b=0.411765)
seagreen1 = _intern(r=0.329412,g=1.000000,b=0.623529)
seagreen2 = _intern(r=0.305882,g=0.933333,b=0.580392)
seagreen3 = _intern(r=0.262745,g=0.803922,b=0.501961)
seagreen4 = _intern(r=0.180392,g=0.545098,b=0.341176)
palegreen1 = _intern(r=0.603922,g=1.000000,b=0.603922)
palegreen2 = _intern(r=0.564706,g=0.933333,b=0.564706)
palegreen3 = _intern(r=0.486275,g=0.803922,b=0.486275)
palegreen4 = _intern(r=0.329412,g=0.545098,b=0.329412)
springgreen1 = _intern(r=0.000000,g=1.000000,b=0.498039)
springgreen2 = _intern(r=0.000000,g=0.933333,b=0.462745)
springgreen3 = _intern(r=0.000000,g=0.803922,b=0.400000)
springgreen4 = _intern(r=0.000000,g=0.545098,b=0.270588)
green1 = _intern(r=0.000000,g=1.000000,b=0.000000)
green2 = _intern(r=0.000000,g=0.933333,b=0.000000)
green3 = _intern(r=0.000000,g=0.803922,b=0.000000)
green4 = _intern(r=0.000000,g=0.545098,b=0.000000)
chartreuse1 = _intern(r=0.498039,g=1.000000,b=0.000000)
chartreuse2 = _intern(r=0.462745,g=0.933333,b=0.000000)
chartreuse3 = _intern(r=0.400000,g=0.803922,b=0.000000)
chartreuse4 = _intern(r=0.270588,g=0.545098,b=0.000000)
olivedrab1 = _intern(r=0.752941,g=1.000000,b=0.243137)
olivedrab2 = _intern(r=0.701961,g=0.933333,b=0.227451)
olivedrab3 = _intern(r=0.603922,g=0.803922,b=0.196078)
olivedrab4 = _intern(r=0.411765,g=0.545098,b=0.133333)
darkolivegreen1 = _intern(r=0.792157,g=1.000000,b=0.439216)
darkolivegreen2 = _intern(r=0.737255,g=0.933333,b=0.407843)
darkolivegreen3 = _intern(r=0.635294,g=0.803922,b=0.352941)
darkolivegreen4 = _intern(r=0.431373,g=0.545098,b=0.239216)
khaki1 = _intern(r=1.000000,g=0.964706,b=0.560784)
khaki2 = _intern(r=0.933333,g=0.901961,b=0.521569)
khaki3 = _intern(r=0.803922,g=0.776471,b=0.450980)
khaki4 = _intern(r=0.545098,g=0.525490,b=0.305882)
lightgoldenrod1 = _intern(r=1.000000,g=0.925490,b=0.545098)
lightgoldenrod2 = _intern(r=0.933333,g=0.862745,b=0.509804)
lightgoldenrod3 = _intern(r=0.803922,g=0.745098,b=0.439216)
lightgoldenrod4 = _intern(r=0.545098,g=0.505882,b=0.298039)
lightyellow1 = _intern(r=1.000000,g=1.000000,b=0.878431)
lightyellow2 = _intern(r=0.933333,g=0.933333,b=0.819608)
lightyellow3 = _intern(r=0.803922,g=0.803922,b=0.705882)
lightyellow4 = _intern(r=0.545098,g=0.545098,b=0.478431)
yellow1 = _intern(r=1.000000,g=1.000000,b=0.000000)
yellow2 = _intern(r=0.933333,g=0.933333,b=0.000000)
yellow3 = _intern(r=0.803922,g=0.803922,b=0.000000)
yellow4 = _intern(r=0.545098,g=0.545098,b=0.000000)
gold1 = _intern(r=1.000000,g=0.843137,b=0.000000)
gold2 = _intern(r=0.933333,g=0.788235,b=0.000000)
gold3 = _intern(r=0.803922,g=0.678431,b=0.000000)
gold4 = _intern(r=0.545098,g=0.458824,b=0.000000)
goldenrod1 = _intern(r=1.000000,g=0.756863,b=0.145098)
goldenrod2 = _intern(r=0.933333,g=0.705882,b=0.133333)
goldenrod3 = _intern(r=0.803922,g=0.607843,b=0.113725)
goldenrod4 = _intern(r=0.545098,g=0.411765,b=0.078431)
darkgoldenrod1 = _intern(r=1.000000,g=0.725490,b=0.058824)
darkgoldenrod2 = _intern(r=0.933333,g=0.678431,b=0.054902)
darkgoldenrod3 = _intern(r=0.803922,g=0.584314,b=0.047059)
darkgoldenrod4 = _intern(r=0.545098,g=0.396078,b=0.031373)
rosybrown1 = _intern(r=1.000000,g=0.756863,b=0.756863)
rosybrown2 = _intern(r=0.933333,g=0.705882,b=0.705882)
rosybrown3 = _intern(r=0.803922,g=0.607843,b=0.607843)
rosybrown4 = _intern(r=0.545098,g=0.411765,b=0.411765)
indianred1 = _intern(r=1.000000,g=0.415686,b=0.415686)
indianred2 = _intern(r=0.933333,g=0.388235,b=0.388235)
indianred3 = _intern(r=0.803922,g=0.333333,b=0.333333)
indianred4 = _intern(r=0.545098,g=0.227451,b=0.227451)
sienna1 = _intern(r=1.000000,g=0.509804,b=0.278431)
sienna2 = _intern(r=0.933333,g=0.474510,b=0.258824)
sienna3 = _intern(r=0.803922,g=0.407843,b=0.223529)
sienna4 = _intern(r=0.545098,g=0.278431,b=0.149020)
burlywood1 = _intern(r=1.000000,g=0.827451,b=0.607843)
burlywood2 = _intern(r=0.933333,g=0.772549,b=0.568627)
burlywood3 = _intern(r=0.803922,g=0.666667,b=0.490196)
burlywood4 = _intern(r=0.545098,g=0.450980,b=0.333333)
wheat1 = _intern(r=1.000000,g=0.905882,b=0.729412)
wheat2 = _intern(r=0.933333,g=0.847059,b=0.682353)
wheat3 = _intern(r=0.803922,g=0.729412,b=0.588235)
wheat4 = _intern(r=0.545098,g=0.494118,b=0.400000)
tan1 = _intern(r=1.000000,g=0.647059,b=0.309804)
tan2 = _intern(r=0.933333,g=0.603922,b=0.286275)
tan3 = _intern(r=0.803922,g=0.521569,b=0.247059)
tan4 = _intern(r=0.545098,g=0.352941,b=0.168627)
chocolate1 = _intern(r=1.000000,g=0.498039,b=0.141176)
chocolate2 = _intern(r=0.933333,g=0.462745,b=0.129412)
chocolate3 = _intern(r=0.803922,g=0.400000,b=0.113725)
chocolate4 = _intern(r=0.545098,g=0.270588,b=0.074510)
firebrick1 = _intern(r=1.000000,g=0.188235,b=0.188235)
firebrick2 = _intern(r=0.933333,g=0.172549,b=0.172549)
firebrick3 = _intern(r=0.803922,g=0.149020,b=0.149020)
firebrick4 = _intern(r=0.545098,g=0.101961,b=0.101961)
brown1 = _intern(r=1.000000,g=0.250980,b=0.250980)
brown2 = _intern(r=0.933333,g=0.231373,b=0.231373)
brown3 = _intern(r=0.803922,g=0.200000,b=0.200000)
brown4 = _intern(r=0.545098,g=0.137255,b=0.137255)
salmon1 = _intern(r=1.000000,g=0.549020,b=0.411765)
salmon2 = _intern(r=0.933333,g=0.509804,b=0.384314)
salmon3 = _intern(r=0.803922,g=0.439216,b=0.329412)
salmon4 = _intern(r=0.545098,g=0.298039,b=0.223529)
lightsalmon1 = _intern(r=1.000000,g=0.627451,b=0.478431)
lightsalmon2 = _intern(r=0.933333,g=0.584314,b=0.447059)
lightsalmon3 = _intern(r=0.803922,g=0.505882,b=0.384314)
lightsalmon4 = _intern(r=0.545098,g=0.341176,b=0.258824)
orange1 = _intern(r=1.000000,g=0.647059,b=0.000000)
orange2 = _intern(r=0.933333,g=0.603922,b=0.000000)
orange3 = _intern(r=0.803922,g=0.521569,b=0.000000)
orange4 = _intern(r=0.545098,g=0.352941,b=0.000000)
darkorange1 = _intern(r=1.000000,g=0.498039,b=0.000000)
darkorange2 = _intern(r=0.933333,g=0.462745,b=0.000000)
darkorange3 = _intern(r=0.803922,g=0.400000,b=0.000000)
darkorange4 = _intern(r=0.545098,g=0.270588,b=0.000000)
coral1 = _intern(r=1.000000,g=0.447059,b=0.337255)
coral2 = _intern(r=0.933333,g=0.415686,b=0.313725)
coral3 = _intern(r=0.803922,g=0.356863,b=0.270588)
coral4 = _intern(r=0.545098,g=0.243137,b=0.184314)
tomato1 = _intern(r=1.000000,g=0.388235,b=0.278431)
tomato2 = _intern(r=0.933333,g=0.360784,b=0.258824)
tomato3 = _intern(r=0.803922,g=0.309804,b=0.223529)
tomato4 = _intern(r=0.545098,g=0.211765,b=0.149020)
orangered1 = _intern(r=1.000000,g=0.270588,b=0.000000)
orangered2 = _intern(r=0.933333,g=0.250980,b=0.000000)
orangered3 = _intern(r=0.803922,g=0.215686,b=0.000000)
orangered4 = _intern(r=0.545098,g=0.145098,b=0.000000)
red1 = _intern(r=1.000000,g=0.000000,b=0.000000)
red2 = _intern(r=0.933333,g=0.000000,b=0.000000)
red3 = _intern(r=0.803922,g=0.000000,b=0.000000)
red4 = _intern(r=0.545098,g=0.000000,b=0.000000)
deeppink1 = _intern(r=1.000000,g=0.078431,b=0.576471)
deeppink2 = _intern(r=0.933333,g=0.070588,b=0.537255)
deeppink3 = _intern(r=0.803922,g=0.062745,b=0.462745)
deeppink4 = _intern(r=0.545098,g=0.039216,b=0.313725)
hotpink1 = _intern(r=1.000000,g=0.431373,b=0.705882)
hotpink2 = _intern(r=0.933333,g=0.415686,b=0.654902)
hotpink3 = _intern(r=0.803922,g=0.376471,b=0.564706)
hotpink4 = _intern(r=0.545098,g=0.227451,b=0.384314)
pink1 = _intern(r=1.000000,g=0.709804,b=0.772549)
pink2 = _intern(r=0.933333,g=0.662745,b=0.721569)
pink3 = _intern(r=0.803922,g=0.568627,b=0.619608)
pink4 = _intern(r=0.545098,g=0.388235,b=0.423529)
lightpink1 = _intern(r=1.000000,g=0.682353,b=0.725490)
lightpink2 = _intern(r=0.933333,g=0.635294,b=0.678431)
lightpink3 = _intern(r=0.803922,g=0.549020,b=0.584314)
lightpink4 = _intern(r=0.545098,g=0.372549,b=0.396078)
palevioletred1 = _intern(r=1.000000,g=0.509804,b=0.670588)
palevioletred2 = _intern(r=0.933333,g=0.474510,b=0.623529)
palevioletred3 = _intern(r=0.803922,g=0.407843,b=0.537255)
palevioletred4 = _intern(r=0.545098,g=0.278431,b=0.364706)
maroon1 = _intern(r=1.000000,g=0.203922,b=0.701961)
maroon2 = _intern(r=0.933333,g=0.188235,b=0.654902)
maroon3 = _intern(r=0.803922,g=0.160784,b=0.564706)
maroon4 = _intern(r=0.545098,g=0.109804,b=0.384314)
violetred1 = _intern(r=1.000000,g=0.243137,b=0.588235)
violetred2 = _intern(r=0.933333,g=0.227451,b=0.549020)
violetred3 = _intern(r=0.803922,g=0.196078,b=0.470588)
violetred4 = _intern(r=0.545098,g=0.133333,b=0.321569)
magenta1 = _intern(r=1.000000,g=0.000000,b=1.000000)
magenta2 = _intern(r=0.933333,g=0.000000,b=0.933333)
magenta3 = _intern(r=0.803922,g=0.000000,b=0.803922)
magenta4 = _intern(r=0.545098,g=0.000000,b=0.545098)
orchid1 = _intern(r=1.000000,g=0.513725,b=0.980392)
orchid2 = _intern(r=0.933333,g=0.478431,b=0.913725)
orchid3 = _intern(r=0.803922,g=0.411765,b=0.788235)
orchid4 = _intern(r=0.545098,g=0.278431,b=0.537255)
plum1 = _intern(r=1.000000,g=0.733333,b=1.000000)
plum2 = _intern(r=0.933333,g=0.682353,b=0.933333)
plum3 = _intern(r=0.803922,g=0.588235,b=0.803922)
plum4 = _intern(r=0.545098,g=0.400000,b=0.545098)
mediumorchid1 = _intern(r=0.878431,g=0.400000,b=1.000000)
mediumorchid2 = _intern(r=0.819608,g=0.372549,b=0.933333)
mediumorchid3 = _intern(r=0.705882,g=0.321569,b=0.803922)
mediumorchid4 = _intern(r=0.478431,g=0.215686,b=0.545098)
darkorchid1 = _intern(r=0.749020,g=0.243137,b=1.000000)
darkorchid2 = _intern(r=0.698039,g=0.227451,b=0.933333)
darkorchid3 = _intern(r=0.603922,g=0.196078,b=0.803922)
darkorchid4 = _intern(r=0.407843,g=0.133333,b=0.545098)
purple1 = _intern(r=0.607843,g=0.188235,b=1.000000)
purple2 = _intern(r=0.568627,g=0.172549,b=0.933333)
purple3 = _intern(r=0.490196,g=0.149020,b=0.803922)
purple4 = _intern(r=0.333333,g=0.101961,b=0.545098)
mediumpurple1 = _intern(r=0.670588,g=0.509804,b=1.000000)
mediumpurple2 = _intern(r=0.623529,g=0.474510,b=0.933333)
mediumpurple3 = _intern(r=0.537255,g=0.407843,b=0.803922)
mediumpurple4 = _intern(r=0.364706,g=0.278431,b=0.545098)
thistle1 = _intern(r=1.000000,g=0.882353,b=1.000000)
thistle2 = _intern(r=0.933333,g=0.823529,b=0.933333)
thistle3 = _intern(r=0.803922,g=0.709804,b=0.803922)
thistle4 = _intern(r=0.545098,g=0.482353,b=0.545098)
gray00 = _intern(r=0.000000,g=0.000000,b=0.000000)
gray01 = _intern(r=0.011765,g=0.011765,b=0.011765)
gray02 = _intern(r=0.019608,g=0.019608,b=0.019608)
gray03 = _intern(r=0.031373,g=0.031373,b=0.031373)
gray04 = _intern(r=0.039216,g=0.039216,b=0.039216)
gray05 = _intern(r=0.050980,g=0.050980,b=0.050980)
gray06 = _intern(r=0.058824,g=0.058824,b=0.058824)
gray07 = _intern(r=0.070588,g=0.070588,b=0.070588)
gray08 = _intern(r=0.078431,g=0.078431,b=0.078431)
gray09 = _intern(r=0.090196,g=0.090196,b=0.090196)
gray10 = _intern(r=0.101961,g=0.101961,b=0.101961)
gray11 = _intern(r=0.109804,g=0.109804,b=0.109804)
gray12 = _intern(r=0.121569,g=0.121569,b=0.121569)
gray13 = _intern(r=0.129412,g=0.129412,b=0.129412)
gray14 = _intern(r=0.141176,g=0.141176,b=0.141176)
gray15 = _intern(r=0.149020,g=0.149020,b=0.149020)
gray16 = _intern(r=0.160784,g=0.160784,b=0.160784)
gray17 = _intern(r=0.168627,g=0.168627,b=0.168627)
gray18 = _intern(r=0.180392,g=0.180392,b=0.180392)
gray19 = _intern(r=0.188235,g=0.188235,b=0.188235)
gray20 = _intern(r=0.200000,g=0.200000,b=0.200000)
gray21 = _intern(r=0.211765,g=0.211765,b=0.211765)
gray22 = _intern(r=0.219608,g=0.219608,b=0.219608)
gray23 = _intern(r=0.231373,g=0.231373,b=0.231373)
gray24 = _intern(r=0.239216,g=0.239216,b=0.239216)
gray25 = _intern(r=0.250980,g=0.250980,b=0.250980)
gray26 = _intern(r=0.258824,g=0.258824,b=0.258824)
gray27 = _intern(r=0.270588,g=0.270588,b=0.270588)
gray28 = _intern(r=0.278431,g=0.278431,b=0.278431)
gray29 = _intern(r=0.290196,g=0.290196,b=0.290196)
gray30 = _intern(r=0.301961,g=0.301961,b=0.301961)
gray31 = _intern(r=0.309804,g=0.309804,b=0.309804)
gray32 = _intern(r=0.321569,g=0.321569,b=0.321569)
gray33 = _intern(r=0.329412,g=0.329412,b=0.329412)
gray34 = _intern(r=0.341176,g=0.341176,b=0.341176)
gray35 = _intern(r=0.349020,g=0.349020,b=0.349020)
gray36 = _intern(r=0.360784,g=0.360784,b=0.360784)
gray37 = _intern(r=0.368627,g=0.368627,b=0.368627)
gray38 = _intern(r=0.380392,g=0.380392,b=0.380392)
gray39 = _intern(r=0.388235,g=0.388235,b=0.388235)
gray40 = _intern(r=0.400000,g=0.400000,b=0.400000)
gray41 = _intern(r=0.411765,g=0.411765,b=0.411765)
gray42 = _intern(r=0.419608,g=0.419608,b=0.419608)
gray43 = _intern(r=0.431373,g=0.431373,b=0.431373)
gray44 = _intern(r=0.439216,g=0.439216,b=0.439216)
gray45 = _intern(r=0.450980,g=0.450980,b=0.450980)
gray46 = _intern(r=0.458824,g=0.458824,b=0.458824)
gray47 = _intern(r=0.470588,g=0.470588,b=0.470588)
gray48 = _intern(r=0.478431,g=0.478431,b=0.478431)
gray49 = _intern(r=0.490196,g=0.490196,b=0.490196)
gray50 = _intern(r=0.498039,g=0.498039,b=0.498039)
gray51 = _intern(r=0.509804,g=0.509804,b=0.509804)
gray52 = _intern(r=0.521569,g=0.521569,b=0.521569)
gray53 = _intern(r=0.529412,g=0.529412,b=0.529412)
gray54 = _intern(r=0.541176,g=0.541176,b=0.541176)
gray55 = _intern(r=0.549020,g=0.549020,b=0.549020)
gray56 = _intern(r=0.560784,g=0.560784,b=0.560784)
gray57 = _intern(r=0.568627,g=0.568627,b=0.568627)
gray58 = _intern(r=0.580392,g=0.580392,b=0.580392)
gray59 = _intern(r=0.588235,g=0.588235,b=0.588235)
gray60 = _intern(r=0.600000,g=0.600000,b=0.600000)
gray61 = _intern(r=0.611765,g=0.611765,b=0.611765)
gray62 = _intern(r=0.619608,g=0.619608,b=0.619608)
gray63 = _intern(r=0.631373,g=0.631373,b=0.631373)
gray64 = _intern(r=0.639216,g=0.639216,b=0.639216)
gray65 = _intern(r=0.650980,g=0.650980,b=0.650980)
gray66 = _intern(r=0.658824,g=0.658824,b=0.658824)
gray67 = _intern(r=0.670588,g=0.670588,b=0.670588)
gray68 = _intern(r=0.678431,g=0.678431,b=0.678431)
gray69 = _intern(r=0.690196,g=0.690196,b=0.690196)
gray70 = _intern(r=0.701961,g=0.701961,b=0.701961)
gray71 = _intern(r=0.709804,g=0.709804,b=0.709804)
gray72 = _intern(r=0.721569,g=0.721569,b=0.721569)
gray73 = _intern(r=0.729412,g=0.729412,b=0.729412)
gray74 = _intern(r=0.741176,g=0.741176,b=0.741176)
gray75 = _intern(r=0.749020,g=0.749020,b=0.749020)
gray76 = _intern(r=0.760784,g=0.760784,b=0.760784)
gray77 = _intern(r=0.768627,g=0.768627,b=0.768627)
gray78 = _intern(r=0.780392,g=0.780392,b=0.780392)
gray79 = _intern(r=0.788235,g=0.788235,b=0.788235)
gray80 = _intern(r=0.800000,g=0.800000,b=0.800000)
gray81 = _intern(r=0.811765,g=0.811765,b=0.811765)
gray82 = _intern(r=0.819608,g=0.819608,b=0.819608)
gray83 = _intern(r=0.831373,g=0.831373,b=0.831373)
gray84 = _intern(r=0.839216,g=0.839216,b=0.839216)
gray85 = _intern(r=0.850980,g=0.850980,b=0.850980)
gray86 = _intern(r=0.858824,g=0.858824,b=0.858824)
gray87 = _intern(r=0.870588,g=0.870588,b=0.870588)
gray88 = _intern(r=0.878431,g=0.878431,b=0.878431)
gray89 = _intern(r=0.890196,g=0.890196,b=0.890196)
gray90 = _intern(r=0.898039,g=0.898039,b=0.898039)
gray91 = _intern(r=0.909804,g=0.909804,b=0.909804)
gray92 = _intern(r=0.921569,g=0.921569,b=0.921569)
gray93 = _intern(r=0.929412,g=0.929412,b=0.929412)
gray94 = _intern(r=0.941176,g=0.941176,b=0.941176)
gray95 = _intern(r=0.949020,g=0.949020,b=0.949020)
gray96 = _intern(r=0.960784,g=0.960784,b=0.960784)
gray97 = _intern(r=0.968627,g=0.968627,b=0.968627)
gray98 = _intern(r=0.980392,g=0.980392,b=0.980392)
gray99 = _intern(r=0.988235,g=0.988235,b=0.988235)
gray100 = _intern(r=1.000000,g=1.000000,b=1.000000)
darkgray = _intern(r=0.662745,g=0.662745,b=0.662745)
darkblue = _intern(r=0.000000,g=0.000000,b=0.545098)
darkcyan = _intern(r=0.000000,g=0.545098,b=0.545098)
darkmagenta = _intern(r=0.545098,g=0.000000,b=0.545098)
darkred = _intern(r=0.545098,g=0.000000,b=0.000000)
lightgreen = _intern(r=0.564706,g=0.933333,b=0.564706)
default = black
_name_table = None
def name_table():
global _name_table
if not _name_table:
_name_table = pychart_util.symbol_lookup_table(globals(), standards)
return _name_table

View File

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
r(type:number) default="The intensity of red. The value is between 0 and 1.".
b(type:number) default="The intensity of blue. The value is between 0 and 1.".
g(type:number) default="The intensity of green. The value is between 0 and 1.".
"""

View File

@ -1,50 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
class T(object):
def get_canvas_pos(self, size, val, min, max):
"""
Compute the screen location at which a sample value would be drawn.
``size`` is the width or height of the chart, in points.
``val`` is the sample value.
``min`` and ``max`` are the minimum and maximum sample values that
are to be displayed over the length of ``size``.
For example, suppose the width of a chart is 200 points and the
minimum and maximum X values in the sample data are 100 and 150
respectively. When Pychart wants to draw a sample point at the X
value of 120, it will call
area.T.x_coord.get_canvas_pos(size = 200, val = 120, min = 100, max = 150).
"""
raise Exception
def get_tics(self, min, max, interval):
"""Generate the list of places for drawing tick marks."""
raise Exception
def get_min_max(self, min, max, interval):
"""Compute the min/max values to be displayed in the chart.
Parameters ``min`` and ``max`` are the minimum and maximum values
of the sample data passed to the plots. Parameter ``interval`` is
the value of attribute area.T.x_grid_interval (or y_grid_interval).
It is None if these attributes are non-specified.
This method must return tuple (dmin, dmax, dinterval).
dmin should be ``min`` rounded down to some good number.
dmax should be ``max`` rounded up to some good number.
dinterval should be ``interval`` if it is non-None. Otherwise, the
method must compute some good value.
"""
raise Exception

View File

@ -1,123 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import string
import sys
import re
import os.path
from pychart import *
from types import *
from pychart.pychart_types import *
oldstdout = sys.stdout
if os.path.exists("/dev/null"):
sys.stdout = open("/dev/null", "w")
modules = {}
values = []
sys.stdout = oldstdout
g = globals()
for mod in g.keys():
val = g[mod]
if type(val) == ModuleType:
dic = {}
for name in val.__dict__.keys():
v = val.__dict__[name]
if name[0] != '_':
values.append((v, mod + "." + name))
if type(v) == type and issubclass(v, chart_object.T):
dic[name] = v
modules[mod] = dic
def stringify_type(t):
s = str(t)
if t == AnyType:
return "any"
if t == ShadowType:
return "(xoff,yoff,fill)"
elif re.search("NumType", s):
return "number"
elif re.search("UnitType", s):
return "length in points (\\\\xref{unit})"
elif re.search("CoordType", s):
return "(x,y)"
elif re.search("CoordSystemType", s):
return "['linear'|'log'|'category']"
elif re.search("CoordOrNoneType", s):
return "(x,y) or None"
elif re.search("TextAlignType", s):
return "['R'|'L'|'C'|None]"
elif re.search("FormatType", s):
return "printf format string"
elif re.search("IntervalType", s):
return "Number or function"
mo = re.match("<type '([^']+)'>", s)
if mo:
return mo.group(1)
mo = re.match("<class 'pychart\.([^']+)'>", s)
if mo:
return mo.group(1)
mo = re.match("<class '([^']+)'>", s)
if mo:
return mo.group(1)
mo = re.match("pychart\\.(.*)", s)
if mo:
return mo.group(1)
return s
def stringify_value(val):
t = type(val)
if t == StringType:
return '"' + val + '"'
if t == bool:
if val: return "True"
else: return "False"
if t in (IntType, LongType, FloatType):
return str(val)
if val == None:
return "None"
if type(val) == ListType:
return map(stringify_value, val)
for pair in values:
if pair[0] == val:
return pair[1]
return str(val)
def break_string(name):
max_len = 10
if len(name) < max_len:
return name
name = re.sub("(\\d\\d)([^\\d])", "\\1-\n\\2", name)
name = re.sub("black(.)", "black-\n\\1", name)
elems = string.split(name, "\n")
while 1:
broken = 0
for i in range(len(elems)):
elem = elems[i]
if len(elem) < max_len:
continue
broken = 1
elem1 = elem[0:len(elem)/2]
elem2 = elem[len(elem)/2:]
elems[i:i+1] = [elem1, elem2]
break
if not broken:
break
name = "\n".join(elems)
return name

View File

@ -1,45 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
def generate_doc(name, suffix="", append = 0):
if append:
fp = open(name + "_doc.py", "a+")
else:
fp = open(name + "_doc.py", "w")
fp.write("# automatically generated by generate_docs.py.\n")
fp.write("doc" + suffix + "=\" \"\n")
fp.close()
generate_doc( "area")
generate_doc( "arrow")
generate_doc( "axis", "_x")
generate_doc( "axis", "_y", 1)
generate_doc( "bar_plot")
generate_doc( "color")
generate_doc( "error_bar","_1")
generate_doc( "error_bar", "_2", 1)
generate_doc( "error_bar", "_3", 1)
generate_doc( "error_bar", "_4", 1)
generate_doc( "error_bar", "_5", 1)
generate_doc( "error_bar", "_6", 1)
generate_doc( "fill_style")
generate_doc("line_plot")
generate_doc("pie_plot")
generate_doc("text_box")
generate_doc("range_plot")
generate_doc("legend")
generate_doc("legend", "_entry", 1)
generate_doc("line_style")
generate_doc("tick_mark")

View File

@ -1,160 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import tick_mark
import line_style
import pychart_util
import chart_object
import fill_style
import types
import error_bar_doc
import object_set
from pychart_types import *
__doc__ = """Pychart offers several styles of error bars. Some of them
only displays the min/max confidence interval, while others can display
quartiles in addition to min/max."""
class T(chart_object.T):
keys = {}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
pass
# Two horizontal lines at min & max locations.
class error_bar1(T):
__doc__ = error_bar_doc.doc_1
keys = {"tic_len" : (UnitType, 10, "Length of the horizontal bars"),
"line_style": (line_style.T, line_style.default, "")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin = None, qmax = None):
x = loc[0]
y = min
can.line(self.line_style, x-self.tic_len/2.0, y, x+self.tic_len/2.0, y)
y = max
can.line(self.line_style, x-self.tic_len/2.0, y, x+self.tic_len/2.0, y)
class error_bar2(T):
__doc__ = error_bar_doc.doc_2
keys = {"tic_len" : (UnitType, 3,
"The length of the horizontal bars"),
"hline_style": (line_style.T, line_style.default,
"The style of the horizontal bars."),
"vline_style": (line_style.T, None,
"The style of the vertical bar.")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin = None, qmax = None):
vline_style = self.vline_style
if not vline_style:
vline_style = self.hline_style
x = loc[0]
y1 = min
can.line(self.hline_style, x-self.tic_len/2.0, y1, x+self.tic_len/2.0, y1)
y2 = max
can.line(self.hline_style, x-self.tic_len/2.0, y2, x+self.tic_len/2.0, y2)
can.line(vline_style, x, y1, x, y2)
class error_bar3(T):
# Tufte style
__doc__ = "This style is endorsed by the Tufte's books. " \
+ error_bar_doc.doc_3
keys = { "line_style": (line_style.T, line_style.default, "")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin, qmax):
x = loc[0]
can.line(self.line_style, x, min, x, qmin)
can.line(self.line_style, x, qmax, x, max)
class error_bar4(T):
__doc__ = error_bar_doc.doc_4
keys = { "line_style": (line_style.T, line_style.default, ""),
"fill_style": (fill_style.T, fill_style.gray70, ""),
"box_width": (UnitType, 4, ""),
"tic_len": (UnitType, 4, "")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin, qmax):
x = loc[0]
style = self.line_style
y1 = min
can.line(style, x-self.tic_len/2.0, y1, x+self.tic_len/2.0, y1)
y2 = max
can.line(style, x-self.tic_len/2.0, y2, x+self.tic_len/2.0, y2)
can.line(style, x, y1, x, y2)
can.rectangle(style, self.fill_style,
x-self.box_width/2.0, qmin,
x+self.box_width/2.0, qmax)
# vertical line
class error_bar5(T):
__doc__ = error_bar_doc.doc_5
keys = { "line_style": (line_style.T, line_style.default, "")
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin = None, qmax = None):
x = loc[0]
y = loc[1]
min = (min - y) *1 + y
max = (max - y) *1+ y
can.line(self.line_style, x, min, x, max)
# a box
class error_bar6(T):
__doc__ = error_bar_doc.doc_6
keys = { "line_style": (line_style.T, line_style.default, ""),
"fill_style": (fill_style.T, fill_style.gray70, ""),
"center_line_style": (line_style.T, line_style.T(width=0.5), ""),
"box_width": (UnitType, 4, ""),
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, can, loc, min, max, qmin = None, qmax = None):
x = loc[0]
y = loc[1]
can.rectangle(self.line_style, self.fill_style,
x - self.box_width / 2.0, min,
x + self.box_width / 2.0, max)
can.line(self.center_line_style,
x - self.box_width/2.0, (min+max)/2.0,
x + self.box_width/2.0, (min+max)/2.0)
bar1 = error_bar1()
bar2 = error_bar2()
bar3 = error_bar3()
bar4 = error_bar4()
bar5 = error_bar5()
bar6 = error_bar6()
standards = object_set.T(bar1, bar2, bar3, bar4, bar5, bar6)

View File

@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc_1="""Attributes supported by this class are:
line_style(type:line_style.T) default="".
tic_len(type:length in points (\\xref{unit})) default="Length of the horizontal bars".
"""
doc_2="""Attributes supported by this class are:
vline_style(type:line_style.T) default="The style of the vertical bar.".
hline_style(type:line_style.T) default="The style of the horizontal bars.".
tic_len(type:length in points (\\xref{unit})) default="The length of the horizontal bars".
"""
doc_3="""Attributes supported by this class are:
line_style(type:line_style.T) default="".
"""
doc_4="""Attributes supported by this class are:
line_style(type:line_style.T) default="".
box_width(type:length in points (\\xref{unit})) default="".
tic_len(type:length in points (\\xref{unit})) default="".
fill_style(type:fill_style.T) default="".
"""
doc_5="""Attributes supported by this class are:
line_style(type:line_style.T) default="".
"""
doc_6="""Attributes supported by this class are:
box_width(type:length in points (\\xref{unit})) default="".
line_style(type:line_style.T) default="".
center_line_style(type:line_style.T) default="".
fill_style(type:fill_style.T) default="".
"""

View File

@ -1,286 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import pychart_util
import color
import line_style
import chart_object
import object_set
import types
import theme
import fill_style_doc
from pychart_types import *
from scaling import *
_keys = {
"bgcolor" : (color.T, color.white, "The background color."),
"line_style": (line_style.T, line_style.default,
pychart_util.line_desc),
"line_interval": (NumType, 3,
"The interval between successive stitch lines.")
}
class T(chart_object.T):
__doc__ = fill_style_doc.doc
keys = _keys
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def __str__(self):
s = name_table().lookup(self)
if s:
return s
return "<fillstyle: bg=%s line=%s interval=%s>" % \
(self.bgcolor, self.line_style, self.line_interval)
class Plain(T):
"""This class just fills the region with solid background color.
Attributes line_style and line_interval are ignored."""
def draw(self, can, x1, y1, x2, y2):
pass
class Diag(T):
"This class fills the region with diagonal lines."
def draw(self, can, x1, y1, x2, y2):
line_width = self.line_style.width
interval = self.line_interval * 1.414
x1 -= line_width
y1 -= line_width
x2 += line_width
y2 += line_width
len = max(y2 - y1, x2 - x1)
curx = x1 - len
while curx < x2:
can.line(self.line_style, curx, y1, curx+len, y1+len)
curx += interval
class Rdiag(T):
"""Fills the region with diagonal lines, but tilted in the opposite
direction from fill_style.Diag."""
def draw(self, can, x1, y1, x2, y2):
line_width = self.line_style.width
interval = self.line_interval * 1.414
x1 -= line_width
y1 -= line_width
x2 += line_width
y2 += line_width
len = max(y2 - y1, x2 - x1)
curx = x1
while curx < x2 + len:
can.line(self.line_style, curx, y1, curx-len, y1+len)
curx += interval
class Vert(T):
"Fills the region with vertical lines"
def draw(self, can, x1, y1, x2, y2):
interval = self.line_interval
curx = x1
while curx < x2:
can.line(self.line_style, curx, y1, curx, y2)
curx += interval
class Horiz(T):
"Fills the region with horizontal lines"
def draw(self, can, x1, y1, x2, y2):
interval = self.line_interval
cury = y1
while cury < y2:
can.line(self.line_style, x1, cury, x2, cury)
cury += interval
class Stitch(T):
"Fills the region with horizontal and vertical lines."
def draw(self, can, x1, y1, x2, y2):
interval = self.line_interval
cury = y1
while cury < y2:
can.line(self.line_style, x1, cury, x2, cury)
cury += interval
curx = x1
while curx < x2:
can.line(self.line_style, curx, y1, curx, y2)
curx += interval
class Wave(T):
"Fills the region with horizontal wavy lines."
def draw(self, can, x1, y1, x2, y2):
x1 = xscale(x1)
x2 = xscale(x2)
y1 = yscale(y1)
y2 = yscale(y2)
line_width = nscale(self.line_style.width)
interval = nscale(self.line_interval)
can.set_line_style(self.line_style)
x1 -= line_width
x2 += line_width
cury = y1
half = interval/2.0
while cury < y2:
curx = x1
can.newpath()
can.moveto(curx, cury)
while curx < x2:
can.lineto(curx + half, cury + half)
can.lineto(curx + interval, cury)
curx += interval
can.stroke()
cury += interval
class Vwave(T):
"""Fills the region with vertical wavy lines."""
def draw(self, can, x1, y1, x2, y2):
x1 = xscale(x1)
x2 = xscale(x2)
y1 = yscale(y1)
y2 = yscale(y2)
line_width = nscale(self.line_style.width)
interval = nscale(self.line_interval)
can.set_line_style(self.line_style)
y1 -= line_width
y2 += line_width
curx = x1
half = interval/2.0
while curx < x2:
cury = y1
can.newpath()
can.moveto(curx, cury)
while cury < y2:
can.lineto(curx + half, cury + half)
can.lineto(curx, cury + interval)
cury += interval
can.stroke()
curx += interval
class Lines(T):
"""Fills the region with a series of short line segments."""
def draw(self, can, x1, y1, x2, y2):
interval = nscale(self.line_interval)
cury = y1
j = 0
while cury < y2:
curx = x1
if j % 2 == 1:
curx += interval/2.0
while curx < x2:
can.line(self.line_style, curx, cury, curx+interval/2.0, cury)
curx += interval * 1.5
j += 1
cury += interval
default = Plain()
color_standards = object_set.T()
grayscale_standards = object_set.T()
def _intern_both(style):
global color_standards, grayscale_standards
color_standards.add(style)
grayscale_standards.add(style)
return style
def _intern_color(style):
global color_standards, grayscale_standards
color_standards.add(style)
return style
def _intern_grayscale(style):
global color_standards, grayscale_standards
grayscale_standards.add(style)
return style
black = _intern_both(Plain(bgcolor=color.gray_scale(0.0), line_style=None))
red = _intern_color(Plain(bgcolor=color.red))
darkseagreen = _intern_color(Plain(bgcolor=color.darkseagreen))
blue = _intern_color(Plain(bgcolor=color.blue))
aquamarine1 = _intern_color(Plain(bgcolor=color.aquamarine1))
gray70 = _intern_both(Plain(bgcolor=color.gray70, line_style=None))
brown = _intern_color(Plain(bgcolor=color.brown))
darkorchid = _intern_color(Plain(bgcolor=color.darkorchid))
diag = _intern_both(Diag(line_style=line_style.T(cap_style=2)))
green = _intern_color(Plain(bgcolor=color.green))
gray50 = _intern_both(Plain(bgcolor=color.gray50, line_style=None))
white = _intern_both(Plain(bgcolor=color.gray_scale(1.0), line_style=None))
goldenrod = _intern_color(Plain(bgcolor=color.goldenrod))
rdiag = _intern_both(Rdiag(line_style=line_style.T(cap_style=2)))
vert = _intern_both(Vert(line_interval=1.8))
gray30 = _intern_both(Plain(bgcolor=color.gray30, line_style=None))
gray20 = _intern_both(Plain(bgcolor=color.gray20, line_style=None))
gray10 = _intern_both(Plain(bgcolor=color.gray10, line_style=None))
diag2 = _intern_both(Diag(line_style=line_style.T(width=3, cap_style=2),
line_interval=6))
rdiag2 = _intern_both(Rdiag(line_style=line_style.T(width=3, cap_style=2),
line_interval=6))
yellow = _intern_color(Plain(bgcolor=color.yellow))
diag3 = _intern_both(Diag(line_style=line_style.T(width=3, color=color.gray50, cap_style=2),
line_interval=6))
horiz = _intern_both(Horiz(line_interval=1.8))
gray90 = _intern_both(Plain(bgcolor=color.gray90, line_style=None))
rdiag3 = _intern_both(Rdiag(line_style=line_style.T(width=3,
color=color.gray50,
cap_style=2),
line_interval=6))
wave = _intern_both(Wave(line_style=line_style.T(cap_style=2, join_style=1)))
vwave = _intern_both(Vwave(line_style=line_style.T(cap_style=2, join_style=1)))
stitch = _intern_both(Stitch(line_style=line_style.T(cap_style=2, join_style=1)))
lines = _intern_both(Lines(line_style=line_style.T()))
diag_fine = _intern_both(Diag(line_style=line_style.T(width=0.75,cap_style=2),
line_interval = 1.5))
diag2_fine = _intern_both(Diag(line_style=line_style.T(width=0.75, cap_style=2),
line_interval=1.5))
diag3_fine = _intern_both(Diag(line_style=line_style.T(width=0.75,
color = color.gray50,
cap_style=2),
line_interval=1.5))
rdiag_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75,cap_style=2),
line_interval = 1.5))
rdiag2_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75, cap_style=2),
line_interval=1.5))
rdiag3_fine = _intern_both(Rdiag(line_style=line_style.T(width=0.75,
color = color.gray50,
cap_style=2),
line_interval=1.5))
horiz_fine = _intern_both(Horiz(line_interval=1.5))
vert_fine = _intern_both(Vert(line_interval=1.5))
#
# Fill styles for color charts.
#
standards = None
_name_table = None
def init():
global standards, _name_table
if theme.use_color:
standards = color_standards
else:
standards = grayscale_standards
_name_table = None
def name_table():
global _name_table
if not _name_table:
_name_table = pychart_util.symbol_lookup_table(globals(), standards)
return _name_table
init()
theme.add_reinitialization_hook(init)

View File

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
bgcolor(type:color.T) default="The background color.".
line_style(type:line_style.T) default="The style of the line. ".
line_interval(type:number) default="The interval between successive stitch lines.".
"""

View File

@ -1,455 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import color
import string
import pychart_util
import re
import theme
import afm.dir
__doc__ = """The module for manipulating texts and their attributes.
Pychart supports extensive sets of attributes in texts. All attributes
are specified via "escape sequences", starting from letter "/". For
example, the below examples draws string "Hello" using a 12-point font
at 60-degree angle:
/12/a60{}Hello
List of attributes:
/hA
Specifies horizontal alignment of the text. A is one of L (left
alignment), R (right alignment), or C (center alignment).
/vA
Specifies vertical alignment of the text. A is one of "B"
(bottom), "T" (top), " M" (middle).
/F{FONT}
Switch to FONT font family.
/T
Shorthand of /F{Times-Roman}.
/H
Shorthand of /F{Helvetica}.
/C
Shorthand of /F{Courier}.
/B
Shorthand of /F{Bookman-Demi}.
/A
Shorthand of /F{AvantGarde-Book}.
/P
Shorthand of /F{Palatino}.
/S
Shorthand of /F{Symbol}.
/b
Switch to bold typeface.
/i
Switch to italic typeface.
/o
Switch to oblique typeface.
/DD
Set font size to DD points.
/20{}2001 space odyssey!
/cDD
Set gray-scale to 0.DD. Gray-scale of 00 means black, 99 means white.
//, /{, /}
Display `/', `@', or `@{'.
{ ... }
Limit the effect of escape sequences. For example, the below
example draws "Foo" at 12pt, "Bar" at 8pt, and "Baz" at 12pt.
/12Foo{/8Bar}Baz
\n
Break the line.
"""
# List of fonts for which their absence have been already warned.
_undefined_font_warned = {}
def _intern_afm(font, text):
global _undefined_font_warned
font2 = _font_aliases.has_key(font) and _font_aliases[font]
if afm.dir.afm.has_key(font):
return afm.dir.afm[font]
if afm.dir.afm.has_key(font2):
return afm.dir.afm[font2]
try:
exec("import pychart.afm.%s" % re.sub("-", "_", font))
return afm.dir.afm[font]
except:
if not font2 and not _undefined_font_warned.has_key(font):
pychart_util.warn("Warning: unknown font '%s' while parsing '%s'" % (font, text))
_undefined_font_warned[font] = 1
if font2:
try:
exec("import pychart.afm.%s" % re.sub("-", "_", font2))
return afm.dir.afm[font2]
except:
if not _undefined_font_warned.has_key(font):
pychart_util.warn("Warning: unknown font '%s' while parsing '%s'" % (font, text))
_undefined_font_warned[font] = 1
return None
def line_width(font, size, text):
table = _intern_afm(font, text)
if not table:
return 0
width = 0
for ch in text:
code = ord(ch)
if code < len(table):
width += table[code]
else:
width += 10000
width = float(width) * size / 1000.0
return width
_font_family_map = {'T': "Times",
'H': "Helvetica",
'C': "Courier",
'N': "Helvetica-Narrow",
'B': "Bookman-Demi",
'A': "AvantGarde-Book",
'P': "Palatino",
'S': "Symbol"}
# Aliases for ghostscript font names.
_font_aliases = {
'Bookman-Demi': "URWBookmanL-DemiBold%I",
'Bookman-DemiItalic': "URWBookmanL-DemiBoldItal",
'Bookman-Demi-Italic': "URWBookmanL-DemiBoldItal",
'Bookman-Light': "URWBookmanL-Ligh",
'Bookman-LightItalic': "URWBookmanL-LighItal",
'Bookman-Light-Italic': "URWBookmanL-LighItal",
'Courier': "NimbusMonL-Regu",
'Courier-Oblique': "NimbusMonL-ReguObli",
'Courier-Bold': "NimbusMonL-Bold",
'Courier-BoldOblique': "NimbusMonL-BoldObli",
'AvantGarde-Book': "URWGothicL-Book",
'AvantGarde-BookOblique': "URWGothicL-BookObli",
'AvantGarde-Book-Oblique': "URWGothicL-BookObli",
'AvantGarde-Demi': "URWGothicL-Demi",
'AvantGarde-DemiOblique': "URWGothicL-DemiObli",
'AvantGarde-Demi-Oblique': "URWGothicL-DemiObli",
'Helvetica': "NimbusSanL-Regu",
'Helvetica-Oblique': "NimbusSanL-ReguItal",
'Helvetica-Bold': "NimbusSanL-Bold",
'Helvetica-BoldOblique': "NimbusSanL-BoldItal",
'Helvetica-Narrow': "NimbusSanL-ReguCond",
'Helvetica-Narrow-Oblique': "NimbusSanL-ReguCondItal",
'Helvetica-Narrow-Bold': "NimbusSanL-BoldCond",
'Helvetica-Narrow-BoldOblique': "NimbusSanL-BoldCondItal",
'Palatino-Roman': "URWPalladioL-Roma",
'Palatino': "URWPalladioL-Roma",
'Palatino-Italic': "URWPalladioL-Ital",
'Palatino-Bold': "URWPalladioL-Bold",
'Palatino-BoldItalic': "URWPalladioL-BoldItal",
'NewCenturySchlbk-Roman': "CenturySchL-Roma",
'NewCenturySchlbk': "CenturySchL-Roma",
'NewCenturySchlbk-Italic': "CenturySchL-Ital",
'NewCenturySchlbk-Bold': "CenturySchL-Bold",
'NewCenturySchlbk-BoldItalic': "CenturySchL-BoldItal",
'Times-Roman': "NimbusRomNo9L-Regu",
'Times': "NimbusRomNo9L-Regu",
'Times-Italic': "NimbusRomNo9L-ReguItal",
'Times-Bold': "NimbusRomNo9L-Medi",
'Times-BoldItalic': "NimbusRomNo9L-MediItal",
'Symbol': "StandardSymL",
'ZapfChancery-MediumItalic': "URWChanceryL-MediItal",
'ZapfChancery-Medium-Italic': "URWChanceryL-MediItal",
'ZapfDingbats': "Dingbats"
}
class text_state:
def copy(self):
ts = text_state()
ts.family = self.family
ts.modifiers = list(self.modifiers)
ts.size = self.size
ts.line_height = self.line_height
ts.color = self.color
ts.halign = self.halign
ts.valign = self.valign
ts.angle = self.angle
return ts
def __init__(self):
self.family = theme.default_font_family
self.modifiers = [] # 'b' for bold, 'i' for italic, 'o' for oblique.
self.size = theme.default_font_size
self.line_height = theme.default_line_height or theme.default_font_size
self.color = color.default
self.halign = theme.default_font_halign
self.valign = theme.default_font_valign
self.angle = theme.default_font_angle
class text_iterator:
def __init__(self, s):
self.str = str(s)
self.i = 0
self.ts = text_state()
self.stack = []
def reset(self, s):
self.str = str(s)
self.i = 0
def __return_state(self, ts, str):
font_name = ts.family
if ts.modifiers != []:
is_bold = 0
if 'b' in ts.modifiers:
is_bold = 1
font_name += "-Bold"
if 'o' in ts.modifiers:
if not is_bold:
font_name += "-"
font_name += "Oblique"
elif 'i' in ts.modifiers:
if not is_bold:
font_name += "-"
font_name += "Italic"
elif font_name in ("Palatino", "Times", "NewCenturySchlbk"):
font_name += "-Roman"
return (font_name, ts.size, ts.line_height, ts.color,
ts.halign, ts.valign, ts.angle, str)
def __parse_float(self):
istart = self.i
while self.i < len(self.str) and self.str[self.i] in string.digits or self.str[self.i] == '.':
self.i += 1
return float(self.str[istart:self.i])
def __parse_int(self):
istart = self.i
while self.i < len(self.str) and \
(self.str[self.i] in string.digits or
self.str[self.i] == '-'):
self.i += 1
return int(self.str[istart:self.i])
def next(self):
"Get the next text segment. Return an 8-element array: (FONTNAME, SIZE, LINEHEIGHT, COLOR, H_ALIGN, V_ALIGN, ANGLE, STR."
l = []
changed = 0
self.old_state = self.ts.copy()
while self.i < len(self.str):
if self.str[self.i] == '/':
self.i = self.i+1
ch = self.str[self.i]
self.i = self.i+1
self.old_state = self.ts.copy()
if ch == '/' or ch == '{' or ch == '}':
l.append(ch)
elif _font_family_map.has_key(ch):
self.ts.family = _font_family_map[ch]
changed = 1
elif ch == 'F':
# /F{font-family}
if self.str[self.i] != '{':
raise Exception, "'{' must follow /F in \"%s\"" % self.str
self.i += 1
istart = self.i
while self.str[self.i] != '}':
self.i += 1
if self.i >= len(self.str):
raise Exception, "Expecting /F{...}. in \"%s\"" % self.str
self.ts.family = self.str[istart:self.i]
self.i += 1
changed = 1
elif ch in string.digits:
self.i -= 1
self.ts.size = self.__parse_int()
self.ts.line_height = self.ts.size
changed = 1
elif ch == 'l':
self.ts.line_height = self.__parse_int()
changed = 1
elif ch == 'b':
self.ts.modifiers.append('b')
changed = 1
elif ch == 'i':
self.ts.modifiers.append('i')
changed = 1
elif ch == 'o':
self.ts.modifiers.append('q')
changed = 1
elif ch == 'c':
self.ts.color = color.gray_scale(self.__parse_float())
elif ch == 'v':
if self.str[self.i] not in "BTM":
raise Exception, "Undefined escape sequence: /v%c (%s)" % (self.str[self.i], self.str)
self.ts.valign = self.str[self.i]
self.i += 1
changed = 1
elif ch == 'h':
if self.str[self.i] not in "LRC":
raise Exception, "Undefined escape sequence: /h%c (%s)" % (self.str[self.i], self.str)
self.ts.halign = self.str[self.i]
self.i += 1
changed = 1
elif ch == 'a':
self.ts.angle = self.__parse_int()
changed = 1
else:
raise Exception, "Undefined escape sequence: /%c (%s)" % (ch, self.str)
elif self.str[self.i] == '{':
self.stack.append(self.ts.copy())
self.i += 1
elif self.str[self.i] == '}':
if len(self.stack) == 0:
raise ValueError, "unmatched '}' in \"%s\"" % (self.str)
self.ts = self.stack[-1]
del self.stack[-1]
self.i += 1
changed = 1
else:
l.append(self.str[self.i])
self.i += 1
if changed and len(l) > 0:
return self.__return_state(self.old_state, ''.join(l))
else:
# font change in the beginning of the sequence doesn't count.
self.old_state = self.ts.copy()
changed = 0
if len(l) > 0:
return self.__return_state(self.old_state, ''.join(l))
else:
return None
#
#
def unaligned_get_dimension(text):
"""Return the bounding box of the text, assuming that the left-bottom corner
of the first letter of the text is at (0, 0). This procedure ignores
/h, /v, and /a directives when calculating the BB; it just returns the
alignment specifiers as a part of the return value. The return value is a
tuple (width, height, halign, valign, angle)."""
xmax = 0
ymax = 0
ymax = 0
angle = None
halign = None
valign = None
itr = text_iterator(None)
for line in str(text).split("\n"):
cur_height = 0
cur_width = 0
itr.reset(line)
while 1:
elem = itr.next()
if not elem:
break
(font, size, line_height, color, new_h, new_v, new_a, chunk) = elem
if halign != None and new_h != halign:
raise Exception, "Only one /h can appear in string '%s'." % str(text)
if valign != None and new_v != valign:
raise Exception, "Only one /v can appear in string '%s'." % str(text)
if angle != None and new_a != angle:
raise Exception, "Only one /a can appear in string '%s'." % str(text)
halign = new_h
valign = new_v
angle = new_a
cur_width += line_width(font, size, chunk)
cur_height = max(cur_height, line_height)
xmax = max(cur_width, xmax)
ymax += cur_height
return (xmax, ymax,
halign or theme.default_font_halign,
valign or theme.default_font_valign,
angle or theme.default_font_angle)
def get_dimension(text):
"""Return the bounding box of the <text>,
assuming that the left-bottom corner
of the first letter of the text is at (0, 0). This procedure ignores
/h, /v, and /a directives when calculating the boundingbox; it just returns the
alignment specifiers as a part of the return value. The return value is a
tuple (width, height, halign, valign, angle)."""
(xmax, ymax, halign, valign, angle) = unaligned_get_dimension(text)
xmin = ymin = 0
if halign == "C":
xmin = -xmax / 2.0
xmax = xmax / 2.0
elif halign == "R":
xmin = -xmax
xmax = 0
if valign == "M":
ymin = -ymax / 2.0
ymax = ymax / 2.0
elif valign == "T":
ymin = -ymax
ymax = 0
if angle != 0:
(x0, y0) = pychart_util.rotate(xmin, ymin, angle)
(x1, y1) = pychart_util.rotate(xmax, ymin, angle)
(x2, y2) = pychart_util.rotate(xmin, ymax, angle)
(x3, y3) = pychart_util.rotate(xmax, ymax, angle)
xmax = max(x0, x1, x2, x3)
xmin = min(x0, x1, x2, x3)
ymax = max(y0, y1, y2, y3)
ymin = min(y0, y1, y2, y3)
return (xmin, xmax, ymin, ymax)
return (xmin, xmax, ymin, ymax)
def unaligned_text_width(text):
x = unaligned_get_dimension(text)
return x[0]
def text_width(text):
"""Return the width of the <text> in points."""
(xmin, xmax, d1, d2) = get_dimension(text)
return xmax-xmin
def unaligned_text_height(text):
x = unaligned_get_dimension(text)
return x[1]
def text_height(text):
"""Return the total height of the <text> and the length from the
base point to the top of the text box."""
(d1, d2, ymin, ymax) = get_dimension(text)
return (ymax-ymin, ymax)
def get_align(text):
"Return (halign, valign, angle) of the <text>."
(x1, x2, h, v, a) = unaligned_get_dimension(text)
return (h, v, a)
def quotemeta(text):
"""Quote letters with special meanings in pychart so that <text> will display
as-is when passed to canvas.show().
>>> font.quotemeta("foo/bar")
"foo//bar"
"""
text = re.sub("/", "//", text)
text = re.sub("\\{", "/{", text)
text = re.sub("\\}", "/}", text)
return text

View File

@ -1,126 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import string
import doc_support
import sys
import re
import os
import area
import arrow
import axis
import bar_plot
import line_plot
import pie_plot
import color
import error_bar
import fill_style
import font
import text_box
import line_style
import legend
import range_plot
import tick_mark
indent = 4
max_line_len = 64
def format_paragraph(fp, str):
line_len = indent
fp.write(" " * indent)
for word in str.split():
if line_len >= max_line_len:
fp.write("\n")
fp.write(" " * indent)
line_len = indent
fp.write(word + " ")
line_len += len(word) + 1
def format_string(fp, str):
str = re.sub("<<([^>]+)>>", "See also pychart.\\1", str)
str2 = ""
in_example = 0
for l in str.split("\n"):
if re.match("@example", l):
in_example = 1
if re.match("@end example", l):
in_example = 0
if in_example:
str2 += l
else:
l = re.sub("^[ \t]*", "", l)
str2 += l
str2 += "\n"
fname = os.tempnam()
out_fp = open(fname, "w")
out_fp.write(str2)
out_fp.close()
in_fp = os.popen("makeinfo --fill-column=64 --no-headers " + fname, "r")
for l in in_fp.readlines():
fp.write(" " * indent)
fp.write(l)
in_fp.close()
os.remove(fname)
def generate_doc(c, name, suffix="", append = 0):
if append:
fp = open(name + "_doc.py", "a+")
else:
fp = open(name + "_doc.py", "w")
fp.write("# automatically generated by generate_docs.py.\n")
fp.write("doc" + suffix + "=\"\"\"Attributes supported by this class are:\n")
for key in c.keys.keys():
val=c.keys[key]
desc = ""
defaultValDesc = None
if len(val) > 3:
desc = val[3]
if len(val) > 4:
defaultValDesc = val[4]
fp.write(key + "(type:" + doc_support.stringify_type(val[0]))
if defaultValDesc:
fp.write(") default:" + defaultValDesc)
else:
fp.write(") default=" + str(doc_support.stringify_value(val[2])) + ".\n")
format_string(fp, desc)
fp.write("\"\"\"\n\n")
fp.close()
generate_doc(arrow.T, "arrow")
generate_doc(area.T, "area")
generate_doc(axis.X, "axis", "_x")
generate_doc(axis.Y, "axis", "_y", 1)
generate_doc(bar_plot.T, "bar_plot")
generate_doc(line_plot.T, "line_plot")
generate_doc(pie_plot.T, "pie_plot")
generate_doc(color.T, "color")
generate_doc(error_bar.error_bar1, "error_bar","_1")
generate_doc(error_bar.error_bar2, "error_bar", "_2", 1)
generate_doc(error_bar.error_bar3, "error_bar", "_3", 1)
generate_doc(error_bar.error_bar4, "error_bar", "_4", 1)
generate_doc(error_bar.error_bar5, "error_bar", "_5", 1)
generate_doc(error_bar.error_bar6, "error_bar", "_6", 1)
generate_doc(fill_style.T, "fill_style")
generate_doc(text_box.T, "text_box")
generate_doc(range_plot.T, "range_plot")
generate_doc(legend.T, "legend")
generate_doc(legend.Entry, "legend", "_entry", 1)
generate_doc(line_style.T, "line_style")
generate_doc(tick_mark.T, "tick_mark")

View File

@ -1,88 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import pychart_util
import theme
import sys
import os
import os.path
import pscanvas
import tempfile
import string
import basecanvas
from scaling import *
def get_gs_path():
"""Guess where the Ghostscript executable is
and return its absolute path name."""
path = os.defpath
if os.environ.has_key("PATH"):
path = os.environ["PATH"]
for dir in path.split(os.pathsep):
for name in ("gs", "gs.exe", "gswin32c.exe"):
g = os.path.join(dir, name)
if os.path.exists(g):
return g
raise Exception, "Ghostscript not found."
class T(pscanvas.T):
def __write_contents(self, fp):
fp.write(pscanvas.preamble_text)
for name, id in self.__font_ids.items():
fp.write("/%s {/%s findfont SF} def\n" % (id, name))
fp.write("%d %d translate\n" % (-self.bbox[0], -self.bbox[1]))
fp.writelines(self.__output_lines)
fp.write("showpage end\n")
fp.flush()
def close(self):
# Don't call pscanvas.T.close, as it creates a
# ps file.
basecanvas.T.close(self)
def start_gs(self, arg):
self.bbox = theme.adjust_bounding_box([xscale(self.__xmin),
yscale(self.__ymin),
xscale(self.__xmax),
yscale(self.__ymax)])
gs_path = get_gs_path()
self.pipe_fp = None
if self.__output_lines == []:
return
if sys.platform != "win32" and hasattr(os, "popen"):
# UNIX-like systems
cmdline = "\"%s\" -q %s -g%dx%d -q >/dev/null 2>&1" % \
(gs_path, arg,
self.bbox[2] - self.bbox[0],
self.bbox[3] - self.bbox[1])
self.pipe_fp = os.popen(cmdline, "w")
self.__write_contents(self.pipe_fp)
else:
# XXX should use mktemp, but need to support python<=2.2 as well.
fname = tempfile.mktemp("xxx")
fp = open(fname, "wb")
self.__write_contents(fp)
fp.close()
cmdline = "\"%s\" -q %s -g%dx%d -q <%s >NUL" % \
(gs_path, arg,
self.bbox[2] - self.bbox[0],
self.bbox[3] - self.bbox[1], fname)
os.system(cmdline)
os.unlink(fname)
def close_gs(self):
if self.pipe_fp:
self.pipe_fp.close()
self.pipe_fp = None

View File

@ -1,229 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import line_style
import fill_style
import pychart_util
import chart_object
import legend
import bar_plot_doc
import theme
from types import *
from pychart_types import *
fill_styles = None
_keys = {
"direction" : (StringType, "vertical",
"""The direction the growth of the bars. The value is either 'horizontal'
or 'vertical'."""),
"data" : (AnyType, None, """Specifes data points. Unlike other types
of charts, the "hcol"th column of the data must be a sequence of
numbers, not just a single number. See also the description of
"hcol"."""
),
"data_label_offset": (CoordType, (0, 5),
"The location of data labels relative to the sample point. See also attribute data_label_format."),
"data_label_format": (FormatType, None, """The
format string for the label displayed besides each
bar. It can be a `printf' style format
string, or a two-parameter function that
takes (x,y) values and returns a string. """
+ pychart_util.string_desc),
"label": (StringType, "???", pychart_util.label_desc),
"bcol" : (IntType, 0,
"""Specifies the column from which base values (i.e., X values when attribute "direction" is "vertical", Y values otherwise) are extracted.
The
combination of "data", "bcol", and "hcol" attributes defines
the set of boxes drawn by this chart.
See also the descriptions of the 'bcol' and 'data' attributes.
"""),
"hcol": (IntType, 1,
"""The column from which the base and height of
bars are extracted. See the below example:
@example
d = [[5,[10,15,22]], [7,[22,23,5,10]], [8,[25,3]]]
p = interval_bar_plot.T(data = d, bcol = 0, hcol = 1)
@end example
Here, three sequence of bars will be drawn.
The X locations of the bars
will be 5, 7, and 8. For example, at location X=7,
three bars are drawn,
one corresponding to Y values of 22 to 45 (=22+23),
and the second one for values 45 to 50, and the third one
for values 50 to 60. The line and fill styles of the bars
are picked in a round-robin fashion
from attributes "line_styles" and
"fill_styles".
"""),
"line_styles": (ListType, [line_style.default, None],
"""The list of line styles for bars.
The style of each bar is chosen in a round-robin fashion, if the
number of elements in "line_styles" is smaller than
actual number of boxes."""),
"fill_styles": (ListType, [lambda: fill_styles.next(), None],
"""List of fill styles for bars.
The style of each bar is chosen in a round-robin fashion, if the
number of elements in "line_styles" is smaller than
actual number of boxes.
If this attribute is omitted,
a style is picked from standard styles round-robin. <<fill_style>>."""),
"cluster": (TupleType, (0, 1), """This attribute is used to
cluster multiple bar plots side by side in a single chart.
The value should be a tuple of two integers. The second value should be equal to the total number of bar plots in the chart. The first value should be the relative position of this chart; 0 places this chart the leftmost, and N-1
(where N is the 2nd value of this attribute) places this chart the rightmost. Consider the below example:
@example
a = area.T(...)
p1 = interval_bar_plot.T(data = [[1, [20,10]][2,[30,5]]], cluster=(0,2))
p2 = interval_bar_plot.T(data = [[1,[25,11,2]],[2,[10,5,3]]], cluster=(1,2))
a.add_plot(p1, p2)
a.draw()
@end example
In this example, one group of bars will be drawn side-by-side at
position x=1.
Other two bars will be drawn side by side at position x=2.
See also the description of attribute "cluster" for bar_plot.T.
"""),
"width": (UnitType, 5, """Width of each box. The unit is in points.
@cindex width, bar chart
@cindex size, bar chart
"""),
"cluster_sep": (UnitType, 0, """The separation between
clustered boxes. The unit is points."""),
"stack_on": (AnyType, None,
"The value must be either None or bar_plot.T. If not None, bars of this plot are stacked on top of another bar plot."),
}
class T(chart_object.T):
__doc__ = bar_plot_doc.doc
keys = _keys
def check_integrity(self):
self.type_check()
def get_value(self, bval):
for pair in self.data:
if pair[self.bcol] == bval:
return pair[self.hcol]
raise ValueError, str(bval) + ": can't find the xval"
def __get_data_range(self, col):
gmin = 99999999
gmax = -99999999
for item in self.data:
seq = item[col]
if seq[0] < gmin: gmin = seq[0]
max = 0
for v in seq:
max += v
if max > gmax: gmax = max
return (gmin, gmax)
def get_data_range(self, which):
if self.direction == 'vertical':
if which == 'X':
return pychart_util.get_data_range(self.data, self.bcol)
else:
return self.__get_data_range(self.hcol)
else:
assert self.direction == 'horizontal'
if which == 'Y':
return pychart_util.get_data_range(self.data, self.bcol)
else:
return self.__get_data_range(self.hcol)
def get_style(self, nth):
line_style = self.line_styles[nth % len(self.line_styles)]
fill_style = self.fill_styles[nth % len(self.fill_styles)]
return (line_style, fill_style)
def draw_vertical(self, ar, can):
for pair in self.data:
xval = pair[self.bcol]
yvals = pychart_util.get_sample_val(pair, self.hcol)
if None in (xval, yvals): continue
ybot = 0
totalWidth = (self.width+self.cluster_sep) * self.cluster[1] - self.cluster_sep
firstX = ar.x_pos(xval) - totalWidth/2.0
thisX = firstX + (self.width+self.cluster_sep) * self.cluster[0] - self.cluster_sep
cury = yvals[0]
n = 0
for yval in yvals[1:]:
(line_style, fill_style) = self.get_style(n)
can.rectangle(line_style, fill_style,
thisX, ar.y_pos(cury), thisX+self.width,
ar.y_pos(cury + yval))
cury += yval
n += 1
if self.data_label_format:
can.show(thisX + self.width/2.0 + self.data_label_offset[0],
ar.y_pos(cury) + self.data_label_offset[1],
"/hC" + pychart_util.apply_format(self.data_label_format, (pair[self.bcol], pair[self.hcol]), 1))
def draw_horizontal(self, ar, can):
for pair in self.data:
yval = pair[self.bcol]
xvals = pychart_util.get_sample_val(pair, self.hcol)
if None in (xvals, yval): continue
totalWidth = (self.width+self.cluster_sep) * self.cluster[1] - self.cluster_sep
firstY = ar.y_pos(yval) - totalWidth/2.0
thisY = firstY + (self.width+self.cluster_sep) * self.cluster[0] - self.cluster_sep
curx = xvals[0]
n = 0
for xval in xvals[1:]:
line_style, fill_style = self.get_style(n)
can.rectangle(line_style, fill_style,
ar.x_pos(curx), thisY,
ar.x_pos(xval), thisY+self.width)
curx = xval
n += 1
def get_legend_entry(self):
if self.label:
return legend.Entry(line_style=self.line_styles[0],
fill_style=self.fill_styles[0],
label=self.label)
return None
def draw(self, ar, can):
self.type_check()
can.clip(ar.loc[0], ar.loc[1],
ar.loc[0] + ar.size[0], ar.loc[1] + ar.size[1])
if self.direction == "vertical":
self.draw_vertical(ar, can)
else:
self.draw_horizontal(ar, can)
can.endclip()
def init():
global fill_styles
fill_styles = fill_style.standards.iterate()
theme.add_reinitialization_hook(init)

View File

@ -1,182 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import tick_mark
import font
import line_style
import color
import fill_style
import chart_object
import pychart_util
import types
import legend_doc
import theme
from pychart_types import *
from types import *
class Entry(chart_object.T):
keys = {"line_len" : (UnitType, None,
"Length of the sample line for line plots. If omitted, it is set to be theme.default_font_size"),
"rect_size" : (UnitType, None,
"Size of the sample 'blob' for bar range charts. If omitted, it is set to be 70% of theme.default_size"),
"tick_mark": (tick_mark.T, None, ""),
"line_style": (line_style.T, None, ""),
"fill_style": (fill_style.T, None, ""),
"label": (StringType, "???", ""),
}
__doc__ = legend_doc.doc_entry
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def label_width(self):
return font.text_width(" " + self.label)
def get_line_len(self):
return self.line_len or theme.default_font_size
def get_rect_size(self):
return self.rect_size or theme.default_font_size * 7 / 10.0
def sample_width(self):
w = 0
if self.fill_style != None:
w += self.get_line_len()
elif self.line_style != None:
w += self.get_line_len()
elif self.tick_mark != None:
w += self.tick_mark.size
return w
def height(self):
h = font.text_height(self.label)[0]
return h
def draw(self, ar, can, x_tick, x_label, y):
"""Draw a legend entry. X_TICK and X_LABEL are the X location \
(in points) of where the sample and label are drawn."""
rect_size = self.get_rect_size()
line_len = self.get_line_len()
nr_lines = len(self.label.split("\n"))
text_height = font.text_height(self.label)[0]
line_height = text_height / float(nr_lines)
y_center = y + text_height - line_height/1.5
if self.fill_style != None:
can.rectangle(self.line_style, self.fill_style,
x_tick, y_center - rect_size/2.0,
x_tick + rect_size,
y_center + rect_size/2.0)
elif self.line_style != None:
can.line(self.line_style, x_tick, y_center,
x_tick + line_len, y_center)
if self.tick_mark != None:
self.tick_mark.draw(can, x_tick + line_len/2.0, y_center)
elif self.tick_mark != None:
self.tick_mark.draw(can, x_tick, y_center)
can.show(x_label, y, self.label)
__doc__ = """Legend is a rectangular box drawn in a chart to describe
the meanings of plots. The contents of a legend box is extracted from
plots' "label", "line-style", and "tick-mark" attributes.
This module exports a single class, legend.T. Legend.T is a part of
an area.T object, and is drawn automatically when area.draw() method
is called. """
class T(chart_object.T):
__doc__ = legend_doc.doc
keys = {
"inter_row_sep": (UnitType, 0,
"Space between each row in the legend."),
"inter_col_sep": (UnitType, 0,
"Space between each column in the legend."),
"frame_line_style": (line_style.T, line_style.default, ""),
"frame_fill_style": (fill_style.T, fill_style.white, ""),
"top_fudge": (UnitType, 0,
"Amount of space above the first line."),
"bottom_fudge": (UnitType, 3,
"Amount of space below the last line."),
"left_fudge": (UnitType, 5,
"Amount of space left of the legend."),
"right_fudge": (UnitType, 5,
"Amount of space right of the legend."),
"loc": (CoordType, None,
"""Bottom-left corner of the legend.
The default location of a legend is the bottom-right end of the chart."""),
"shadow": (ShadowType, None, pychart_util.shadow_desc),
"nr_rows": (IntType, 9999, "Number of rows in the legend. If the number of plots in a chart is larger than nr_rows, multiple columns are created in the legend."),
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def draw(self, ar, entries, can):
if not self.loc:
x = ar.loc[0] + ar.size[0] * 1.1
y = ar.loc[1]
else:
x = self.loc[0]
y = self.loc[1]
nr_rows = min(self.nr_rows, len(entries))
nr_cols = (len(entries)-1) / nr_rows + 1
ymin = y
max_label_width = [0] * nr_cols
max_sample_width = [0] * nr_cols
heights = [0] * nr_rows
for i in range(len(entries)):
l = entries[i]
(col, row) = divmod(i, nr_rows)
max_label_width[col] = max(l.label_width(), max_label_width[col])
max_sample_width[col] = max(l.sample_width(), max_sample_width[col])
heights[row] = max(l.height(), heights[row])
for h in heights:
y += h
y += self.inter_row_sep * (nr_rows - 1)
ymax = y
tot_width = self.inter_col_sep * (nr_cols -1)
for w in max_label_width:
tot_width += w
for w in max_sample_width:
tot_width += w
can.rectangle(self.frame_line_style, self.frame_fill_style,
x - self.left_fudge,
ymin - self.bottom_fudge,
x + tot_width + self.right_fudge,
ymax + self.top_fudge,
self.shadow)
for col in range(nr_cols):
this_y = y
this_x = x
for row in range(nr_rows):
idx = col * nr_rows + row
if idx >= len(entries):
continue
this_y -= heights[row]
l = entries[idx]
if row != 0:
this_y -= self.inter_row_sep
l.draw(ar, can, this_x, this_x + max_sample_width[col], this_y)
x += max_label_width[col] + max_sample_width[col] + self.inter_col_sep

View File

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
inter_col_sep(type:length in points (\\xref{unit})) default="Space between each column in the legend.".
loc(type:(x,y)) default="Bottom-left corner of the legend.
The default location of a legend is the bottom-right end of the chart.".
bottom_fudge(type:length in points (\\xref{unit})) default="Amount of space below the last line.".
frame_line_style(type:line_style.T) default="".
nr_rows(type:int) default="Number of rows in the legend. If the number of plots in a chart is larger than nr_rows, multiple columns are created in the legend.".
right_fudge(type:length in points (\\xref{unit})) default="Amount of space right of the legend.".
inter_row_sep(type:length in points (\\xref{unit})) default="Space between each row in the legend.".
top_fudge(type:length in points (\\xref{unit})) default="Amount of space above the first line.".
left_fudge(type:length in points (\\xref{unit})) default="Amount of space left of the legend.".
shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None,
a drop-shadow is drawn beneath the object. X-off, and y-off specifies the
offset of the shadow relative to the object, and fill specifies the
style of the shadow (@pxref{module-fill-style}).".
frame_fill_style(type:fill_style.T) default="".
"""
doc_entry="""Attributes supported by this class are:
line_len(type:length in points (\\xref{unit})) default="Length of the sample line for line plots. If omitted, it is set to be theme.default_font_size".
label(type:str) default="".
rect_size(type:length in points (\\xref{unit})) default="Size of the sample 'blob' for bar range charts. If omitted, it is set to be 70% of theme.default_size".
tick_mark(type:tick_mark.T) default="".
line_style(type:line_style.T) default="".
fill_style(type:fill_style.T) default="".
"""

View File

@ -1,151 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import tick_mark
import line_style
import pychart_util
import error_bar
import chart_object
import legend
import object_set
import line_plot_doc
import theme
from pychart_types import *
from types import *
default_width = 1.2
line_style_itr = None
_keys = {
"data" : (AnyType, None, pychart_util.data_desc),
"label": (StringType, "???", pychart_util.label_desc),
"data_label_offset": (CoordType, (0, 5),
"""The location of data labels relative to the sample point. Meaningful only when data_label_format != None."""),
"data_label_format": (FormatType, None,
"""The format string for the label printed
beside a sample point.
It can be a `printf' style format string, or
a two-parameter function that takes the (x, y)
values and returns a string. """
+ pychart_util.string_desc),
"xcol" : (IntType, 0, pychart_util.xcol_desc),
"ycol": (IntType, 1, pychart_util.ycol_desc),
"y_error_minus_col": (IntType, 2,
"""The column (within "data") from which the depth of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>"""),
"y_error_plus_col": (IntType, -1,
"""The column (within "data") from which the height of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>"""),
"y_qerror_minus_col": (IntType, -1, "<<error_bar>>"),
"y_qerror_plus_col": (IntType, -1, "<<error_bar>>"),
"line_style": (line_style.T, lambda: line_style_itr.next(), pychart_util.line_desc,
"By default, a style is picked from standard styles round-robin. <<line_style>>"),
"tick_mark": (tick_mark.T, None, pychart_util.tick_mark_desc),
"error_bar": (error_bar.T, None,
"The style of the error bar. <<error_bar>>"),
}
class T(chart_object.T):
__doc__ = line_plot_doc.doc
keys = _keys
def check_integrity(self):
self.type_check()
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def get_data_range(self, which):
if which == 'X':
return pychart_util.get_data_range(self.data, self.xcol)
else:
return pychart_util.get_data_range(self.data, self.ycol)
def get_legend_entry(self):
if self.label:
return legend.Entry(line_style=self.line_style,
tick_mark=self.tick_mark,
fill_style=None,
label=self.label)
return None
def draw(self, ar, can):
# Draw the line
clipbox = theme.adjust_bounding_box([ar.loc[0], ar.loc[1],
ar.loc[0] + ar.size[0],
ar.loc[1] + ar.size[1]]);
can.clip(clipbox[0],clipbox[1],clipbox[2],clipbox[3])
if self.line_style:
points = []
for pair in self.data:
yval = pychart_util.get_sample_val(pair, self.ycol)
xval = pair[self.xcol]
if None not in (xval, yval):
points.append((ar.x_pos(xval), ar.y_pos(yval)))
can.lines(self.line_style, points)
can.endclip()
# Draw tick marks and error bars
can.clip(ar.loc[0] - 10, ar.loc[1] - 10,
ar.loc[0] + ar.size[0] + 10,
ar.loc[1] + ar.size[1] + 10)
for pair in self.data:
x = pair[self.xcol]
y = pychart_util.get_sample_val(pair, self.ycol)
if None in (x, y): continue
x_pos = ar.x_pos(x)
y_pos = ar.y_pos(y)
if self.error_bar:
plus = pair[self.y_error_plus_col or self.y_error_minus_col]
minus = pair[self.y_error_minus_col or self.y_error_plus_col]
if self.y_qerror_minus_col or self.y_qerror_plus_col:
q_plus = pair[self.y_qerror_plus_col or self.y_qerror_minus_col]
q_minus = pair[self.y_qerror_minus_col or self.y_qerror_plus_col]
if None not in (minus,plus,q_minus,q_plus):
self.error_bar.draw(can, (x_pos, y_pos),
ar.y_pos(y - minus),
ar.y_pos(y + plus),
ar.y_pos(y - q_minus),
ar.y_pos(y + q_plus))
else:
if None not in (minus,plus): #PDS
self.error_bar.draw(can, (x_pos, y_pos),
ar.y_pos(y - minus),
ar.y_pos(y + plus))
if self.tick_mark:
self.tick_mark.draw(can, x_pos, y_pos)
if self.data_label_format:
can.show(x_pos + self.data_label_offset[0],
y_pos + self.data_label_offset[1],
"/hC" + pychart_util.apply_format(self.data_label_format, (x, y), 1))
can.endclip()
def init():
global line_style_itr
line_styles = object_set.T()
for org_style in line_style.standards.list():
style = line_style.T(width = default_width, color = org_style.color,
dash = org_style.dash)
line_styles.add(style)
line_style_itr = line_styles.iterate()
theme.add_reinitialization_hook(init)

View File

@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
y_qerror_minus_col(type:int) default="<<error_bar>>".
xcol(type:int) default="The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>".
error_bar(type:error_bar.T) default="The style of the error bar. <<error_bar>>".
data_label_format(type:printf format string) default="The format string for the label printed
beside a sample point.
It can be a `printf' style format string, or
a two-parameter function that takes the (x, y)
values and returns a string. The appearance of the string produced here can be
controlled using escape sequences. <<font>>".
ycol(type:int) default="The column, within attribute "data", from which the Y values of sample points are extracted. <<chart_data>>".
label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>".
line_style(type:line_style.T) default="The style of the line. ".
By default, a style is picked from standard styles round-robin.
See also pychart.line_style
y_error_plus_col(type:int) default="The column (within "data") from which the height of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>".
tick_mark(type:tick_mark.T) default="Tick marks to be displayed at each sample point. <<tick_mark>>".
y_error_minus_col(type:int) default="The column (within "data") from which the depth of the errorbar is extracted. Meaningful only when error_bar != None. <<error_bar>>".
data_label_offset(type:(x,y)) default="The location of data labels relative to the sample point. Meaningful only when data_label_format != None.".
data(type:any) default="Specifies the data points. <<chart_data>>".
y_qerror_plus_col(type:int) default="<<error_bar>>".
"""

View File

@ -1,159 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import color
import pychart_util
import chart_object
import object_set
import theme
import line_style_doc
from pychart_types import *
from types import *
_keys = {
"width" : (UnitType, theme.default_line_width, "Width of the line, in points."),
"color": (color.T, color.default, "The color of the line."),
"dash" : (TupleType, None,
"""The value
of None will draw a solid line. Otherwise, this
attribute specifies the style of dashed lines.
The 2N'th value specifies the length of the line (in points),
and 2N+1'th value specifies the length of the blank.
For example, the dash style of (3,2,4,1) draws a dashed line that
looks like @samp{---__----_---__----_...}.
"""),
"cap_style": (IntType, 0,
"""Defines the style of the tip of the line segment.
0: butt cap (square cutoff, with no projection beyond),
1: round cap (arc), 2: projecting square cap
(square cutoff, but the line extends half the line width).
See also Postscript/PDF reference manual."""),
"join_style": (IntType, 0,
"""Join style. 0: Miter join (sharp, pointed corners),
1: round join (rounded corners),
2: bevel join (flattened corners).
See also Postscript/PDF reference manual.""")
}
class T(chart_object.T):
__doc__ = line_style_doc.doc
keys = _keys
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def __str__(self):
s = name_table().lookup(self)
if s:
return s
return "<linestyle: width=%s, color=%s, dash=%s, cap=%d, join=%d>" \
% (self.width, self.color, self.dash, self.cap_style, self.join_style)
default = T(color=color.default)
dash1 = 1.5,1.5 # - - - -
dash2 = 5,2,5,2 # -- -- -- --
dash3 = 1,1
black = T(color=color.black)
black_dash1 = T(color=color.black, dash=dash1)
black_dash2 = T(color=color.black, dash=dash2)
black_dash3 = T(color=color.black, dash=dash3)
gray70 = T(color=color.gray70)
gray70_dash1 = T(color=color.gray70, dash=dash1)
gray70_dash2 = T(color=color.gray70, dash=dash2)
gray70_dash3 = T(color=color.gray70, dash=dash3)
gray10 = T(color=color.gray10)
gray10_dash1 = T(color=color.gray10, dash=dash1)
gray10_dash2 = T(color=color.gray10, dash=dash2)
gray10_dash3 = T(color=color.gray10, dash=dash3)
gray50 = T(color=color.gray50)
gray50_dash1 = T(color=color.gray50, dash=dash1)
gray50_dash2 = T(color=color.gray50, dash=dash2)
gray50_dash3 = T(color=color.gray50, dash=dash3)
gray60 = T(color=color.gray60)
gray60_dash1 = T(color=color.gray60, dash=dash1)
gray60_dash2 = T(color=color.gray60, dash=dash2)
gray60_dash3 = T(color=color.gray60, dash=dash3)
gray90 = T(color=color.gray90)
gray90_dash1 = T(color=color.gray90, dash=dash1)
gray90_dash2 = T(color=color.gray90, dash=dash2)
gray90_dash3 = T(color=color.gray90, dash=dash3)
gray30 = T(color=color.gray30)
gray30_dash1 = T(color=color.gray30, dash=dash1)
gray30_dash2 = T(color=color.gray30, dash=dash2)
gray30_dash3 = T(color=color.gray30, dash=dash3)
white = T(color=color.white)
default = black
red = T(color=color.red)
darkblue = T(color=color.darkblue)
darkseagreen = T(color=color.darkseagreen)
darkkhaki = T(color = color.darkkhaki)
blue = T(color=color.blue)
green = T(color=color.green)
red_dash1 = T(color=color.red, dash=dash1)
darkblue_dash1 = T(color=color.darkblue, dash=dash1)
darkseagreen_dash1 = T(color=color.darkseagreen, dash=dash1)
darkkhaki_dash1 = T(color=color.darkkhaki, dash=dash1)
red_dash2 = T(color=color.red, dash=dash2)
darkblue_dash2 = T(color=color.darkblue, dash=dash2)
darkseagreen_dash2 = T(color=color.darkseagreen, dash=dash2)
darkkhaki_dash2 = T(color=color.darkkhaki, dash=dash2)
standards = None
_name_table = None
def init():
global standards, _name_table
standards = object_set.T()
if theme.use_color:
standards.add(black, red, darkblue, gray70, darkseagreen,
darkkhaki, gray30,
black_dash1, red_dash1, darkblue_dash1, gray70_dash1,
darkseagreen_dash1, darkkhaki_dash1, gray30_dash1,
black_dash2, red_dash2, darkblue_dash2, gray70_dash2,
darkseagreen_dash2, darkkhaki_dash2, gray30_dash2)
else:
standards.add(black, black_dash1, black_dash2,
gray70, gray70_dash1, gray70_dash2,
gray10, gray10_dash1, gray10_dash2,
gray50, gray50_dash1, gray50_dash2,
gray90, gray90_dash1, gray90_dash2,
gray30, gray30_dash1, gray30_dash2,
black_dash3,
gray70_dash3, gray10_dash3, gray50_dash3, gray90_dash3)
for style in standards.list():
style.width = theme.default_line_width
_name_table = None
def name_table():
global _name_table
if not _name_table:
_name_table = pychart_util.symbol_lookup_table(globals(), standards)
return _name_table
init()
theme.add_reinitialization_hook(init)

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
color(type:color.T) default="The color of the line.".
width(type:length in points (\\xref{unit})) default="Width of the line, in points.".
dash(type:tuple) default="The value
of None will draw a solid line. Otherwise, this
attribute specifies the style of dashed lines.
The 2N'th value specifies the length of the line (in points),
and 2N+1'th value specifies the length of the blank.
For example, the dash style of (3,2,4,1) draws a dashed line that
looks like @samp{---__----_---__----_...}.
".
cap_style(type:int) default="Defines the style of the tip of the line segment.
0: butt cap (square cutoff, with no projection beyond),
1: round cap (arc), 2: projecting square cap
(square cutoff, but the line extends half the line width).
See also Postscript/PDF reference manual.".
join_style(type:int) default="Join style. 0: Miter join (sharp, pointed corners),
1: round join (rounded corners),
2: bevel join (flattened corners).
See also Postscript/PDF reference manual.".
"""

View File

@ -1,38 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import coord
import math
import pychart_util
class T(coord.T):
def get_canvas_pos(self, size, val, min, max2):
return size * (val - min) / max(float(max2 - min),0.01)
def get_tics(self, min, max, interval):
v = []
x = min
while x <= max:
v.append(x)
x += interval
return v
def get_min_max(self, dmin, dmax, interval):
if not interval:
if dmax == dmin:
interval = 10
else:
interval = 10 ** (float(int(math.log(dmax-dmin)/math.log(10))))
dmin = min(dmin, pychart_util.round_down(dmin, interval))
dmax = max(dmax, pychart_util.round_up(dmax, interval) + interval/2.0)
return dmin, dmax, interval

View File

@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import coord
import math
class T(coord.T):
def get_canvas_pos(self, size, val, min, max):
if val <= 0:
return 0
xminl = math.log(min)
xmaxl = math.log(max)
vl = math.log(val)
return size * (vl-xminl) / float(xmaxl-xminl)
def get_tics(self, min, max, interval):
"Generate the list of places for drawing tick marks."
v = []
if min <= 0:
raise Exception, "Min value (%s) < 0 in a log coordinate." % min
x = min
while x <= max:
v.append(x)
x = x * interval
return v
def get_min_max(self, dmin, dmax, interval):
interval = interval or 10
dmin = max(0, dmin) # we can't have a negative value with a log scale.
v = 1.0
while v > dmin:
v = v / interval
dmin = v
v = 1.0
while v < dmax:
v = v * interval
dmax = v
return dmin, dmax, interval

View File

@ -1,44 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
class T(object):
def __init__(self, *objs):
self.__objs = list(objs)
def add(self, *objs):
self.__objs.extend(objs)
def add_objects(self, objs):
self.__objs.extend(objs)
def iterate(self):
return Iterator(self)
def list(self):
return self.__objs
def __getitem__(self, idx):
return self.__objs[idx]
def nth(self, idx):
return self.__objs[idx]
class Iterator(object):
def __init__(self, set_):
self.__set = set_
self.__idx = 0
def reset(self):
self.__idx = 0
def next(self):
val = self.__set.nth(self.__idx)
self.__idx += 1
if self.__idx >= len(self.__set.list()):
self.__idx = 0
return val

View File

@ -1,298 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import pychart_util
import string
import re
import math
import theme
import os
import basecanvas
from scaling import *
try:
import zlib
_zlib_available_p = 1
except:
_zlib_available_p = 0
class pdf_stream(object):
def __init__(self, fp):
self.fp = fp
self.off = 0
def write(self, str):
self.fp.write(str)
self.off += len(str)
def tell(self):
return self.off
def to_radian(deg):
return deg*2*math.pi / 360.0
class T(basecanvas.T):
def __init__(self, fname, compress_p_):
basecanvas.T.__init__(self)
self.__out_fname = fname
self.__reset_context()
self.__next_obj_id = 1
self.__next_font_id = 1
self.__obj_offsets = {}
self.__registered_fonts = {}
self.__lines = []
self.__nr_gsave = 0
if compress_p_ and not _zlib_available_p:
pychart_util.warn("Zlib not available. Compression request ignored.\n")
compress_p_ = 0
self.__compress_p = compress_p_
def __intern_font(self, name):
"Assign an ID to the font NAME. Return its ID."
if not self.__registered_fonts.has_key(name):
self.__registered_fonts[name] = self.__next_font_id
self.__next_font_id += 1
return self.__registered_fonts[name]
def __define_obj(self, fp, str):
obj_id = self.__next_obj_id
self.__next_obj_id += 1
self.__obj_offsets[obj_id] = fp.tell()
fp.write("%d 0 obj\n%s\nendobj\n" % (obj_id, str))
return obj_id
def __define_stream_obj(self, fp, s):
if self.__compress_p:
p = zlib.compress(s)
return self.__define_obj(fp, "<</Length %d/Filter/FlateDecode>>\nstream\n%sendstream"
% (len(p), p))
else:
return self.__define_obj(fp, "<</Length %d\n>>\nstream\n%s\nendstream"
% (len(s), s))
def __define_font_obj(self, fp, name, font_id):
obj_id = self.__define_obj(fp, """<</Type/Font /Subtype/Type1 /Name/F%d /BaseFont/%s /Encoding/MacRomanEncoding>>""" % (font_id, name))
return obj_id
def __reset_context(self):
self.__font_name = None
self.__font_size = -1
self.__line_style = None
self.__fill_color = None
self.__stroke_color = None
self.__mtx_pushed = 0
def newpath(self):
pass
def set_fill_color(self, color):
if self.__fill_color == color:
return
if color.r == color.g and color.r == color.b:
self.__write("%f g\n" % (color.r))
self.__write("%f G\n" % (color.r))
else:
self.__write("%f %f %f rg\n" % (color.r, color.g, color.b))
self.__write("%f %f %f RG\n" % (color.r, color.g, color.b))
self.__fill_color = color
def set_stroke_color(self, color):
self.set_fill_color(color)
return
def __arcsub(self, x, y, radius, start, theta):
xcos = math.cos(to_radian(theta))
xsin = math.sin(to_radian(theta))
x0 = radius * xcos
y0 = radius * xsin
x1 = radius * (4-xcos)/3.0
y1 = radius * (1-xcos)*(xcos-3)/(3*xsin)
xx0, xy0 = pychart_util.rotate(x0, y0, start+theta)
xx1, xy1 = pychart_util.rotate(x1, -y1, start+theta)
xx2, xy2 = pychart_util.rotate(x1, y1, start+theta)
self.__write("%f %f %f %f %f %f c\n" %
(x+xx1, y+xy1, x+xx2, y+xy2, x+xx0, y+xy0))
def path_arc(self, x, y, radius, ratio, start, end):
self.comment("PATHARC %f %f %f %f %f %f\n"
% (x, y, radius, ratio, start, end))
step = 10
if radius < 10:
step = 20
if radius < 5:
step = 30
if ratio != 1.0:
self.push_transformation((x, y), (1, ratio), None)
deg = start
while deg < end:
theta = min(step, end-deg)
self.__arcsub(x, y, radius, deg, theta/2)
deg += theta
self.pop_transformation()
else:
deg = start
while deg < end:
theta = min(step, end-deg)
self.__arcsub(x, y, radius, deg, theta/2)
deg += theta
self.comment("end PATHARC\n")
def text_begin(self):
self.__write("BT ")
self.__font_name = None
self.__font_size = None
def text_end(self):
self.__write("ET\n")
def text_moveto(self, x, y, angle):
if angle != None:
xcos = math.cos(to_radian(angle))
xsin = math.sin(to_radian(angle))
self.__write("%f %f %f %f %f %f Tm " % (xcos, xsin, -xsin, xcos, x, y))
else:
self.__write("1 0 0 1 %f %f Tm " % (x, y))
def text_show(self, font_name, font_size, color, str):
if self.__font_name != font_name or self.__font_size != font_size:
font_id = self.__intern_font(font_name)
self.__write("/F%d %d Tf " % (font_id, font_size))
self.__font_name = font_name
self.__font_size = font_size
self.set_fill_color(color)
self.__write("(%s) Tj " % (str))
def push_transformation(self, baseloc, scale, angle, in_text = 0):
if in_text:
op = "Tm"
else:
op = "cm"
self.gsave()
if baseloc == None:
baseloc = (0,0)
if angle != None:
radian = to_radian(angle)
self.__write("%f %f %f %f %f %f %s\n" %
(math.cos(radian), math.sin(radian),
-math.sin(radian), math.cos(radian),
baseloc[0], baseloc[1], op))
if scale != None:
self.__write("%f 0 0 %f %f %f %s\n" % (scale[0], scale[1],
baseloc[0],
baseloc[1], op))
def pop_transformation(self, in_text = 0):
if not in_text:
self.grestore()
def closepath(self):
self.__write("h\n")
def clip_sub(self):
self.__write("W n\n")
def fill(self):
self.__write("f n\n")
def gsave(self):
self.__write("q\n")
def grestore(self):
self.__write("Q\n")
self.__reset_context()
def moveto(self, x, y):
self.__write('%f %f m ' % (x, y))
def lineto(self, x, y):
self.__write("%f %f l\n" % (x, y))
def stroke(self):
self.__write("S\n")
def set_line_style(self, style):
if (self.__line_style == style):
pass
else:
self.set_stroke_color(style.color)
self.__write("%f w " % nscale(style.width))
if style.dash != None:
self.__write("[%s] 0 d\n" %
" ".join(map(str, nscale_seq(style.dash))))
else:
self.__write("[] 0 d\n")
self.__write("%d j %d J\n" % (style.cap_style, style.join_style))
self.__line_style = style
def comment(self, str):
if not self.__compress_p:
self.__write("%%" + str + "\n")
def verbatim(self, str):
self.__write(str)
def __write(self, str):
self.__lines.append(str)
# def setbb(self, xmin, ymin, xmax, ymax):
# self.__xmin = xmin
# self.__ymin = ymin
# self.__xmax = xmax
# self.__ymax = ymax
def close(self):
basecanvas.T.close(self)
if self.__lines == []:
return
_fp, need_close = self.open_output(self.__out_fname)
fp = pdf_stream(_fp)
fp.write("%PDF-1.2\n")
stream_obj_id = self.__define_stream_obj(fp, " ".join(self.__lines))
fontstr = ""
for font_name, font_id in self.__registered_fonts.items():
obj_id = self.__define_font_obj(fp, font_name, font_id)
fontstr += "/F%d %d 0 R " % (font_id, obj_id)
pages_obj_id = self.__define_obj(fp, " <</Type/Pages /Kids [%d 0 R] /Count 1 >>" % (self.__next_obj_id + 1))
bbox = theme.adjust_bounding_box([xscale(self.__xmin), yscale(self.__ymin),
xscale(self.__xmax), yscale(self.__ymax)])
page_obj_id = self.__define_obj(fp, """ <</Type/Page
\t/Parent %d 0 R
\t/Contents %d 0 R
\t/MediaBox [%d %d %d %d]
\t/Resources << /ProcSet [/PDF /Text]
\t\t/Font << %s >>
>> >>""" % (pages_obj_id, stream_obj_id,
bbox[0], bbox[1], bbox[2], bbox[3], fontstr))
info_str = "/Producer (%s)\n/CreationDate (%s)" % (self.creator, self.creation_date)
if self.title:
info_str += "\n/Title (%s)" % (self.title, )
if self.author:
info_str += "\n/Author (%s)" % (self.author, )
info_obj_id = self.__define_obj(fp, """<<%s>>""" % info_str)
catalog_obj_id = self.__define_obj(fp, """ <</Type/Catalog/Pages %d 0 R>>""" % (pages_obj_id))
xref_offset = fp.tell()
fp.write("xref\n0 %d\n" % (len(self.__obj_offsets)+1))
fp.write("0000000000 65535 f \n")
id = 1
while id <= len(self.__obj_offsets):
fp.write("%010d 00000 n \n" % (self.__obj_offsets[id]))
id += 1
fp.write("trailer << /Size %d /Root %d 0 R /Info %d 0 R\n>>\n" % (len(self.__obj_offsets)+1, catalog_obj_id, info_obj_id))
fp.write("startxref\n%d\n%%%%EOF\n" % xref_offset)
if need_close:
_fp.close()

View File

@ -1,149 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import text_box
import fill_style
import line_style
import pychart_util
import chart_object
import arrow
import legend
import font
import pie_plot_doc
import theme
from pychart_types import *
from types import *
class T(chart_object.T):
__doc__ = pie_plot_doc.doc
keys = {
"start_angle" : (NumType, 90,
"""The angle at which the first item is drawn."""),
"center" : (CoordType, None, "The location of the center of the pie."),
"radius" : (UnitType, None, "The radius of the pie."),
"line_style" : (line_style.T, line_style.default, "The style of the outer edge of each pie slice."),
"fill_styles" : (ListType, fill_style.standards.list(),
"""The fill style of each item. The length of the
list should be equal to the length of the data.
"""),
"arc_offsets" : (ListType, None,
"""You can draw each pie "slice" shifted off-center.
This attribute, if non-None,
must be a number sequence whose length is equal to
the number of pie slices. The Nth value in arc_offsets
specify the amount of offset
(from the center of the circle)
for the Nth slice.
The value of None will draw all the slices
anchored at the center.
"""
),
"data" : (AnyType, None, pychart_util.data_desc),
"label_format" : (FormatType, "%s",
"Format string of the label"),
"label_col" : (IntType, 0,
"""The column, within "data", from which the labels of items are retrieved."""),
"data_col": (IntType, 1,
""" The column, within "data", from which the data values are retrieved."""),
"label_offset": (UnitType, None, "The distance from the center of each label."),
"arrow_style": (arrow.T, None,
"""The style of arrow that connects a label
to the corresponding "pie"."""),
"label_line_style": (line_style.T, None, "The style of the frame surrounding each label."),
"label_fill_style": (fill_style.T, fill_style.default, "The fill style of the frame surrounding each label."),
"shadow": (ShadowType, None, pychart_util.shadow_desc)
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def _total(self):
v = 0
for val in self.data:
v += val[self.data_col]
return v
def check_integrity(self):
self.type_check()
def get_data_range(self, which):
return (0, 1)
def get_legend_entry(self):
legends = []
i = 0
for val in self.data:
fill = self.fill_styles[i]
i = (i + 1) % len(self.fill_styles)
legends.append(legend.Entry(line_style=self.line_style,
fill_style=fill,
label=val[self.label_col]))
return legends
def draw(self, ar, can):
center = self.center
if not center:
center = (ar.loc[0] + ar.size[0]/2.0,
ar.loc[1] + ar.size[1]/2.0)
radius = self.radius
if not radius:
radius = min(ar.size[0]/2.0, ar.size[1]/2.0) * 0.5
label_offset = radius + (self.label_offset or radius * 0.1)
total = self._total()
i = 0
cur_angle = self.start_angle
for val in self.data:
fill = self.fill_styles[i]
degree = 360 * float(val[self.data_col]) / float(total)
off = (0, 0)
if len(self.arc_offsets) > i:
off = pychart_util.rotate(self.arc_offsets[i], 0, cur_angle - degree/2.0)
x_center = center[0]+ off[0]
y_center = center[1]+ off[1]
can.ellipsis(self.line_style, fill,
x_center, y_center, radius, 1,
cur_angle - degree, cur_angle,
self.shadow)
label = pychart_util.apply_format(self.label_format, val,
self.label_col)
if label != None:
(x_label, y_label) = pychart_util.rotate(label_offset, 0, cur_angle - degree/2.0)
(x_arrowtip, y_arrowtip) = pychart_util.rotate(radius, 0, cur_angle - degree/2.0)
# Labels on left side of pie need
# their text to avoid obscuring the pie
if x_label < 0:
x_label = x_label - font.text_width(label)
t = text_box.T(loc = (x_label + x_center, y_label + y_center),
text = label,
line_style = self.label_line_style,
fill_style = self.label_fill_style)
if self.arrow_style:
t.add_arrow((x_arrowtip + x_center, y_arrowtip + y_center),
None, self.arrow_style)
t.draw(can)
cur_angle = (cur_angle - degree) % 360
i = (i + 1) % len(self.fill_styles)
def init():
old_val = T.keys["fill_styles"]
T.keys["fill_styles"] = (old_val[0], fill_style.standards.list(),
old_val[2])
theme.add_reinitialization_hook(init)

View File

@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
label_fill_style(type:fill_style.T) default="The fill style of the frame surrounding each label.".
center(type:(x,y)) default="The location of the center of the pie.".
arrow_style(type:arrow.T) default="The style of arrow that connects a label
to the corresponding "pie".".
start_angle(type:number) default="The angle at which the first item is drawn.".
label_format(type:printf format string) default="Format string of the label".
arc_offsets(type:list) default="You can draw each pie "slice" shifted off-center.
This attribute, if non-None,
must be a number sequence whose length is equal to
the number of pie slices. The Nth value in arc_offsets
specify the amount of offset
(from the center of the circle)
for the Nth slice.
The value of None will draw all the slices
anchored at the center.
".
label_offset(type:length in points (\\xref{unit})) default="The distance from the center of each label.".
label_line_style(type:line_style.T) default="The style of the frame surrounding each label.".
label_col(type:int) default="The column, within "data", from which the labels of items are retrieved.".
data_col(type:int) default=" The column, within "data", from which the data values are retrieved.".
radius(type:length in points (\\xref{unit})) default="The radius of the pie.".
fill_styles(type:list) default="The fill style of each item. The length of the
list should be equal to the length of the data.
".
line_style(type:line_style.T) default="The style of the outer edge of each pie slice.".
data(type:any) default="Specifies the data points. <<chart_data>>".
shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None,
a drop-shadow is drawn beneath the object. X-off, and y-off specifies the
offset of the shadow relative to the object, and fill specifies the
style of the shadow (@pxref{module-fill-style}).".
"""

View File

@ -1,56 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import os
import gs_frontend
import theme
class T(gs_frontend.T):
def close(self):
gs_frontend.T.close(self)
if self.__output_lines == []:
return
if theme.use_color:
gs_args = "-sDEVICE=png256 -dTextAlphaBits=4 -q -dNOPAUSE" #PDS
else:
gs_args = "-sDEVICE=pnggray -dTextAlphaBits=4 -q -dNOPAUSE" #PDS
temp_fname = None # the temporary file desc.
out_fd = None # the final destination.
if self.__out_fname and isinstance(self.__out_fname, str):
gs_args += " -sOutputFile=%s" % self.__out_fname
else:
if not self.__out_fname:
out_fd = sys.stdout
else:
if not hasattr(self.__out_fname, "write"):
raise Exception, "Expecting either a filename or a file-like object, but got %s" % self.__out_fname
out_fd = self.__out_fname
import tempfile
temp_fname = tempfile.mktemp()
gs_args += " -sOutputFile=%s" % temp_fname
self.start_gs(gs_args)
self.close_gs()
if temp_fname:
temp_fd = file(temp_fname, 'rb')
out_fd.write(temp_fd.read())
temp_fd.close()

View File

@ -1,258 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import re
import theme
import version
import basecanvas
from scaling import *
comment_p = 0
class T(basecanvas.T):
def __init__(self, fname):
basecanvas.T.__init__(self)
self.__out_fname = fname
self.__reset_context()
self.__output_lines = []
self.__nr_gsave = 0
self.__font_ids = {}
self.__nr_fonts = 0
def __reset_context(self):
self.__font_name = None
self.__font_size = -1
self.__line_style = None
self.__color = None
self.__mtx_pushed = 0
self.__txtmtx_pushed = 0
def __intern_font(self, name):
if self.__font_ids.has_key(name):
return self.__font_ids[name]
id = "F%d" % self.__nr_fonts
self.__nr_fonts += 1
self.__font_ids[name] = id
return id
def newpath(self):
self.__write("N\n")
def stroke(self):
self.__write("ST\n")
def closepath(self):
self.__write("CP\n")
def moveto(self, x, y):
self.__write('%g %g M\n' % (x, y))
def set_fill_color(self, color):
if self.__color == color:
pass
else:
if color.r == color.g and color.r == color.b:
self.__write("%g SG\n" % color.r)
else:
self.__write("%g %g %g SC\n" % (color.r, color.g, color.b))
self.__color = color
def set_stroke_color(self, color):
self.set_fill_color(color)
def set_line_style(self, style):
self.set_stroke_color(style.color)
if (self.__line_style == style):
pass
else:
self.__write("%g %d %d " % (nscale(style.width),
style.cap_style, style.join_style))
if style.dash != None:
self.__write("[%s] 0 SLD " %
" ".join(map(str, nscale_seq(style.dash))))
else:
self.__write("SL ")
self.__line_style = style
def gsave(self):
self.__nr_gsave += 1
self.__write("GS\n")
def grestore(self):
self.__write("GR\n")
self.__nr_gsave -= 1
self.__reset_context()
def clip_sub(self):
self.__write("clip\n")
def path_arc(self, x, y, radius, ratio, start_angle, end_angle):
self.push_transformation((x, y), (1, ratio), None)
self.__write("0 0 %g %g %g arc\n" % (radius, start_angle, end_angle))
self.pop_transformation()
def curveto(self, a,b,c,d,e,f):
self.__write("%g %g %g %g %g %g curveto\n" % (a,b,c,d,e,f))
def push_transformation(self, baseloc, scale, angle, in_text=0):
self.__mtx_pushed += 1
self.__write("GB\n")
if baseloc != None:
self.__write("%g %g T\n" % (baseloc[0], baseloc[1]))
if angle != None and angle != 0:
self.__write("%g R\n" % (angle))
if scale != None:
self.__write("%g %g scale\n" % (scale[0], scale[1]))
def pop_transformation(self, in_text=0):
if self.__mtx_pushed == 0:
raise ValueError, "mtx not pushed"
self.__mtx_pushed -= 1
self.__write("GE\n")
def text_begin(self):
self.__txtmtx_pushed += 1
self.__write("TB\n")
def text_end(self):
self.__txtmtx_pushed -= 1
self.__write("TE\n")
def text_moveto(self, x, y, angle):
self.__write("%g %g T " % (x,y))
if angle != None and angle != 0:
self.__write("%g R " % angle)
self.moveto(0, 0)
def text_show(self, font_name, size, color, str):
self.set_fill_color(color)
if (self.__font_name == font_name and self.__font_size == size):
pass
else:
id = self.__intern_font(font_name)
self.__write("%g %s\n" % (size, id))
self.__font_name = font_name
self.__font_size = size
self.__write("(%s) show\n" % (str))
def _path_polygon(self, points):
if (len(points) == 4
and points[0][0] == points[1][0]
and points[2][0] == points[3][0]
and points[0][1] == points[3][1]
and points[1][1] == points[2][1]):
# a rectangle.
(xmin, ymin, xmax, ymax) = basecanvas._compute_bounding_box(points)
if basecanvas.invisible_p(xmax, ymax):
return
self.setbb(xmin, ymin)
self.setbb(xmax, ymax)
self.__write("%g %g %g %g RECT\n" % \
(xscale(points[0][0]), yscale(points[0][1]),
xscale(points[2][0]), yscale(points[2][1])))
else:
basecanvas.T._path_polygon(self, points)
def lineto(self, x, y):
self.__write("%g %g L\n" % (x, y))
def fill(self):
self.__write("fill\n")
def comment(self, str):
if comment_p:
self.verbatim("%" + str)
def verbatim(self, str):
self.__write(str)
def close(self):
basecanvas.T.close(self)
if self.__output_lines == []:
return
fp, need_close = self.open_output(self.__out_fname)
if self.__nr_gsave != 0:
raise Exception, "gsave misnest (%d)" % (self.__nr_gsave)
self.write_preamble(fp)
fp.writelines(self.__output_lines)
fp.writelines(["showpage end\n",
"%%Trailer\n",
"%%EOF\n"])
if need_close:
fp.close()
def __write(self, str):
self.__output_lines.append(str)
def writelines(self, l):
self.__output_lines.extend(l)
def write_preamble(self, fp):
bbox = [self.__xmin-1, self.__ymin-1, self.__xmax+1, self.__ymax+1]
fp.write("%!PS-Adobe-2.0 EPSF-1.2\n")
fp.write("%%Title: " + self.title + "\n")
fp.write("%%Creator: " + self.creator + "\n")
if self.author:
fp.write("%%Author: " + self.author + "\n")
fp.write("%%CreationDate: " + self.creation_date + "\n")
fp.write("%%DocumentFonts: " + " ".join(self.__font_ids.keys()) + "\n")
fp.write("%%Pages: 1\n")
bbox = theme.adjust_bounding_box(bbox)
fp.write("%%%%BoundingBox: %d %d %d %d\n" % \
(round(xscale(bbox[0])),
round(yscale(bbox[1])),
round(xscale(bbox[2])),
round(yscale(bbox[3]))))
fp.write("%%EndComments\n")
if self.aux_comments != "":
for line in self.aux_comments.split("\n"):
fp.write("% " + line + "\n")
fp.write(preamble_text)
for name, id in self.__font_ids.items():
fp.write("/%s {/%s findfont SF} def\n" % (id, name))
fp.write("%%EndProlog\n%%Page: 1 1\n")
preamble_text="""
40 dict begin
/RECT {4 dict begin
/y2 exch def
/x2 exch def
/y1 exch def
/x1 exch def
newpath x1 y1 moveto x2 y1 lineto x2 y2 lineto x1 y2 lineto closepath
end
} def
/SF {exch scalefont setfont} def
/TB {matrix currentmatrix} def
/TE {setmatrix} def
/GB {matrix currentmatrix} def
/GE {setmatrix} def
/SG {1 1 1 setrgbcolor setgray} def
/SC {1 setgray setrgbcolor} def
/SL {[] 0 setdash setlinejoin setlinecap setlinewidth} def
/SLD {setdash setlinejoin setlinecap setlinewidth} def
/M {moveto} def
/L {lineto} def
/T {translate} def
/R {rotate} def
/N {newpath} def
/ST {stroke} def
/CP {closepath} def
/GR {grestore} def
/GS {gsave} def
"""
# SL: set line style.
# width [dash] x linecap linejoin SL ->
# SF: set font.
# name size SF ->

View File

@ -1,71 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import pychart_util
import types
AnyType = 9998
def CoordType(val):
if type(val) != types.TupleType and type(val) != types.ListType:
return (" not a valid coordinate.")
if len(val) != 2:
return "Coordinate must be a pair of numbers.\n"
if val[0] != None:
error = NumType(val[0])
if error: return error
if val[1] != None:
error = NumType(val[1])
if error: return error
return None
def IntervalType(val):
if type(val) in (types.IntType, types.LongType,
types.FloatType, types.FunctionType):
return None
return "Expecting a number or a function"
def CoordOrNoneType(val):
if type(val) not in (types.TupleType, types.ListType):
return "Expecting a tuple or a list."
if len(val) != 2:
return "Coordinate must be a pair of numbers.\n"
for v in val:
if v != None and NumType(val[0]) != None:
return "Expecting a pair of numbers"
return None
def NumType(val):
if type(val) in (types.IntType, types.LongType, types.FloatType):
return None
else:
return "Expecting a number, found \"" + str(val) + "\""
def UnitType(val):
if type(val) in (types.IntType, types.LongType, types.FloatType):
return None
else:
return "Expecting a unit, found \"" + str(val) + "\""
def ShadowType(val):
if type(val) not in (types.TupleType, types.ListType):
return "Expecting tuple or list."
if len(val) != 3:
return "Expecting (xoff, yoff, fill)."
return None
def FormatType(val):
if type(val) in (types.StringType, types.FunctionType):
return None
return "Format must be a string or a function"

View File

@ -1,143 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import math
import types
import traceback
from types import *
def inch_to_point(inch):
return inch * 72.0
def point_to_inch(pt):
return float(pt) / 72.0
def rotate(x, y, degree):
"""Rotate a coordinate around point (0,0).
- x and y specify the coordinate.
- degree is a number from 0 to 360.
Returns a new coordinate.
"""
radian = float(degree) * 2 * math.pi / 360.0
newx = math.cos(radian) * x - math.sin(radian) * y
newy = math.sin(radian) * x + math.cos(radian) * y
return (newx, newy)
debug_level = 1
def warn(*strs):
for s in strs:
sys.stderr.write(str(s))
sys.stderr.write(" ")
sys.stderr.write("\n")
def info(*strs):
if debug_level < 100:
return
for s in strs:
sys.stderr.write(str(s))
sys.stderr.write("\n")
def get_sample_val(l, col):
if len(l) <= col:
return None
return l[col]
def get_data_list(data, col):
# data = [ elem[col] for elem in data if elem[col] != None ]
r = []
for item in data:
val = get_sample_val(item, col)
if val != None:
r.append(val)
return r
def get_data_range(data, col):
data = get_data_list(data, col)
for item in data:
if type(item) not in (types.IntType, types.LongType, types.FloatType):
raise TypeError, "Non-number passed to data: %s" % (data)
return (min(data), max(data))
def round_down(val, bound):
return int(val/float(bound)) * bound
def round_up(val, bound):
return (int((val-1)/float(bound))+1) * bound
#
# Attribute type checking stuff
#
def new_list():
return []
def union_dict(dict1, dict2):
dict = dict1.copy()
dict.update(dict2)
return dict
def TextVAlignType(val):
if val in ('T', 'B', 'M', None):
return None
return "Text vertical alignment must be one of T(op), B(ottom), or M(iddle).\n"
def TextAlignType(val):
if val in ('C', 'R', 'L', None):
return None
return "Text horizontal alignment must be one of C(enter), R(ight), or L(eft)."
def apply_format(format, val, defaultidx):
if format == None:
return None
elif type(format) == StringType:
return format % val[defaultidx]
else:
return apply(format, val)
data_desc = "Specifies the data points. <<chart_data>>"
label_desc = "The label to be displayed in the legend. <<legend>>, <<font>>"
xcol_desc = """The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>"""
ycol_desc = """The column, within attribute "data", from which the Y values of sample points are extracted. <<chart_data>>"""
tick_mark_desc = "Tick marks to be displayed at each sample point. <<tick_mark>>"
line_desc="The style of the line. "
def interval_desc(w):
return "When the value is a number, it specifies the interval at which %s are drawn. Otherwise, the value must be a function that takes no argument and returns the list of numbers. The return value specifies the X or Y points at which %s are drawn." % (w,w)
shadow_desc = """The value is either None or a tuple. When non-None,
a drop-shadow is drawn beneath the object. X-off, and y-off specifies the
offset of the shadow relative to the object, and fill specifies the
style of the shadow (@pxref{module-fill-style})."""
string_desc = """The appearance of the string produced here can be
controlled using escape sequences. <<font>>"""
#
#
class symbol_lookup_table:
def __init__(self, dict, objs):
self.names = {}
for name, val in dict.items():
for obj in objs.list():
if val == obj:
self.names[val] = name
break
def lookup(self, obj):
if self.names.has_key(obj):
return self.names[obj]
return None

View File

@ -1,145 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import line_style
import pychart_util
import chart_object
import fill_style
import legend
import range_plot_doc
from pychart_types import *
from types import *
from scaling import *
class T(chart_object.T):
__doc__ = range_plot_doc.doc
keys = {
"data" : (AnyType, None, pychart_util.data_desc),
"label": (StringType, "???", pychart_util.label_desc),
"xcol" : (IntType, 0, pychart_util.xcol_desc),
"min_col": (IntType, 1,
"The lower bound of the sweep is extracted from "
+ "this column of data."),
"max_col": (IntType, 2,
"The upper bound of the sweep is extracted from "
+ "this column of data."),
"line_style": (line_style.T, line_style.default,
"The style of the boundary line."),
"fill_style": (fill_style.T, fill_style.default,
""),
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def check_integrity(self):
self.type_check()
def get_data_range(self, which):
if which == 'X':
return pychart_util.get_data_range(self.data, self.xcol)
else:
ymax = (pychart_util.get_data_range(self.data, self.max_col))[1]
ymin = (pychart_util.get_data_range(self.data, self.min_col))[0]
return (ymin, ymax)
def get_legend_entry(self):
if self.label:
return legend.Entry(line_style=self.line_style,
fill_style=self.fill_style,
label=self.label)
return None
def draw(self, ar, can):
prevPair = None
xmin=999999
xmax=-999999
ymin=999999
ymax=-999999
# Draw the boundary in a single stroke.
can.gsave()
can.newpath()
for pair in self.data:
x = pair[self.xcol]
y = pychart_util.get_sample_val(pair, self.max_col)
if y == None:
continue
xmin = min(xmin, ar.x_pos(x))
xmax = max(xmax, ar.x_pos(x))
ymin = min(ymin, ar.y_pos(y))
ymax = max(ymax, ar.y_pos(y))
if prevPair != None:
can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
else:
can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
prevPair = pair
for i in range(len(self.data)-1, -1, -1):
pair = self.data[i]
x = pair[self.xcol]
y = pychart_util.get_sample_val(pair, self.min_col)
if None in (x, y):
continue
xmin = min(xmin, ar.x_pos(x))
xmax = max(xmax, ar.x_pos(x))
ymin = min(ymin, ar.y_pos(y))
ymax = max(ymax, ar.y_pos(y))
can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
can.closepath()
# create a clip region, and fill it.
can.clip_sub()
can.fill_with_pattern(self.fill_style, xmin, ymin, xmax, ymax)
can.grestore()
if self.line_style:
# draw the boundary.
prevPair = None
can.newpath()
can.set_line_style(self.line_style)
for pair in self.data:
x = pair[self.xcol]
y = pychart_util.get_sample_val(pair, self.min_col)
if None in (x, y):
continue
if prevPair != None:
can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
else:
can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
prevPair = pair
can.stroke()
prevPair = None
can.newpath()
can.set_line_style(self.line_style)
for pair in self.data:
x = pair[self.xcol]
y = pychart_util.get_sample_val(pair, self.max_col)
if y == None:
continue
if prevPair != None:
can.lineto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
else:
can.moveto(xscale(ar.x_pos(x)), yscale(ar.y_pos(y)))
prevPair = pair
can.stroke()

View File

@ -1,12 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
xcol(type:int) default="The column, within attribute "data", from which the X values of sample points are extracted. <<chart_data>>".
max_col(type:int) default="The upper bound of the sweep is extracted from this column of data.".
min_col(type:int) default="The lower bound of the sweep is extracted from this column of data.".
label(type:str) default="The label to be displayed in the legend. <<legend>>, <<font>>".
line_style(type:line_style.T) default="The style of the boundary line.".
fill_style(type:fill_style.T) default="".
data(type:any) default="Specifies the data points. <<chart_data>>".
"""

View File

@ -1,144 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import canvas
import fill_style
import line_style
import pychart_util
import chart_object
import legend
import font
import color
from pychart_types import *
class T(chart_object.T):
"""Plots sector diagram which can be superimposed on one another.
Sector diagrams are also known as wind roses"""
keys = {
"start_angle" : (NumType, 90, ""), # top of chart (north)
"center" : (CoordType, None, ""),
"base_radius" : (NumType, None, ""),
"line_style" : (line_style.T, line_style.T(color=color.black, width=0.3), ""),
"fill_styles" : (list, fill_style.standards.list()[:],
"""The fill style of each item. The length of the
list should be equal to the length of the data.
"""),
"sector_centred":(int, 1,
"""Bool indicating whether the sectors should be centred on each sector_width(e.g. on 0)"""),
"dir_offset": (UnitType, None,
"""The distance between the directions and the outermost circle. Defaults fine for most cases"""),
"data" : (AnyType, None, pychart_util.data_desc),
"label_col" : (int, 0,
"""The column, within "data", from which the labels of items are retrieved."""),
"data_col": (int, 1,
""" The column, within "data", from which the data values are retrieved."""),
"dir_line_style": (line_style.T, None, ""),
"dir_fill_style": (fill_style.T, fill_style.default, ""),
"shadow": (ShadowType, None, pychart_util.shadow_desc),
"sector_width": (int, None, ""), # automatically generated
}
def __init__(self, colour=True, **args):
chart_object.T.init(self, args)
if colour:
# the theme.color flag does not seem to affect the fill_style.standards,
#besides, I want the first two colors to resemble those of gnuplot's postscript terminal
self.fill_styles = [fill_style.Plain(bgcolor=color.red),
fill_style.Plain(bgcolor=color.green),
fill_style.Plain(bgcolor=color.blue),
fill_style.Plain(bgcolor=color.magenta)]
def check_integrity(self):
nSectors = len(self.data[0][self.data_col])
if (360%nSectors != 0):
raise Exception('Length of dataset ' + str(nSectors) + ' not a divisor of 360 degrees!')
for dataset in self.data:
length = len(dataset[self.data_col])
if length != nSectors:
raise Exception('Lengths of datasets given is different!')
for val in dataset[self.data_col]:
if (val < 0) | (val > 1):
raise Exception('Data value ' + str(val) + ' not between 0 and 1!')
self.sector_width = 360/nSectors
self.type_check()
def get_data_range(self, which):
return (0, 1)
def get_legend_entry(self):
legends = []
i = 0
for dataset in self.data:
fill = self.fill_styles[i]
i = (i + 1) % len(self.fill_styles)
legends.append(legend.Entry(line_style=self.line_style,
fill_style=fill,
label=dataset[self.label_col]))
return legends
def draw(self, ar, can):
center = self.center
if not center:
center = (ar.loc[0] + ar.size[0]/2.0,
ar.loc[1] + ar.size[1]/2.0)
base_radius = self.base_radius # the maximum radius of a wedge
if not base_radius:
base_radius = min(ar.size[0]/2.0, ar.size[1]/2.0) #* 0.8
sector_decrement = 1./(len(self.data)*2) * self.sector_width # each following sector diagram will have its sector width decremented by half this amount (in degrees)
i = 0
for dataset in self.data:
cur_angle = self.start_angle
if self.sector_centred:
cur_angle -= self.sector_width/2.
fill = self.fill_styles[i]
x_center = center[0]
y_center = center[1]
if not i: # draw directions around sector diagram once off
dir_offset = base_radius + (self.dir_offset or base_radius * 0.04)
directions = ['N', 'E', 'S', 'W']
angle = self.start_angle
can.ellipsis(line_style.T(color=color.black, width=0.3, dash=line_style.dash1), None,
x_center, y_center, base_radius, 1,
0, 360) #
for d in directions:
x_label, y_label = pychart_util.rotate(dir_offset, 0, angle) # coords for bottom left corner of box
tw = font.text_width(d)
half = 1/3. # normal arithmetic does not seem to apply to these text_box objects...
if (angle == 0): # east
y_label -= font.text_height(d)[0]*half # move down half
elif (angle == -180): # west
y_label -= font.text_height(d)[0]*half # move down half
x_label -= font.text_width(d) # move left full
elif (angle == 90): # north
x_label -= font.text_height(d)[0]*half # move left half
elif (angle == -90): # south
y_label -= font.text_height(d)[0]*.8 # move down (couldn't figure out how to set this dynamically so I fudged...)
x_label -= font.text_height(d)[0]*half # move left half
canvas.show(x_label + x_center, y_label + y_center, d)
angle -= 360/len(directions)
for val in dataset[self.data_col]: # now draw the sectors
radius = base_radius*val # scale the radius
start = cur_angle-self.sector_width+i*sector_decrement
stop = cur_angle-i*sector_decrement # these may seem confusing, but remember that we need to go counterclockwise
can.ellipsis(self.line_style, fill,
x_center, y_center, radius, 1, start, stop, self.shadow)
cur_angle = (cur_angle - self.sector_width) % 360 # we want to go in anticlockwise direction (North, West, South, etc. as in meteorology)
i = (i + 1) % len(self.fill_styles)

View File

@ -1,29 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import theme
x_base = 300
y_base = 300
def xscale(x):
return x * theme.scale_factor + x_base
def yscale(y):
return y * theme.scale_factor + y_base
def nscale(x):
return x * theme.scale_factor
def nscale_seq(x):
return map(nscale, x)

View File

@ -1,429 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys,string,re,math
from xml.dom.minidom import Document,Comment
import theme
import basecanvas
import version
from scaling import *
# Note we flip all y-coords and negate all angles because SVG's coord
# system is inverted wrt postscript/PDF - note it's not enough to
# scale(1,-1) since that turns text into mirror writing with wrong origin
_comment_p = 0 # whether comment() writes output
# Convert a PyChart color object to an SVG rgb() value
def _svgcolor(color): # see color.py
return 'rgb(%d,%d,%d)' % tuple(map(lambda x:int(255*x),
[color.r,color.g,color.b]))
# Take an SVG 'style' attribute string like 'stroke:none;fill:black'
# and parse it into a dictionary like {'stroke' : 'none', 'fill' : 'black'}
def _parseStyleStr(s):
styledict = {}
if s :
# parses L -> R so later keys overwrite earlier ones
for keyval in s.split(';'):
l = keyval.strip().split(':')
if l and len(l) == 2: styledict[l[0].strip()] = l[1].strip()
return styledict
# Make an SVG style string from the dictionary described above
def _makeStyleStr(styledict):
s = ''
for key in styledict.keys():
s += "%s:%s;"%(key,styledict[key])
return s
def _protectCurrentChildren(elt):
# If elt is a group, check to see whether there are any non-comment
# children, and if so, create a new group to hold attributes
# to avoid affecting previous children. Return either the current
# elt or the newly generated group.
if (elt.nodeName == 'g') :
for kid in elt.childNodes :
if kid.nodeType != Comment.nodeType:
g = elt.ownerDocument.createElement('g')
g.setAttribute('auto','')
if _comment_p:
g.appendChild(g.ownerDocument.createComment
('auto-generated group'))
elt.appendChild(g)
elt = g
break
return elt
class T(basecanvas.T):
def __init__(self, fname):
basecanvas.T.__init__(self)
self.__out_fname = fname
self.__xmin, self.__xmax, self.__ymin, self.__ymax = 0,0,0,0
self.__doc = Document()
self.__doc.appendChild(self.__doc.createComment
('Created by PyChart ' + version.version + ' ' + version.copyright))
self.__svg = self.__doc.createElement('svg') # the svg doc
self.__doc.appendChild(self.__svg)
self.__defs = self.__doc.createElement('defs') # for clip paths
self.__svg.appendChild(self.__defs)
self.__currElt = self.__svg
self.gsave() # create top-level group for dflt styles
self._updateStyle(font_family = theme.default_font_family,
font_size = theme.default_font_size,
font_style = 'normal',
font_weight = 'normal',
font_stretch = 'normal',
fill = 'none',
stroke = 'rgb(0,0,0)', #SVG dflt none, PS dflt blk
stroke_width = theme.default_line_width,
stroke_linejoin = 'miter',
stroke_linecap = 'butt',
stroke_dasharray = 'none')
def _updateStyle(self, **addstyledict):
elt = _protectCurrentChildren(self.__currElt)
# fetch the current styles for this node
mystyledict = _parseStyleStr(elt.getAttribute('style'))
# concat all parent style strings to get dflt styles for this node
parent,s = elt.parentNode,''
while parent.nodeType != Document.nodeType :
# prepend parent str so later keys will override earlier ones
s = parent.getAttribute('style') + s
parent = parent.parentNode
dfltstyledict = _parseStyleStr(s)
# Do some pre-processing on the caller-supplied add'l styles
# Convert '_' to '-' so caller can specify style tags as python
# variable names, eg. stroke_width => stroke-width.
# Also convert all RHS values to strs
for key in addstyledict.keys():
k = re.sub('_','-',key)
addstyledict[k] = str(addstyledict[key]) # all vals => strs
if (k != key) : del addstyledict[key]
for k in addstyledict.keys() :
if (mystyledict.has_key(k) or # need to overwrite it
(not dfltstyledict.has_key(k)) or # need to set it
dfltstyledict[k] != addstyledict[k]) : # need to override it
mystyledict[k] = addstyledict[k]
s = _makeStyleStr(mystyledict)
if s : elt.setAttribute('style',s)
self.__currElt = elt
####################################################################
# methods below define the pychart backend device API
# First are a set of methods to start, construct and finalize a path
def newpath(self): # Start a new path
if (self.__currElt.nodeName != 'g') :
raise OverflowError, "No containing group for newpath"
# Just insert a new 'path' element into the document
p = self.__doc.createElement('path')
self.__currElt.appendChild(p)
self.__currElt = p
# This set of methods add data to an existing path element,
# simply add to the 'd' (data) attribute of the path elt
def moveto(self, x, y): #
if (self.__currElt.nodeName != 'path') :
raise OverflowError, "No path for moveto"
d = ' '.join([self.__currElt.getAttribute('d'),'M',`x`,`-y`]).strip()
self.__currElt.setAttribute('d', d)
def lineto(self, x, y):
if (self.__currElt.nodeName != 'path') :
raise OverflowError, "No path for lineto"
d = ' '.join([self.__currElt.getAttribute('d'),'L',`x`,`-y`]).strip()
self.__currElt.setAttribute('d', d)
def path_arc(self, x, y, radius, ratio, start_angle, end_angle):
# mimic PS 'arc' given radius, yr/xr (=eccentricity), start and
# end angles. PS arc draws from CP (if exists) to arc start,
# then draws arc in counterclockwise dir from start to end
# SVG provides an arc command that draws a segment of an
# ellipse (but not a full circle) given these args:
# A xr yr rotate majorArcFlag counterclockwiseFlag xe ye
# We don't use rotate(=0) and flipped axes => all arcs are clockwise
if (self.__currElt.nodeName != 'path') :
raise OverflowError, "No path for path_arc"
self.comment('x=%g, y=%g, r=%g, :=%g, %g-%g'
% (x,y,radius,ratio,start_angle,end_angle))
xs = x+radius*math.cos(2*math.pi/360.*start_angle)
ys = y+ratio*radius*math.sin(2*math.pi/360.*start_angle)
xe = x+radius*math.cos(2*math.pi/360.*end_angle)
ye = y+ratio*radius*math.sin(2*math.pi/360.*end_angle)
if (end_angle < start_angle) : # make end bigger than start
while end_angle <= start_angle: # '<=' so 360->0 becomes 360->720
end_angle += 360
full_circ = (end_angle - start_angle >= 360) # draw a full circle?
d = self.__currElt.getAttribute('d')
d += ' %s %g %g' % (d and 'L' or 'M',xs,-ys) # draw from CP, if exists
if (radius > 0) : # skip, eg. 0-radius 'rounded' corners which blowup
if (full_circ) :
# If we're drawing a full circle, move to the end coord
# and draw half a circle to the reflected xe,ye
d += ' M %g %g A %g %g 0 1 0 %g %g'%(xe,-ye,
radius,radius*ratio,
2*x-xe,-(2*y-ye))
# Draw arc from the CP (either reflected xe,ye for full circle else
# xs,ys) to the end coord - note with full_circ the
# 'bigArcFlag' value is moot, with exactly 180deg left to draw
d += ' A %g %g 0 %d 0 %g %g' % (radius,radius*ratio,
end_angle-start_angle>180,
xe,-ye)
self.__currElt.setAttribute('d',d.strip())
def curveto(self, x1,y1,x2,y2,x3,y3):
# Equivalent of PostScript's x1 y1 x2 y2 x3 y3 curveto which
# draws a cubic bezier curve from curr pt to x3,y3 with ctrl points
# x1,y1, and x2,y2
# In SVG this is just d='[M x0 y0] C x1 y1 x2 y2 x3 y3'
#! I can't find an example of this being used to test it
if (self.__currElt.nodeNode != 'path') :
raise OverflowError, "No path for curveto"
d = ' '.join([self.__currElt.getAttribute('d'),'C',
`x1`,`-y1`,`x2`,`-y2`,`x3`,`-y3`,]).strip()
self.__currElt.setAttribute('d', d)
def closepath(self): # close back to start of path
if (self.__currElt.nodeName != 'path') :
raise OverflowError, "No path for closepath"
d = ' '.join([self.__currElt.getAttribute('d'),'Z']).strip()
self.__currElt.setAttribute('d', d)
# Next we have three methods for finalizing a path element,
# either fill it, clip to it, or draw it (stroke)
# canvas.polygon() can generate fill/clip cmds with
# no corresponding path so just ignore them
def stroke(self):
if (self.__currElt.nodeName != 'path') :
self.comment('No path - ignoring stroke')
return
self._updateStyle(fill='none')
self.__currElt = self.__currElt.parentNode
def fill(self):
if (self.__currElt.nodeName != 'path') :
self.comment('No path - ignoring fill')
return
self._updateStyle(stroke='none')
self.__currElt = self.__currElt.parentNode
def clip_sub(self):
if (self.__currElt.nodeName != 'path') :
self.comment('No path - ignoring clip')
return
# remove the current path from the tree ...
p = self.__currElt
self.__currElt=p.parentNode
self.__currElt.removeChild(p)
# ... add it to a clipPath elt in the defs section
clip = self.__doc.createElement('clipPath')
clipid = 'clip'+`len(self.__defs.childNodes)`
clip.setAttribute('id',clipid)
clip.appendChild(p)
self.__defs.appendChild(clip)
# ... update the local style to point to it
self._updateStyle(clip_path = 'url(#%s)'%clipid)
# The text_xxx routines specify the start/end and contents of text
def text_begin(self):
if (self.__currElt.nodeName != 'g') :
raise ValueError, "No group for text block"
t = self.__doc.createElement('text')
self.__currElt.appendChild(t)
self.__currElt = t
def text_moveto(self, x, y, angle):
if (self.__currElt.nodeName != 'text') :
raise ValueError, "No text for moveto"
self.__currElt.setAttribute('x',`x`)
self.__currElt.setAttribute('y',`-y`)
if (angle) :
self.__currElt.setAttribute('transform',
'rotate(%g,%g,%g)' % (-angle,x,-y))
def text_show(self, font_name, size, color, str):
if (self.__currElt.nodeName != 'text') :
raise ValueError, "No text for show"
# PyChart constructs a postscript font name, for example:
#
# Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
# Helvetica-Narrow Times-Roman Times-Italic
# Symbol Palatino-Roman Bookman-Demi Courier AvantGarde-Book
#
# We need to deconstruct this to get the font-family (the
# piece before the '-'), and other characteristics.
# Note that 'Courier' seems to correspond to SVGs 'CourierNew'
# and that the SVG Symbol font is Unicode where the ascii text
# 'Symbol' doesn't create greek characters like 'Sigma ...' -
# should really pass a unicode string, or provide translation
#
# SVG defines:
# font-style = normal (aka roman) | italic | oblique
# font-weight = normal | bold (aka demi?)
# font-stretch = normal | wider | narrower | ultra-condensed |
# extra-condensed | condensed | semi-condensed |
# semi-expanded | expanded | extra-expanded | ultra-expanded
# ('narrow' seems to correspond to 'condensed')
m = re.match(r'([^-]*)(-.*)?',font_name)
font_name,modifiers = m.groups()
if font_name == 'Courier' : font_name = 'CourierNew'
font_style = font_weight = font_stretch = 'normal'
if modifiers :
if re.search('Italic',modifiers) : font_style = 'italic'
elif re.search('Oblique',modifiers) : font_style = 'oblique'
if re.search('Bold|Demi',modifiers) : font_weight = 'bold'
if re.search('Narrow',modifiers) : font_stretch = 'condensed'
#! translate ascii symbol font chars -> unicode (see www.unicode.org)
#! http://www.unicode.org/Public/MAPPINGS/VENDORS/ADOBE/symbol.txt
#! but xml Text element writes unicode chars as '?' to XML file...
str = re.sub(r'\\([()])',r'\1',str) # unescape brackets
self._updateStyle(fill=_svgcolor(color),
stroke='none',
font_family=font_name,
font_size=size,
font_style=font_style,
font_weight=font_weight,
font_stretch=font_stretch)
self.__currElt.appendChild(self.__doc.createTextNode(str))
def text_end(self):
if (self.__currElt.nodeName != 'text') :
raise ValueError, "No text for close"
self.__currElt = self.__currElt.parentNode
# Three methods that change the local style of elements
# If applied to a group, they persist until the next grestore,
# If applied within a path element, they only affect that path -
# although this may not in general correspond to (say) PostScript
# behavior, it appears to correspond to reflect mode of use of this API
def set_fill_color(self, color):
self._updateStyle(fill=_svgcolor(color))
def set_stroke_color(self, color):
self._updateStyle(stroke=_svgcolor(color))
def set_line_style(self, style): # see line_style.py
linecap = {0:'butt', 1:'round', 2:'square'}
linejoin = {0:'miter', 1:'round', 2:'bevel'}
if style.dash: dash = ','.join(map(str,style.dash))
else : dash = 'none'
self._updateStyle(stroke_width = style.width,
stroke = _svgcolor(style.color),
stroke_linecap = linecap[style.cap_style],
stroke_linejoin = linejoin[style.join_style],
stroke_dasharray = dash)
# gsave & grestore respectively push & pop a new context to hold
# new style and transform parameters. push/pop transformation are
# similar but explicitly specify a coordinate transform at the
# same time
def gsave(self):
if (self.__currElt.nodeName not in ['g','svg']) :
raise ValueError, "No group for gsave"
g = self.__doc.createElement('g')
self.__currElt.appendChild(g)
self.__currElt = g
def grestore(self):
if (self.__currElt.nodeName != 'g'):
raise ValueError, "No group for grestore"
# first pop off any auto-generated groups (see protectCurrentChildren)
while (self.__currElt.hasAttribute('auto')) :
self.__currElt.removeAttribute('auto')
self.__currElt = self.__currElt.parentNode
# then pop off the original caller-generated group
self.__currElt = self.__currElt.parentNode
def push_transformation(self, baseloc, scale, angle, in_text=0):
#? in_text arg appears to always be ignored
# In some cases this gets called after newpath, with
# corresonding pop_transformation called after the path is
# finalized so we check specifically for that, and generate
# an enclosing group to hold the incomplete path element
# We could add the transform directly to the path element
# (like we do with line-style etc) but that makes it harder
# to handle the closing 'pop' and might lead to inconsitency
# with PostScript if the closing pop doesn't come right after
# the path element
elt = self.__currElt
if elt.nodeName == 'g':
elt = None
elif (elt.nodeName == 'path' and not elt.hasAttribute('d')) :
g = elt.parentNode
g.removeChild(elt)
self.__currElt = g
else:
raise ValueError, "Illegal placement of push_transformation"
t = ''
if baseloc :
t += 'translate(%g,%g) '%(baseloc[0],-baseloc[1])
if angle :
t += 'rotate(%g) '%-angle
if scale :
t += 'scale(%g,%g) '%tuple(scale)
self.gsave()
self.__currElt.setAttribute('transform',t.strip())
if elt: # elt has incomplete 'path' or None
self.__currElt.appendChild(elt)
self.__currElt = elt
def pop_transformation(self, in_text=0): #? in_text unused?
self.grestore()
# If verbose, add comments to the output stream (helps debugging)
def comment(self, str):
if _comment_p :
self.__currElt.appendChild(self.__doc.createComment(str))
# The verbatim method is currently not supported - presumably with
# the SVG backend the user would require access to the DOM since
# we're not directly outputting plain text here
def verbatim(self, str):
self.__currElt.appendChild(self.__doc.createComment('verbatim not implemented: ' + str))
# The close() method finalizes the SVG document and flattens the
# DOM document to XML text to the specified file (or stdout)
def close(self):
basecanvas.T.close(self)
self.grestore() # matching the gsave in __init__
if (self.__currElt.nodeName != 'svg') :
raise ValueError, "Incomplete document at close!"
# Don't bother to output an empty document - this can happen
# when we get close()d immediately by theme reinit
if (len(self.__svg.childNodes[-1].childNodes) == 0) :
return
fp, need_close = self.open_output(self.__out_fname)
bbox = theme.adjust_bounding_box([self.__xmin, self.__ymin,
self.__xmax, self.__ymax])
self.__svg.setAttribute('viewBox','%g %g %g %g'
% (xscale(bbox[0]),
-yscale(bbox[3]),
xscale(bbox[2])-xscale(bbox[0]),
yscale(bbox[3])-yscale(bbox[1])))
self.__doc.writexml(fp,'',' ','\n')
if need_close:
fp.close()

View File

@ -1,153 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import canvas
import line_style
import pychart_util
import fill_style
import font
import chart_object
import color
import arrow
import text_box_doc
from pychart_types import *
from types import *
class T(chart_object.T):
__doc__ = text_box_doc.doc
keys = {"text": (StringType, "???", "Text body. <<font>>"),
"loc": (TupleType, (0,0),
"The location of the text box."),
"line_style": (line_style.T, line_style.default,
"""The line style of the surrounding frame."""),
"fill_style": (fill_style.T, fill_style.white,
"Specifies the fill style of the text box."),
"top_fudge": (UnitType, 0,
"The amount of space (in points) above the first line"),
"bottom_fudge": (UnitType, 5,
"The amount of space below the last line"),
"left_fudge": (UnitType, 5,
"The amount of space left of the box"),
"right_fudge": (UnitType, 5,
"The amount of space right of the box"),
"_arrows": (ListType, pychart_util.new_list, "The list of arrows. Not to be touched by the user directly"),
"radius": (UnitType, 0,
"""Radius of the four corners of the rectangle.
If the value is zero, a sharp-cornered
rectangle is drawn."""),
"shadow": (ShadowType, None,
pychart_util.shadow_desc)
}
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def get_dimension(self):
x = self.loc[0] - self.left_fudge
y = self.loc[1] - self.bottom_fudge
width = font.text_width(self.text) + self.right_fudge + self.left_fudge
height = (font.text_height(self.text))[0] + self.top_fudge + self.bottom_fudge
return (x, y, width, height)
def choose_end_point(self, tipx, tipy):
(x, y, width, height) = self.get_dimension()
minDist = -1
minPoint = None
vertices = [(x, y),
(x+width, y),
(x+width, y+height),
(x, y+height)]
if tipx >= x and tipx < x+width:
vertices.append((tipx, y))
vertices.append((tipx, y+height))
if tipy >= y and tipy < y+height:
vertices.append((x, tipy))
vertices.append((x+width, tipy))
for startPoint in vertices:
dist = ((startPoint[0] - tipx) **2 + (startPoint[1] - tipy) **2)
if not minPoint or dist < minDist:
minPoint = startPoint
minDist = dist
return minPoint
def add_arrow(self, tipLoc, tail=None, arrow = arrow.default):
"""This method adds a straight arrow that points to
@var{TIPLOC}, which is a tuple of integers. @var{TAIL}
specifies the starting point of the arrow. It is either None
or a string consisting of the following letters: 'l', 'c',
'r', 't', 'm,', and 'b'. Letters 'l', 'c', or 'r' means to
start the arrow from the left, center, or right of the text
box, respectively. Letters 't', 'm', or 'b' means to start the
arrow from the top, middle or bottom of the text box. For
example, when @samp{tail = 'tc'} then arrow is drawn from
top-center point of the text box. ARROW specifies the style of
the arrow. <<arrow>>.
"""
self._arrows.append((tipLoc, tail, arrow))
def draw(self, can = None):
if can == None:
can = canvas.default_canvas()
x = self.loc[0]
y = self.loc[1]
text_width = font.text_width(self.text)
text_height = font.text_height(self.text)[0]
(halign, valign, angle) = font.get_align(self.text)
if self.line_style or self.fill_style:
width = text_width+self.left_fudge+self.right_fudge
height = text_height+self.bottom_fudge+self.top_fudge
can.round_rectangle(self.line_style, self.fill_style,
x-self.left_fudge, y-self.bottom_fudge,
x-self.left_fudge+width, y-self.bottom_fudge+height,
self.radius, self.shadow)
if halign == 'L':
can.show(x, y, self.text)
elif halign == 'C':
can.show(x+text_width/2.0, y, self.text)
elif halign == 'R':
can.show(x+text_width, y, self.text)
else:
raise Exception, "Unsupported alignment (" + halign + ")"
# draw arrows
for t in self._arrows:
(tipLoc, tail, arrow) = t
if tail:
(x, y, width, height) = self.get_dimension()
origin = [x, y]
for ch in tail:
if ch == 'l':
origin[0] = x
elif ch == 'c':
origin[0] = x+width/2.0
elif ch == 'r':
origin[0] = x+width
elif ch == 'b':
origin[1] = y
elif ch == 'm':
origin[1] = y+height/2.0
elif ch == 't':
origin[1] = y+height
else:
raise ValueError, tail + ": unknown tail location spec."
else:
origin = self.choose_end_point(tipLoc[0], tipLoc[1])
arrow.draw((origin, tipLoc), can)

View File

@ -1,21 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
loc(type:tuple) default="The location of the text box.".
shadow(type:<function ShadowType at 0xb7d4db8c>) default="The value is either None or a tuple. When non-None,
a drop-shadow is drawn beneath the object. X-off, and y-off specifies the
offset of the shadow relative to the object, and fill specifies the
style of the shadow (@pxref{module-fill-style}).".
left_fudge(type:length in points (\\xref{unit})) default="The amount of space left of the box".
bottom_fudge(type:length in points (\\xref{unit})) default="The amount of space below the last line".
fill_style(type:fill_style.T) default="Specifies the fill style of the text box.".
right_fudge(type:length in points (\\xref{unit})) default="The amount of space right of the box".
top_fudge(type:length in points (\\xref{unit})) default="The amount of space (in points) above the first line".
text(type:str) default="Text body. <<font>>".
radius(type:length in points (\\xref{unit})) default="Radius of the four corners of the rectangle.
If the value is zero, a sharp-cornered
rectangle is drawn.".
line_style(type:line_style.T) default="The line style of the surrounding frame.".
_arrows(type:list) default="The list of arrows. Not to be touched by the user directly".
"""

View File

@ -1,235 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import sys
import os
import re
import getopt
import pychart_util
__doc__ = """This module is defines variables for changing the looks
of charts. All the variables can be changed either via environment
variable PYCHART_OPTIONS or via the command-line options.
The value of PYCHART_OPTIONS should be a sequence of var=val separated
by space. Below is an example, which tells Pychart to write to file
foo.pdf and use Times-Roman as the default font.
PYCHART_OPTIONS="output=foo.pdf font-family=Times"
The summary of attributes that can be set via PYCHART_OPTIONS follows:
output=FILENAME (default: stdout)
Set the output file name.
format=[ps|pdf|pdf-uncompressed|png|x11|svg] (default: ps)
Set the output file format.
font-family=NAME (default: Helvetica)
Set the default font to be used by texts.
font-size=N (default: 9)
Set the default font to be used by texts.
line-width=X (default: 0.4)
Set the default line width, in points. See also
pychart.line_style.
scale=X (default: 1.0)
Set the scaling factor. The default is 1.0.
color=[yes|no] (default: no)
If yes, Pychart colorizes default object attributes.
You can also set these variables by calling theme.get_options.
"""
use_color = 0
scale_factor = 1
output_format = None # "ps", "pdf", "png", "x11", or "svg"
compress_output = 1
output_file = ""
default_font_family = "Helvetica"
default_font_size = 9
default_line_height = None
default_font_halign = "L"
default_font_valign = "B"
default_font_angle = 0
default_line_width = 0.4
debug_level = 1
delta_bounding_box = [-3, -3, 3, 3]
bounding_box = {}
def parse_yesno(str):
if str in ("yes", "true", "1"):
return 1
else:
return 0
def parse_bounding_box(arg):
global delta_bounding_box, bounding_box
l = arg.split(",")
if len(l) != 4:
raise ValueError, "Need to specify margin=LEFT,BOTTOM,RIGHT,TOP"
for i in range(0, 4):
val = l[i].strip()
if val[0] == '+':
delta_bounding_box[i] = int(val[1:])
elif val[0] == '-':
delta_bounding_box[i] = int(val[1:])
else:
bounding_box[i] = int(val)
def adjust_bounding_box(bbox):
"""Adjust the bounding box as specified by user.
Returns the adjusted bounding box.
- bbox: Bounding box computed from the canvas drawings.
It must be a four-tuple of numbers.
"""
for i in range(0, 4):
if bounding_box.has_key(i):
bbox[i] = bounding_box[i]
else:
bbox[i] += delta_bounding_box[i]
return bbox
def parse_option(opt, arg):
global use_color, scale_factor, margin
global output_format, output_file, compress_output
global default_font_family, default_font_size
global default_line_height
global default_line_width, debug_level
if opt == "format":
if arg in ("ps", "eps"):
output_format = "ps"
elif arg == "png":
output_format = "png"
elif arg == "svg":
output_format = "svg"
elif arg == "x11":
output_format = "x11"
elif arg == "pdf-uncompressed":
output_format = "pdf"
compress_output = 0
elif arg in ("pdf-compressed", "pdf"):
output_format = "pdf"
compress_output = 1
else:
raise ValueError, "Unknown output option: " + str(arg)
elif opt == "output":
output_file = arg
elif opt == "color":
use_color = 1
elif opt == "scale":
scale_factor = float(arg)
elif opt == "bbox":
parse_bounding_box(arg)
elif opt == "font-family":
default_font_family = arg
elif opt == "font-size":
default_font_size = float(arg)
default_line_height = float(arg)
elif opt == "line-width":
default_line_width = float(arg)
elif opt == "debug-level":
debug_level = int(arg)
else:
raise getopt.GetoptError, "Unknown option: " + opt + " " + arg
if os.environ.has_key("PYCHART_OPTIONS"):
for opt in os.environ["PYCHART_OPTIONS"].split():
opt, arg = opt.split("=")
parse_option(opt, arg)
hooks = []
def add_reinitialization_hook(proc):
global hooks
hooks.append(proc)
proc()
def usage():
print "Usage: %s [options..]" % sys.argv[0]
print """
--scale=X: Set the scaling factor to X (default: 1.0).
--format=[ps|png|pdf|x11|svg]: Set the output format (default: ps).
--font-family=NAME: Set the default font family (default: Helvetica).
--font-size=NAME: Set the default font size (default: 9pts).
--line-width=NAME: Set the default line width (default: 0.4).
--debug-level=N: Set the messaging verbosity (default: 0).
--bbox=LEFT,BOTTOM,RIGHT,TOP: Specifies the amount of space (in PS points) to be left in the edges of the picture (default: -1,-1,+1,+1).
"""
def reinitialize():
"""This procedure must be called after setting variables in
the |theme| module. This procedure propagates the new values of
the theme variables to other modules that depend on their values."""
for proc in hooks:
proc()
def get_options(argv = None):
"""This procedure takes a list of command line arguments in <argv>
and parses
options. It returns the non-parsed portion of <argv>. Parameter
<argv> can be
omitted, in which case its value defaults to |sys.argv[1:]|.
The options supported are: "|--format=[ps,png,pdf,x11,svg]|",
"|--output=|<file>", "|--color=[yes,no]|"
"|--scale=|<X>", "|--font-family=|<name>", "|--font-size=|<X>",
"|--line-width=|<X>",
"|--debug-level=|<N>", "|bbox=|<left,bottom,right,top>".
The below code shows an example.
#!/usr/bin/python
from pychart import *
args = theme.get_options()
ar = area.T(...)
...
"""
if argv == None:
argv = sys.argv[1:]
try:
opts, args = getopt.getopt(argv, "d:co:f:",
["format=", "output=", "color=",
"scale=", "font-family=", "font-size=",
"line-width=", "debug-level=",
"bbox="])
except getopt.GetoptError, foo:
print foo
usage()
raise getopt.GetoptError
for opt, arg in opts:
if opt == "-d":
parse_option("debug-level", arg)
elif opt == "-c":
parse_option("color", None)
elif opt == "-o":
parse_option("output", arg)
elif opt == "-f":
parse_option("format", arg)
else:
parse_option(opt[2:], arg)
reinitialize()
return args

View File

@ -1,189 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import color
import line_style
import fill_style
import chart_object
import object_set
import pychart_util
import tick_mark_doc
from pychart_types import *
_keys = {
"line_style": (line_style.T, line_style.default, "The line style of the tick mark."),
"fill_style": (fill_style.T, fill_style.white, "The fill style."),
"size": (UnitType, 5, "Size of the tick mark."),
}
class T(chart_object.T):
__doc__ = tick_mark_doc.doc
keys = _keys
##AUTOMATICALLY GENERATED
##END AUTOMATICALLY GENERATED
def predraw_check(self):
if not hasattr(self, "type_checked"):
self.type_check()
self.type_checked = 1
class Circle(T):
"""Draws a circle. """
def draw(self, can, x, y):
self.predraw_check()
can.ellipsis(self.line_style, self.fill_style, x, y,
self.size/2.0, 1)
class Square(T):
"""Draws a square."""
def draw(self, can, x, y):
self.predraw_check()
# move to the bottom-left corner
x = x - self.size/2.0
y = y - self.size/2.0
can.rectangle(self.line_style, self.fill_style,
x, y, x+self.size, y+self.size)
class Triangle(T):
"""Draws a triangle pointing up."""
def draw(self, can, x, y):
self.predraw_check()
can.polygon(self.line_style, self.fill_style,
((x-self.size/1.6, y-self.size/2.0),
(x+self.size/1.6, y-self.size/2.0),
(x, y+self.size/2.0)))
class DownTriangle(T):
"""Draws a triangle pointing down."""
def draw(self, can, x, y):
self.predraw_check()
can.polygon(self.line_style, self.fill_style,
((x, y-self.size/2.0),
(x-self.size/1.6, y+self.size/2.0),
(x+self.size/1.6, y+self.size/2.0)))
class X(T):
"""Draw a "X"-shaped tick mark. Attribute "fill-style" is ignored."""
keys = pychart_util.union_dict(T.keys,
{"line_style": (line_style.T,
line_style.T(width=0.7),
"The line style of the tick mark")})
def draw(self, can, x, y):
self.predraw_check()
# move to the bottom-left corner
x = x - self.size/2.0
y = y - self.size/2.0
can.line(self.line_style, x, y, x+self.size, y+self.size)
can.line(self.line_style, x+self.size, y, x, y+self.size)
class Plus(T):
"""Draw a "+"-shaped tick mark. Attribute "fill-style" is ignored."""
keys = pychart_util.union_dict(T.keys,
{"line_style": (line_style.T,
line_style.T(width=1),
"The line style of the tick mark.")})
def draw(self, can, x, y):
self.predraw_check()
# move to the bottom-left corner
can.line(self.line_style, x-self.size/1.4, y, x+self.size/1.4, y)
can.line(self.line_style, x, y-self.size/1.4, x, y+self.size/1.4)
class Diamond(T):
"""Draw a square rotated at 45 degrees."""
def draw(self, can, x, y):
self.predraw_check()
# move to the bottom-left corner
can.polygon(self.line_style, self.fill_style,
((x-self.size/1.4, y), (x, y+self.size/1.4),
(x+self.size/1.4, y), (x, y-self.size/1.4)))
class Star(T):
"""Draw a "*". Attribute "fill-style" is ignored."""
keys = pychart_util.union_dict(T.keys,
{"line_style": (line_style.T,
line_style.T(width=1),
"The line style of the tick mark.")})
def draw(self, can, x, y):
self.predraw_check()
# move to the bottom-left corner
midx = x
midy = y
d_len = self.size / 2.0
r_len = self.size * 1.414 / 2.0
can.line(self.line_style, x-d_len, y-d_len, x+d_len, y+d_len)
can.line(self.line_style, x+d_len, y-d_len, x-d_len, y+d_len)
can.line(self.line_style, midx, y-r_len, midx, y+r_len)
can.line(self.line_style, x-r_len, midy, x+r_len, midy)
class Null(T):
"""This tickmark doesn't draw anything. All the attributes are ignored."""
def __init__ (self):
self.line_style = None
self.fill_style = None
self.size = -1
def draw(self, can, x, y):
pass
standards = object_set.T()
def _intern(style):
standards.add(style)
return style
square = _intern(Square())
square3 = _intern(Square(size=3))
square5 = square
x = _intern(X())
x3 = _intern(X(size=3))
x5 = x
star = _intern(Star())
star3 = _intern(Star(size=3))
star5 = star
plus = _intern(Plus())
plus3 = _intern(Plus(size=3))
plus5 = plus
dia = _intern(Diamond())
dia3 = _intern(Diamond(size=3))
dia5 = dia
tri = _intern(Triangle())
tri3 = _intern(Triangle(size=3))
tri5 = tri
dtri = _intern(DownTriangle())
dtri3 = _intern(DownTriangle(size=3))
dtri5 = dtri
circle1 = _intern(Circle(size=1))
circle2 = _intern(Circle(size=3))
circle3 = _intern(Circle(size=5))
blacksquare = _intern(Square(fill_style=fill_style.black))
blacksquare3 = _intern(Square(size=3, fill_style=fill_style.black))
blackdia = _intern(Diamond(fill_style=fill_style.black))
blackdia3 = _intern(Diamond(size=3, fill_style=fill_style.black))
blacktri = _intern(Triangle(fill_style=fill_style.black))
blacktri3 = _intern(Triangle(size=3, fill_style=fill_style.black))
blackdtri = _intern(DownTriangle(fill_style=fill_style.black))
blackdtri3 = _intern(DownTriangle(size=3, fill_style=fill_style.black))
blackcircle1 = _intern(Circle(size=1, fill_style=fill_style.black))
blackcircle3 = _intern(Circle(size=3, fill_style=fill_style.black))
gray70square = _intern(Square(fill_style=fill_style.gray70))
gray70square3 = _intern(Square(size=3, fill_style=fill_style.gray70))
gray70dia = _intern(Diamond(fill_style=fill_style.gray70))
gray70dia3 = _intern(Diamond(size=3, fill_style=fill_style.gray70))
gray70tri = _intern(Triangle(fill_style=fill_style.gray70))
gray70tri3 = _intern(Triangle(size=3, fill_style=fill_style.gray70))
gray70dtri = _intern(DownTriangle(fill_style=fill_style.gray70))
gray70dtri3 = _intern(DownTriangle(size=3, fill_style=fill_style.gray70))
gray70circle1 = _intern(Circle(size=1, fill_style=fill_style.gray70))
gray70circle3 = _intern(Circle(size=3, fill_style=fill_style.gray70))
default = _intern(Null())

View File

@ -1,8 +0,0 @@
# -*- coding: utf-8 -*-
# automatically generated by generate_docs.py.
doc="""Attributes supported by this class are:
line_style(type:line_style.T) default="The line style of the tick mark.".
size(type:length in points (\\xref{unit})) default="Size of the tick mark.".
fill_style(type:fill_style.T) default="The fill style.".
"""

View File

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2000-2005 by Yasushi Saito (yasushi.saito@gmail.com)
#
# Jockey is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
#
# Jockey is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
import types
class IntervalTypeClass:
def typeCheck(self, val):
if type(val) in (types.IntType, types.LongType, types.FloatType,
types.FunctionType):
return None
return "Expecting a number or a function, but received '%s'", val
def typeDescription(self):
return "A number or function"
def varDescription(self, name):
return "A number or function"
IntervalType = IntervalTypeClass()

Some files were not shown because too many files have changed in this diff Show More