TGViewer
Записки м̶о̶л̶о̶д̶о̶г̶о̶ вебмастера Записки м̶о̶л̶о̶д̶о̶г̶о̶ вебмастера @yawebmaster · 976 subscribers
Post #2339 766


# Добавляем прямоугольники (vrect) для Google Updates
for upd in GOOGLE_UPDATES:
if upd['name'] in selected_updates:
fig.add_vrect(
x0=upd['start'], x1=upd['end'],
fillcolor='red', opacity=0.1, layer='below', line_width=0,
annotation_text=upd['name'],
annotation_position="top left"
)

# Добавляем события (вертикальные линии) для выбранных ev
for ev in EVENTS:
if ev['name'] in selected_events:
date_str = pd.to_datetime(ev['date']).strftime('%Y-%m-%d')
print(f"Adding event line: {ev['name']} at {date_str}") # Диагностика
fig.add_vline(
x=date_str,
line_color='blue',
opacity=1.0,
line_width=2,
layer='above'
)
fig.add_annotation(
x=date_str,
y=1,
xref='x',
yref='paper',
text=ev['name'],
showarrow=True,
arrowhead=2,
ax=0,
ay=-40,
font=dict(color='blue', size=12)
)

# Настройка осей
fig.update_layout(
title="GSC Трафик",
xaxis_title="Дата",
yaxis_title="Значение",
legend_title="Сайты и метрики",
xaxis=dict(
tickmode='linear',
tick0=pd.to_datetime(START_DATE),
dtick=86400000.0, # один день (в мс)
tickformat="%d-%m-%Y",
rangeslider=dict(visible=True),
)
)

# Если метрик нет => вручную задаём X-ось (иначе range может оказаться [0..1])
if not selected_metrics:
print("No metrics selected -> Forcing x-range to START..END")
fig.update_xaxes(range=[START_DATE, END_DATE])

# Обработка зума (для Y-оси)
if relayoutData:
if "xaxis.range[0]" in relayoutData and "xaxis.range[1]" in relayoutData and selected_metrics:
x_start = pd.to_datetime(relayoutData["xaxis.range[0]"])
x_end = pd.to_datetime(relayoutData["xaxis.range[1]"])
mask = (filtered_df['date'] >= x_start) & (filtered_df['date'] <= x_end)
zoomed_df = filtered_df[mask]
if not zoomed_df.empty:
y_min = zoomed_df[selected_metrics].min().min()
y_max = zoomed_df[selected_metrics].max().max()
y_padding = (y_max - y_min) * 0.05
fig.update_yaxes(range=[y_min - y_padding, y_max + y_padding])

# Чтобы при переключении чекбоксов не сбрасывался зум или аннотации
fig.update_layout(uirevision='fixed')

return fig

if __name__ == '__main__':
app.run(debug=True)


В данном коде необходимо изменить следующее:

Строка 14 - вписать ваши домены, которые нужно вывести на графике
Строка 19 - указываем период, за который нужны данные (если проектов много, рекомендую не брать слишком большой период - будет долго подгружать)
Строка - 25-46 - тут я вписал апы Гугла - вы можете добавить если что то не указано
Строка 48 - тут вписываете события, которые хотите видеть на графике (они будут показаны вертикальной линией, как на скрине выше)
Строка 84 - название вашего JSON - файла (который расположен в той же папке, что и сам скрипт)

Все - вы почти готовы начинать...

Устанавливаем зависимости этой командой

pip install dash plotly pandas google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client


И запускаем скрипт
python main.py


Когда скрипт запустится вы увидите в терминале, что дашборд доступен по локальному адресу, в моем случае это - http://127.0.0.1:8050 - переходим по этому адресу и работаем с дашбордом

Ну и да, новые апы нужно будет добавлять руками уже самостоятельно, а как вы хотели, некоммерческие проекты они такие🤷
  • 👍 4
More from @yawebmaster
  1. Aug 5, 2026С появлением ИИ я очень плотно с ним начал взаимодействовать, но не на уровне - "эт самое,…
  2. Jul 24, 2026Ох давненько я ничего не писал тут)) Аж скулы сводит)) Короче, прикольная штука приключила…
  3. Oct 23, 2025video post
  4. Oct 23, 2025Я в последнее время часто работаю с прокси, и обратил внимание, как изменились мобильные п…
  5. Oct 22, 2025video post
  6. Oct 22, 2025Какой же трэш, Индусы дорвались до Кворка. Подыскиваю чувака на крауд, и полез на Кворк, а…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →