📄 twowaygraph_g.class
字号:
// twowaygraph_g
//
// Base class for twoway graphs
*! version 1.1.6 02feb2005
version 8
class {
class:
graphfamily = "twoway"
instance:
n_views = 0
n_plotregions = 0
n_text = 0
last_style = 0 // last style id
x_scales = ""
y_scales = ""
} , inherit(graph_g)
// ---------------------------------------------------------------------------
// .new
//
// Creates a two-way graph with overlaid plotregions (if needed) for a
// series of views (see addplots).
//
// Handles whether reading from a log. Does not use the mechanism of
// graph_g.class.
program new
.Super.new
._scheme.ref = .`c(curscm)'.ref // declare local scheme
capture syntax [ , READLOG(string) * ]
if "`readlog'" != "" { // reading from a file
.runfromfile `readlog'
exit
}
.parse `0'
end
// ---------------------------------------------------------------------------
program addplots
.parse `0'
end
// ---------------------------------------------------------------------------
// .parse
//
// Creates a two-way graph with overlaid plotregions (if needed) for a
// series of views specified as:
//
// twoway (<viewtype> varlist [ , options ]) (...) ... [ , options ]
// or
// twoway <viewtype> varlist [ , options] [ || <viewtype> varlist ...]
//
// First creates an array/log of commands then runs that array.
//
// Does not inherit from nor use many of the facilities of loggraph_g.class
// though it could (there are issues with notitling).
//
// Special options:
//
// nologging do not post the commands to the objects __LOG, this is useful
// when the command that precipitated the .addplots has already
// logged itself and that is sufficient for replay.
//
// norescaling specifies that existing plotregions are not rescaled even
// if plot/views are added to them.
//
// notitling specifies that titles are not to be created, useful
// when plots are being added to an existing graph. Needed for
// backward compatibility only, now inferred from graph itself
//
// plotregion() and -add- specify that a single existing plotregion is to
// be the recipient of all the created plots. -add- means the
// first plotregion in the graph.
// When adding to an existing plot, it is the responsibility of
// the caller to either use add or plotregion, or to specify x
// and yaxis()s for axes that do not already exist.
// Add is kept only for backward compatibility, it is now the
// default behaviour when the graph already exists.
program parse
// Processing new input
// Create edit log, then run it
tempname log
.`log' = {}
// options handled by graph_g
local graph_g_opts ///
TItle(string) SUBtitle(string) CAPtion(string) ///
NOTE(string) LEGend(string) LEGLOC(string) ///
T1title(string) T2title(string) B1title(string) ///
B2title(string) L1title(string) L2title(string) ///
R1title(string) R2title(string) ///
XLabels(string) YLabels(string) TLabels(string) ///
XTICks(string) YTICks(string) TTICks(string) ///
XMLabels(string) YMLabels(string) TMLabels(string) ///
XMTicks(string) YMTicks(string) TMTicks(string) ///
XSCale(string) YSCale(string) TSCale(string) ///
XTitle(string) YTitle(string) TTitle(string) ///
XLInes(string) YLInes(string) TLInes(string) ///
PLOTRegion(string) GRAPHRegion(string) SPACErs(string) ///
BGColor(string) TEXT(string) TTEXT(string)
// global options for us
local graph_opts OMITANYMiss OMITALLMiss OMITDUPmiss OMITNothing ///
USEPLOTRegion(string) ADD noLOGging noTITLING ///
ASPECTratio(string asis) PCYCle(real -999) ///
SCALE(string) noRESCALING
_parse expand cmd glob : 0 , common(`graph_opts' `graph_g_opts')
local 0 `glob_if' `glob_in' , `glob_op'
syntax [if] [in] [ , `graph_opts' * ]
if `"`aspectratio'"' != `""' {
_fr_aspect_parse_and_log `log' `aspectratio'
}
if `pcycle' != -999 {
.`log'.Arrpush .style.editstyle pcycle(`pcycle') editcopy
}
else {
local pcycle `.style.pcycle.val'
}
// graph area style
_fr_area_parse_and_log `log' "" GRAPHRegion , `options'
local goptions `r(rest)'
local omit `omitanymiss'`omitallmiss'`omitdupmiss'`omitnothing'
SetCheckPlotregion useplotregion : `"`useplotregion'"' `"`add'"'
tempname gtouse // overall touse
mark `gtouse' `if' `in'
if "`.plotregion1.isa'" != "" { // if just adding
local titling "notitling"
}
// restore stored
// parsing structures
local base_ss 0`.sersets.arrnels'
local n_plreg `.n_plotregions'
local j 0
foreach xscl in `.x_scales' {
local xscale`++j' `xscl'
}
local j 0
foreach yscl in `.y_scales' {
local yscale`++j' `yscl'
}
// pre-parse each subcommand to
// to prepare for sersets, etc.
local n_ss 0
local n 0
forvalues i = 1/`cmd_n' {
local ++n
gettoken cmd rest : cmd_`i' , parse(" ,[")
_unab_cmd cmd : `cmd'
// parse view
tempname pnm
capture cutil which twoway_`cmd'_parse
if _rc {
capture which yxtype-`cmd'.style
if _rc {
capture which yxview_`cmd'_draw
if _rc {
di as error "`cmd' is not a twoway plot type"
exit 198
}
}
.`pnm' = .twoway_yxview_parse.new // default parser
}
else { // custom parser
.`pnm' = .twoway_`cmd'_parse.new
}
.`pnm'.viewtype = "`cmd'"
.`pnm'.parse `rest'
local pobj`n' `pnm'
// parse x and yaxis (scale)
ParseOpts xscale yscale serset options : ///
`"`useplotregion'"' , `.`pnm'.options'
local 0 `", `options'"'
syntax [, FAKE_OPT_FOR_BETTER_MSG ]
// determine plotregion
if "`useplotregion'" == "" {
forvalues j = 1/`n_plreg' {
if "`:list xscale`j' & xscale'" != "" {
if "`:list yscale`j' & yscale'" != "" {
local plreg`n' plotregion`j'
local xscale`j' : list xscale`j' | xscale
local yscale`j' : list yscale`j' | yscale
continue , break // Break
}
}
}
if "`plreg`n''" == "" {
local plreg`n' plotregion`++n_plreg'
local xscale`n_plreg' `xscale'
local yscale`n_plreg' `yscale'
}
}
/* track sersets by touses */
tempname touse
mark `touse' `.`pnm'.if' `.`pnm'.in'
qui replace `touse' = 0 if `gtouse' != 1
if 0`.`pnm'.must_create_serset' | `"`serset'"' != "" {
local serset`n' `=`base_ss'+`++n_ss''
local ss_obj`n_ss' `pnm'
local ss_id `n_ss'
if `"`serset'"' == `""' {
local ss_use_cmd`n_ss' 1
}
else {
local ss_existing_ss`n_ss' `serset'
}
}
else {
forvalues j = 1/`n_ss' {
if "`.`pnm'.sort'" == "`ss_sort`j''" {
if ! 0`ss_use_cmd`j'' {
capture assert `touse' == `ss_touse`j''
if ! _rc {
local ss_id `j'
local serset`n' `=`base_ss'+`j''
continue , break // Break
}
}
}
}
if "`serset`n''" == "" {
local serset`n' `=`base_ss'+`++n_ss''
local ss_touse`n_ss' `touse'
if "`.`pnm'.sort'" != "" {
local ss_sort`n_ss' sort(`.`pnm'.sort')
}
local ss_use_cmd`n_ss' 0
local ss_id `n_ss'
}
}
local varlist `.`pnm'.varlist'
local ss_varlist`ss_id' : list ss_varlist`ss_id' | varlist
}
forvalues s = 1/`n_ss' { /* create the sersets */
local ssdex = `base_ss' + `s'
if "`ss_existing_ss`s''" != "" {
.`log'.Arrpush .sersets[`ssdex'] = .`ss_existing_ss`s''
}
else {
if 0`ss_use_cmd`s'' {
.`ss_obj`s''.log_create_serset , log(`log') ///
sersetname(sersets[`ssdex']) ///
touse(`gtouse') `omit'
}
else {
.`log'.Arrpush .sersets[`ssdex'] = ///
.serset.new `ss_varlist`s'' if `ss_touse`s'' ///
, `ss_sort`s'' `omit' nocount
}
}
}
// create the plot regions
// ignores style because fills
// a problem with overlays
if 0`.n_plotregions' {
local at at `.cells.plotregion1.minrow' `.cells.plotregion1.mincol'
}
else {
local at at 1 1
}
forvalues i = `=`.n_plotregions'+1'/0`n_plreg' {
local scheme = cond(`i' == 1, "scheme twoway" , "transparent")
.`log'.Arrpush .insert (plotregion`i' = .plotregion.new , ///
style(`scheme') graph(\`.objkey')) `at'
if `i' != 1 {
_fr_area_parse_and_log `log' plotregion`i' ///
PLOTRegion , `goptions' marginonly // preg margin
}
forvalues j = 1/`=`i'-1' { // common scales
if "`:list xscale`i' & xscale`j''" != "" {
.`log'.Arrpush .plotregion`i'.xscale.ref = ///
.plotregion`j'.xscale.ref
}
if "`:list yscale`i' & yscale`j''" != "" {
.`log'.Arrpush .plotregion`i'.yscale.ref = ///
.plotregion`j'.yscale.ref
}
}
}
_fr_area_parse_and_log `log' plotregion1 PLOTRegion , `goptions'
local goptions `"`r(rest)'"'
// create the views
local serid `.last_style'
local plotid `.n_views'
forvalues i = 1/`n' {
forvalues j = 1/0`.`pobj`i''.n' {
if "`useplotregion'" == "" {
local pregion `plreg`i''
}
else {
local pregion `useplotregion'
}
.`pobj`i''.log_create_view , log(`log') view(`j') ///
name(plot`++plotid') plotregion(`pregion') ///
serset(sersets[`serset`i'']) ///
seriesid(`=mod(`++serid'-1, 0`pcycle')+1')
.`pobj`i''.log_edits `log' `pregion'.plot`plotid' `j'
}
}
.n_views = `plotid'
.last_style = `serid'
// scale the plotregions
forvalues i = 1/0`n_plreg' {
if "`rescaling'" == "" | `i' > `.n_plotregions' {
.`log'.Arrpush .plotregion`i'.clear_scales
}
}
forvalues i = 1/0`n_plreg' {
if "`rescaling'" == "" | `i' > `.n_plotregions' {
.`log'.Arrpush .plotregion`i'.reset_scales , noclear
}
}
// add the axes
if (_caller() < 8.2) local tmth safe
else local tmth clean
local n_ys 0
local n_xs 0
forvalues i = `n_plreg'(-1)`=`.n_plotregions'+1' {
foreach d in y x {
// local one = cond("`d'" == "y" , "one" , "")
// special title considerations
foreach ax in `:list `d'scale`i' & `d's' {
local j : list posof "`ax'" in `d's
if `j' {
local tti ///
`"`.plotregion`i'.dimtitle_`tmth' `d''"'
if `"`tti'"' != `"``d's_title`j''"' {
local `d's_dots`j' "..."
}
// ineffective, needs Arrpush
}
// one axis representing multiple plotregions,
// not fully consistent with axis.set_ticks
// neither is two axes representing same plreg.
}
// collect list of axes to make
foreach ax in `:list `d'scale`i' - `d's' {
local `d's ``d's' `ax'
local `d'preg ``d'preg' plotregion`i'
local `d's_title`++n_`d's' ///
`"`.plotregion`i'.dimtitle_`tmth' `d'' `one'"'
.`log'.Arrpush local `d's_title`n_`d's' ///
`"\`.plotregion`i'.dimtitle_`tmth' `d' `one''"'
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -