dvSLEEPmap = (elem,data,xField,yField,valueField,options) => {
if (typeof(options) === "undefined") {options = {}}
if (typeof(options.boxSize) === "undefined") {options.boxSize = 5}
if (typeof(options.boxSizeX) === "undefined") {options.boxSizeX = options.boxSize}
if (typeof(options.boxSizeY) === "undefined") {options.boxSizeY = options.boxSize}
if (typeof(options.startPos) === "undefined") {options.startPos = {x:0,y:0}}
if (typeof(options.padding) === "undefined") {options.padding = 1}
if (typeof(options.paddingX) === "undefined") {options.paddingX = options.padding}
if (typeof(options.paddingY) === "undefined") {options.paddingY = options.padding}
if (typeof(options.colorScale) === "undefined") {options.colorScale = d3.scaleLinear().domain(d3.extent(data,d=>toNum(d[valueField]))).range(["white","black"])}
if (typeof(options.rotateColumnTextDeg) === "undefined") {options.rotateColumnTextDeg = -90}
let listOfYField = [];
data.forEach(d => {if (!listOfYField.includes(d[yField])) {listOfYField.push(d[yField]);}});
let listOfXField = [];
data.forEach(d => {if (!listOfXField.includes(d[xField])) {listOfXField.push(d[xField]);}});
let hm = elem.selectAll(".heatBox")
.data(data)
.join("rect")
.classed("heatBox",true)
.attr("title", d => d["Country Name"] + ": " + d.year)
.attr("width", options.boxSizeX)
.attr("height", options.boxSizeY)
.attr("x", d => options.startPos.x + listOfXField.indexOf(d[xField]) * (options.boxSizeX + options.paddingX))
.attr("y", d => options.startPos.y + listOfYField.indexOf(d[yField]) * (options.boxSizeY + options.paddingY))
.attr("fill", d => options.colorScale(toNum(d[valueField])))
let hm_labelY = elem.selectAll(".heatBoxLabelY")
.data(listOfYField)
.join("text")
.style("text-anchor","end")
.style("font-size", options.boxSizeY)
.classed("heatBoxLabelY", true)
.text(d => d)
.attr("x", options.startPos.x - 5)
.attr("y", (d,i) => options.startPos.y + i * (options.boxSizeY + options.paddingY) + options.boxSizeY)
let hm_labelX = elem.selectAll(".heatBoxLabelX")
.data(listOfXField)
.join("text")
.style("font-size", options.boxSizeX)
.classed("heatBoxLabelX", true)
.text(d => d)
.attr("x", (d,i) => options.startPos.x + i * (options.boxSizeX + options.paddingX) + options.boxSizeX)
.attr("y", options.startPos.y - 5)
.attr("transform", (d,i,nodes) => {return "rotate(" + options.rotateColumnTextDeg + " " + nodes[i].getAttribute("x") + "," + nodes[i].getAttribute("y") + ")"});
return hm;
}