📄 graph_g.class
字号:
// graph_g
//
// Base class for graphs
//
*! version 1.0.12 24nov2004
version 8
class {
instance:
graphstyle style
array sersets // some graphs only use 1
_scheme = .scheme.new , clear // scheme
array __LOG // allows logging
_drawing = 1 // for aspect ratios
_xstretch_hold = .stretch_g.new // held for aspect ratios
_ystretch_hold = .stretch_g.new
gversion = 2 // graph version
clsversion = 2 // graph class version
command = "" // header information
date = ""
time = ""
dta_file = ""
dta_date = ""
} , inherit(grid)
program new
syntax [, READLOG(string) * ]
._scheme.ref = .`c(curscm)'.ref // declare local scheme
.Super.new , `options'
if "`readlog'" != "" {
.runfromfile `readlog'
}
end
/* -------------------------------------------------------------------------*/
/*
Usage: .parse serlist [if] [in] [wt] [, omit_opts sort graph_opts ]
where:
serlist = varlist
or
serlist = (varlist [if] [in] [wt], options ) (...) ...
*/
program parse_sersets
/* handle reading from a file */
syntax [anything(name=vlist id=varlist equalok)] [if] [in] ///
[aw fw pw] [, READLOG(string) LABels ///
SCHeme(string) USESCHEME(string) * ]
if "`readlog'" != "" {
// run cmds to create this graph
file read `readlog' cmd
gettoken tok : cmd
while "`tok'" != "<BeginCmd>" { // prefix commands
`cmd'
.__LOG.Arrpush `macval(cmd)'
file read `readlog' cmd
gettoken tok : cmd
}
file read `readlog' cmd
`cmd' // _map_sersets
file read `readlog' cmd
`cmd' // fills in fullopts
file read `readlog' cmd // ignore <EndCmd>
if r(eof) {
exit // problem
}
._scheme.ref = .`c(curscm)'.ref // declare local scheme
.log_cmd local fullopts `fullopts'
if "`.sersets[1].isa'" != "" {
.sersets[1].set
}
.makegraph , `fullopts' // child defines this
.runfromfile `readlog' // remaining commands
exit // Exit
}
._scheme.ref = .`c(curscm)'.ref /* declare local scheme */
/* pull off () bound varlists */
local paren (
while "`paren'" != "" {
gettoken bnd 0 : 0 , match(paren)
if "`paren'" != "" {
local bndlist `bndlist' (`bnd')
}
}
local 0 `bnd' `0'
/* parse global options */
syntax [anything(name=vlist id=varlist)] [if] [in] /*
*/ [aw fw pw] [, /*
*/ OMITANYMiss OMITALLMiss OMITDUPmiss OMITNothing /*
*/ SORT(passthru) LABels USESCHEME(string) * ]
if "`vlist'" != "" {
if "`bndlist'" != "" {
di in red "may not combine standard varlist " /*
*/ "and varlists in parentheses"
exit 198
}
local bndlist (`vlist')
}
local allif `if'
local allin `in'
local allsort `sort'
local allwt [`weight'`exp']
local allomit `omitanymiss' `omitallmiss' `omitdupmiss' `omitnothing'
if "`allomit'" == "" {
local allomit omitallmis
}
local alloptions `options'
/* process (varlist, options) */
/* create sersets if not created */
gettoken 0 bndlist : bndlist , match(paren)
local i 1
while "`paren'" != "" {
syntax [anything(name=vlist id=varlist)] /*
*/ [if] [in] [aw fw pw] , [ /*
*/ OMITANYMiss OMITALLMiss OMITDUPmiss OMITNothing /*
*/ SOrt(passthru) * ]
local omit `omitanymiss' `omitallmiss' /*
*/ `omitdupmiss' `omitnothing'
local wt [`weight'`exp']
if `"`if'"' == `""' {
local if `allif'
}
if `"`in'"' == `""' {
local in `allin'
}
if `"`sort'"' == `""' {
local sort `allsort'
}
if `"`omit'"' == `""' {
local omit `allomit'
}
if "`wt'" == "[]" {
local wt `allwt'
}
local bndoptions `bndoptions' (, `options')
if "`readlog'" == "" {
.sersets[`i'] = .serset.new `vlist' `if' `in' /*
*/ `wt' , `sort' `omit'
}
gettoken 0 bndlist : bndlist , match(paren)
local i = `i' + 1
}
/*
if "`labels'" != "" { /* fetch labels */
forvalues i = 2/0`.sersets[1].sers.arrnels' {
.sersets[1].sers[`i'].set_labels `if' `in'
}
}
*/
.log_cmd local fullopts `alloptions' bndoptions(`"`bndoptions'"')
if "`.sersets[1].isa'" != "" {
.sersets[1].set
}
.makegraph , `alloptions' bndoptions(`"`bndoptions'"')
end
/* -------------------------------------------------------------------------*/
/* Arrpush the commands onto the __LOG array that are used by save and undo
to recreate this graph.
*/
program define log_cmd
/* keys of sersets */
forvalues i = 1/`.sersets.arrnels' {
local keys `keys' `.sersets[`i'].uname'
}
.__LOG.Arrpush <BeginCmd>
.__LOG.Arrpush ._map_sersets `keys'
.__LOG.Arrpush `0'
.__LOG.Arrpush <EndCmd>
end
/* -------------------------------------------------------------------------*/
/* Used when reading a graph from disk or recreating for an undo to map
build a sersets array for this graph from the already created sersets.
*/
program define _map_sersets
local i 1
foreach keynm of local 0 {
.sersets[`i++'] = .__Map.`keynm'.ref
}
end
/*
.sersets[`i'] = .serset.new
.sersets[`i'].seton ${T_Curserset`i'}
*/
// ---------------------------------------------------------------------------
// Set the gmetric scaling for the graph to the specified value (#) or
// multiplier (*#).
program set_scale
args scale
if `"`scale'"' != `""' {
tempname rsz
.`rsz' = .numstyle.new, style(`.gmetric_mult')
.`rsz'.setstyle , style(`scale')
.gmetric_mult = `.`rsz'.val'
}
end
// ---------------------------------------------------------------------------
// Sets the plotregion for an axis and registers the axis with the
// plotregion and scale. Both the axis and plotregion must exist in the
// current graph.
program set_axis_plotregion
args axis plotregion xy
if (!0`.Local.`axis'.isofclass axis') exit
if (!0`.Local.`plotregion'.isofclass plotregion') exit
.`axis'.set_plotregion `.`plotregion'.objkey' `xy'
end
// ---------------------------------------------------------------------------
// Parse title options and push its declaration and any style edits onto the
// specified log.
//
// This call MUST occur after the declaration of plotregion1 has been pushed.
// Returns the unparsed options.
//
// Usage: local options = `".parse_and_log_title <logname> `options'"'
program parse_and_log_titles , rclass
gettoken log 0 : 0
gettoken obj 0 : 0
// ordererd for spanning
_fr_title_parse_and_log `log' "`obj'" r1title R1title r1title `0'
_fr_title_parse_and_log `log' "`obj'" r2title R2title r2title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" l1title L1title l1title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" l2title L2title l2title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" t1title T1title t1title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" t2title T2title t2title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" b1title B1title b1title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" b2title B2title b1title `r(rest)'
_fr_title_parse_and_log `log' "`obj'" note NOTE note `r(rest)'
_fr_title_parse_and_log `log' "`obj'" caption CAPtion caption `r(rest)'
_fr_title_parse_and_log `log' "`obj'" subtitle SUBtitle subtitle `r(rest)'
_fr_title_parse_and_log `log' "`obj'" title Title title `r(rest)'
return local rest `r(rest)'
end
program parse_and_log_titles_edits , rclass
gettoken log 0 : 0
gettoken obj 0 : 0
// ordererd for spanning
_fr_tedits_parse_and_log `log' "`obj'" r1title R1title `0'
_fr_tedits_parse_and_log `log' "`obj'" r2title R2title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" l1title L1title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" l2title L2title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" t1title T1title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" t2title T2title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" b1title B1title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" b2title B2title `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" note NOTE `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" caption CAPtion `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" subtitle SUBtitle `r(rest)'
_fr_tedits_parse_and_log `log' "`obj'" title Title `r(rest)'
return local rest `r(rest)'
end
// ---------------------------------------------------------------------------
// Creates spacers around plotregion as part of allowing the region to
// become fixed size and thus lock aspect ratio.
//
// This call MUST occur after the declaration of plotregion1 has been pushed.
// Returns the unparsed options.
//
// Usage: local options = `".parse_and_log_spacers <logname> <obj> `options'"'
//
// Only option allowed is ring(#) to allow the spacers to be
// placed inside or outside titles -- rarely used. Default is
// between t1title and t2titles, etc.
program parse_and_log_spacers , rclass
gettoken log 0 : 0
gettoken obj 0 : 0
local 0 `", `0'"'
syntax [ , SPACErs(string asis) * ]
local rest `"`options'"'
local 0 `", `spacers'"'
syntax [, RING(string)]
if ("`ring'" == "") {
local ring `.style.spacers_ring.setting'
}
.`log'.Arrpush `obj'.insert (spacert = .spacer.new) ///
above plotregion1 , ring(`ring')
.`log'.Arrpush `obj'.insert (spacerb = .spacer.new) ///
below plotregion1 , ring(`ring')
.`log'.Arrpush `obj'.insert (spacerl = .spacer.new) ///
leftof plotregion1 , ring(`ring')
.`log'.Arrpush `obj'.insert (spacerr = .spacer.new) ///
rightof plotregion1 , ring(`ring')
return local rest `rest'
end
program set_spacers_fixed
.spacert.ystretch.set fixed
.spacert.xstretch.set fixed
.spacerb.ystretch.set fixed
.spacerb.xstretch.set fixed
.spacerl.ystretch.set fixed
.spacerl.xstretch.set fixed
.spacerr.ystretch.set fixed
.spacerr.xstretch.set fixed
end
/* -------------------------------------------------------------------------*/
/* Initialize a drawing area and draw this object into that area
*/
program define drawgraph
.popifendsin drawgraph
syntax [ , SCALE(string) XSIZE(real -99) YSIZE(real -99) ]
if `"`scale'"' != `""' {
.__LOG.Arrpush .set_scale `scale'
.set_scale `scale'
}
if `xsize' != -99 {
.__LOG.Arrpush .style.editstyle declared_xsize(`xsize') editcopy
.style.editstyle declared_xsize(`xsize') editcopy
}
else local xsize = `.style.declared_xsize.val'
if `ysize' != -99 {
.__LOG.Arrpush .style.editstyle declared_ysize(`ysize') editcopy
.style.editstyle declared_ysize(`ysize') editcopy
}
else local ysize = `.style.declared_ysize.val'
gdi end
gdi init `xsize' `ysize' `.bgcolor.rgb' , live
.set_gu_scaling `gdi(xmetric)' `gdi(ymetric)'
/* put in gu's */
if `xsize' < `ysize' {
local y_gus = `ysize' * 100 / `xsize'
local x_gus = 100
}
else {
local x_gus = `xsize' * 100 / `ysize'
local y_gus = 100
}
.draw , xsize(`x_gus') ysize(`y_gus')
gdi update
gdi end
end
// ---------------------------------------------------------------------------
// Draw the graph. Needed only to draw all grids and x/y lines owned by the
// plotregions before anything else is drawn on the graph. Also implements
// aspect ratios. Otherwise, the heavy lifting is done by .grid.
program draw
if 0`._Gr_Cglobal.gversion' < 2 {
.Super.draw `0'
exit
}
if 0`._use_aspect_ratio' & 0`._drawing' {
._draw_and_set_aspect `0'
}
.draw_setup1 `0' // break into grid setup
.draw_setup2
foreach plreg_dex in `.list_ofclass_indices plotregion' {
.draw_cell `plreg_dex' gridonly
}
.draw_cells // main part of .grid.draw
end
program _draw_and_set_aspect
._drawing = 0
tempname holds
.`holds' = {}
._hold_for_aspect `holds'
capture .draw `0'
local rc = _rc
._reset_for_aspect `holds'
._drawing = 1
if (`rc') exit `rc'
._setup_aspect_ratio
end
program _hold_for_aspect
args holds
.`holds'[1] = .xtransform
.`holds'[2] = .ytransform
.`holds'[3] = `gdi(xalpha)'
.`holds'[4] = `gdi(xbeta)'
.`holds'[5] = `gdi(yalpha)'
.`holds'[6] = `gdi(ybeta)'
.`holds'[7] = .get_gu_scaling
._reinit_stretches
gdi record = no
gdi maybedraw = no
end
program _reset_for_aspect
args holds
gdi record = yes
gdi maybedraw = yes
gdi resetregs
gdi xalpha = `.`holds'[3]'
gdi xbeta = `.`holds'[4]'
gdi yalpha = `.`holds'[5]'
gdi ybeta = `.`holds'[6]'
.xtransform = .`holds'[1]
.ytransform = .`holds'[2]
.reset_gu_scaling `.`holds'[7]'
end
// be sure we are alway on original stretch settings
program _reinit_stretches
if (! 0`._xstretch_hold.current') {
._xstretch_hold.setcode `.plotregion1.xstretch.current'
._ystretch_hold.setcode `.plotregion1.ystretch.current'
}
else {
.plotregion1.xstretch.setcode `._xstretch_hold.current'
.plotregion1.ystretch.setcode `._ystretch_hold.current'
}
.set_spacers_fixed // and spacers are all fixed and 0
end
program _setup_aspect_ratio
// di in white ":`.plotregion1.xsize_ren': :`.plotregion1.ysize_ren':"
if 0`.plotregion1.ysize_ren' / 0`.plotregion1.xsize_ren' > ///
`.style.aspect_ratio.val' {
local ord y
local size = 0`.plotregion1.xsize_ren' * ///
`.style.aspect_ratio.val'
if 0`.style.aspect_pos.issouth_orcenter' ///
.spacert.ystretch.set free
if 0`.style.aspect_pos.isnorth_orcenter' ///
.spacerb.ystretch.set free
}
else {
local ord x
local size 0`.plotregion1.ysize_ren' / ///
`.style.aspect_ratio.val'
if 0`.style.aspect_pos.iswest_orcenter' ///
.spacerr.xstretch.set free
if 0`.style.aspect_pos.iseast_orcenter' ///
.spacerl.xstretch.set free
}
foreach preg in `.list_ofclass plotregion' {
.`preg'.`ord'stretch.set fixed
.`preg'.`ord'size = `size'
}
foreach axis in `.list_ofclass axis' {
local pos `.`axis'.position.snm'
if "`ord'" == "y" {
if "`pos'" == "left" {
.`axis'.`ord'stretch.set fixed
.`axis'.box_alignment.setstyle , style(west)
}
else if "`pos'" == "right" {
.`axis'.`ord'stretch.set fixed
.`axis'.box_alignment.setstyle , style(east)
}
}
else if "`ord'" == "x" {
if "`pos'" == "above" {
.`axis'.`ord'stretch.set fixed
.`axis'.box_alignment.setstyle , style(north)
}
else if "`pos'" == "below" {
.`axis'.`ord'stretch.set fixed
.`axis'.box_alignment.setstyle , style(south)
}
}
}
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -