*! 1.3.3 NJC/CFB 21 Jun 2003
* 1.3.2 NJC/CFB 29 July 2002
* 1.3.1 NJC/CFB 26 July 2002
* 1.3.0 NJC/CFB 10 Jun 2002
* 1.2.3 NJC/CFB 30 Nov 2001
* 1.2.2 NJC/CFB 6 Nov 2001
* 1.2.1 NJC/CFB 6 Nov 2001
* 1.2.0 NJC/CFB 4 Oct 2001
* 1.1.0 NJC/CFB 17 Sept 2001
* 1.0.1 NJC/CFB 18 June 2001
* 1.0.0 NJC/CFB 7 June 2001
program define tsgraph, sort
        version 7.0

	qui tsset /* error if not set as time series */
	local timevar "`r(timevar)'"
	local panelvar "`r(panelvar)'"

	syntax varlist(ts num min=1) [if] [in] /*
	*/ [, Connect(str) Symbol(str) XLAbel XLAbel(str) /*
	*/ Rescale YLAbel YLAbel(str) YLOg L1title(str) L2title(str) /*
	*/ Gap(int 5) SEParate(varname) BY(varname) NLAbel(int 4) * ]

	* separate() option is undocumented

	* novarlist to get plot whenever at least one value not missing
	marksample touse, novarlist
	local ny : word count `varlist'

	if "`panelvar'" != "" & `ny' == 1 & "`separate'" == "" {
		qui tab `panelvar' if `touse'
		if r(r) <= 4 & r(r) > 1 { local separate "`panelvar'" }
	}

	if "`separate'" != "" {
		if `ny' > 1 {
			di as err "separate() option allowed only with" _c
			di as err "one response variable"
			exit 198
		}
		qui tab `separate' if `touse'
		if r(r) > 20 {
			di as err "too many groups in `separate': maximum 20"
			exit 198
		}
		else if r(r) == 1 { local separate } /* blank it out */
		local ny = r(r)
	}

	if "`connect'" == "" {
		if `ny' == 1 { local connect "L" }
		else if `ny' == 2 { local connect "LL[_]" }
		else if `ny' == 3 { local connect "LL[_]L[-]" }
		else if `ny' == 4 { local connect "LL[_]L[-]L[.]" }
		else local connect : di _dup(`ny') "L"
	}

	if "`symbol'" == "" {
		local symbol : di _dup(`ny') "i"
	}

	if "`xlabel'" == "" {
		tempvar year
		local format : format `timevar'
		local which = substr("`format'",2,1)
		local which2 = substr("`format'",3,.)

		/* formats beginning "%t", but not "%ty" */
		if "`which'" == "t" & "`which2'" != "y" {
	 		local which = substr("`format'",3,1)
			if "`which'" != "d" {
				tempname xx
				qui gen `year' = yofd(dof`which'(`timevar'))
				su `year' if `touse', meanonly
				Nicenum `nlabel'
				local X "`r(numlist)'"
				if "`X'" != "" {
					foreach x of local X {
						local x = int(`x')
						local la = `which'(`x'`which'1)
						local LA "`LA'`la' "
					}
				}
			}
		}

		/* format "%ty" */
		else if "`which'" == "t" & "`which2'" == "y" {
			su `timevar' if `touse', meanonly
			Nicenum `nlabel'
			local X "`r(numlist)'"
			if "`X'" != "" { local LA "`X'" }
		}

		/* formats beginning "%d" or "%td" */
		else if "`which'" == "d" {
			qui gen `year' = yofd(`timevar')
			su `year' if `touse', meanonly
			Nicenum `nlabel'
			local X "`r(numlist)'"
			if "`X'" != "" {
				foreach x of local X {
					local la = d(1jan`x')
					local LA "`LA'`la' "
				}
			}
		}

		if "`LA'" != "" { local xlabel "xlabel(`LA')" }
	}
	else if "`xlabel'" != "xlabel" { local xlabel "xla(`xlabel')" }

	if "`ylabel'" == "" { local ylabel "ylabel" }
	else if "`ylabel'" != "ylabel" {
		local ylabel "yla(`ylabel')"
	}

	if "`ylog'" != "" & `"`l2title'"' == "" {
		local l2title "(log scale)"
	}
	if `"`l2title'"' != "" { local l2title `"l2("`l2title'")"' }
	if `"`l1title'"' == "" {
		if `ny' == 1 | "`separate'" != "" {
			capture local l1title : variable label `varlist'
			if `"`l1title'"' == "" { local l1title "`varlist'" }
		}
	}
	if `"`l1title'"' != "" { local l1title "l1(`l1title')" }

 	* this depends on Stata 7 dropping variables with a tempname as stub
	if "`separate'" != "" {
		tempname sep
		qui separate `varlist' if `touse', by(`separate') gen(`sep')
	        unab varlist : `sep'*

		* fix variable labels
		foreach v of local varlist {
			local label : variable label `v'
			local pos = index(`"`label'"',"=")
			local label = substr(`"`label'"',`pos' + 2,.)
			label variable `v' `"`label'"'
		}

		* -separate- can mess up sort order
		qui tsset
	}

	if "`by'" != "" {
		sort `by' `timevar'
		local byby "by(`by')"
	}

	graph `varlist' `timevar' if `touse', /*
	*/ c(`connect') `xlabel' `ylabel' `ylog' `byby' /*
	*/ symbol(`symbol') `rescale' `l1title' `l2title' g(`gap') `options'
end

* main algorithm based on -nicenum- 1.1.0 11/4/94 (STB-25: dm28)
program define Nicenum, rclass
	version 7.0
	args nlabel
	tempname gmin gmax grange exp d f nf tmp1 tmp2

	* these arguments from -summarize- just earlier
	scalar `gmin' = r(min)
	scalar `gmax' = r(max)

	* all within same year? no go!
	if `gmin' == `gmax' {
		exit 0
	}

	local N = `nlabel'
        local inter = `N' + 1
	local ntick = `inter'

	scalar `grange' = `gmax' - `gmin'
	scalar `exp' = log10(`grange')
	scalar `exp' = int(`exp') - (`exp' < 0.0)

	scalar `f' = `grange' / (10^`exp')
	if `f' <= 1      { scalar `nf' = 1  }
	else if `f' <= 2 { scalar `nf' = 2  }
	else if `f' <= 5 { scalar `nf' = 5  }
	else             { scalar `nf' = 10 }

	scalar `grange' = `nf' * 10^`exp'
	scalar `d' = `grange' / (`ntick' - 1)
	scalar `exp' = log10(`d')
	scalar `exp' = int(`exp') - (`exp' < 0.0)

	scalar `f' = `d' / (10^`exp')
	if `f' < 1.5    { scalar `nf' = 1 }
	else if `f' < 3 { scalar `nf' = 2 }
	else if `f' < 7 { scalar `nf' = 5 }
	else            { scalar `nf' = 10 }

	scalar `d' = `nf' * 10^`exp'
	scalar `gmin' = `gmin' / `d'
	scalar `gmin' = (int(`gmin') - (`gmin' < 0.0)) * `d'
	scalar `tmp1' = `gmax' / `d'
	scalar `tmp2' = int(`tmp1')
	if `tmp2' < float(`tmp1') { scalar `tmp2' = `tmp2' + 1 }
	scalar `gmax' = `tmp2' * `d'
	scalar `tmp1' = log10(`d')

	local nfrac = int(-`tmp1') + (`tmp1' < 0.0)
	if `nfrac' <= 0 { local nfrac = 0 }
	if `nfrac' == 0 { scalar `tmp1' = `gmin' }
	else scalar `tmp1' = `gmin' + 1 / (10^(`nfrac' + 1))
	scalar `tmp2' = `gmax' + `d'/ 2

	while `tmp1' <= `tmp2' {
		local stub = int(`tmp1')
		if `nfrac' {
			local gminb = int(`tmp1' * (10^`nfrac'))
			local stubb = int(`stub' * (10^`nfrac'))
			local frac = `gminb' - `stubb'
			local frst = "00000000000000000000" + /*
			*/	string(`frac')
			local fstr = substr("`frst'", -`nfrac', .)
			local numlist "`numlist' `stub'.`fstr'"
		}
		else	{
			local tstr = string(`tmp1')
			local numlist "`numlist' `tstr'"
		}
		scalar `tmp1' = `tmp1' + `d'
	}

	return local numlist "`numlist'"
end