new commit

This commit is contained in:
54CHA
2025-07-19 17:56:06 +03:00
commit 4153e2c00a
140 changed files with 66097 additions and 0 deletions

View File

@ -0,0 +1,216 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Тест Box and Whisker диаграммы AnyChart</title>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-ui.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/v8/js/anychart-data-adapter.min.js"></script>
<link rel="stylesheet" href="https://cdn.anychart.com/releases/v8/css/anychart-ui.min.css">
<link rel="stylesheet" href="https://cdn.anychart.com/releases/v8/fonts/css/anychart-font.min.css">
<style>
body {
font-family: Arial, sans-serif;
background: linear-gradient(to right, #9da8f9, #fce7ff);
margin: 0;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 12px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
#chart-container {
height: 500px;
margin: 20px 0;
}
.legend {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
font-size: 14px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
}
.legend-box {
width: 16px;
height: 12px;
border: 1px solid;
}
</style>
</head>
<body>
<div class="container">
<h1>Тест Box and Whisker диаграммы - Сравнение позиций товаров</h1>
<p>Тестируем Box and Whisker диаграмму с исправлением для одинаковых позиций</p>
<div id="chart-container"></div>
<div class="legend">
<div class="legend-item">
<div class="legend-box" style="background-color: rgba(34, 197, 94, 0.3); border-color: #22c55e;"></div>
<span>Диапазон позиций</span>
</div>
<div class="legend-item">
<div class="legend-box" style="background-color: #16a34a; border-color: #16a34a; height: 3px;"></div>
<span>Медиана</span>
</div>
</div>
</div>
<script>
anychart.onDocumentReady(function () {
// Тестовые данные позиций
const testData = [
{ city: 'Москва', myPosition: 5, competitorPosition: 3 },
{ city: 'СПб', myPosition: 2, competitorPosition: 7 },
{ city: 'Екатеринбург', myPosition: 1, competitorPosition: 1 }, // Одинаковые позиции
{ city: 'Новосибирск', myPosition: 8, competitorPosition: 4 },
{ city: 'Казань', myPosition: 3, competitorPosition: 12 }
];
// Преобразуем данные для Box and Whisker диаграммы с исправлением одинаковых значений
function prepareBoxData(data) {
return data.map((item) => {
// Собираем все позиции (исключаем нулевые и отрицательные)
const positions = [item.myPosition, item.competitorPosition].filter(p => p > 0);
if (positions.length === 0) {
// Если нет валидных позиций, создаем базовый элемент
return {
x: item.city,
low: 1,
q1: 1,
median: 1,
q3: 1,
high: 1,
outliers: []
};
}
if (positions.length === 1) {
// Если только одна позиция, показываем её как точку
const pos = positions[0];
return {
x: item.city,
low: pos,
q1: pos,
median: pos,
q3: pos,
high: pos,
outliers: []
};
}
// Если две позиции
let [pos1, pos2] = positions;
// Если позиции одинаковые, добавляем небольшое смещение для визуализации
if (pos1 === pos2) {
pos2 = pos1 + 0.1; // Небольшое смещение
}
const min = Math.min(pos1, pos2);
const max = Math.max(pos1, pos2);
const median = (pos1 + pos2) / 2;
return {
x: item.city,
low: min,
q1: min,
median: median,
q3: max,
high: max,
outliers: []
};
});
}
try {
// Подготавливаем данные
const boxData = prepareBoxData(testData);
console.log('Данные для диаграммы:', boxData);
// Создаем Box and Whisker диаграмму
const chart = anychart.box();
// Настраиваем заголовок
chart.title('Сравнение позиций товаров по городам');
chart.title().fontColor('#22c55e');
chart.title().fontSize(18);
// Настраиваем оси
chart.yAxis().title('Позиция');
chart.yAxis().labels().format('{%value}');
chart.xAxis().title('Города');
chart.xAxis().staggerMode(true);
// Инвертируем ось Y (позиция 1 сверху)
try {
chart.yScale().inverted(true);
} catch (error) {
console.log('Не удалось инвертировать ось Y:', error);
}
// Создаем серию
const series = chart.box(boxData);
// Настраиваем внешний вид
series.whiskerWidth('60%');
series.fill('#22c55e', 0.3);
series.stroke('#22c55e', 2);
series.whiskerStroke('#22c55e', 2);
series.medianStroke('#16a34a', 3);
// Настраиваем подсказки
series.tooltip().format(
'Город: {%x}' +
'\nМин позиция: {%low}' +
'\nМакс позиция: {%high}' +
'\nМедиана: {%median}'
);
// Настраиваем сетку
try {
chart.grid(0).stroke('#e5e7eb', 1, '2 2');
chart.grid(1).layout('vertical').stroke('#e5e7eb', 1, '2 2');
} catch (error) {
console.log('Не удалось настроить сетку:', error);
try {
chart.yGrid(true);
chart.xGrid(true);
} catch (gridError) {
console.log('Альтернативная настройка сетки также недоступна:', gridError);
}
}
// Настраиваем фон
chart.background().fill('transparent');
// Устанавливаем контейнер и отрисовываем
chart.container('chart-container');
chart.draw();
console.log('Диаграмма успешно создана!');
} catch (error) {
console.error('Ошибка при создании диаграммы:', error);
document.getElementById('chart-container').innerHTML =
'<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: #ef4444;">' +
'<div><h3>Ошибка загрузки диаграммы</h3><p>' + error.message + '</p></div>' +
'</div>';
}
});
</script>
</body>
</html>