📄 grid.class
字号:
if "`.`view'.`ord'stretch.setting'" != "fixed" { /* not fixed */
exit
}
if 0`.max`dim'' < 0`.`cell'.max`dim'' { // expand maxrows/cols
.max`dim' = 0`.`cell'.max`dim''
}
if 0`.min`dim'' < 0`.`cell'.min`dim'' {
.min`dim' = 0`.`cell'.min`dim''
}
/* compute # and size of contained
* fixed row/cols. count shared too */
local shr_ct 0
local all_ct 0
local sum_sz 0
forvalues i = `.`cell'.min`dim''/`.`cell'.max`dim'' {
if 0`.`dim'pos[`i']' {
local sum_sz = `sum_sz' + `.`dim'pos[`i']'
}
else {
if 0`.`shrfrac'[`i']' {
local ++shr_ct
}
}
local ++all_ct
}
local view_sz = 0`.`view'.extent `ord''
if `view_sz' <= `sum_sz' {
exit /* big enough */
}
/* expand shared sized row/cols
* if possible */
if 0`shr_ct' {
local sz = (`view_sz' - `sum_sz') / `shr_ct'
forvalues i = `.`cell'.min`dim''/`.`cell'.max`dim'' {
if ! 0`.`dim'pos[`i']' {
if 0`.`shrfrac'[`i']' {
.`dim'pos[`i'] = `sz'
}
}
}
exit /* EXIT */
}
/* expand all contained row/cols
* proportionally */
if `sum_sz' {
local prop = `view_sz' / `sum_sz'
forvalues i = `.`cell'.min`dim''/`.`cell'.max`dim'' {
if ! 0`.`dim'pos[`i']' {
.`dim'pos[`i'] = `prop' * `.`dim'pos[`i']'
}
}
exit /* EXIT */
}
/* contract all contained row/cols
* a common fixed amount */
local adj = `view_sz' / `all_ct'
forvalues i = `.`cell'.min`dim''/`.`cell'.max`dim'' {
.`dim'pos[`i'] = `adj' + 0`.`dim'pos[`i']'
}
end
program define _set_sizes
args shrfrac dim
/* sum fixed sizes, etc */
._sum_fixed size negsize shr_ct : `shrfrac' `dim'
local ord = cond("`dim'"=="col", "x", "y")
local dimsize `.`ord'size_ren'
if `size'+`negsize' > `dimsize' {
/* bad case, sum of row/col sizes is bigger
* than our size. Just scale them to overlap
* and fit. Sizeables get a small size
* just so they show */
local t_shr_sz .06
local shr_ct 0`._shr_only_ct'
if `shr_ct' { /* sizeables */
local shr_sz = `t_shr_sz' / `shr_ct'
.shared_`dim'sz = `shr_sz'
}
else {
local t_shr_sz 0
.shared_`dim'sz = 0
}
local scale = (`dimsize'-`t_shr_sz') / (`size'+`negsize'-`t_shr_sz')
local fx_shr = 1e300
forvalues i = 1/`.max`dim'' {
if `.`dim'pos[`i']' == 0 {
if 0`.`shrfrac'[`i']' {
.`dim'pos[`i'] = `.shared_`dim'sz' / `.`shrfrac'[`i']'
}
}
else {
.`dim'pos[`i'] = `scale' * `.`dim'pos[`i']'
if 0`.`shrfrac'[`i']' {
local fx_shr = min(`fx_shr', `.`dim'pos[`i']')
}
}
}
if `fx_shr' < 1e300 {
.shared_`dim'sz = max(`.shared_`dim'sz', `fx_shr')
}
exit /* EXIT */
}
if `shr_ct' == 0 & `size' != 0 {
/* unusual case, no stretchable row/cols.
* just expand them all, need rules
* or other scale settings */
/* loop will be more sophisticated */
local scale = `dimsize' / `size'
forvalues i = 1/`.max`dim'' {
.`dim'pos[`i'] = `scale' * `.`dim'pos[`i']'
}
exit /* EXIT */
}
if `shr_ct' == 0 { /* size == 0 */
/* another unusual case, no stretchable
* row/cols and all column sizes are 0 */
* just make all a fixed equal size,
* need rules or other scale settings */
if `.max`dim'' <= 1 {
exit /* nothing to do */
}
/* loop will be more sophisticated */
local size = `dimsize' / (`.max`dim'' - 1)
local m = `.max`dim'' - 1
forvalues i = 1/`=`.max`dim''-1' {
.`dim'pos[`i'] = `size'
}
exit /* EXIT */
}
/* standard case, just size the stretchables */
/* try equal sizes for all stretchables make
* any that need more size fixed and
* keep iterating until we have only fixed and
* stretchables that fit the standard size */
local allfit = 0
while (! `allfit') {
* di in white "local shared_sz = (`dimsize' - `size') / `shr_ct'"
local shared_sz = (`dimsize' - `size') / `shr_ct'
local allfit = 1
forvalues i = 1/`.max`dim'' {
if ! 0`.`shrfrac'[`i']' {
continue
}
if `.`dim'pos[`i']' > `shared_sz'/`.`shrfrac'[`i']' {
local allfit = 0
local size = `size' + `.`dim'pos[`i']'
local shr_ct = `shr_ct' - 1 / `.`shrfrac'[`i']'
.`shrfrac'[`i'] = 0
}
}
}
.shared_`dim'sz = `shared_sz'
forvalues i = 1/`.max`dim'' {
if 0`.`shrfrac'[`i']' {
.`dim'pos[`i'] = `shared_sz' / `.`shrfrac'[`i']'
}
}
end
program define _sum_fixed
args szmac shrszmac ctmac colon shrfrac dim
local size 0
local negsize 0
local shr_ct 0
forvalues i = 1/`.max`dim'' {
if 0`.`shrfrac'[`i']' {
local negsize = `negsize' + 0`.`dim'pos[`i']'
local shr_ct = `shr_ct' + 1 / `.`shrfrac'[`i']'
}
else {
local size = `size' + 0`.`dim'pos[`i']'
}
}
c_local `szmac' `size'
c_local `shrszmac' `negsize'
c_local `ctmac' `shr_ct'
end
program define _shr_only_ct
args shrfrac dim
local ct 0
forvalues i = 1/`.max`dim'' {
if 0`.`shrfrac'[`i']' {
if `.`dim'pos[`i']' == 0 {
local ct = `ct' + 1 / `.`shrfrac'[`i']'
}
}
}
class exit = `ct'
end
program define _posn_from_size
args dim
local dsz = 0`.`dim'pos[1]'
.`dim'pos[1] = 0
forvalues i = 1/`.max`dim'' {
local dsz1 = 0`.`dim'pos[`i'+1]'
.`dim'pos[`i'+1] = 0`.`dim'pos[`i']' + `dsz'
local dsz `dsz1'
}
end
program define _rev_row_pos /* reverses row array */
local n = int((`.maxrow'+2)/2)
forvalues i = 1/`n' {
local tpos `.rowpos[`i']'
.rowpos[`i'] = `.rowpos[`.maxrow'+1-`i']'
.rowpos[`.maxrow'+1-`i'] = `tpos'
}
end
/* -------------------------------------------------------------------------*/
/* Scale the gmetric to nicely size text, symbols, ticks, keys, etc given the
specified # of rows or columns (or whatever value you would like to use
for the scaling). The scaling is less than proportional for
# < knot (or the default if not specified) then becomes proportional
for #'s above knot. The slopes of the 2-part spline may also be
specified.
Usage: scale_gmetric # [ [knot] beta1 beta2 ]
*/
program scale_gmetric
args n k1 b1 b2
if `"`k1'"' == `""' {
local k1 = `.`c(curscm)'.special.default_knot1'
}
if `"`b1'"' == `""' {
local b1 = `.`c(curscm)'.special.default_slope1'
}
if `"`b2'"' == `""' {
local b2 = `.`c(curscm)'.special.default_slope2'
}
local b_fctr = (`n' - 1) / `n'
local resz = `b_fctr' * `b1'
if `n' > `k1' {
local resz = `resz' + (`b2'-`b1') * (`n'-`k1') / `n'
}
local resz = 1 - `resz'
.gmetric_mult = `resz'
end
/* -------------------------------------------------------------------------*/
/* _set_ programs for making changes to values that require a side effect.
*/
program define _set_fixed_xsize
._set_fixed_dimsize x `0'
end
program define _set_fixed_ysize
._set_fixed_dimsize y `0'
end
program define _set_fixed_dimsize
gettoken dim val : 0
if `val' == `.fixed_`dim'size' {
exit
}
if `val' >= . {
if "`.`dim'stretch.setting'" == "fixed" {
.`dim'stretch.set free
}
.fixed_`dim'size = (.)
exit
}
.`dim'stretch.set fixed
.fixed_`dim'size = `val'
end
/* -------------------------------------------------------------------------*/
/* Return a list of .Declared objects that are of the specified class type
Usage: .list_ofclassname
*/
program list_ofclassname
args classnm
forvalues i = 1/0`.cells.dynamicmv.arrnels' {
if "`.cells.dynamicmv[`i'].isa'" == "array" {
forvalues j = 1/0`.cells.dynamicmv[`i'].arrnels' {
if "`.dynamicmv[`i'][`j'].classname'" == "`classnm'" {
class nameoflocal dynamicmv[`i']
local list `list' `r(name)'[`j']
}
}
}
else {
if "`.dynamicmv[`i'].classname'" == "`classnm'" {
class nameoflocal dynamicmv[`i']
local list `list' `r(name)'
}
}
}
class exit "`list'"
end
/* -------------------------------------------------------------------------*/
/* Return a list of .Declared objects that are of the specified class type
or inherit from the specified classtype.
Usage: .list_ofclass
*/
program list_ofclass
args classnm
forvalues i = 1/0`.cells.dynamicmv.arrnels' {
if "`.cells.dynamicmv[`i'].isa'" == "array" {
forvalues j = 1/0`.cells.dynamicmv[`i'].arrnels' {
if 0`.dynamicmv[`i'][`j'].isofclass `classnm'' {
class nameoflocal dynamicmv[`i']
local list `list' `r(name)'[`j']
}
}
}
else {
if 0`.dynamicmv[`i'].isofclass `classnm'' {
class nameoflocal dynamicmv[`i']
local list `list' `r(name)'
}
}
}
class exit "`list'"
end
/* -------------------------------------------------------------------------*/
/* Return a list of indexes into .Declared objects that are of the specified
class type or inherit from the specified classtype.
Usage: .list_ofclass_indices
*/
program list_ofclass_indices
args classnm
forvalues i = 1/0`.cells.dynamicmv.arrnels' {
if "`.cells.dynamicmv[`i'].isa'" == "array" {
forvalues j = 1/0`.cells.dynamicmv[`i'].arrnels' {
if 0`.dynamicmv[`i'][`j'].isofclass `classnm'' {
local list `list' [`i'][`j']
}
}
}
else {
if 0`.dynamicmv[`i'].isofclass `classnm'' {
local list `list' [`i']
}
}
}
class exit "`list'"
end
/* -------------------------------------------------------------------------*/
/* Return 1 if the named view is in the specified row/col of the grid. If
the view spans rows/columns then returns 1 if any of those spanned
rows/columns includes the on specified.
*/
program in_row
args view row
class exit = `.cells.`view'.minrow' <= `row' & ///
`.cells.`view'.maxrow' >= `row'
end
program in_col
args view col
class exit = `.cells.`view'.mincol' <= `col' & ///
`.cells.`view'.maxcol' >= `col'
end
/* -------------------------------------------------------------------------*/
/* Return the (minimum) row/col position of the specified object in the
grid. Returns missing if not found.
Usage: .minrowof
.mincolof
The maximum postions are returned by,
.maxrowof
.maxcolof
*/
program minrowof
class exit = cond("`.cells.`1'.minrow'"=="", . , `.cells.`1'.minrow')
end
program mincolof
class exit = cond("`.cells.`1'.mincol'"=="", . , `.cells.`1'.mincol')
end
program maxrowof
class exit = cond("`.cells.`1'.maxrow'"=="", . , `.cells.`1'.maxrow')
end
program maxcolof
class exit = cond("`.cells.`1'.maxcol'"=="", . , `.cells.`1'.maxcol')
end
/* -------------------------------------------------------------------------*/
/* Return the minimum/maximum row/col position of any object in the
specified list.
Returns 0. for max/min respectively if nothing found.
*/
program minrow_oflist
local min = .
foreach i of local 0 {
if 0`.cells.`i'.minrow' < `min' {
local min = 0`.cells.`i'.minrow'
}
}
class exit 0`min'
end
program maxrow_oflist
local max = 0
foreach i of local 0 {
if 0`.cells.`i'.maxrow' > `max' {
local max = 0`.cells.`i'.maxrow'
}
}
class exit `max'
end
program mincol_oflist
local min = .
foreach i of local 0 {
if 0`.cells.`i'.mincol' < `min' {
local min = 0`.cells.`i'.mincol'
}
}
class exit 0`min'
end
program maxcol_oflist
local max = 0
foreach i of local 0 {
if 0`.cells.`i'.maxcol' > `max' {
local max = 0`.cells.`i'.maxcol'
}
}
class exit `max'
end
/* -------------------------------------------------------------------------*/
/* Given a row and list of viewnames, return the max/min column where
something from the list was found. Returns 0 if none found in the row
Likewise for a column.
*/
program maxcol_oflist_inrow
gettoken row list : 0
local max = 0
foreach i of local list {
if 0`.cells.`i'.minrow' >= `row' & 0`.cells.`i'.maxrow' <= `row' {
if 0`.cells.`i'.maxcol' > `max' {
local max = 0`.cells.`i'.maxcol'
}
}
}
class exit = `max'
end
program mincol_oflist_inrow
gettoken row list : 0
local min = .
foreach i of local list {
if 0`.cells.`i'.minrow' >= `row' & 0`.cells.`i'.maxrow' <= `row' {
if 0`.cells.`i'.mincol' < `min' {
local min = 0`.cells.`i'.mincol'
}
}
}
class exit = 0`min'
end
program maxrow_oflist_incol
gettoken col list : 0
local max = 0
foreach i of local list {
if 0`.cells.`i'.mincol' >= `col' & 0`.cells.`i'.maxcol' <= `col' {
if 0`.cells.`i'.maxrow' > `max' {
local max = 0`.cells.`i'.maxrow'
}
}
}
class exit = `max'
end
program minrow_oflist_incol
gettoken col list : 0
local min = .
foreach i of local list {
if 0`.cells.`i'.mincol' >= `col' & 0`.cells.`i'.maxcol' <= `col' {
if 0`.cells.`i'.minrow' < `min' {
local min = 0`.cells.`i'.minrow'
}
}
}
class exit = 0`min'
end
exit
/* -------------------------------------------------------------------------*/
/*
Implmentation notes:
A grid contains views that are referenced by dynamically declared
attributes of class cell. If a name is used more than once for
different attribute (e.g. 2 or 3 scatters), then an array of
attributes with that name is created. Each dynamically declared cell
attribute holds the grid position of the attribute, the style of the
cell, and a reference to the view itself
We cannot store the position information directly in the view as a
view may be included many times in a grid through references.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -