📄 tickset_g.class
字号:
`"`max' must be a number or valid argument for `s(fmt)'() function"'
exit 198
}
local min `dmin'
local max `dmax'
}
if `min' >= `max' {
exit
}
.min = `min'
.max = `max'
.delta = `delta'
._between_ticks = 0
.use_rule.set_true
._default = 0
end
// ---------------------------------------------------------------------------
// Add a specific major tick/label (or multiple ticks/labels)
//
// Usage:
//
// add_ticks numlist ["label"] [numlist ["label"]] ...
//
// or
//
// add_ticks datelist ["label"] [datelist ["label"]] ...
program add_ticks
syntax [ anything(name=ticks) ] [, clear ]
if "`clear'" != "" {
.clear_ticks
}
local 0 `"`ticks'"'
local fmt `.label_format'
local i = 0`.ticks.arrnels'
gettoken pos 0 : 0 , quotes parse(" ()") match(par)
while `"`pos'"' != `""' {
if "`par'" != "" {
local pos `"(`pos')"'
}
_date2elapsed, format(`fmt') datelist(`pos')
local tfmt `s(fmt)'
local pos `s(args)'
capture confirm number `pos'
if _rc {
if "`tfmt'" == "" {
di as err ///
`"invalid ticklist, `pos' must be number"'
}
else {
di as err `"invalid ticklist,"' ///
`"`pos' must be a number or valid argument for `tfmt'() function"'
}
exit 198
}
._tmin = min(`._tmin' , `pos')
._tmax = max(`._tmax' , `pos')
gettoken label : 0 , q qed(qed) // quoted
if 0`qed' {
gettoken label 0 : 0 , q
.ticks[`++i'] = { `pos' , `label' }
}
else { // position only
.ticks[`++i'] = { `pos' , "" }
}
gettoken pos 0 : 0 , quotes parse(" ()") match(par)
}
end
// ---------------------------------------------------------------------------
// Return our overall min
program overallmin
if 0`.use_rule.istrue' {
if "`.scale.transform.snm'" == "log" {
class exit = max(min(`.min', `._tmin'), 1)
}
else {
class exit = min(`.min', `._tmin')
}
}
class exit = cond("`.scale.transform.snm'" == "log", ///
max(`._tmin', 1) , `._tmin')
end
program overallmax
if 0`.use_rule.istrue' {
class exit = max(`.max', `._tmax')
}
class exit = `._tmax'
end
// ---------------------------------------------------------------------------
program draw
args style pos z0 drawgrid gridonly pregsize lowmargin highmargin labels
// set the style to the gdi
.`style'.tickstyle.setgdifull , ///
angle(`.`style'.tickangle.val') posdefault(`pos')
// special case for ##<#>
if 0`._between_ticks' {
.reset_between_ticks
}
// tick and text z positions
local op = cond("`pos'" == "right" | "`pos'" == "above", "+", "-")
local tpos `.`style'.tickstyle.position.stylename'
local tin = -0`.`style'.tickstyle.tick_length' * ///
cond("`tpos'"== "inside", 1 , cond("`tpos'" == "outside", 0, .5))
local tout = 0`.`style'.tickstyle.tick_length' * ///
cond("`tpos'"== "inside", 0 , cond("`tpos'" == "outside", 1, .5))
local zi = `z0' `op' `tin'
local zo = `z0' `op' `tout'
local zt = `zo' `op' 0`.`style'.tickstyle.textgap.gmval'
local otol 0`.`style'.gridstyle.outer_tolerance.val'
// grid positions
local islr = ("`pos'" == "left" | "`pos'" == "right")
local ln = "`.scale.transform.stylename'" == "log" // logged
if 0`drawgrid' {
local g0 = `z0' + ///
0`.`style'.gridstyle.extend_low.isfalse' * 0`lowmargin'
local g1 = `g0' + 0`pregsize' + ///
0`.`style'.gridstyle.extend_low.istrue' * 0`lowmargin' + ///
0`.`style'.gridstyle.extend_high.istrue' * 0`highmargin'
local drawmin = 0`.`style'.gridstyle.draw_min.istrue'
local drawmax = 0`.`style'.gridstyle.draw_max.istrue'
local omin = `.overallmin'
local omax = `.overallmax'
local odif = `omax' - `omin'
if ( `.scale.min' <= `omin' ) local drawmin 1
if ( `.scale.max' >= `omax' ) local drawmax 1
if (abs((`.scale.min'-`omin') / `.delta') < .6) local drawmin 1
if (abs((`.scale.max'-`omax') / `.delta') < .6) local drawmax 1
local omin = min(`.scale.min' , `omin')
local omax = max(`.scale.max' , `omax')
if 0`.`style'.gridstyle.force_nomin.istrue' { // nogmin
local extra_min & (\\\`i' > 1)
}
if 0`.`style'.gridstyle.force_nomax.istrue' { // nogmax
local last = int((`.max'+.48*`.delta'-`.min')/`.delta')
local extra_max & (\\\`i' <= `last')
}
local d = cond(`islr', "y", "x")
local draw ///
(`omax' - \``d'' > `otol' * `.delta' | `drawmax') & ///
(\``d'' - `omin' > `otol' * `.delta' | `drawmin') ///
`extra_min' `extra_max'
if (`ln') local draw 1
}
// draw ticks and labels
local fmt `.label_format'
local labeled 0`.`style'.tickstyle.show_labels.istrue'
local uselbl 0`.`style'.use_labels.istrue'
local ticked 0`.`style'.tickstyle.show_ticks.istrue' & ///
"`.`style'.tickstyle.linestyle.snm'" != "none" & ///
"`.`style'.tickstyle.linestyle.color.snm'" != "none"
local alt = 0`.`style'.alternate.istrue'
local altsz = 0`.`style'.alternate_gap.gmval' + ///
0`.`style'.tickstyle.textstyle.size.gmval'
if 0`.use_rule.istrue' { // min/max/delta
if `islr' & `.delta' != 0 { // left or right
local i 0
forvalues yf = `.min'(`.delta')`=`.max'+.48*`.delta'' {
local ++i
if (abs(`yf') < `.delta' * 1e-6) local y 0
else local y `yf'
if `ln' & `y' < 0 {
continue // Continue
}
if `labeled' {
if 0`._between_ticks' { // skip majors
if 0`.on_a_major `y'' {
continue // Continue
}
}
}
if `ticked' & ! `gridonly' {
gdi line `zi' `y' `zo' `y'
}
if `labeled' & ! `gridonly' {
local xt `zt'
local lab
if `alt' {
if mod((`i'-1), 2) {
local xt = `xt' `op' `altsz'
}
}
if `uselbl' {
local lab ///
`"`.`labels'.value_label `y' `fmt''"'
}
if !`uselbl' | `"`lab'"' == `""' {
local lab `:di `fmt' `y'' // sic
}
gdi text `xt' `y' `lab'
}
if 0`drawgrid' {
if 0`=`draw'' {
.`style'.gridstyle.linestyle.setgdifull
gdi line `g0' `y' `g1' `y'
.`style'.tickstyle.linestyle.setgdifull
}
}
local yc = `y'
}
}
else if `.delta' != 0 { // above or below
local i 0
forvalues xf = `.min'(`.delta')`=`.max'+.48*`.delta'' {
local ++i
if (abs(`xf') < `.delta' * 1e-6) local x 0
else local x `xf'
if `ln' & `x' < 0 {
continue // Continue
}
if `labeled' {
if 0`._between_ticks' { // skip majors
if 0`.on_a_major `x'' {
continue // Continue
}
}
}
if `ticked' & ! `gridonly' {
gdi line `x' `zi' `x' `zo'
}
if `labeled' & ! `gridonly' {
local yt `zt'
local lab
if `alt' {
if mod((`i'-1), 2) {
local yt = `yt' `op' `altsz'
}
}
if `uselbl' {
local lab ///
`"`.`labels'.value_label `x' `fmt''"'
}
if !`uselbl' | `"`lab'"' == `""' {
local lab `:di `fmt' `x'' // sic
}
gdi text `x' `yt' `lab'
}
if 0`drawgrid' {
if 0`=`draw'' {
.`style'.gridstyle.linestyle.setgdifull
gdi line `x' `g0' `x' `g1'
.`style'.tickstyle.linestyle.setgdifull
}
}
local xc = `x'
}
}
}
// specified ticks
if `islr' {
forvalues i = 1/0`.ticks.arrnels' {
local xt `zt'
local lab
if `alt' {
if mod((`i'-1), 2) {
local xt = `xt' `op' `altsz'
}
}
local y `.ticks[`i'][1]'
if `ln' & `y' < 0 {
continue // Continue
}
if `ticked' & ! `gridonly' {
gdi line `zi' `y' `zo' `y'
}
if `labeled' & ! `gridonly' {
if `"`.ticks[`i'][2]'"' == `""' {
if `uselbl' {
local lab ///
`"`.`labels'.value_label `y' `fmt''"'
}
if !`uselbl' | `"`lab'"' == `""' {
local lab `:di `fmt' `y'' // sic
}
}
else {
local lab `"`.ticks[`i'][2]'"'
}
gettoken chk1 chk2 : lab , qed(quoted)
if `quoted' & `"`chk2'"' != `""' {
._mtext_label `style' `pos' `xt' `y' `lab'
}
else gdi text `xt' `y' `lab'
}
if 0`drawgrid' {
if 0`=`draw'' {
.`style'.gridstyle.linestyle.setgdifull
gdi line `g0' `y' `g1' `y'
.`style'.tickstyle.linestyle.setgdifull
}
}
}
}
else {
forvalues i = 1/0`.ticks.arrnels' {
local yt `zt'
local lab
if `alt' {
if mod((`i'-1), 2) {
local yt = `yt' `op' `altsz'
}
}
local x `.ticks[`i'][1]'
if `ln' & `x' < 0 {
continue // Continue
}
if `ticked' & ! `gridonly' {
gdi line `x' `zi' `x' `zo'
}
if `labeled' & ! `gridonly' {
if `"`.ticks[`i'][2]'"' == `""' {
if `uselbl' {
local lab ///
`"`.`labels'.value_label `x' `fmt''"'
}
if `"`lab'"' == `""' {
local lab `:di `fmt' `x'' // sic
}
}
else {
local lab `"`.ticks[`i'][2]'"'
}
gettoken chk1 chk2 : lab , qed(quoted)
if `quoted' & `"`chk2'"' != `""' {
._mtext_label `style' `pos' `x' `yt' `lab'
}
else gdi text `x' `yt' `lab'
}
if 0`drawgrid' {
if 0`=`draw'' {
.`style'.gridstyle.linestyle.setgdifull
gdi line `x' `g0' `x' `g1'
.`style'.tickstyle.linestyle.setgdifull
}
}
}
}
end
// ----------------------------------------------------------------------------
// Make a temporary positioned textbox to display the multiline label.
program _mtext_label
gettoken style lab : 0
gettoken pos lab : lab
gettoken x lab : lab
gettoken y lab : lab
tempname postb
.`postb' = .pos_textbox.new , xpos(`x') ypos(`y') mtext(`lab')
// style from textstyle
local fs `.`style'.tickstyle.textstyle.objkey'
.`postb'.style.editstyle horizontal(`.`fs'.horizontal.snm') ///
vertical(`.`fs'.vertical.snm') angle(`.`fs'.angle.val') ///
size(`.`fs'.size.val') color(`.`fs'.color.rgb') ///
linegap(`.`fs'.linegap.val') editcopy
// approximate orienation
.`postb'.orientation.setstyle ///
, style(`.`style'.tickangle.nearest_orientation')
// box placement/alignment
local cpos "`.`fs'.align2compass `pos''"
.`postb'.style.box_alignment.setstyle , style(`cpos')
if ("`cpos'" == "N") .`postb'.style.editstyle vertical(bottom) editcopy
if ("`cpos'" == "S") .`postb'.style.editstyle vertical(top) editcopy
if ("`cpos'" == "W") .`postb'.style.editstyle horizontal(right) editcopy
if ("`cpos'" == "E") .`postb'.style.editstyle horizontal(left) editcopy
.`postb'.draw
end
// ---------------------------------------------------------------------------
// Whether the specified values is on a major tick of .mymajor. cannot check
// .show_labels or .length of .mymajor because the style is not accessible.
program on_a_major
args xory
if ! 0`.mymajor.isofclass tickset_g' {
class exit 0
}
local tol = (`.max' - `.min') / 10000
local hit 0
if `.mymajor.delta' != 0 {
forvalues z = `.mymajor.min'(`.mymajor.delta')`.mymajor.max' {
if abs(`xory' - `z') < `tol' {
local hit 1
continue, break
}
}
}
if `hit' {
class exit `hit'
}
forvalues i = 1/0`.ticks.arrnels' {
if abs(`xory' - `.ticks[`i'][1]') < `tol' {
local hit 1
continue, break
}
}
class exit `hit'
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -