Как сделать плиточную диаграмму?
Нужно сделать такую плиточную диаграмму, где цвет и высота плиток зависят от значений. Как можно реализовать такое?
Ответы (2 шт):
А в чём собственно возникают сложности? Нарисовать это можно на чистом CSS, смотрите пример ниже. А значения подставлять, например, через переменные с помощью скрипта, думаю, сами справитесь, ничего сложного в этом нет.
.chart {
display: inline-flex;
height: 10em;
margin: 10px;
font-size: 1.5em;
}
.bar {
transform: rotateX(-30deg) rotateY(-135deg);
transform-style: preserve-3d;
}
.face {
width: 2em;
height: 2em;
}
.left,
.right {
height: 10em;
}
.left {
transform: rotateY(90deg) translateZ(1em);
background: #ffd988;
}
.right {
transform: rotateY(180deg) translateY(-10em) translateZ(1em);
background: #fecd5e;
}
.top {
transform: rotateX(90deg) translateZ(21em);
background: #ffe8af;
}
.bottom {
transform: rotateX(-90deg) translateY(0em) translateZ(-13em) rotate(180deg);
background: #ffe8af;
box-shadow: 0 0 0.6em rgb(0 0 0 / 30%), 0.6em -1em 3em rgb(0 0 0 / 30%), 1em 1em 10em rgb(254 254 254 / 80%);
}
.chart_m .left,
.chart_m .right {
height: 2em;
}
.chart_m .left {
transform: rotateY( 90deg) translateY(8em) translateZ(1em);
background: #ededed;
}
.chart_m .right {
transform: rotateY(180deg) translateY(6em) translateZ(1em);
background: #e4e2e2;
}
.chart_m .top {
transform: rotateX(90deg) translateZ(-3em);
background: #f3f2f2;
}
.chart_m .bottom {
transform: rotateX(-90deg) translateY(0em) translateZ(3em) rotate(180deg);
background: #f3f2f2;
}
<div class="chart">
<div class="bar">
<div class="face left"></div>
<div class="face right"></div>
<div class="face top"></div>
<div class="face bottom"></div>
</div>
</div>
<div class="chart chart_m">
<div class="bar">
<div class="face left"></div>
<div class="face right"></div>
<div class="face top"></div>
<div class="face bottom"></div>
</div>
</div>
Вариант с three.js как раз вам предмет для изучения ... там где 3D это в самый раз ..
За геометрию куба отвечает вот такая строка: new THREE.BoxGeometry(1,2,1);
За освещение отвечает эта строка: new THREE.MeshNormalMaterial();
Как создавать в цикле с правильным положением камеры и объектов я пока не знаю ...чем больше кубов тем больше кода в моём случае ...
Вот такая попытка показать 3D диаграму .... лично я дальше буду изучать так как мне понравилось ...
<body style="height: 100vh; margin: 0; overflow: hidden">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r126/three.min.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry1 = new THREE.BoxGeometry(1, 2, 1);
const geometry2 = new THREE.BoxGeometry(1, 3, 1);
const geometry3 = new THREE.BoxGeometry(1, 5, 1);
const geometry4 = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshNormalMaterial();
const cube = new THREE.Mesh(geometry1, material);
const cube1 = new THREE.Mesh(geometry2, material);
const cube2 = new THREE.Mesh(geometry3, material);
const cube3 = new THREE.Mesh(geometry4, material);
cube.position.set(0, 0, 0);
cube1.position.set(2, 0.5, 0);
cube2.position.set(4, 1.5, 0);
cube3.position.set(5.6, -0.4, 0);
scene.add(cube, cube1, cube2, cube3);
camera.position.set(10, 1, 10);
camera.rotation.set(0, 0.6, 0);
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame(animate);
cube.rotation.y += 0.01;
cube1.rotation.y += 0.01;
cube2.rotation.y += 0.01;
cube3.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
</script>
