And can this be done on the net CSS?Well, you can't do anything without scruples. But most of it's quite feasible with styles.let oJson = JSON.parse(`{
"Понедельник": [47,230,1,164,20,219,72,235,145,209,25,205],
"Вторник": [175,38,13,151,185,237,85,126,103,125,153,165],
"Среда": [112,19,183,201,21,64,60,35,193,236,73,207],
"Четверг": [50,192,211,148,198,86,217,32,49,113,218,62],
"Пятница": [69,54,210,74,7,222,78,92,77,142,162,23],
"Суббота": [101,39,212,157,131,139,178,149,206,147,71,122],
"Воскресенье": [46,11,109,26,43,158,28,227,34,90,121,129]
}`);
function fFillChart() {
let oChart = document.querySelector(".girder-chart");
let nItems = 0;
let nQ = Math.max(...Object.values(oJson).flat()) / 100;
for (let k in oJson) {
let oRow = document.createElement("div");
oChart.append(oRow);
oJson[k].forEach((el) => {
let nValue = el / nQ;
nItems++;
oRow.insertAdjacentHTML("beforeend",
<div class="girder" data-grp="${Math.floor(nValue / 25)}" style=" transition-delay:${nItems / 100}s; --girder-height: ${nValue}; filter: drop-shadow(0 2px 3px #0008) hue-rotate(${(100 - nValue) * 3 - 45}deg) saturate(${(nValue / 100) * 0.75}); opacity:${nValue / 110 + 0.1}; "> <div class="girder_l"></div> <div class="girder_r"></div> <div class="girder_t" data-val="${el}"></div> </div>
);
});
}
}
fFillChart();body {
margin: 0;
min-height: 100vh;
background-image: radial-gradient(#181100, #000);
background-position: 0% 110%;
background-repeat: no-repeat;
background-size: auto;
display: flex;
flex-flow: column nowrap;
justify-content: space-around;
align-items: center;
}
.girder-wrap {
display: flex;
flex-flow: row wrap;
justify-content: center;
align-items: center;
width: min-content;
color: #fff;
text-shadow: -1px -1px 3px #000, -1px 1px 3px #000, 1px -1px 3px #000, 1px 1px 3px #000;
}
.girder-wrap>input:not(:first-child) {
margin-left: 2em;
}
hr {
margin: 20px 40px 80px;
width: 100%;
}
.girder-chart {
--girder-think: 50;
font-size: calc(var(--girder-think, 100) * 1px) !important;
position: relative;
display: inline-flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
padding: 1em 2em;
}
.girder-chart::before {
content: "";
position: absolute;
top: 0em; left: 0.23em;
height: 100%; width: calc(100% - 0.49em);
background-image: repeating-linear-gradient( 210.9deg, #0000 0 calc(0.49em - 1px), #8888 0.49em, #0000 calc(0.49em + 1px) 0.514em), repeating-linear-gradient( -210.9deg, #0000 0 calc(0.24em - 1px), #8888 0.24em, #0000 calc(0.24em + 1px) 0.514em);
-webkit-mask-image: radial-gradient(ellipse closest-side, #0000, #000, #0000);
mask-image: radial-gradient(ellipse closest-side, #0000, #000, #0000);
pointer-events: none;
}
.girder-chart>div {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: flex-end;
height: 0.3em;
}
.girder-chart>div:nth-child(odd) { margin-right: calc(var(--girder-think) / 2 * 1px); }
.girder-chart>div:nth-child(even) { margin-left: calc(var(--girder-think) / 2 * 1px); }
.girder {
transform: translate3d(0, 0, 0);
position: relative;
display: flex;
justify-content: center;
align-items: flex-start;
will-change: height, opacity;
height: calc(var(--girder-height, 0) * 1px + 0.3em) !important; width: 1em;
filter: drop-shadow(0 3px 1px #000a) saturate(100%);
transition: height 0.4s cubic-bezier(0.65, 0.45, 0.33, 1.18), opacity 0.5s ease-in-out 0s;
}
.girder_t {
position: relative;
height: 0.68em; width: 0.68em;
border-radius: 0.066em 0.066em 0.066em 0.033em;
transform-origin: 50% 50%;
transform: rotate(-45deg) skew(15deg, 15deg) translate(48%, -48%) scale(0.87);
background-image: linear-gradient(135deg, #fa0f, #fa0d);
box-shadow: inset -0.1em -0.155em 0.45em -0.01em #fa0f, -0.02em 0.02em 0.033em -0.01em #fa0a;
}
/* Плашка со значением */
.girder_t::before,
.girder_t::after {
position: absolute;
bottom: 50%; left: 100%; z-index: 1;
font-size: initial !important;
opacity: 0;
transition: transform 0.4s cubic-bezier(0.65, 0.45, 0.33, 1.18), opacity 0.4s linear 0s;
pointer-events: none;
}
.girder_t::before {
content: "";
height: 2em;
transform: rotate(45deg) skew(0deg, 0deg) translate(-50%, 0%) scale(1, 1.5);
box-shadow: 0 0 0 1px #f0f;
}
.girder_t::after {
content: attr(data-val);
padding: 0.5em 0.7em;
border-radius: 0.3em;
transform: rotate(45deg) skew(0deg, 0deg) translate(-33%, -1em) scale(0.1, 1.5);
font-family: sans-serif;
text-align: center;
background-color: #eee;
box-shadow: inset 0 0 0 2px #f0f;
}
.girder:hover .girder_t::before,
.girder:hover .girder_t::after {
opacity: 1;
transition: transform 0.4s cubic-bezier(0.65, 0.45, 0.33, 1.18) 1s, opacity 0.4s linear 1s;
}
.girder:hover .girder_t::after {
transform: rotate(45deg) skew(0deg, 0deg) translate(-33%, -1em) scale(1, 1.5);
}
.girder_l,
.girder_r {
position: absolute;
height: calc(100% - 0.3em); width: calc(50% + 0.015em);
}
.girder_l {
left: 0;
border-radius: 0 0 0.055em 0.033em;
transform-origin: 0% 0%; transform: skewy(30deg);
background-image: linear-gradient(90deg, #fa0f, #805500, #0001);
box-shadow: inset -0.34em -0.1em 0.25em -0.2em #000e, inset 0.84em 0.54em 0.95em -0.4em #fa08;
}
.girder_r {
right: 0;
border-radius: 0 0 0.033em 0.055em;
transform-origin: 100% 0%; transform: skewy(-30deg);
background-image: linear-gradient(90deg, #000c, #805500);
box-shadow: inset -0.125em 0.1em 0.425em -0.225em #fa0c;
}
input[name="grp"][value=""]:checked~.girder-chart:hover>div>div:not(:hover) {
height: 0.3em !important;
transition: height 1s ease-in-out, opacity 0.5s ease-in-out;
transition-delay: 0s !important;
}
input[name="grp"][value="0"]:checked~.girder-chart>div>div:not([data-grp="0"]),
input[name="grp"][value="1"]:checked~.girder-chart>div>div:not([data-grp="1"]),
input[name="grp"][value="2"]:checked~.girder-chart>div>div:not([data-grp="2"]),
input[name="grp"][value="3"]:checked~.girder-chart>div>div:not([data-grp="3"]) {
height: 0.3em !important;
opacity: 0 !important;
pointer-events: none;
transition: height 1s ease-in-out, opacity 0.5s ease-in-out;
transition-delay: 0s !important;
}
.girder-chart:hover>div>div:hover {
opacity: 1 !important;
transition-delay: 0s !important;
}<div class="girder-wrap">
<input type="radio" name="grp" value="" checked>Все
<input type="radio" name="grp" value="0">0-25%
<input type="radio" name="grp" value="1">26-50%
<input type="radio" name="grp" value="2">51-75%
<input type="radio" name="grp" value="3">76-100%
<hr>
<div class="girder-chart"></div>
</div>The function only computes the input data for the components being created while controlling the appearance of the columns. Narrow effects (different colour, transparency) can be commented or removed.As the commentaries have rightly pointed out, the need for a clamping in the form of input data and their sausage (this should be pushed away from it at the outset).