[MERGE] Remove the embedded pychart library, and use the online version
bzr revid: stw@openerp.com-20120823150546-3pi7gw8oq2elpnt4
This commit is contained in:
commit
b90a483138
|
@ -32,7 +32,6 @@ import modules
|
|||
import netsvc
|
||||
import osv
|
||||
import pooler
|
||||
import pychart
|
||||
import release
|
||||
import report
|
||||
import run_tests
|
||||
|
|
|
@ -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" ]
|
||||
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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, )
|
|
@ -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"]
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
afm = {}
|
||||
|
|
@ -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)
|
|
@ -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
|
||||
".
|
||||
"""
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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)
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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.
|
||||
"""
|
|
@ -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.
|
||||
"""
|
|
@ -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)
|
||||
|
|
@ -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.
|
||||
".
|
||||
"""
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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))
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -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)
|
|
@ -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
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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")
|
|
@ -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)
|
||||
|
|
@ -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="".
|
||||
"""
|
||||
|
|
@ -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)
|
||||
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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
|
|
@ -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")
|
|
@ -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
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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="".
|
||||
"""
|
||||
|
|
@ -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)
|
||||
|
|
@ -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>>".
|
||||
"""
|
||||
|
|
@ -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)
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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()
|
|
@ -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)
|
|
@ -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}).".
|
||||
"""
|
||||
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
@ -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 ->
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
|
@ -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()
|
||||
|
||||
|
|
@ -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>>".
|
||||
"""
|
||||
|
|
@ -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)
|
||||
|
|
@ -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)
|
||||
|
|
@ -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()
|
|
@ -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)
|
||||
|
||||
|
|
@ -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".
|
||||
"""
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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())
|
||||
|
|
@ -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.".
|
||||
"""
|
||||
|
|
@ -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
Loading…
Reference in New Issue