В течение нескольких дней я сталкивался с проблемой настройки диаграммы аккордов Holoviews. Я создал диаграмму Chord, используя некоторый набор данных. Когда я наводю курсор на узел, узел и связанные с ним ребра выделяются некоторым цветом по умолчанию. Но я хочу, чтобы при наведении указателя мыши на узел узел и связанные с ним ребра должны выделяться, а также в то же время другие невыбранные узлы и ребра должны исчезать.
Я получаю тот же эффект при нажатии на узел. Но мне нужна эта функция при наведении курсора. Я знаю, что это можно сделать с помощью некоторого обратного вызова javascript в Bokeh HoverTool, но не смог найти способ сделать это.
Например, текущая диаграмма аккордов выглядит так при наведении курсора на узел: Текущий эффект наведения
Но я хочу, чтобы это происходило при наведении без нажатия: Требование наведения
Добавление кода для справки:
source_data = [{"from": "Cronje", "to": "Lord Kitchener", "value": 1}, {"from": "Cronje", "to": "Lord Selborne", "value": 1}, {"from": "Cronje", "to": "George Godfrey", "value": 1}, {"from": "Cronje", "to": "Lord Milner", "value": 1}, {"from": "Cronje", "to": "Booker T. Washington", "value": 1}, {"from": "Cronje", "to": "Dada Abdulla", "value": 1}, {"from": "Cronje", "to": "Lord Lansdowne", "value": 1}, {"from": "Cronje", "to": "Escombe", "value": 1}, {"from": "Cronje", "to": "Messrs", "value": 1}, {"from": "Cronje", "to": "Lawley", "value": 1}, {"from": "Cronje", "to": "Sheth Haji Adam", "value": 1}, {"from": "Cronje", "to": "Lord Ripon", "value": 1}, {"from": "Cronje", "to": "Lord Elgin", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Kitchener", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Selborne", "value": 1}, {"from": "Sheth Haji Adam", "to": "George Godfrey", "value": 1}, {"from": "Sheth Haji Adam", "to": "Dada Abdulla", "value": 1}, {"from": "Sheth Haji Adam", "to": "Booker T. Washington", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Milner", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Lansdowne", "value": 1}, {"from": "Sheth Haji Adam", "to": "Escombe", "value": 1}, {"from": "Sheth Haji Adam", "to": "Messrs", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lawley", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Elgin", "value": 1}, {"from": "Sheth Haji Adam", "to": "Lord Ripon", "value": 1}, {"from": "Lord Selborne", "to": "Lord Elgin", "value": 1}, {"from": "Lord Selborne", "to": "George Godfrey", "value": 1}, {"from": "Lord Selborne", "to": "Merriman", "value": 1}, {"from": "Lord Selborne", "to": "Olive Schreiner", "value": 1}, {"from": "Lord Selborne", "to": "Dada Abdulla", "value": 1}, {"from": "Lord Selborne", "to": "Booker T. Washington", "value": 1}, {"from": "Lord Selborne", "to": "Lord Milner", "value": 1}, {"from": "Lord Selborne", "to": "Lord Kitchener", "value": 1}, {"from": "Lord Selborne", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Selborne", "to": "Escombe", "value": 1}, {"from": "Lord Selborne", "to": "Messrs", "value": 1}, {"from": "Lord Selborne", "to": "Lawley", "value": 1}, {"from": "Lord Selborne", "to": "John Molteno", "value": 1}, {"from": "Lord Selborne", "to": "Lord Ripon", "value": 1}, {"from": "George Godfrey", "to": "Dada Abdulla", "value": 1}, {"from": "George Godfrey", "to": "Booker T. Washington", "value": 1}, {"from": "George Godfrey", "to": "Lord Milner", "value": 1}, {"from": "George Godfrey", "to": "Lord Kitchener", "value": 1}, {"from": "George Godfrey", "to": "Lord Lansdowne", "value": 1}, {"from": "George Godfrey", "to": "Escombe", "value": 1}, {"from": "George Godfrey", "to": "Messrs", "value": 1}, {"from": "George Godfrey", "to": "Lawley", "value": 1}, {"from": "George Godfrey", "to": "Lord Elgin", "value": 1}, {"from": "George Godfrey", "to": "Lord Ripon", "value": 1}, {"from": "Merriman", "to": "Lord Lansdowne", "value": 1}, {"from": "Merriman", "to": "John Molteno", "value": 1}, {"from": "Merriman", "to": "Olive Schreiner", "value": 1}, {"from": "Olive Schreiner", "to": "Lord Lansdowne", "value": 1}, {"from": "Olive Schreiner", "to": "John Molteno", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Kitchener", "value": 1}, {"from": "Dada Abdulla", "to": "Booker T. Washington", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Milner", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Lansdowne", "value": 1}, {"from": "Dada Abdulla", "to": "Escombe", "value": 1}, {"from": "Dada Abdulla", "to": "Messrs", "value": 1}, {"from": "Dada Abdulla", "to": "Lawley", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Elgin", "value": 1}, {"from": "Dada Abdulla", "to": "Lord Ripon", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Milner", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Kitchener", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Lansdowne", "value": 1}, {"from": "Booker T. Washington", "to": "Escombe", "value": 1}, {"from": "Booker T. Washington", "to": "Messrs", "value": 1}, {"from": "Booker T. Washington", "to": "Lawley", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Elgin", "value": 1}, {"from": "Booker T. Washington", "to": "Lord Ripon", "value": 1}, {"from": "Lord Milner", "to": "Lord Kitchener", "value": 1}, {"from": "Lord Milner", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Milner", "to": "Escombe", "value": 1}, {"from": "Lord Milner", "to": "Messrs", "value": 1}, {"from": "Lord Milner", "to": "Lawley", "value": 1}, {"from": "Lord Milner", "to": "Lord Elgin", "value": 1}, {"from": "Lord Milner", "to": "Lord Ripon", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Lansdowne", "value": 1}, {"from": "Lord Kitchener", "to": "Escombe", "value": 1}, {"from": "Lord Kitchener", "to": "Messrs", "value": 1}, {"from": "Lord Kitchener", "to": "Lawley", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Elgin", "value": 1}, {"from": "Lord Kitchener", "to": "Lord Ripon", "value": 1}, {"from": "Lord Lansdowne", "to": "Escombe", "value": 1}, {"from": "Lord Lansdowne", "to": "Messrs", "value": 1}, {"from": "Lord Lansdowne", "to": "Lawley", "value": 1}, {"from": "Lord Lansdowne", "to": "John Molteno", "value": 1}, {"from": "Lord Lansdowne", "to": "Lord Elgin", "value": 1}, {"from": "Lord Lansdowne", "to": "Lord Ripon", "value": 1}, {"from": "Escombe", "to": "Messrs", "value": 1}, {"from": "Escombe", "to": "Lawley", "value": 1}, {"from": "Escombe", "to": "Lord Elgin", "value": 1}, {"from": "Escombe", "to": "Lord Ripon", "value": 1}, {"from": "Messrs", "to": "Lawley", "value": 1}, {"from": "Messrs", "to": "Lord Elgin", "value": 1}, {"from": "Messrs", "to": "Lord Ripon", "value": 1}, {"from": "Lawley", "to": "Lord Elgin", "value": 1}, {"from": "Lawley", "to": "Lord Ripon", "value": 1}, {"from": "Lord Elgin", "to": "Lord Ripon", "value": 1}]
import pandas as pd
import holoviews as hv
from holoviews import opts, dim
import numpy as np
hv.extension('bokeh')
hv.output(size=300)
df_json = pd.DataFrame(source_data)
df_links = pd.DataFrame(columns = ['source', 'target', 'value'])
df_links['source'] = df_json['from'].values.tolist()
df_links['target'] = df_json['to'].values.tolist()
df_links['value'] = df_json['value'].values.tolist()
unique_names = set(df_json['from'].unique().tolist() + df_json['to'].unique().tolist())
df_nodes = pd.DataFrame(columns=['name', 'group'])
df_nodes['name'] = list(unique_names)
## Grouping the nodes
df_nodes['group'][0:5] = 0
df_nodes['group'][5:10] = 1
df_nodes['group'][10:] = 2
## mapping to numerical value for the source and target node
mapper = {key: i for i, key in enumerate(list(unique_names))}
df_links['source'] = df_links['source'].map(mapper)
df_links['target'] = df_links['target'].map(mapper)
links = df_links
nodes = hv.Dataset(df_nodes, 'index')
chord = hv.Chord((links, nodes)).select(value=(1, None))
chord.opts(
opts.Chord(cmap='Category10', edge_cmap='Category10', edge_color=dim('source').str(),
labels='name', node_color=dim('group').str()))