Вопрос или проблема
Я работаю над случаем использования, где хочу отображать полный текст метки легенды в виде всплывающей подсказки при наведении на символ легенды в Vega-Lite. Причина в том, что метки легенды усечены, поэтому я хочу показывать полное имя метки при наведении как обходное решение.
Вот что я пробовал до сих пор:
Я попытался добавить атрибут title
к целевому HTML-элементу, используя следующий код:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Пример всплывающей подсказки легенды Vega</title>
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
</head>
<body>
<div id="vis"></div>
<script>
const vegaLiteSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"category": "Длинное название категории 1", "value": 10},
{"category": "Длинное название категории 2", "value": 15},
{"category": "Длинное название категории 3", "value": 20}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "category", "type": "nominal"},
"y": {"field": "value", "type": "quantitative"},
"color": {
"field": "category",
"type": "nominal",
"legend": {"title": "Категории"}
}
}
};
vegaEmbed('#vis', vegaLiteSpec).then(result => {
const view = result.view;
// Ждем, пока представление Vega полностью отобразится
view.runAsync().then(() => {
// Выбираем все группы символов легенды и добавляем атрибуты `title` для всплывающих подсказок
const legendSymbols = document.querySelectorAll('.role-legend-symbol');
// Массив названий категорий для символов легенды
const categories = ["Длинное название категории 1", "Длинное название категории 2", "Длинное название категории 3"];
legendSymbols.forEach((symbol, index) => {
// Устанавливаем полное название категории как заголовок всплывающей подсказки
symbol.setAttribute('title', categories[index]);
});
});
});
</script>
</body>
</html>
Код успешно добавляет атрибут title
к нужным HTML-элементам, но я все равно не вижу всплывающую подсказку при наведении на символы легенды.
Может кто-то подсказать, как это можно сделать в Vega-Lite или Vega? Я читал о использовании сигналов в Vega для взаимодействия с пользователями, но не уверен, как их применить в данном случае. Предпочтительнее использовать Vega-Lite, но поскольку я использую JavaScript для отображения графика, я также могу управлять базовой Vega, если это необходимо.
Спасибо заранее!
Ответ или решение
Чтобы отобразить полное название легенды в качестве подсказки при наведении на символ легенды в Vega-Lite, вам необходимо использовать встроенные методы JavaScript для манипуляции с DOM-элементами, так как простое добавление атрибута title
может не срабатывать из-за особенностей визуализации.
Шаги для реализации:
-
Использование Vega-Lite для создания графика: Начнем с базового создание графика, где ваша легенда будет содержать длинные названия элементов.
-
Установка событий наведения: Вместо использования
title
вы можете использоватьmouseover
иmouseout
события для динамического отображения подсказок.
Пример кода:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Пример подсказки легенды Vega</title>
<script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite@5"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
<style>
.tooltip {
position: absolute;
visibility: hidden;
background-color: white;
border: 1px solid black;
padding: 5px;
z-index: 10;
}
</style>
</head>
<body>
<div id="vis"></div>
<div class="tooltip" id="tooltip"></div>
<script>
const vegaLiteSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"values": [
{"category": "Длинное название категории 1", "value": 10},
{"category": "Длинное название категории 2", "value": 15},
{"category": "Длинное название категории 3", "value": 20}
]
},
"mark": "bar",
"encoding": {
"x": {"field": "category", "type": "nominal"},
"y": {"field": "value", "type": "quantitative"},
"color": {
"field": "category",
"type": "nominal",
"legend": {"title": "Категории"}
}
}
};
vegaEmbed('#vis', vegaLiteSpec).then(result => {
const view = result.view;
view.runAsync().then(() => {
const legendSymbols = document.querySelectorAll('.role-legend-symbol');
const tooltip = document.getElementById('tooltip');
const categories = [
"Длинное название категории 1",
"Длинное название категории 2",
"Длинное название категории 3"
];
legendSymbols.forEach((symbol, index) => {
symbol.addEventListener('mouseover', (event) => {
tooltip.innerHTML = categories[index];
tooltip.style.visibility = 'visible';
tooltip.style.left = `${event.pageX + 5}px`;
tooltip.style.top = `${event.pageY + 5}px`;
});
symbol.addEventListener('mouseout', () => {
tooltip.style.visibility = 'hidden';
});
});
});
});
</script>
</body>
</html>
Объяснение кода:
-
Стиль для подсказки: Мы создали стиль для элемента
<div>
с классомtooltip
, чтобы он выглядел как обычное всплывающее окно. -
Обработка событий:
- Для каждого символа легенды добавляется обработчик события
mouseover
, который делает видимым элементtooltip
, и соответственно устанавливает его позицию и содержание. - Обработчик события
mouseout
скрывает подсказку.
- Для каждого символа легенды добавляется обработчик события
-
Динамическое обновление: Мы используем позицию курсора, чтобы позиционировать подсказку непосредственно рядом с курсором.
Заключение:
Предложенное решение позволяет устранить проблему с усечением названий легенды, благодаря чему пользователи получают полный доступ к информации при наведении на символы. Так вы обеспечите лучший пользовательский опыт, обратив внимание на детали в вашем визуализационном проекте с помощью Vega-Lite.