// Nov 14 2018 20:13:03
// A version of the heatmap program that takes RGB values for each cell

program define bhhmaprgb
di "entering bhhmaprgb"
version 8.2
// Based on hmap.ado version 1.0 16mar2010 by Austin Nichols <austinnichols@gmail.com>
  syntax varlist(min=5 max=5) [if] [in]  ///
                      [,  ///
                       BOTtom(string) TOP(string) ///
                       SYMmetric ///
                       SCatter ///
                       MLABsize(passthru) ///
                       XLabel(passthru) ///
                       YLabel(passthru) ///
                       ADDPlot(string) ///
                       NAME(string) * ]

marksample touse
tokenize `varlist'

if ("`name'"!="") {
  local name = "name(`name')"
}
xunits `1' `touse'
local xdist=r(units)
xunits `2' `touse'
local ydist=r(units)
if (`"`xlabel'"'=="") {
  su `1', mean
  local xlabel `"xlabel(`r(min)'(`xdist')`r(max)', val angle(90) nogrid)"'
}

if (`"`ylabel'"'=="") {
  su `2', mean
  local ylabel `"ylabel(`r(min)'(`ydist')`r(max)', val angle(0) nogrid)"'
}
if (`"`addplot'"'!="") {
  local addplot `"||`addplot'"'
}


tempvar y0 y1 zvar
qui gen `y1'=`2'+`ydist'/2
label value `y1' `:val lab `2''
qui gen `y0'=`2'-`ydist'/2
su `3' if `touse', mean
local minlev=r(min)
local maxlev=r(max)
if ("`bottom'"!="") {
  local minlev=`bottom'
}
if ("`top'"!="") {
  local maxlev=`top'
}
/* if `maxlev'==`minlev' { */
/*   di as err "variable `3' does not vary; graph would be a solid color" */
/*   err 198 */
/* } */
local limit = `maxlev'
local limit = max(`limit', abs(`minlev'))

qui gen `zvar' = `3' + 256*( `4' + `5'*256)

local gcom
sort `zvar'
tempvar first
qui by `zvar': gen `first' = _n==1
qui levelsof `zvar' if `touse', loc(lev)
foreach x of local lev {
  preserve
  qui keep if `zvar'==`x'
  local R=`3'[1]
  local G=`4'[1]
  local B=`5'[1]
  // di "`R' `G' `B'"
  local gcom `"`gcom'||rbar `y1' `y0' `1' if (abs(`zvar'-`x')<0.000000001) & `touse', barw(`xdist') col("`R' `G' `B'") fi(inten100) lw(none)"'
  restore
}

if "`scatter'"!="" {
  tempvar signlab
  qui gen str1 `signlab' = "-"
  qui replace `signlab' = " " if inrange(`zvar', -0.1,0.1)
  qui replace `signlab' = "+" if `zvar' > 0.1
  local sc `"|| scatter `2' `1' if `touse', mlab(`signlab') mlabcolor(white) mlabpos(0) `mlabsize' msy(i)"'
}

local gcom `"`gcom' legend(off)  `ylabel' `xlabel'  xtitle("") ytitle("")"'
twoway `gcom' plotr(fc(gray) m(zero)) `name' `options' `addplot' `sc'
end

program xunits, rclass
args v touse
qui summ `v' if `touse', mean
local p = 1
capture assert float(`v') == float(round(`v',1)) if `touse'
if _rc == 0 {
  while _rc == 0 {
    local p=`p'*10
    capture assert float(`v') == float(round(`v',`p')) if `touse'
  }
  local p=`p'/10
}
else {
  while _rc {
    local p=`p'/10
    capture assert float(`v') == float(round(`v',`p')) if `touse'
  }
}
return scalar units = `p'
end