📄 bargraph_g.class
字号:
}
local gpos = 0`.`style'.label.position.setting'
if `gpos' == 0 {
local shift 0
}
else {
local shift = `.`style'.marker.size.gmval' / 2 + ///
`.`style'.label.textgap.gmval'
}
local angle `.`style'.label.position.angle'
local xshift = `shift' * cos(`angle')
local yshift = `shift' * sin(`angle')
while serset(`.boxsrt', `=`j'+1') == 9999 {
scalar `j' = `j' + 1
if `=`x'' >= . | `=`y'' >= . {
continue // Continue
}
/*
if `.pvar' < . { // custom position
local pos = serset(`.pvar', `j')
local lab ///
`"`._get_label `dolbl' `dostr' "`fmt'" `j' `labarr''"'
if `"`lab'"' != `""' {
if `pos' >= . {
local pos `gpos'
}
_draw_point `=`x'' `=`y'' `pos' `drawn' `lab'
continue // Continue
}
}
if ! `.grouped.istrue' {
.obs_styles[`j'].marker.setgdifull // symbols
.obs_styles[`j'].label.setgdifull // text
local shift = `.obs_styles[`j'].marker.size.gmval' ///
/ 2 + `.`style'.label.textgap.gmval'
local angle `.obs_styles[`j'].label.position.angle'
local xshift = `shift' * cos(`angle')
local yshift = `shift' * sin(`angle')
}
*/
if `drawn' { // draw point
gdi point `=`x'' `=`y''
}
else {
gdi moveto `=`x'' `=`y''
}
gdi gm_rmoveto `xshift' `yshift' // offset for labels
if `dolbl' {
gdi ctext `.`labarr'.value_label `=serset(`lvar',`j')''
}
else {
if `dostr' {
local lab : di `fmt' `"`=strserset(`lvar',`j')'"'
local lab `lab' // sic
gdi ctext `lab'
}
else {
gdi ctext `=string(`=serset(`lvar',`j')',"`fmt'")'
}
}
}
end
// ---------------------------------------------------------------------------
// Insert a bar label for the specified point
program MakeLabel
args stacked x0 y0 size i_v i_g nolook // may really be y x size
if `.horizontal.istrue' {
// position
if "`.barlabel_pos.stylename'" == "base" {
local x = `y0'
}
else if "`.barlabel_pos.stylename'" == "center" {
local x = `y0' + `size' / 2
}
else local x = `size' + cond(`stacked' , `y0' , 0)
local y =`x0' + `.barsize' / 2
local gap = 0`.graphstyle.barlabel_gap.val' * ///
`gdi(gbeta)' / `gdi(xbeta)'
// box align and gap
if "`.barlabel_pos.stylename'" == "outside" | ///
"`.barlabel_pos.stylename'" == "base" {
if ( `.reverse_scale.istrue' ) local boxalign west
else local boxalign east
}
else if "`.barlabel_pos.stylename'" == "inside" {
local gap = -`gap'
if ( `.reverse_scale.istrue' ) local boxalign east
else local boxalign west
}
else local boxalign center
if ( `.reverse_scale.istrue' ) local gap = -`gap'
if "`.barlabel_pos.stylename'" != "center" {
if `size' < 0 {
local x = `x' - `gap'
if "`.barlabel_pos.stylename" != "crossing" | ///
"`.barlabel_pos.stylename'" == "base" {
local edit swap_alignment horizontal
}
}
else {
local x = `x' + `gap'
}
}
}
else {
// position
if "`.barlabel_pos.stylename'" == "base" {
local y = `y0'
}
else if "`.barlabel_pos.stylename'" == "center" {
local y = `y0' + `size' / 2
}
else local y = `size' + cond(`stacked' , `y0' , 0)
local x = `x0' + `.barsize' / 2
local gap = 0`.graphstyle.barlabel_gap.val' * ///
`gdi(gbeta)' / `gdi(ybeta)'
// box align and gap
if "`.barlabel_pos.stylename'" == "outside" | ///
"`.barlabel_pos.stylename'" == "base" {
if ( `.reverse_scale.istrue' ) local boxalign south
else local boxalign north
}
else if "`.barlabel_pos.stylename'" == "inside" {
local gap = -`gap'
if ( `.reverse_scale.istrue' ) local boxalign north
else local boxalign south
}
else local boxalign center
if ( `.reverse_scale.istrue' ) local gap = -`gap'
if "`.barlabel_pos.stylename'" != "center" {
if `size' < 0 {
local y = `y' - `gap'
if "`.barlabel_pos.stylename'" != "crossing" | ///
"`.barlabel_pos.stylename'" == "base" {
local edit swap_alignment vertical
}
}
else {
local y = `y' + `gap'
}
}
}
if ("`boxalign'" == "east") local justopt horizontal(left)
else if ("`boxalign'" == "west") local justopt horizontal(right)
.graphstyle.editstyle ///
barlabelstyle(box_alignment(`boxalign') `justopt') editcopy
// label
if "`.barlabel_method.stylename'" == "name" {
local series sersets[1].sers[`.vargroup']
if 0`nolook' {
local lab `.`series'.value_label `i_v''
}
else {
local lab `.`series'.value_label `=serset(`.vargroup',`i_v')''
}
}
else if "`.barlabel_method.stylename'" == "group" {
local series sersets[1].sers[`.group']
if 0`nolook' {
local lab `.`series'.value_label `i_g''
}
else {
local i_ob = 1 + (`i_g' - 1) * ///
max(1, 0`.sersets[1].sers[`.vargroup'].categories')
local lab `.`series'.value_label `=serset(`.group',`i_ob')''
}
}
else {
if `stacked' {
local sz = `size' + ///
("`.barlabel_method.snm'" == "total") * `y0'
}
else local sz `size'
local lab = string(`sz', "`.graphstyle.barlabel_format'")
}
// create
.plotregion1.Declare barlabels = .pos_textbox.new , ///
xpos(`x') ypos(`y') forcesized mtext(`lab') ///
styleref(`.graphstyle.barlabelstyle.objkey')
local labname `r(name)'
if "`edit'" != "" {
.plotregion1.`labname'.`edit'
}
tempname log // apply options
.`log' = {}
_fr_sztextbox_parse_and_log `log' plotregion1.`labname' , ///
`.barlabel_opts'
local 0 `", `r(rest)'"'
syntax [, FAKE_OPT_FOR_BETTER_MSG ]
_fr_runlog `log' , nologging
end
/* -------------------------------------------------------------------------*/
/* Draw a line of dots at specified position.
*/
program _draw_dots
args pos
if `.horizontal.istrue' {
_get_xy_minmax min max delta : x
if "`.graphstyle.dottype.stylename'" == "line" {
.graphstyle.dot_linestyle.setgdifull
gdi line `min' `pos' `max' `pos'
}
else if "`.graphstyle.dottype.stylename'" == "rectangle" {
local half = `.graphstyle.dot_areawidth.val'
_fr_draw_rect graphstyle.dot_areastyle ///
`min' `=`pos'-`half'' ///
`max' `=`pos'+`half''
}
else {
.graphstyle.dots_ptstyle.setgdifull
if (`max' - `min') / `delta' > 10000 {
exit // avoid endless
}
forvalues x = `min'(`delta')`max' {
gdi point `x' `pos'
}
}
}
else {
_get_xy_minmax min max delta : y
if "`.graphstyle.dottype.stylename'" == "line" {
.graphstyle.dot_linestyle.setgdifull
gdi line `pos' `min' `pos' `max'
}
else if "`.graphstyle.dottype.stylename'" == "rectangle" {
local half = `.graphstyle.dot_areawidth.val'
_fr_draw_rect graphstyle.dot_areastyle ///
`=`pos'-`half'' `min' ///
`=`pos'+`half'' `max'
}
else {
.graphstyle.dots_ptstyle.setgdifull
if (`max' - `min') / `delta' > 10000 {
exit // avoid endless
}
forvalues y = `min'(`delta')`max' {
gdi point `pos' `y'
}
}
}
end
program _get_xy_minmax
args minmac maxmac deltamac colon d
local min `.plotregion1.`d'scale.curmin'
local max `.plotregion1.`d'scale.curmax'
if `.graphstyle.extend_dots.istrue' {
if 0`.plotregion1.`d'scale.reverse.istrue' {
local a max
local b min
}
else {
local a min
local b max
}
if "`d'" == "x" {
local `a'addgsz = `.plotregion1.style.margin.gmleft'
local `b'addgsz = `.plotregion1.style.margin.gmright'
}
else {
local `a'addgsz = `.plotregion1.style.margin.gmbottom'
local `b'addgsz = `.plotregion1.style.margin.gmtop'
}
local sz = `max' - `min'
local gsz = `.plotregion1.`d'size_ren'
local min = `min' - `minaddgsz' * `sz' / `gsz'
local max = `max' + `maxaddgsz' * `sz' / `gsz'
}
local range100 = (`max' - `min') / 100
c_local `minmac' `=`min'-`range100'*`.graphstyle.dot_extend_low.val''
c_local `maxmac' `=`max'+`range100'*`.graphstyle.dot_extend_high.val''
c_local `deltamac' = (`max' - `min') / `.graphstyle.num_dots.val'
end
/* -------------------------------------------------------------------------*/
/* Draws the bars for the bargraph.
Sidenote: an instance of barview.class holding a bargraph instance is
inserted into the plotregion. barview.draw then redirects drawing to this
program.
*/
program drawbars
.sersets[1].set /* set the current serset */
/* count by groups */
._set_barsize
._get_grp_cts base grp sup
._get_gaps gap_base gap_grp gap_sup gap_out
._makelbls = ("`.barlabel_method.stylename'" != "none" & ///
0`.plotregion1.barlabels.arrnels' == 0)
tempname j x
scalar `j' = 0
scalar `x' = `gap_out'
forvalues i_s = 1/`sup' {
if 0`.shadevar' == 0`.supergroup' {
local styledex `._style_cat `=`j'+1''
local has_pat `._set_barstyle `styledex''
}
forvalues i_g = 1/`grp' {
if 0`.shadevar' == 0`.group' {
local styledex `._style_cat `=`j'+1''
local has_pat `._set_barstyle `styledex''
}
/* draw bars */
local drawn 0
if `.boxplot.istrue' {
._draw_boxset `j' `x' drawn 0`has_pat' `i_g' `styledex'
}
else if `.stack.istrue' {
._draw_barstack `j' `x' drawn 0`has_pat' `i_g' `styledex'
}
else {
._draw_barset `j' `x' drawn 0`has_pat' `i_g' `styledex'
}
if `drawn' | `.fill.istrue' {
local grp_drawn 1
scalar `x' = `x' + `gap_grp'
}
}
if 0`grp_drawn' | `.fill.istrue' {
scalar `x' = `x' - `gap_grp'
scalar `x' = `x' + `gap_sup'
}
}
end
program _get_grp_cts
args basemac grpmac supmac
c_local `basemac' = cond(`.stack.istrue', 1 , /*
*/ max(1, 0`.sersets[1].sers[`.vargroup'].categories'))
c_local `grpmac' = max(1, 0`.sersets[1].sers[`.group'].categories')
c_local `supmac' = max(1, 0`.sersets[1].sers[`.supergroup'].categories')
end
program _get_gaps
args gap_base gap_grp gap_sup gap_out
c_local `gap_base' = `.barsize'*`.graphstyle.gap.prop'
c_local `gap_grp' = `.barsize'*`.graphstyle.group_gap.prop'
c_local `gap_sup' = `.barsize'*`.graphstyle.supgroup_gap.prop'
c_local `gap_out' = `.barsize'*`.graphstyle.outer_gap.prop'
end
program _draw_barset
args j pos drawnmac has_pat i_g styledex
local gap = 0`.barsize' * `.graphstyle.gap.prop'
if `.percentages.istrue' {
local sumrng = `._sumrange_vargrp `j''
}
/* base of bars */
if `.horizontal.istrue' {
local min = `.plotregion1.xscale.curmin'
local max = `.plotregion1.xscale.curmax'
}
else {
local min = `.plotregion1.yscale.curmin'
local max = `.plotregion1.yscale.curmax'
}
if `min' <= 0 & `max' >= 0 {
local base 0
}
else {
local base = cond(`max' < 0 , `max' , `min')
}
forvalues i = 1/0`.sersets[1].sers[`.vargroup'].categories' {
scalar `j' = `j' + 1
local sz = serset(1, `j')
if `.percentages.istrue' {
local sz = 100 * `sz' / `sumrng'
}
if `sz' < . {
if `.dotplot.istrue' {
if `i' == 1 | `.graphstyle.gap.val' != -100 {
_draw_dots `=`pos'+`.barsize'/2'
}
}
if 0`.shadevar' == 0`.vargroup' {
local styledex `._style_cat `=`j'''
local has_pat `._set_barstyle `styledex''
}
.draw_bar `=`pos'' `base' `=`sz'-`base'' `i' ///
0`has_pat' `styledex'
if `._makelbls' {
.MakeLabel 0 `=`pos'' `base' `sz' `i' `i_g' 0
}
scalar `pos' = `pos' + `.barsize' + `gap'
local drawn 1
}
else {
if `.fill.istrue' {
scalar `pos' = `pos' + `.barsize' + `gap'
if `.dotplot.istrue' {
if `i' == 1 | `.graphstyle.gap.val' != -100 {
_draw_dots `=`pos'+`.barsize'/2'
}
}
}
}
}
if 0`drawn' | `.fill.istrue' {
scalar `pos' = `pos' - `gap'
}
c_local `drawnmac' 0`drawn'
end
program _draw_barstack
args j pos drawnmac has_pat i_g styledex
local sumsz 0
local sumszneg 0
local p0 = `pos' /* pos is a scalar */
if `.percentages.istrue' {
local sumrng = `._sumrange_vargrp `j''
}
if `.dotplot.istrue' {
_draw_dots `=`pos'+`.barsize'/2'
}
forvalues i = 1/0`.sersets[1].sers[`.vargroup'].categories' {
scalar `j' = `j' + 1
if 0`.shadevar' == 0`.vargroup' {
local styledex `._style_cat `=`j'''
local has_pat `._set_barstyle `styledex''
}
local sz = serset(1, `j')
if 0`.percentages.istrue' {
local sz = 100 * `sz' / `sumrng'
}
if `sz' < . & `sz' != 0 {
if `sz' > 0 {
.draw_bar `p0' `sumsz' `sz' `i' ///
0`has_pat' `styledex'
if `._makelbls' {
.MakeLabel 1 `=`pos'' `sumsz' `sz' `i' `i_g' 0
}
local sumsz = `sumsz' + `sz'
local drawn 1
}
else {
.draw_bar `p0' `sumszneg' `sz' `i' ///
0`has_pat' `styledex'
if `._makelbls' {
.MakeLabel 1 `=`pos'' `sumszneg' ///
`sz' `i' `i_g' 0
}
local sumszneg = `sumszneg' + `sz'
local drawn 1
}
}
else if `sz' == 0 {
if `._makelbls' {
.MakeLabel 1 `=`pos'' `sumsz' `sz' `i' 0
}
}
}
if 0`drawn' | `.fill.istrue'{
scalar `pos' = `pos' + `.barsize'
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -