@Time used to display the current hovered time (nested dataframe), is showing inaccurate reading and doesn’t match with the corresponding Time Axis .
Possibly due to the cb_data.index.lineindices value being same for different points(refer gif) .
How to resolve this ?
from bokeh.models import NumeralTickFormatter, LinearAxis, Range1d, DatetimeTickFormatter, ColumnDataSource, HoverTool, \
CustomJS
from bokeh.plotting import figure, show, output_file
from pandasPivot.numberFormat import pad_func
import pandas as pd
def chartInteractive_func(df):
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.to_datetime(df['Time'], format='%H:%M')
SOURCE = ColumnDataSource(data = df)
print("SOURCE")
print(SOURCE.data)
jsHover = """
var tooltipString = '';
var data = source.data;
const idx = cb_data.index.line_indices;
if (idx.length > 0){
console.log(idx);
const date = new Date(data['Time'][idx]);
const timeStr = new Intl.DateTimeFormat('en-US', {hour12: false, timeZone: 'GMT-0', timeStyle: 'short'}).format(date);
tooltipString += timeStr + ": @Spot<br>"
tooltipString += "Time inaccurate (Spot accurate)><br>"
tooltipString += "line_indices same over adjacent points"
}
hover.tooltips = tooltipString;
"""
plot = figure(title=f'Index repeats for Nested dataframe(Time inaccurate)', x_axis_label="Time",x_axis_type="datetime",y_axis_label = "SellOi",background_fill_color="black",sizing_mode="stretch_both")
df['Time'] = pd.to_datetime(df['Time'], format='%H:%M')
df.sort_values(by='Time', inplace=True)
# plot.xaxis.formatter = DatetimeTickFormatter(hours=["%H:%M"])
plot.xaxis.formatter = DatetimeTickFormatter(
days="%Y-%m-%d",
hours="%H:%M:%S",
minutes="%H:%M"
)
# Set the x-axis and y-axis line dash
plot.xgrid.grid_line_alpha = 0.2
plot.ygrid.grid_line_alpha = 0.2
# spotAxis
spotAxis_min = df["Spot"].min()
spotAxis_max = df["Spot"].max()
padY = pad_func(0.1, spotAxis_min, spotAxis_max)
plot.extra_y_ranges["spotAxis"] = Range1d(start=spotAxis_min - padY, end=spotAxis_max + padY)
plot.add_layout(LinearAxis(y_range_name="spotAxis", axis_label="Spot"), 'right')
#r1 Hover Tooltip
spotLine = plot.line( source= SOURCE,x = "Time",y = "Spot", line_width=3, line_color="white",
visible= True, alpha=0.8, muted_color="white", muted_alpha=0.1,
legend_label='Spot', y_range_name="spotAxis")
spotCircle = plot.circle_dot(x = "Time" , y = "Spot",size = 5, color="white",legend_label='Spot', y_range_name="spotAxis", source= SOURCE)
hoverTool = HoverTool(tooltips=None)
cb = CustomJS(args={'source': SOURCE, 'hover': hoverTool}, code=jsHover)
hoverTool.callback = cb
hoverTool.renderers = [spotLine]
plot.add_tools(hoverTool)
# Interactive legend
plot.legend.location = 'bottom_left'
plot.legend.orientation = "vertical"
plot.legend.click_policy="mute"
show(plot)
def dataFeed():
data = {
"Time": ["12:03", "12:03", "12:03", "12:03", "13:12", "13:12", "13:12", "13:12", "14:17", "14:17", "14:17",
"14:17"],
"Spot": [19653, 19653, 19653, 19653, 19629, 19629, 19629, 19629, 19640, 19640, 19640, 19640],
"Strike": [19500, 19600, 19700, 19800, 19500, 19600, 19700, 19800, 19500, 19600, 19700, 19800],
"cLtp": [99, 174, 167, 167, 91, 165, 161, 93, 95, 16, 12, 31],
"pLtp": [49, 24, 42, 25, 51, 74, 36, 53, 21, 29, 75, 32],
}
df = pd.DataFrame(data)
# Convert the 'Time' column to datetime
df['Time'] = pd.to_datetime(df['Time'], format='%H:%M')
df.sort_values(by='Time', inplace=True)
chartInteractive_func(df)
dataFeed()