Published
Edited
Nov 7, 2019
Fork of Cube
1 fork
Insert cell
md`# 3D Tank`
Insert cell
Insert cell
Insert cell
grow_config = {
let repaint = 1;
let group=[
//tank
{id:"tank_1", xtype:"tank", x:0, y:0, value:"70", min:15, max:150, title:"Buffer Tank" , repaint:1},
{id:"tank_2", xtype:"tank", x:400, y:0, value:"30", title:"Tank2", width:100, height:150,depth:200, color:"rgb(37, 110, 170)", repaint:0},
]
return group;
}
Insert cell
Insert cell
Insert cell
Insert cell
shape_tank = {

const tank_style = `
<style>
</style>`;
const tank = function(conf){
const obj = {}
const _config = conf ? conf:{value:20, max:100, min:0, color:"#717e29", width:300, height:200, depth:100} ;

let colormap = {
orange: ["#c5682f","#f5a173","#f48138"],
yellow:["#c89b16","#ffd257","#ffc60c"],
green:["#5d903a","#94c476","#75b44b"],
blue:["#3d60a2","#7394d5","#4976ca"],
blue2:["#a0c9e6","#729cc7","#84b5dc"],
green2:["#00e400ff","#26c100ff","#00a100ff"]}
let color = d3.scaleThreshold().domain([15,18,19]).range(["blue2","green","yellow","orange"]);
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--front")
.transition()
.duration(1000)
.style("height",node.wScale(v)+"px");
cubesGroup.select(".box__face--water")
.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'] ;
var box = cubesGroup.selectAll('foreignObject').data([{id:'t',faces:boxfaces}],d=>d.id)
.enter()
.append('foreignObject')
.attr("width",500)
.attr("height",500)
.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(45deg) rotateX(-16deg) rotateZ(-16deg)")
;
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","1px solid white")
.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=="left"? config.title:""))
;
box.select(".box__face--water")
.style("border","0px")
.style("background-color","hsla(186, 87%, 48%, 0.3)")
.style("transform","rotateX( 90deg) translateZ("+shiftH+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeDepth+"px")
.style("top",shiftTB+"px")
;
box.select(".box__face--front")
.style("background-color","hsla(186, 87%, 48%, 0.8)")
.style("background-image",`url("data:image/svg+xml;base64,${window.btoa(svg_bubble.outerHTML)}")`)
.style("transform","rotateY(0deg) translateZ("+shiftD+"px)")
.style("width",cubeWidth+"px")
.style("height",cubeHeight+"px")
.style("bottom", -(cubeHeight+2)+"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("transform","rotateY(-90deg) translateZ("+shiftW+"px)")
.style("width",cubeDepth+"px")
.style("height",cubeHeight+"px")
.style("left",shiftRL+"px")
;

box.select(".box__face--top")
.style("transform","rotateX(90deg) translateZ("+shiftH+"px)")
.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 / 230 ;
alpha = (d3.event.y - my + mouseY) * Math.PI / 230 * (-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;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more