Compare commits
10 Commits
757d60e2d3
...
sem2-lab3-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2869d51a52 | ||
| 76e3d0b5dd | |||
| 6a6883f7e1 | |||
|
|
31af179546 | ||
|
|
8d1aeb7f5c | ||
|
|
718fbbc0ef | ||
|
|
49d5a4dadd | ||
| c368e1eef8 | |||
| 1121944fb1 | |||
|
|
19e22c4235 |
@@ -7,7 +7,8 @@ block variables
|
|||||||
Photography: './photography-details.html',
|
Photography: './photography-details.html',
|
||||||
Table: './table.html',
|
Table: './table.html',
|
||||||
Institute: './images/institute.png',
|
Institute: './images/institute.png',
|
||||||
"SVG Playground": './svg_playground.html'
|
"SVG Playground": './svg_playground.html',
|
||||||
|
"Graph": './graph.html'
|
||||||
};
|
};
|
||||||
|
|
||||||
var smallCards = [
|
var smallCards = [
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
import './styles/index.styl'
|
import './styles/index.styl'
|
||||||
|
import './styles/graph.styl'
|
||||||
import './styles/details.styl'
|
import './styles/details.styl'
|
||||||
import './styles/table.styl'
|
import './styles/table.styl'
|
||||||
43
current_site/src/pages/graph.pug
Normal file
43
current_site/src/pages/graph.pug
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
include ../components/mixins.pug
|
||||||
|
|
||||||
|
doctype html
|
||||||
|
html(lang="ru")
|
||||||
|
head
|
||||||
|
meta(charset="utf-8")
|
||||||
|
script(src="graph/d3.v7.min.js")
|
||||||
|
script(src="graph/data.js")
|
||||||
|
script(src="graph/main.js")
|
||||||
|
script(src="graph/table.js")
|
||||||
|
script(src="graph/chart.js")
|
||||||
|
body
|
||||||
|
+navbarMixin("Graph")
|
||||||
|
|
||||||
|
h3 Цена на оперативную память
|
||||||
|
svg
|
||||||
|
p Значение по оси OX
|
||||||
|
|
||||||
|
input(type="radio" value="0" name="OX" checked)
|
||||||
|
span Maker
|
||||||
|
br
|
||||||
|
input(type="radio" value="1" name="OX")
|
||||||
|
span Release Year
|
||||||
|
|
||||||
|
p Значение по оси OY
|
||||||
|
p#errorDisplay(hidden) Выберете хотя бы одно
|
||||||
|
|
||||||
|
input(type="checkbox" value="0" name="OY" checked)
|
||||||
|
span Min
|
||||||
|
br
|
||||||
|
input(type="checkbox" value="1" name="OY")
|
||||||
|
span Max
|
||||||
|
|
||||||
|
br
|
||||||
|
select#graphType
|
||||||
|
option(value="0" selected) Точечная
|
||||||
|
option(value="1") Гистограма
|
||||||
|
option(value="2") График
|
||||||
|
button#drawButton Рисовать
|
||||||
|
|
||||||
|
br
|
||||||
|
button#tableVisibilityButton Скрыть Таблицу
|
||||||
|
table#build
|
||||||
135
current_site/src/pages/graph/chart.js
Normal file
135
current_site/src/pages/graph/chart.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// Входные данные:
|
||||||
|
// data - исходный массив (например, buildings)
|
||||||
|
// key - поле, по которому осуществляется группировка
|
||||||
|
|
||||||
|
function createArrGraph(data, key) {
|
||||||
|
|
||||||
|
const groupObj = d3.group(data, d => d[key]);
|
||||||
|
|
||||||
|
let arrGraph = [];
|
||||||
|
for (let entry of groupObj) {
|
||||||
|
const minMax = d3.extent(entry[1].map(d => d['price']));
|
||||||
|
arrGraph.push({ labelX: entry[0], values: minMax });
|
||||||
|
}
|
||||||
|
|
||||||
|
return arrGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGraph(data, keyX, drawMin, drawMax, graphtype) {
|
||||||
|
// значения по оси ОХ
|
||||||
|
|
||||||
|
// создаем массив для построения графика
|
||||||
|
let arrGraph = createArrGraph(data, keyX);
|
||||||
|
if (keyX == "release") {
|
||||||
|
arrGraph = d3.sort(arrGraph, (x, y) => Number(x["labelX"]) - Number(y["labelX"]));
|
||||||
|
}
|
||||||
|
const svg = d3.select("svg")
|
||||||
|
svg.selectAll('*').remove();
|
||||||
|
|
||||||
|
// создаем словарь с атрибутами области вывода графика
|
||||||
|
const attr_area = {
|
||||||
|
width: parseFloat(svg.style('width')),
|
||||||
|
height: parseFloat(svg.style('height')),
|
||||||
|
marginX: 50,
|
||||||
|
marginY: 50
|
||||||
|
}
|
||||||
|
|
||||||
|
const scaleYDomain = [ d3.min(arrGraph.map(d => d.values[drawMin? 0:1])) , d3.max(arrGraph.map(d => d.values[drawMax?1:0]))];
|
||||||
|
|
||||||
|
|
||||||
|
// создаем шкалы преобразования и выводим оси
|
||||||
|
const [scX, scY] = createAxis(svg, arrGraph, attr_area,scaleYDomain);
|
||||||
|
|
||||||
|
// рисуем график
|
||||||
|
|
||||||
|
if (drawMin && drawMax) {
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "blue", 0, graphtype, 0, scaleYDomain)
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "red", 1, graphtype, 0, scaleYDomain)
|
||||||
|
}
|
||||||
|
else if (drawMin) {
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "blue", 0, graphtype, 1, scaleYDomain)
|
||||||
|
}
|
||||||
|
else if (drawMax) {
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "red", 1, graphtype, 1, scaleYDomain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAxis(svg, data, attr_area,scaleYDomain) {
|
||||||
|
// находим интервал значений, которые нужно отложить по оси OY
|
||||||
|
// максимальное и минимальное значение и максимальных высот по каждой стране
|
||||||
|
const [min, max] = scaleYDomain;
|
||||||
|
|
||||||
|
// функция интерполяции значений на оси
|
||||||
|
// по оси ОХ текстовые значения
|
||||||
|
const scaleX = d3.scaleBand()
|
||||||
|
.domain(data.map(d => d.labelX))
|
||||||
|
.range([0, attr_area.width - 2 * attr_area.marginX]);
|
||||||
|
|
||||||
|
const scaleY = d3.scaleLinear()
|
||||||
|
.domain([min * 0.85, max * 1.1])
|
||||||
|
.range([attr_area.height - 2 * attr_area.marginY, 0]);
|
||||||
|
|
||||||
|
// создание осей
|
||||||
|
const axisX = d3.axisBottom(scaleX); // горизонтальная
|
||||||
|
const axisY = d3.axisLeft(scaleY); // вертикальная
|
||||||
|
|
||||||
|
// отрисовка осей в SVG-элементе
|
||||||
|
svg.append("g")
|
||||||
|
.attr("transform", `translate(${attr_area.marginX},
|
||||||
|
${attr_area.height - attr_area.marginY})`)
|
||||||
|
.call(axisX)
|
||||||
|
.selectAll("text") // подписи на оси - наклонные
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.attr("dx", "-.8em")
|
||||||
|
.attr("dy", ".15em")
|
||||||
|
.attr("transform", d => "rotate(-45)");
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.call(axisY);
|
||||||
|
|
||||||
|
return [scaleX, scaleY]
|
||||||
|
}
|
||||||
|
|
||||||
|
function createChart(svg, data, scaleX, scaleY, attr_area, color, valueIdx, graphType, horisontalScale, scaleYDomain) {
|
||||||
|
if (graphType == 1) {
|
||||||
|
svg.selectAll(".dot")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append("rect")
|
||||||
|
.attr("x", d => scaleX(d.labelX) + valueIdx * 6)
|
||||||
|
.attr("y", d => scaleY(d.values[valueIdx]))
|
||||||
|
.attr("width", 6 * (horisontalScale + 1))
|
||||||
|
.attr("height", d => scaleY(scaleYDomain[0] * 0.85) - scaleY(d.values[valueIdx]))
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.style("fill", color)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (graphType == 2) {
|
||||||
|
const line = d3.line()
|
||||||
|
.x(d => scaleX(d.labelX) + scaleX.bandwidth() / 2 + valueIdx * 4)
|
||||||
|
.y(d => scaleY(d.values[valueIdx]));
|
||||||
|
|
||||||
|
svg.append('path')
|
||||||
|
.datum(data)
|
||||||
|
.attr('d', line.curve(d3.curveBasis))
|
||||||
|
.attr('stroke-width',2)
|
||||||
|
.attr('fill', 'none')
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.attr('stroke', color);
|
||||||
|
}
|
||||||
|
else if (graphType == 0) {
|
||||||
|
const r = 4;
|
||||||
|
|
||||||
|
svg.selectAll(".dot")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append("circle")
|
||||||
|
.attr("r", r)
|
||||||
|
.attr("cx", d => scaleX(d.labelX) + scaleX.bandwidth() / 2 + valueIdx * 4)
|
||||||
|
.attr("cy", d => scaleY(d.values[valueIdx]))
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.style("fill", color)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
current_site/src/pages/graph/d3.v7.min.js
vendored
Normal file
2
current_site/src/pages/graph/d3.v7.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
68
current_site/src/pages/graph/data.js
Normal file
68
current_site/src/pages/graph/data.js
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
let ram_sticks = [
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1600-4GB-A1", "size": 4, "maker": "Kingston", "release": "2014-03", "price": 18, },
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1600-8GB-A2", "size": 8, "maker": "Corsair", "release": "2015-06", "price": 26, },
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1866-8GB-A3", "size": 8, "maker": "G.Skill", "release": "2016-02", "price": 29, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-2133-8GB-B1", "size": 8, "maker": "Crucial", "release": "2017-01", "price": 24, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-2400-8GB-B2", "size": 8, "maker": "Kingston", "release": "2017-09", "price": 27, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-2666-16GB-B3", "size": 16, "maker": "Corsair", "release": "2018-04", "price": 48, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3000-16GB-B4", "size": 16, "maker": "G.Skill", "release": "2018-11", "price": 52, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-16GB-B5", "size": 16, "maker": "HyperX", "release": "2019-03", "price": 55, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-32GB-B6", "size": 32, "maker": "Crucial", "release": "2019-08", "price": 92, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3600-32GB-B7", "size": 32, "maker": "Corsair", "release": "2020-02", "price": 99, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-4800-16GB-C1", "size": 16, "maker": "Kingston", "release": "2021-01", "price": 78, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-5200-16GB-C2", "size": 16, "maker": "Corsair", "release": "2021-06", "price": 84, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-5600-32GB-C3", "size": 32, "maker": "G.Skill", "release": "2022-02", "price": 145, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-32GB-C4", "size": 32, "maker": "Crucial", "release": "2022-07", "price": 158, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6400-32GB-C5", "size": 32, "maker": "Corsair", "release": "2023-01", "price": 172, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6600-64GB-C6", "size": 64, "maker": "Kingston", "release": "2023-05", "price": 310, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6800-64GB-C7", "size": 64, "maker": "G.Skill", "release": "2023-09", "price": 329, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-7200-64GB-C8", "size": 64, "maker": "Corsair", "release": "2024-02", "price": 355, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-7600-96GB-C9", "size": 96, "maker": "Crucial", "release": "2024-06", "price": 520, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-8000-96GB-C10", "size": 96, "maker": "Kingston", "release": "2024-10", "price": 560, },
|
||||||
|
{ "type": "LPDDR4", "name": "LP4-3200-8GB-D1", "size": 8, "maker": "Samsung", "release": "2019-01", "price": 34, },
|
||||||
|
{ "type": "LPDDR4", "name": "LP4-4266-8GB-D2", "size": 8, "maker": "Micron", "release": "2019-07", "price": 39, },
|
||||||
|
{ "type": "LPDDR5", "name": "LP5-5500-12GB-D3", "size": 12, "maker": "Samsung", "release": "2020-03", "price": 58, },
|
||||||
|
{ "type": "LPDDR5", "name": "LP5-6400-16GB-D4", "size": 16, "maker": "SKHynix", "release": "2021-01", "price": 74, },
|
||||||
|
{ "type": "LPDDR5X", "name": "LP5X-7500-24GB-D5", "size": 24, "maker": "Micron", "release": "2022-05", "price": 118, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-2666-8GB-E1", "size": 8, "maker": "Patriot", "release": "2018-05", "price": 25, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3000-8GB-E2", "size": 8, "maker": "ADATA", "release": "2018-09", "price": 28, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-8GB-E3", "size": 8, "maker": "TeamGroup", "release": "2019-04", "price": 30, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3600-16GB-E4", "size": 16, "maker": "ADATA", "release": "2020-01", "price": 53, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-4000-16GB-E5", "size": 16, "maker": "Patriot", "release": "2020-06", "price": 61, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-5200-8GB-F1", "size": 8, "maker": "TeamGroup", "release": "2021-03", "price": 52, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-5600-16GB-F2", "size": 16, "maker": "ADATA", "release": "2021-10", "price": 88, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-16GB-F3", "size": 16, "maker": "Patriot", "release": "2022-03", "price": 95, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6400-32GB-F4", "size": 32, "maker": "TeamGroup", "release": "2022-09", "price": 168, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-7200-32GB-F5", "size": 32, "maker": "ADATA", "release": "2023-04", "price": 185, },
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1333-4GB-G1", "size": 4, "maker": "Samsung", "release": "2013-02", "price": 15, },
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1600-4GB-G2", "size": 4, "maker": "Micron", "release": "2014-08", "price": 17, },
|
||||||
|
{ "type": "DDR3", "name": "DDR3-1866-8GB-G3", "size": 8, "maker": "Samsung", "release": "2015-11", "price": 28, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-8400-128GB-H1", "size": 128, "maker": "Corsair", "release": "2025-01", "price": 890, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-8800-128GB-H2", "size": 128, "maker": "G.Skill", "release": "2025-03", "price": 940, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-9200-128GB-H3", "size": 128, "maker": "Kingston", "release": "2025-06", "price": 990, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X1", "size": 48, "maker": "Corsair", "release": "2024-01", "price": 210, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X2", "size": 48, "maker": "Kingston", "release": "2024-02", "price": 215, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X3", "size": 48, "maker": "G.Skill", "release": "2024-03", "price": 218, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X4", "size": 48, "maker": "ADATA", "release": "2024-04", "price": 222, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X5", "size": 48, "maker": "Patriot", "release": "2024-05", "price": 225, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X6", "size": 48, "maker": "TeamGroup", "release": "2024-06", "price": 228, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X7", "size": 48, "maker": "Crucial", "release": "2024-07", "price": 230, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X8", "size": 48, "maker": "Samsung", "release": "2024-08", "price": 235, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X9", "size": 48, "maker": "Micron", "release": "2024-09", "price": 238, },
|
||||||
|
{ "type": "DDR5", "name": "DDR5-6000-48GB-X10", "size": 48, "maker": "SKHynix", "release": "2024-10", "price": 240, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y1", "size": 64, "maker": "Corsair", "release": "2021-01", "price": 180, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y2", "size": 64, "maker": "Kingston", "release": "2021-02", "price": 182, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y3", "size": 64, "maker": "G.Skill", "release": "2021-03", "price": 185, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y4", "size": 64, "maker": "ADATA", "release": "2021-04", "price": 188, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y5", "size": 64, "maker": "Patriot", "release": "2021-05", "price": 190, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y6", "size": 64, "maker": "TeamGroup", "release": "2021-06", "price": 192, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y7", "size": 64, "maker": "Crucial", "release": "2021-07", "price": 195, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y8", "size": 64, "maker": "Samsung", "release": "2021-08", "price": 198, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y9", "size": 64, "maker": "Micron", "release": "2021-09", "price": 200, },
|
||||||
|
{ "type": "DDR4", "name": "DDR4-3200-64GB-Y10", "size": 64, "maker": "SKHynix", "release": "2021-10", "price": 205, }
|
||||||
|
|
||||||
|
]
|
||||||
|
ram_sticks = ram_sticks.map((x) => ({
|
||||||
|
...x,
|
||||||
|
release: Number(x.release.split("-")[0]),
|
||||||
|
}))
|
||||||
50
current_site/src/pages/graph/main.js
Normal file
50
current_site/src/pages/graph/main.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
showTable('build', ram_sticks);
|
||||||
|
let tableIsDisplayed = true;
|
||||||
|
tableVisibilityButton.addEventListener("click", () => {
|
||||||
|
if (tableIsDisplayed) {
|
||||||
|
clearTable('build')
|
||||||
|
tableVisibilityButton.innerHTML = "Показать таблицу";
|
||||||
|
} else {
|
||||||
|
showTable('build', ram_sticks);
|
||||||
|
tableVisibilityButton.innerHTML = "Скрыть таблицу";
|
||||||
|
}
|
||||||
|
tableIsDisplayed = !tableIsDisplayed;
|
||||||
|
})
|
||||||
|
updateGraph();
|
||||||
|
drawButton.addEventListener("click", () => {
|
||||||
|
clearGraph();
|
||||||
|
updateGraph();
|
||||||
|
});
|
||||||
|
document.querySelectorAll("[name=\"OY\"]").forEach((x) => {
|
||||||
|
x.addEventListener("click", () => { d3.select("#drawButton").attr("class", getOY().length == 0 ? "error" : ""); })
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function updateGraph() {
|
||||||
|
const keyX = ["maker", "release"][getOX()];
|
||||||
|
const yAxis = getOY();
|
||||||
|
d3.select("#drawButton").attr("class", yAxis.length == 0 ? "error" : "");
|
||||||
|
drawGraph(ram_sticks, keyX, yAxis.includes(0), yAxis.includes(1), getGraphType());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getOX() {
|
||||||
|
return Number(document.querySelector("input[name=\"OX\"]:checked").value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOY() {
|
||||||
|
return d3.map(document.querySelectorAll("input[name=\"OY\"]:checked"),
|
||||||
|
(x) => Number(x.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearGraph() {
|
||||||
|
d3.select("svg").selectAll('*').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGraphType() {
|
||||||
|
return Number(graphType.value);
|
||||||
|
}
|
||||||
36
current_site/src/pages/graph/table.js
Normal file
36
current_site/src/pages/graph/table.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// создание таблицы
|
||||||
|
const showTable = (idTable, data) => {
|
||||||
|
const table = d3.select("#" + idTable);
|
||||||
|
|
||||||
|
// создание строк таблицы (столько, сколько элементов в массиве)
|
||||||
|
const rows = table
|
||||||
|
.selectAll("tr")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append('tr')
|
||||||
|
.style("display", "");
|
||||||
|
|
||||||
|
// создание ячеек каждой строки на основе каждого элемента массива
|
||||||
|
const cells = rows
|
||||||
|
.selectAll("td")
|
||||||
|
.data(d => Object.values(d))
|
||||||
|
.enter()
|
||||||
|
.append("td")
|
||||||
|
.text(d => d);
|
||||||
|
|
||||||
|
// создание шапки таблицы
|
||||||
|
const head = table
|
||||||
|
.insert("tr", "tr")
|
||||||
|
.selectAll("th")
|
||||||
|
.data(d => Object.keys(data[0]))
|
||||||
|
.enter()
|
||||||
|
.append("th")
|
||||||
|
.text(d => d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearTable = (idTable) => {
|
||||||
|
const table = document.getElementById(idTable);
|
||||||
|
while (table.children.length > 0) {
|
||||||
|
table.removeChild(table.children[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
include ../components/mixins.pug
|
include ../components/mixins.pug
|
||||||
|
|
||||||
|
|
||||||
doctype html
|
doctype html
|
||||||
html(lang="ru")
|
html(lang="ru")
|
||||||
head
|
head
|
||||||
|
|||||||
16
current_site/src/styles/graph.styl
Normal file
16
current_site/src/styles/graph.styl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
svg
|
||||||
|
width: 800px
|
||||||
|
height: 400px
|
||||||
|
|
||||||
|
text
|
||||||
|
font: 8px Verdana
|
||||||
|
|
||||||
|
path,
|
||||||
|
line
|
||||||
|
fill: none
|
||||||
|
|
||||||
|
.error
|
||||||
|
color: red
|
||||||
|
background-color: black
|
||||||
|
font-weight: bolder
|
||||||
|
width: min-content
|
||||||
@@ -22,7 +22,7 @@ grid-responsive(columns)
|
|||||||
.navbar
|
.navbar
|
||||||
double-border()
|
double-border()
|
||||||
font-size 0
|
font-size 0
|
||||||
grid-responsive(repeat(7, min-content))
|
grid-responsive(repeat(8, min-content))
|
||||||
justify-items start
|
justify-items start
|
||||||
|
|
||||||
&__link-wrapper
|
&__link-wrapper
|
||||||
|
|||||||
19
labs/lab3/CSS/style.css
Normal file
19
labs/lab3/CSS/style.css
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
svg {
|
||||||
|
width: 800px;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
svg text {
|
||||||
|
font: 8px Verdana;
|
||||||
|
}
|
||||||
|
svg path, line {
|
||||||
|
fill: none;
|
||||||
|
stroke: #333333;
|
||||||
|
width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error{
|
||||||
|
color:red;
|
||||||
|
background-color: black;
|
||||||
|
font-weight: bolder;
|
||||||
|
width: min-content;
|
||||||
|
}
|
||||||
120
labs/lab3/JavaScript/chart.js
Normal file
120
labs/lab3/JavaScript/chart.js
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
// Входные данные:
|
||||||
|
// data - исходный массив (например, buildings)
|
||||||
|
// key - поле, по которому осуществляется группировка
|
||||||
|
|
||||||
|
function createArrGraph(data, key) {
|
||||||
|
|
||||||
|
const groupObj = d3.group(data, d => d[key]);
|
||||||
|
|
||||||
|
let arrGraph = [];
|
||||||
|
for (let entry of groupObj) {
|
||||||
|
const minMax = d3.extent(entry[1].map(d => d['Высота']));
|
||||||
|
arrGraph.push({ labelX: entry[0], values: minMax });
|
||||||
|
}
|
||||||
|
|
||||||
|
return arrGraph;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGraph(data, keyX, drawMin, drawMax, graphtype) {
|
||||||
|
// значения по оси ОХ
|
||||||
|
|
||||||
|
// создаем массив для построения графика
|
||||||
|
let arrGraph = createArrGraph(data, keyX);
|
||||||
|
if(keyX=="Год"){
|
||||||
|
arrGraph = d3.sort(arrGraph, (x,y)=>Number(x["labelX"])-Number(y["labelX"]));
|
||||||
|
}
|
||||||
|
const svg = d3.select("svg")
|
||||||
|
svg.selectAll('*').remove();
|
||||||
|
|
||||||
|
// создаем словарь с атрибутами области вывода графика
|
||||||
|
const attr_area = {
|
||||||
|
width: parseFloat(svg.style('width')),
|
||||||
|
height: parseFloat(svg.style('height')),
|
||||||
|
marginX: 50,
|
||||||
|
marginY: 50
|
||||||
|
}
|
||||||
|
|
||||||
|
// создаем шкалы преобразования и выводим оси
|
||||||
|
const [scX, scY] = createAxis(svg, arrGraph, attr_area);
|
||||||
|
|
||||||
|
// рисуем график
|
||||||
|
|
||||||
|
const scaleYDomain = d3.extent(arrGraph.map(d => d.values[1]));
|
||||||
|
if (drawMin && drawMax){
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "blue", 0,graphtype,0,scaleYDomain)
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "red", 1,graphtype,0,scaleYDomain)
|
||||||
|
}
|
||||||
|
else if (drawMin) {
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "blue", 0,graphtype,1,scaleYDomain)
|
||||||
|
}
|
||||||
|
else if (drawMax) {
|
||||||
|
createChart(svg, arrGraph, scX, scY, attr_area, "red", 1,graphtype,1,scaleYDomain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAxis(svg, data, attr_area) {
|
||||||
|
// находим интервал значений, которые нужно отложить по оси OY
|
||||||
|
// максимальное и минимальное значение и максимальных высот по каждой стране
|
||||||
|
const [min, max] = d3.extent(data.map(d => d.values[1]));
|
||||||
|
|
||||||
|
// функция интерполяции значений на оси
|
||||||
|
// по оси ОХ текстовые значения
|
||||||
|
const scaleX = d3.scaleBand()
|
||||||
|
.domain(data.map(d => d.labelX))
|
||||||
|
.range([0, attr_area.width - 2 * attr_area.marginX]);
|
||||||
|
|
||||||
|
const scaleY = d3.scaleLinear()
|
||||||
|
.domain([min * 0.85, max * 1.1])
|
||||||
|
.range([attr_area.height - 2 * attr_area.marginY, 0]);
|
||||||
|
|
||||||
|
// создание осей
|
||||||
|
const axisX = d3.axisBottom(scaleX); // горизонтальная
|
||||||
|
const axisY = d3.axisLeft(scaleY); // вертикальная
|
||||||
|
|
||||||
|
// отрисовка осей в SVG-элементе
|
||||||
|
svg.append("g")
|
||||||
|
.attr("transform", `translate(${attr_area.marginX},
|
||||||
|
${attr_area.height - attr_area.marginY})`)
|
||||||
|
.call(axisX)
|
||||||
|
.selectAll("text") // подписи на оси - наклонные
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.attr("dx", "-.8em")
|
||||||
|
.attr("dy", ".15em")
|
||||||
|
.attr("transform", d => "rotate(-45)");
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.call(axisY);
|
||||||
|
|
||||||
|
return [scaleX, scaleY]
|
||||||
|
}
|
||||||
|
|
||||||
|
function createChart(svg, data, scaleX, scaleY, attr_area, color, valueIdx,isHistogram,horisontalScale,scaleYDomain) {
|
||||||
|
if (isHistogram){
|
||||||
|
svg.selectAll(".dot")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append("rect")
|
||||||
|
.attr("x", d => scaleX(d.labelX)+valueIdx*6)
|
||||||
|
.attr("y", d => scaleY(d.values[valueIdx]))
|
||||||
|
.attr("width",6*(horisontalScale+1))
|
||||||
|
.attr("height",d => scaleY(scaleYDomain[0]*0.85)-scaleY(d.values[valueIdx]))
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.style("fill", color)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
const r = 4;
|
||||||
|
|
||||||
|
svg.selectAll(".dot")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append("circle")
|
||||||
|
.attr("r", r)
|
||||||
|
.attr("cx", d => scaleX(d.labelX) + scaleX.bandwidth() / 2+valueIdx*4)
|
||||||
|
.attr("cy", d => scaleY(d.values[valueIdx]))
|
||||||
|
.attr("transform", `translate(${attr_area.marginX}, ${attr_area.marginY})`)
|
||||||
|
.style("fill", color)
|
||||||
|
}
|
||||||
|
}
|
||||||
2
labs/lab3/JavaScript/d3.v7.min.js
vendored
Normal file
2
labs/lab3/JavaScript/d3.v7.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
514
labs/lab3/JavaScript/data.js
Normal file
514
labs/lab3/JavaScript/data.js
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
const buildings= [
|
||||||
|
{
|
||||||
|
"Название": "Бурдж-Халифа",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "ОАЭ",
|
||||||
|
"Город": "Дубай",
|
||||||
|
"Год": 2010,
|
||||||
|
"Высота": 828
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Варшавская радиомачта",
|
||||||
|
"Тип": "Антенная мачта",
|
||||||
|
"Страна": "Польша",
|
||||||
|
"Город": "Константинов",
|
||||||
|
"Год": 1974,
|
||||||
|
"Высота": 646.38
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Tokyo Skytree",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Япония",
|
||||||
|
"Город": "Токио",
|
||||||
|
"Год": 2012,
|
||||||
|
"Высота": 634
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Шанхайская башня",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шанхай",
|
||||||
|
"Год": 2013,
|
||||||
|
"Высота": 632
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Телерадиомачта KVLY-TV",
|
||||||
|
"Тип": "Радиомачта",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Бланчард",
|
||||||
|
"Год": 1963,
|
||||||
|
"Высота": 629
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Телебашня Гуанчжоу",
|
||||||
|
"Тип": "Гиперболоидная башня",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Гуанчжоу",
|
||||||
|
"Год": 2009,
|
||||||
|
"Высота": 600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Международный финансовый центр Пинань",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шэньчжэнь",
|
||||||
|
"Год": 2017,
|
||||||
|
"Высота": 600
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Lotte World Tower",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Южная Корея",
|
||||||
|
"Город": "Сеул",
|
||||||
|
"Год": 2017,
|
||||||
|
"Высота": 555
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Си-Эн Тауэр",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Канада",
|
||||||
|
"Город": "Торонто",
|
||||||
|
"Год": 1976,
|
||||||
|
"Высота": 553
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Останкинская башня",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Россия",
|
||||||
|
"Город": "Москва",
|
||||||
|
"Год": 1967,
|
||||||
|
"Высота": 540.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Уиллис-тауэр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Чикаго",
|
||||||
|
"Год": 1974,
|
||||||
|
"Высота": 527.3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Тайбэй 101",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Тайвань",
|
||||||
|
"Город": "Тайбэй",
|
||||||
|
"Год": 2004,
|
||||||
|
"Высота": 509.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Шанхайский всемирный финансовый центр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шанхай",
|
||||||
|
"Год": 2008,
|
||||||
|
"Высота": 492
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Международный коммерческий центр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Гонконг",
|
||||||
|
"Город": "Гонконг",
|
||||||
|
"Год": 2009,
|
||||||
|
"Высота": 484
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Восточная жемчужина",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шанхай",
|
||||||
|
"Год": 1994,
|
||||||
|
"Высота": 467.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Лахта-центр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Россия",
|
||||||
|
"Город": "Санкт-Петербург",
|
||||||
|
"Год": 2018,
|
||||||
|
"Высота": 462
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Landmark 81",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Вьетнам",
|
||||||
|
"Город": "Хошимин",
|
||||||
|
"Год": 2018,
|
||||||
|
"Высота": 461.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "875 Норт-Мичиган-авеню",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Чикаго",
|
||||||
|
"Год": 1969,
|
||||||
|
"Высота": 457.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Петронас. башня 1 и 2",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Малайзия",
|
||||||
|
"Город": "Куала-Лумпур",
|
||||||
|
"Год": 1998,
|
||||||
|
"Высота": 452
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Финансовый центр Наньцзин-Гринлэнд",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Нанкин",
|
||||||
|
"Год": 2009,
|
||||||
|
"Высота": 450
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Эмпайр-стейт-билдинг",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Нью-Йорк",
|
||||||
|
"Год": 1931,
|
||||||
|
"Высота": 448.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Международный финансовый центр. башня зап.",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Гуанчжоу",
|
||||||
|
"Год": 2010,
|
||||||
|
"Высота": 437.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Kingkey 100",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шэньчжэнь",
|
||||||
|
"Год": 2011,
|
||||||
|
"Высота": 439.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Бордже Милад",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Иран",
|
||||||
|
"Город": "Тегеран",
|
||||||
|
"Год": 2003,
|
||||||
|
"Высота": 435
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Парк-авеню. 432",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Нью-Йорк",
|
||||||
|
"Год": 2015,
|
||||||
|
"Высота": 425.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Международная гостиница и башня Трампа",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Чикаго",
|
||||||
|
"Год": 2009,
|
||||||
|
"Высота": 423.4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Менара Куала-Лумпур",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Малайзия",
|
||||||
|
"Город": "Куала-Лумпур",
|
||||||
|
"Год": 1995,
|
||||||
|
"Высота": 421
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Цзинь Мао",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шанхай",
|
||||||
|
"Год": 1999,
|
||||||
|
"Высота": 420.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Экибастузская ГРЭС-2",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Казахстан",
|
||||||
|
"Город": "Экибастуз",
|
||||||
|
"Год": 1987,
|
||||||
|
"Высота": 419.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Международный финансовый центр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Гонконг",
|
||||||
|
"Город": "Гонконг",
|
||||||
|
"Год": 2003,
|
||||||
|
"Высота": 415.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Тяньцзиньская телебашня",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Тяньцзинь",
|
||||||
|
"Год": 1991,
|
||||||
|
"Высота": 415.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Аль-Хамра",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Кувейт",
|
||||||
|
"Город": "Кувейт",
|
||||||
|
"Год": 2010,
|
||||||
|
"Высота": 412
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Пекинская телебашня",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Пекин",
|
||||||
|
"Год": 1992,
|
||||||
|
"Высота": 405
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня CITIC",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Гуанчжоу",
|
||||||
|
"Год": 1997,
|
||||||
|
"Высота": 391.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Киевская телебашня",
|
||||||
|
"Тип": "Решётчатая мачта",
|
||||||
|
"Страна": "Украина",
|
||||||
|
"Город": "Киев",
|
||||||
|
"Год": 1973,
|
||||||
|
"Высота": 385
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Сёньхин",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шэньчжэнь",
|
||||||
|
"Год": 1996,
|
||||||
|
"Высота": 384
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Абу-Даби Плаза",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Казахстан",
|
||||||
|
"Город": "Астана",
|
||||||
|
"Год": 2015,
|
||||||
|
"Высота": 382
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Бурдж-Мохаммед-бин-Рашид",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "ОАЭ",
|
||||||
|
"Город": "Абу-Даби",
|
||||||
|
"Год": 2014,
|
||||||
|
"Высота": 381
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Inco Superstack",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Канада",
|
||||||
|
"Город": "Copper Cliff",
|
||||||
|
"Год": 1971,
|
||||||
|
"Высота": 380
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Тантекс-Скай-Тауэр",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Тайвань",
|
||||||
|
"Город": "Гаосюн",
|
||||||
|
"Год": 1997,
|
||||||
|
"Высота": 378
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "JW Marriott Marquis Dubai. 1 и 2",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "ОАЭ",
|
||||||
|
"Город": "Дубай",
|
||||||
|
"Год": 2010,
|
||||||
|
"Высота": 376
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Ташкентская телебашня",
|
||||||
|
"Тип": "Башня",
|
||||||
|
"Страна": "Узбекистан",
|
||||||
|
"Город": "Ташкент",
|
||||||
|
"Год": 1985,
|
||||||
|
"Высота": 374.9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Федерация «Восток»",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Россия",
|
||||||
|
"Город": "Москва",
|
||||||
|
"Год": 2016,
|
||||||
|
"Высота": 374
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Сентрал-плаза",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Гонконг",
|
||||||
|
"Город": "Гонконг",
|
||||||
|
"Год": 1992,
|
||||||
|
"Высота": 374
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Освобождения",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Кувейт",
|
||||||
|
"Город": "Кувейт",
|
||||||
|
"Год": 1996,
|
||||||
|
"Высота": 372
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Телебашня «Коктобе»",
|
||||||
|
"Тип": "Башня",
|
||||||
|
"Страна": "Казахстан",
|
||||||
|
"Город": "Алматы",
|
||||||
|
"Год": 1983,
|
||||||
|
"Высота": 371.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Дымовая труба электростанции",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Homer City",
|
||||||
|
"Год": 1977,
|
||||||
|
"Высота": 371
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Дымовая труба Берёзовской ГРЭС",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Россия",
|
||||||
|
"Город": "Шарыпово",
|
||||||
|
"Год": 1985,
|
||||||
|
"Высота": 370
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Рижская телебашня",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Латвия",
|
||||||
|
"Город": "Рига",
|
||||||
|
"Год": 1987,
|
||||||
|
"Высота": 368.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Берлинская телебашня",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "Германия",
|
||||||
|
"Город": "Берлин",
|
||||||
|
"Год": 1969,
|
||||||
|
"Высота": 368
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Дымовая труба электростанции.",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Маундсвилл",
|
||||||
|
"Год": 1968,
|
||||||
|
"Высота": 367.6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Банка Китая",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Гонконг",
|
||||||
|
"Город": "Гонконг",
|
||||||
|
"Год": 1990,
|
||||||
|
"Высота": 367.4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Банка Америки",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Нью-Йорк",
|
||||||
|
"Год": 2008,
|
||||||
|
"Высота": 366
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Башня Алмас",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "ОАЭ",
|
||||||
|
"Город": "Дубай",
|
||||||
|
"Год": 2008,
|
||||||
|
"Высота": 363
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Дымовая труба электростанции в Трбовле",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Словения",
|
||||||
|
"Город": "Трбовле",
|
||||||
|
"Год": 1976,
|
||||||
|
"Высота": 360
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Endesa Termic ",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Испания",
|
||||||
|
"Город": "Ферроль",
|
||||||
|
"Год": 1974,
|
||||||
|
"Высота": 356
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "SEG Plaza",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "КНР",
|
||||||
|
"Город": "Шэньчжэнь",
|
||||||
|
"Год": 2000,
|
||||||
|
"Высота": 355.8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "First Canadian Place",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Канада",
|
||||||
|
"Город": "Торонто",
|
||||||
|
"Год": 1976,
|
||||||
|
"Высота": 355
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Эмиратская офисная башня",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "ОАЭ",
|
||||||
|
"Город": "Дубай",
|
||||||
|
"Год": 2000,
|
||||||
|
"Высота": 354.6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "ОКО Южная башня",
|
||||||
|
"Тип": "Небоскрёб",
|
||||||
|
"Страна": "Россия",
|
||||||
|
"Город": "Москва",
|
||||||
|
"Год": 2015,
|
||||||
|
"Высота": 354
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Виннцкая телемачта",
|
||||||
|
"Тип": "Радиомачта",
|
||||||
|
"Страна": "Украина",
|
||||||
|
"Город": "Винница",
|
||||||
|
"Год": 1961,
|
||||||
|
"Высота": 354
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Медеплавильный завод",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Румыния",
|
||||||
|
"Город": "Бая-Маре",
|
||||||
|
"Год": 1995,
|
||||||
|
"Высота": 351.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Стратосфера Лас-Вегас",
|
||||||
|
"Тип": "Бетонная башня",
|
||||||
|
"Страна": "США",
|
||||||
|
"Город": "Лас-Вегас",
|
||||||
|
"Год": 1996,
|
||||||
|
"Высота": 350.2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Название": "Дымовая труба Сырдарьинской электростанции",
|
||||||
|
"Тип": "Дымовая труба",
|
||||||
|
"Страна": "Узбекистан",
|
||||||
|
"Город": "Сырдарья",
|
||||||
|
"Год": 1980,
|
||||||
|
"Высота": 350
|
||||||
|
}
|
||||||
|
]
|
||||||
50
labs/lab3/JavaScript/main.js
Normal file
50
labs/lab3/JavaScript/main.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
showTable('build', buildings);
|
||||||
|
let tableIsDisplayed = true;
|
||||||
|
tableVisibilityButton.addEventListener("click", () => {
|
||||||
|
if (tableIsDisplayed) {
|
||||||
|
clearTable('build')
|
||||||
|
tableVisibilityButton.innerHTML = "Показать таблицу";
|
||||||
|
} else {
|
||||||
|
showTable('build', buildings);
|
||||||
|
tableVisibilityButton.innerHTML = "Скрыть таблицу";
|
||||||
|
}
|
||||||
|
tableIsDisplayed = !tableIsDisplayed;
|
||||||
|
})
|
||||||
|
updateGraph();
|
||||||
|
drawButton.addEventListener("click", () => {
|
||||||
|
clearGraph();
|
||||||
|
updateGraph();
|
||||||
|
});
|
||||||
|
document.querySelectorAll("[name=\"OY\"]").forEach((x) => {
|
||||||
|
x.addEventListener("click", () => { d3.select("#drawButton").attr("class", getOY().length == 0 ? "error" : ""); })
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function updateGraph() {
|
||||||
|
const keyX = ["Год", "Страна"][getOX()];
|
||||||
|
const yAxis = getOY();
|
||||||
|
d3.select("#drawButton").attr("class", yAxis.length == 0 ? "error" : "");
|
||||||
|
drawGraph(buildings, keyX, yAxis.includes(0), yAxis.includes(1), getGraphType());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getOX() {
|
||||||
|
return Number(document.querySelector("input[name=\"OX\"]:checked").value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOY() {
|
||||||
|
return d3.map(document.querySelectorAll("input[name=\"OY\"]:checked"),
|
||||||
|
(x) => Number(x.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearGraph() {
|
||||||
|
d3.select("svg").selectAll('*').remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGraphType() {
|
||||||
|
return Number(graphType.value);
|
||||||
|
}
|
||||||
36
labs/lab3/JavaScript/table.js
Normal file
36
labs/lab3/JavaScript/table.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// создание таблицы
|
||||||
|
const showTable = (idTable, data) => {
|
||||||
|
const table = d3.select("#" + idTable);
|
||||||
|
|
||||||
|
// создание строк таблицы (столько, сколько элементов в массиве)
|
||||||
|
const rows = table
|
||||||
|
.selectAll("tr")
|
||||||
|
.data(data)
|
||||||
|
.enter()
|
||||||
|
.append('tr')
|
||||||
|
.style("display", "");
|
||||||
|
|
||||||
|
// создание ячеек каждой строки на основе каждого элемента массива
|
||||||
|
const cells = rows
|
||||||
|
.selectAll("td")
|
||||||
|
.data(d => Object.values(d))
|
||||||
|
.enter()
|
||||||
|
.append("td")
|
||||||
|
.text(d => d);
|
||||||
|
|
||||||
|
// создание шапки таблицы
|
||||||
|
const head = table
|
||||||
|
.insert("tr", "tr")
|
||||||
|
.selectAll("th")
|
||||||
|
.data(d => Object.keys(data[0]))
|
||||||
|
.enter()
|
||||||
|
.append("th")
|
||||||
|
.text(d => d);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearTable = (idTable) => {
|
||||||
|
const table = document.getElementById(idTable);
|
||||||
|
while (table.children.length > 0) {
|
||||||
|
table.removeChild(table.children[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
41
labs/lab3/index.html
Normal file
41
labs/lab3/index.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="CSS/style.css">
|
||||||
|
<script src="JavaScript/d3.v7.min.js"> </script>
|
||||||
|
<script src="JavaScript/data.js"></script>
|
||||||
|
<script src="JavaScript/main.js"></script>
|
||||||
|
<script src="JavaScript/table.js"></script>
|
||||||
|
<script src="JavaScript/chart.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h3>Список самых высоких зданий</h3>
|
||||||
|
<svg></svg>
|
||||||
|
<p>Значение по оси OX</p>
|
||||||
|
|
||||||
|
<input type="radio" value="0" name="OX" checked> <span>Год</span>
|
||||||
|
<br>
|
||||||
|
<input type="radio" value="1" name="OX"> <span>Страна</span>
|
||||||
|
|
||||||
|
|
||||||
|
<p>Значение по оси OY</p>
|
||||||
|
<p id="errorDisplay" hidden>Выберете хотя бы одно</p>
|
||||||
|
|
||||||
|
<input type="checkbox" value="0" name="OY" checked> <span>Min</span>
|
||||||
|
<br>
|
||||||
|
<input type="checkbox" value="1" name="OY"> <span>Max</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<select id="graphType">
|
||||||
|
<option value="0" selected>Точечная</option>
|
||||||
|
<option value="1">Гистограма</option>
|
||||||
|
</select>
|
||||||
|
<button id="drawButton">Рисовать</button>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<button id="tableVisibilityButton">Скрыть Таблицу</button>
|
||||||
|
<table id="build">
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
labs/lab3/task/d3.v7.min.js
vendored
Normal file
2
labs/lab3/task/d3.v7.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
12
labs/lab3/task/index.html
Normal file
12
labs/lab3/task/index.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru<head>
|
||||||
|
<meta charset=" utf-8">
|
||||||
|
<script src="d3.v7.min.js"> </script>
|
||||||
|
<script src="main.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<svg></svg>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
45
labs/lab3/task/main.js
Normal file
45
labs/lab3/task/main.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
|
svg = d3.select("svg")
|
||||||
|
.attr("width", 2000)
|
||||||
|
.attr("height", 2000);
|
||||||
|
let w = parseFloat(svg.style('width'));
|
||||||
|
let h = parseFloat(svg.style('height'));
|
||||||
|
let r = d3.min([w, h]) * 0.1
|
||||||
|
|
||||||
|
|
||||||
|
const getEntry = () => {
|
||||||
|
return {
|
||||||
|
"x": d3.randomUniform(w)(),
|
||||||
|
"y": d3.randomUniform(h)(),
|
||||||
|
"r": d3.randomUniform(r)(),
|
||||||
|
"color": getRandColor()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = [];
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
data.push(getEntry());
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.selectAll(".dot").data(data)
|
||||||
|
.enter()
|
||||||
|
.append("circle")
|
||||||
|
.attr("r", d => d.r)
|
||||||
|
.attr("cx", d => d.x)
|
||||||
|
.attr("cy", d => d.y)
|
||||||
|
.style("fill", d => d.color)
|
||||||
|
.attr("opacity", 1)
|
||||||
|
.transition()
|
||||||
|
.duration(2000)
|
||||||
|
.ease(d3.easeLinear)
|
||||||
|
.attr("r", d => d.r * 3)
|
||||||
|
.attr("opacity", 0)
|
||||||
|
.on("end",() => {
|
||||||
|
svg.attr("style", `background :${getRandColor()}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
const getRandColor = () => {
|
||||||
|
return `rgb(${d3.randomInt(255)()},${d3.randomInt(255)()},${d3.randomInt(255)()})`
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user