Files
scan-sfera/scan-sphera-main/public/test-column-chart.html
2025-07-19 17:56:06 +03:00

216 lines
9.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>