shape_tank = {
const tank_style = `
<style>
</style>`;
const tank = function(conf){
const obj = {}
const _config = conf ? conf:{value:20, max:100, min:0, color:"rgba(255, 255, 255, 1)", width:300, height:200, depth:100} ;
let origin = [0, 0], scale = 20, cubesData = [], alpha = 0, beta = 0, startAngle = Math.PI/4, css3dbox = {};
obj.updateShape = function(node,config){
d3.select(node).selectAll("*").remove();
this.render(node,config) ;
};
obj.updateValue = function(node,v){
node.value = v;
let conf = node.config ;
let cubesGroup = d3.select(node);
cubesGroup.select(".box__face--water_front")
.transition()
.duration(1000)
.style("height",node.wScale(v)+"px");
cubesGroup.select(".box__face--water_left")
.transition()
.duration(1000)
.style("height",node.wScale(v)+"px");
cubesGroup.select(".box__face--water_top")
.transition()
.duration(1000)
.style("top",node.fScale(v)+"px");
cubesGroup.select(".box__face--front > div ")
.transition()
.duration(1000)
.text(v);
};
obj.render = function(node,config){
config = Object.assign({},_config,config);
node.config = config;
var cubeWidth = config.width, cubeHeight = config.height, cubeDepth = config.depth ;
var shiftW = cubeWidth/2, shiftH = cubeHeight/2, shiftD = cubeDepth/2 ;
var shiftRL = shiftW-shiftD , shiftTB = shiftH-shiftD;
node.wScale = d3.scaleLinear().domain([config.min,config.max]).range([0,cubeHeight]).clamp(true) ;
node.fScale = d3.scaleLinear().domain([config.min,config.max]).range([cubeHeight+shiftTB,shiftTB]).clamp(true) ;
let cubesGroup = d3.select(node)
.attr("transform","translate("+[config.x,config.y]+")")
.append("g")
.attr("class","cubes");
cubesGroup.append("g").node().innerHTML = tank_style;
//build 3d cube
function renderCube(data) {
var cubes = cubesGroup.selectAll('g.cube').data(data, function(d){ return d.id });
var ce = cubes
.enter()
.append('g')
.attr('class', 'cube')
cubes.exit().remove();
//css 3d box
var boxfaces = ['front','back','right','left','top','bottom','water_top','water_front','water_left'] ;
var box = cubesGroup.selectAll('foreignObject').data([{id:'t',faces:boxfaces}],d=>d.id)
.enter()
.append('foreignObject')
.attr("width",2*d3.max([cubeWidth,cubeHeight,cubeWidth]))
.attr("height",2*d3.max([cubeWidth,cubeHeight,cubeWidth]))
.append('xhtml:div')
.attr('xmlns',"http://www.w3.org/1999/xhtml")
.attr('class','scene')
.style("margin","50px")
.style("perspective","240000px")
.append('xhtml:div')
.attr('class', 'box')
.style("position","relative")
.style("border","0px solid blue")
.style("transform-style","preserve-3d")
.style("transform","rotateY(48.6947deg) rotateX(-20.4204deg) rotateZ(-20.4204deg)")
.style("transform-origin", shiftW+"px "+shiftH+"px 0px")
;
box.selectAll('div.box__face').data(function(d){ return d.faces ;})
.enter()
.append('xhtml:div')
.attr('class',d=>'box__face box__face--'+d)
.style("position","absolute")
.style("border","0px solid #CCC")
.style("font-size","24px")
.style("font-weight","bold")
.style("color","white")
.style("text-align","center")
//.style("line-height","200px")
.style("background-color",d=>config.color)
.text(d=>(d=="top"? config.title:""))
;
box.select(".box__face--water_top")
.style("border","0px")
.style("background-color","rgba(63,178,150,0.7)")
.style("transform","rotateX( 90deg) translateZ("+shiftH+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeDepth+"px")
.style("top",shiftTB+"px")
;
box.select(".box__face--water_front")
.style("border","0px")
//.style("background-image",`url("data:image/svg+xml;base64,${window.btoa(svg_bubble.outerHTML)}")`)
.style("background-color","rgba(56,160,134,0.7)")
.style("transform","rotateY(0deg) translateZ("+shiftD+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeHeight+"px")
.style("bottom", -(cubeHeight+0)+"px")
.append("div")
.style("position","relative")
.style("bottom","30px")
;
box.select(".box__face--water_left")
//.style("background-image",`url("data:image/svg+xml;base64,${window.btoa(svg_bubble.outerHTML)}")`)
.style("background-color","rgba(39,111,93,0.7)")
.style("border","0px")
.style("transform","rotateY(-90deg) translateZ("+shiftW+"px)")
.style("width",cubeDepth+"px")
.style("height",cubeHeight+"px")
.style("left",shiftRL+"px")
.style("bottom", -(cubeHeight+0)+"px")
;
box.select(".box__face--front")
.style("background-color","rgba(61, 150, 180, 0.7)")
.style("transform","rotateY(0deg) translateZ("+shiftD+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeHeight+"px")
.style("bottom", -(cubeHeight+0)+"px")
.append("div")
.style("position","relative")
.style("bottom","30px")
;
box.select(".box__face--back")
.style("transform","rotateY(180deg) translateZ("+shiftD+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeHeight+"px")
;
box.select(".box__face--right")
.style("transform","rotateY(90deg) translateZ("+shiftW+"px)")
.style("width",cubeDepth+"px")
.style("height",cubeHeight+"px")
.style("left",shiftRL+"px")
;
box.select(".box__face--left")
//.style("background-color","hsla(186, 87%, 48%, 0.8)")
//.style("background-color","rgba(46, 104, 125, 0.7)")
.style("background-color","rgba(32,84,117,0.7)")
.style("transform","rotateY(-90deg) translateZ("+shiftW+"px)")
.style("width",cubeDepth+"px")
.style("height",cubeHeight+"px")
.style("left",shiftRL+"px")
.style("bottom", -(cubeHeight+0)+"px")
;
box.select(".box__face--top")
.style("background-color","rgba(68,167,201,0.7)")
.style("transform","rotateX(90deg) translateZ("+shiftH+"px)")
//.style("background-image",image_top)
.style("background-size","cover")
.style("width",cubeWidth+"px")
.style("height",cubeDepth+"px")
.style("top",shiftTB+"px")
;
box.select(".box__face--bottom")
.style("transform","rotateX(-90deg) translateZ("+shiftH+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeDepth+"px")
.style("top",shiftTB+"px")
;
}
renderCube([{id:"t1"}]) ;
// enable Drag and Drop
var mx, my, mouseX, mouseY;
function dragStart(){
mx = d3.event.x;
my = d3.event.y;
}
function dragged(){
mouseX = mouseX || 0;
mouseY = mouseY || 0;
beta = (d3.event.x - mx + mouseX) * Math.PI / 360 ;
alpha = (d3.event.y - my + mouseY) * Math.PI / 360 * (-1);
//console.log("rotate(" + (alpha - startAngle) + "," + beta + startAngle + ")");
cubesGroup.select(".box").style("transform", "rotateY("+ 180*(beta+startAngle) +"deg) rotateX("+ 180*(alpha - startAngle) +"deg) rotateZ("+ 180*(alpha - startAngle) +"deg)");
}
function dragEnd(){
mouseX = d3.event.x - mx + mouseX;
mouseY = d3.event.y - my + mouseY;
}
var dd = d3.drag().on('drag', dragged).on('start', dragStart).on('end', dragEnd);
//cubesGroup.call(dd);
// wall interactive
function handleMouseOver(d, i) {
d3.select(this)
.transition()
.duration(400)
.attr("transform","translate(0,-20)");
}
function handleMouseOut(d, i) {
d3.select(this)
.transition()
.duration(400)
.attr("transform","translate(0,0)");
}
//cubesGroup.selectAll('g.cube').on("mouseover",handleMouseOver).on("mouseout",handleMouseOut);
this.updateValue(node,config.value);
};
return obj;
}
return tank;
}