fix(superset): заменена нечитаемая гео-карта
- Зачем: - гео-блок дашборда должен показывать понятную метрику, единицы и сравнение стран. - Что: - legacy world_map заменён на столбцы Top Countries by Events с tooltip и легендой. - синхронизирован экспорт дашборда и добавлены контрактные тесты. - обновлены документы и урок Superset по новому гео-блоку. - Проверка: - uv run --with pytest pytest tests/test_superset_dashboard_config.py. - uv run python -m py_compile superset/create_dashboard.py tests/test_superset_dashboard_config.py. - jq empty superset/dashboards/ecommerce_analytics.zip.json.
This commit is contained in:
@@ -147,18 +147,40 @@ CHARTS_CONFIG = [
|
||||
},
|
||||
# География
|
||||
{
|
||||
"slice_name": "🌍 Geography Map",
|
||||
"viz_type": "world_map",
|
||||
"slice_name": "🌍 Top Countries by Events",
|
||||
"previous_slice_names": ["🌍 Geography Map"],
|
||||
# Legacy world_map показывает разреженную географию плохо: нет явной
|
||||
# легенды, подписи единиц и стабильного tooltip. Для текущего сида
|
||||
# читаемее top-N стран столбцами: сразу видны страна, значение и порядок.
|
||||
# Перекос стран — свойство geo-фактуры из сида, а не настройка чарта.
|
||||
"viz_type": "echarts_timeseries_bar",
|
||||
"dataset_name": "v_events_enriched",
|
||||
"params": {
|
||||
"entity": "geo_country",
|
||||
"metric": {
|
||||
"expressionType": "SQL",
|
||||
"sqlExpression": "COUNT(*)",
|
||||
"label": "Events"
|
||||
},
|
||||
"row_limit": 500,
|
||||
"linear_color_scheme": "blue_white_yellow",
|
||||
"x_axis": "geo_country",
|
||||
"metrics": [
|
||||
{
|
||||
"expressionType": "SQL",
|
||||
"sqlExpression": "COUNT(*)",
|
||||
"label": "Events, pcs",
|
||||
}
|
||||
],
|
||||
"row_limit": 15,
|
||||
"order_desc": True,
|
||||
"sort_series_type": "sum",
|
||||
"orientation": "vertical",
|
||||
"color_scheme": "supersetColors",
|
||||
"show_legend": True,
|
||||
"legendOrientation": "top",
|
||||
"legendType": "scroll",
|
||||
"rich_tooltip": True,
|
||||
"tooltipTimeFormat": "smart_date",
|
||||
"x_axis_title": "Country",
|
||||
"x_axis_title_margin": 15,
|
||||
"truncateXAxis": True,
|
||||
"y_axis_title": "Events, pcs",
|
||||
"y_axis_title_margin": 15,
|
||||
"y_axis_title_position": "Left",
|
||||
"y_axis_format": ",d",
|
||||
"time_range": "No filter"
|
||||
}
|
||||
},
|
||||
@@ -290,7 +312,7 @@ DASHBOARD_ROWS = [
|
||||
# Динамика во времени + разрез по устройствам
|
||||
[("📅 Events over Time", 8), ("📱 Traffic by Device", 4)],
|
||||
# География + эффективность маркетинговых каналов
|
||||
[("🌍 Geography Map", 6), ("🔗 UTM Effectiveness Table", 6)],
|
||||
[("🌍 Top Countries by Events", 6), ("🔗 UTM Effectiveness Table", 6)],
|
||||
# Популярные страницы + прохождение строк по слоям
|
||||
[("🪜 Page Funnel", 6), ("🧱 Rows by Layer (event)", 6)],
|
||||
]
|
||||
@@ -360,6 +382,19 @@ def sync_query_context(chart, params: dict, dataset_id: int) -> None:
|
||||
chart.query_context = json.dumps(query_context)
|
||||
|
||||
|
||||
def choose_chart_to_sync(existing_charts: list, current_name: str):
|
||||
"""Выбирает один chart для синхронизации и отдаёт лишние дубли на удаление."""
|
||||
if not existing_charts:
|
||||
return None, []
|
||||
|
||||
selected = next(
|
||||
(chart for chart in existing_charts if chart.slice_name == current_name),
|
||||
existing_charts[0],
|
||||
)
|
||||
duplicates = [chart for chart in existing_charts if chart is not selected]
|
||||
return selected, duplicates
|
||||
|
||||
|
||||
def build_dashboard_metadata(filter_dataset_id: int | None) -> str:
|
||||
"""Формирует json_metadata с валидными datasetId для native filters."""
|
||||
native_filters = []
|
||||
@@ -467,11 +502,23 @@ def main() -> bool:
|
||||
# идемпотентного rename без дублей в списке Charts.
|
||||
chart_names = [chart_config["slice_name"]]
|
||||
chart_names.extend(chart_config.get("previous_slice_names", []))
|
||||
existing = db.session.query(Slice).filter(
|
||||
existing_charts = db.session.query(Slice).filter(
|
||||
Slice.slice_name.in_(chart_names)
|
||||
).order_by(Slice.id.asc()).first()
|
||||
).order_by(Slice.id.asc()).all()
|
||||
existing, duplicate_charts = choose_chart_to_sync(
|
||||
existing_charts,
|
||||
chart_config["slice_name"],
|
||||
)
|
||||
|
||||
if existing:
|
||||
for duplicate in duplicate_charts:
|
||||
db.session.delete(duplicate)
|
||||
logger.info(
|
||||
"Deleted duplicate chart after rename: %s (ID: %s)",
|
||||
duplicate.slice_name,
|
||||
duplicate.id,
|
||||
)
|
||||
|
||||
# Синхронизируем параметры существующего чарта с конфигом.
|
||||
existing.slice_name = chart_config["slice_name"]
|
||||
existing.viz_type = chart_config["viz_type"]
|
||||
|
||||
@@ -3,12 +3,23 @@
|
||||
{
|
||||
"__Dashboard__": {
|
||||
"dashboard_title": "🛒 E-commerce Analytics Dashboard",
|
||||
"description": "Аналитический дашборд для e-commerce кликстрима: трафик, конверсии, география и качество данных.",
|
||||
"description": "Аналитический дашборд для e-commerce кликстрима: трафик, конверсии, география и прохождение строк по слоям.",
|
||||
"slug": "ecommerce-analytics",
|
||||
"published": true,
|
||||
"json_metadata": "{\"native_filter_configuration\": [{\"id\": \"date_filter\", \"name\": \"📅 Date Range\", \"filterType\": \"filter_time\", \"targets\": [{\"datasetId\": null, \"column\": {\"name\": \"event_date\"}}], \"defaultValue\": \"Last week\", \"scope\": {\"root\": [\"ROOT_ID\"], \"excluded\": []}, \"cascadeParentIds\": [], \"isInstant\": true}, {\"id\": \"country_filter\", \"name\": \"🌍 Country\", \"filterType\": \"filter_select\", \"targets\": [{\"datasetId\": null, \"column\": {\"name\": \"geo_country\"}}], \"scope\": {\"root\": [\"ROOT_ID\"], \"excluded\": []}, \"isInstant\": true, \"allowsMultipleValues\": true, \"isRequired\": false}, {\"id\": \"device_filter\", \"name\": \"📱 Device Type\", \"filterType\": \"filter_select\", \"targets\": [{\"datasetId\": null, \"column\": {\"name\": \"device_type\"}}], \"scope\": {\"root\": [\"ROOT_ID\"], \"excluded\": []}, \"isInstant\": true, \"allowsMultipleValues\": true, \"isRequired\": false}, {\"id\": \"browser_filter\", \"name\": \"🌐 Browser\", \"filterType\": \"filter_select\", \"targets\": [{\"datasetId\": null, \"column\": {\"name\": \"browser_name\"}}], \"scope\": {\"root\": [\"ROOT_ID\"], \"excluded\": []}, \"isInstant\": true, \"allowsMultipleValues\": true, \"isRequired\": false}], \"color_scheme\": \"supersetColors\", \"label_colors\": {}}",
|
||||
"position_json": "{\"DASHBOARD_VERSION_KEY\": \"v2\", \"CHART-1\": {\"id\": \"CHART-1\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 1, \"sliceName\": \"📊 Total Events\", \"height\": 50, \"width\": 4, \"x\": 0, \"y\": 0}}, \"CHART-2\": {\"id\": \"CHART-2\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 2, \"sliceName\": \"👤 Unique Users\", \"height\": 50, \"width\": 4, \"x\": 4, \"y\": 0}}, \"CHART-3\": {\"id\": \"CHART-3\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 3, \"sliceName\": \"🎯 Unique Sessions\", \"height\": 50, \"width\": 4, \"x\": 8, \"y\": 0}}, \"CHART-4\": {\"id\": \"CHART-4\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 4, \"sliceName\": \"📈 Avg Events/Session\", \"height\": 50, \"width\": 4, \"x\": 0, \"y\": 50}}, \"CHART-5\": {\"id\": \"CHART-5\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 5, \"sliceName\": \"📅 Events by Hour\", \"height\": 50, \"width\": 8, \"x\": 0, \"y\": 100}}, \"CHART-6\": {\"id\": \"CHART-6\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 6, \"sliceName\": \"📱 Traffic by Device\", \"height\": 50, \"width\": 4, \"x\": 8, \"y\": 100}}, \"CHART-7\": {\"id\": \"CHART-7\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 7, \"sliceName\": \"🌍 Geography Map\", \"height\": 50, \"width\": 6, \"x\": 0, \"y\": 150}}, \"CHART-8\": {\"id\": \"CHART-8\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 8, \"sliceName\": \"🔗 UTM Effectiveness Table\", \"height\": 50, \"width\": 6, \"x\": 6, \"y\": 150}}, \"CHART-9\": {\"id\": \"CHART-9\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 9, \"sliceName\": \"📄 Top Pages\", \"height\": 50, \"width\": 6, \"x\": 0, \"y\": 200}}, \"CHART-10\": {\"id\": \"CHART-10\", \"type\": \"CHART\", \"parents\": [\"ROOT_ID\"], \"meta\": {\"chartId\": 10, \"sliceName\": \"🔍 Data Quality Summary\", \"height\": 50, \"width\": 6, \"x\": 6, \"y\": 200}}}",
|
||||
"slices": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
"position_json": "{\"DASHBOARD_VERSION_KEY\": \"v2\", \"ROOT_ID\": {\"id\": \"ROOT_ID\", \"type\": \"ROOT\", \"children\": [\"GRID_ID\"]}, \"GRID_ID\": {\"id\": \"GRID_ID\", \"type\": \"GRID\", \"children\": [\"ROW-0\", \"ROW-1\", \"ROW-2\", \"ROW-3\"], \"parents\": [\"ROOT_ID\"], \"meta\": {\"background\": \"BACKGROUND_TRANSPARENT\"}}, \"CHART-1\": {\"id\": \"CHART-1\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-0\"], \"meta\": {\"chartId\": 1, \"sliceName\": \"📊 Total Events\", \"width\": 3, \"height\": 30}}, \"CHART-2\": {\"id\": \"CHART-2\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-0\"], \"meta\": {\"chartId\": 2, \"sliceName\": \"👤 Unique Users\", \"width\": 3, \"height\": 30}}, \"CHART-3\": {\"id\": \"CHART-3\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-0\"], \"meta\": {\"chartId\": 3, \"sliceName\": \"📈 Avg Events/Visit\", \"width\": 3, \"height\": 30}}, \"CHART-4\": {\"id\": \"CHART-4\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-0\"], \"meta\": {\"chartId\": 4, \"sliceName\": \"🎯 Conversion to /confirmation\", \"width\": 3, \"height\": 30}}, \"ROW-0\": {\"id\": \"ROW-0\", \"type\": \"ROW\", \"children\": [\"CHART-1\", \"CHART-2\", \"CHART-3\", \"CHART-4\"], \"parents\": [\"ROOT_ID\", \"GRID_ID\"], \"meta\": {\"background\": \"BACKGROUND_TRANSPARENT\"}}, \"CHART-5\": {\"id\": \"CHART-5\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-1\"], \"meta\": {\"chartId\": 5, \"sliceName\": \"📅 Events over Time\", \"width\": 8, \"height\": 60}}, \"CHART-6\": {\"id\": \"CHART-6\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-1\"], \"meta\": {\"chartId\": 6, \"sliceName\": \"📱 Traffic by Device\", \"width\": 4, \"height\": 60}}, \"ROW-1\": {\"id\": \"ROW-1\", \"type\": \"ROW\", \"children\": [\"CHART-5\", \"CHART-6\"], \"parents\": [\"ROOT_ID\", \"GRID_ID\"], \"meta\": {\"background\": \"BACKGROUND_TRANSPARENT\"}}, \"CHART-7\": {\"id\": \"CHART-7\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-2\"], \"meta\": {\"chartId\": 7, \"sliceName\": \"🌍 Top Countries by Events\", \"width\": 6, \"height\": 60}}, \"CHART-8\": {\"id\": \"CHART-8\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-2\"], \"meta\": {\"chartId\": 8, \"sliceName\": \"🔗 UTM Effectiveness Table\", \"width\": 6, \"height\": 60}}, \"ROW-2\": {\"id\": \"ROW-2\", \"type\": \"ROW\", \"children\": [\"CHART-7\", \"CHART-8\"], \"parents\": [\"ROOT_ID\", \"GRID_ID\"], \"meta\": {\"background\": \"BACKGROUND_TRANSPARENT\"}}, \"CHART-9\": {\"id\": \"CHART-9\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-3\"], \"meta\": {\"chartId\": 9, \"sliceName\": \"🪜 Page Funnel\", \"width\": 6, \"height\": 60}}, \"CHART-10\": {\"id\": \"CHART-10\", \"type\": \"CHART\", \"children\": [], \"parents\": [\"ROOT_ID\", \"GRID_ID\", \"ROW-3\"], \"meta\": {\"chartId\": 10, \"sliceName\": \"🧱 Rows by Layer (event)\", \"width\": 6, \"height\": 60}}, \"ROW-3\": {\"id\": \"ROW-3\", \"type\": \"ROW\", \"children\": [\"CHART-9\", \"CHART-10\"], \"parents\": [\"ROOT_ID\", \"GRID_ID\"], \"meta\": {\"background\": \"BACKGROUND_TRANSPARENT\"}}}",
|
||||
"slices": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -16,51 +27,51 @@
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "📊 Total Events",
|
||||
"viz_type": "big_number",
|
||||
"viz_type": "big_number_total",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"big_number\", \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"column\": null, \"aggregate\": null, \"label\": \"Total Events\", \"optionName\": \"metric_1\"}, \"y_axis_format\": \",d\", \"show_trend_line\": false, \"time_range\": \"No filter\"}",
|
||||
"description": "Общее количество событий"
|
||||
"params": "{\"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"column\": null, \"aggregate\": null, \"label\": \"Total Events\", \"optionName\": \"metric_1\"}, \"y_axis_format\": \",d\", \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"big_number_total\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "👤 Unique Users",
|
||||
"viz_type": "big_number",
|
||||
"viz_type": "big_number_total",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"big_number\", \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(DISTINCT user_domain_id)\", \"label\": \"Unique Users\", \"optionName\": \"metric_2\"}, \"y_axis_format\": \",d\", \"show_trend_line\": false, \"time_range\": \"No filter\"}",
|
||||
"description": "Уникальные пользователи"
|
||||
"params": "{\"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(DISTINCT user_domain_id)\", \"label\": \"Unique Users\", \"optionName\": \"metric_2\"}, \"y_axis_format\": \",d\", \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"big_number_total\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "🎯 Unique Sessions",
|
||||
"viz_type": "big_number",
|
||||
"slice_name": "📈 Avg Events/Visit",
|
||||
"viz_type": "big_number_total",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"big_number\", \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(DISTINCT click_id)\", \"label\": \"Unique Sessions\", \"optionName\": \"metric_3\"}, \"y_axis_format\": \",d\", \"show_trend_line\": false, \"time_range\": \"No filter\"}",
|
||||
"description": "Уникальные сессии"
|
||||
"params": "{\"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*) / COUNT(DISTINCT click_id)\", \"label\": \"Avg Events/Visit\", \"optionName\": \"metric_4\"}, \"y_axis_format\": \".1f\", \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"big_number_total\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "📈 Avg Events/Session",
|
||||
"viz_type": "big_number",
|
||||
"slice_name": "🎯 Conversion to /confirmation",
|
||||
"viz_type": "big_number_total",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"big_number\", \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*) / COUNT(DISTINCT click_id)\", \"label\": \"Avg Events/Session\", \"optionName\": \"metric_4\"}, \"y_axis_format\": \".2f\", \"show_trend_line\": false, \"time_range\": \"No filter\"}",
|
||||
"description": "Среднее количество событий на сессию"
|
||||
"params": "{\"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"if(countIf(page_url_path = '/home') = 0, 0, countIf(page_url_path = '/confirmation') / countIf(page_url_path = '/home'))\", \"label\": \"Conversion to /confirmation\", \"optionName\": \"metric_5\"}, \"y_axis_format\": \".1%\", \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"big_number_total\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "📅 Events by Hour",
|
||||
"slice_name": "📅 Events over Time",
|
||||
"viz_type": "echarts_timeseries_line",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"echarts_timeseries_line\", \"granularity_sqla\": \"event_ts\", \"time_grain_sqla\": \"PT1H\", \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Events\"}], \"groupby\": [], \"time_range\": \"Last week\", \"adhoc_filters\": [], \"row_limit\": 10000}",
|
||||
"description": "События по часам"
|
||||
"params": "{\"granularity_sqla\": \"event_ts\", \"time_grain_sqla\": \"PT5M\", \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Events\"}], \"groupby\": [], \"time_range\": \"No filter\", \"adhoc_filters\": [], \"row_limit\": 10000, \"datasource\": \"1__table\", \"viz_type\": \"echarts_timeseries_line\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -69,18 +80,18 @@
|
||||
"viz_type": "pie",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"pie\", \"groupby\": [\"device_type\"], \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Count\"}, \"row_limit\": 100, \"donut\": true, \"show_legend\": true, \"labels_outside\": true, \"time_range\": \"No filter\"}",
|
||||
"description": "Распределение трафика по устройствам"
|
||||
"params": "{\"groupby\": [\"device_type\"], \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Count\"}, \"row_limit\": 100, \"donut\": true, \"show_legend\": true, \"labels_outside\": true, \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"pie\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "🌍 Geography Map",
|
||||
"viz_type": "world_map",
|
||||
"slice_name": "🌍 Top Countries by Events",
|
||||
"viz_type": "echarts_timeseries_bar",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_events_enriched",
|
||||
"params": "{\"datasource\": \"1__table\", \"viz_type\": \"world_map\", \"entity\": \"geo_country\", \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Events\"}, \"row_limit\": 500, \"linear_color_scheme\": \"blue_white_yellow\", \"time_range\": \"No filter\"}",
|
||||
"description": "География посетителей"
|
||||
"params": "{\"x_axis\": \"geo_country\", \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"COUNT(*)\", \"label\": \"Events, pcs\"}], \"row_limit\": 15, \"order_desc\": true, \"sort_series_type\": \"sum\", \"orientation\": \"vertical\", \"color_scheme\": \"supersetColors\", \"show_legend\": true, \"legendOrientation\": \"top\", \"legendType\": \"scroll\", \"rich_tooltip\": true, \"tooltipTimeFormat\": \"smart_date\", \"x_axis_title\": \"Country\", \"x_axis_title_margin\": 15, \"truncateXAxis\": true, \"y_axis_title\": \"Events, pcs\", \"y_axis_title_margin\": 15, \"y_axis_title_position\": \"Left\", \"y_axis_format\": \",d\", \"time_range\": \"No filter\", \"datasource\": \"1__table\", \"viz_type\": \"echarts_timeseries_bar\"}",
|
||||
"description": "Chart created automatically for v_events_enriched"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -89,28 +100,28 @@
|
||||
"viz_type": "table",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_utm_effectiveness",
|
||||
"params": "{\"datasource\": \"2__table\", \"viz_type\": \"table\", \"groupby\": [\"utm_source\", \"utm_medium\", \"utm_campaign\"], \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(clicks)\", \"label\": \"Clicks\"}, {\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(uniq_users)\", \"label\": \"Users\"}, {\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(uniq_sessions)\", \"label\": \"Sessions\"}], \"row_limit\": 100, \"time_range\": \"No filter\", \"adhoc_filters\": [{\"clause\": \"WHERE\", \"expressionType\": \"SQL\", \"sqlExpression\": \"utm_source IS NOT NULL\", \"subject\": null, \"operator\": null, \"comparator\": null}]}\n",
|
||||
"description": "Эффективность UTM-кампаний"
|
||||
"params": "{\"groupby\": [\"utm_source\", \"utm_medium\", \"utm_campaign\"], \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(clicks)\", \"label\": \"Clicks\"}, {\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(uniq_users)\", \"label\": \"Users\"}, {\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(uniq_sessions)\", \"label\": \"Sessions\"}], \"row_limit\": 100, \"time_range\": \"No filter\", \"adhoc_filters\": [{\"clause\": \"WHERE\", \"expressionType\": \"SQL\", \"sqlExpression\": \"utm_source IS NOT NULL\", \"subject\": null, \"operator\": null, \"comparator\": null}], \"datasource\": \"2__table\", \"viz_type\": \"table\"}",
|
||||
"description": "Chart created automatically for v_utm_effectiveness"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "📄 Top Pages",
|
||||
"viz_type": "dist_bar",
|
||||
"slice_name": "🪜 Page Funnel",
|
||||
"viz_type": "funnel",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.v_top_pages_daily",
|
||||
"params": "{\"datasource\": \"3__table\", \"viz_type\": \"dist_bar\", \"groupby\": [\"page_url_path\"], \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(pageviews)\", \"label\": \"Pageviews\"}], \"row_limit\": 20, \"order_by_cols\": [[\"SUM(pageviews)\", false]], \"time_range\": \"No filter\", \"orientation\": \"vertical\", \"show_legend\": false}",
|
||||
"description": "Топ страниц по просмотрам"
|
||||
"params": "{\"groupby\": [\"page_url_path\"], \"metric\": {\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(pageviews)\", \"label\": \"Pageviews\"}, \"row_limit\": 20, \"time_range\": \"No filter\", \"sort_by_metric\": true, \"percent_calculation_type\": \"first_step\", \"color_scheme\": \"supersetColors\", \"show_legend\": true, \"legendOrientation\": \"top\", \"legendMargin\": 50, \"tooltip_label_type\": 5, \"number_format\": \"SMART_NUMBER\", \"show_labels\": true, \"show_tooltip_labels\": true, \"datasource\": \"3__table\", \"viz_type\": \"funnel\"}",
|
||||
"description": "Chart created automatically for v_top_pages_daily"
|
||||
}
|
||||
},
|
||||
{
|
||||
"__Slice__": {
|
||||
"slice_name": "🔍 Data Quality Summary",
|
||||
"slice_name": "🧱 Rows by Layer (event)",
|
||||
"viz_type": "dist_bar",
|
||||
"datasource_type": "table",
|
||||
"datasource_name": "dm.dq_summary",
|
||||
"params": "{\"datasource\": \"4__table\", \"viz_type\": \"dist_bar\", \"groupby\": [\"layer\"], \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(check_value)\", \"label\": \"Row Count\"}], \"adhoc_filters\": [{\"clause\": \"WHERE\", \"expressionType\": \"SQL\", \"sqlExpression\": \"check_name = 'total_rows'\", \"subject\": null, \"operator\": null, \"comparator\": null}], \"row_limit\": 100, \"time_range\": \"No filter\", \"show_legend\": false}",
|
||||
"description": "Сводка по качеству данных"
|
||||
"params": "{\"groupby\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"multiIf(layer = 'stg', '1 · stg', layer = 'ods', '2 · ods', layer = 'dds', '3 · dds', '4 · dm')\", \"label\": \"Layer\"}], \"metrics\": [{\"expressionType\": \"SQL\", \"sqlExpression\": \"SUM(check_value)\", \"label\": \"Rows\"}], \"adhoc_filters\": [{\"clause\": \"WHERE\", \"expressionType\": \"SQL\", \"sqlExpression\": \"check_name = 'total_rows' AND table_name IN ('browser_raw', 'browser_event', 'event', 'v_events_enriched')\", \"subject\": null, \"operator\": null, \"comparator\": null}], \"order_bars\": true, \"row_limit\": 100, \"time_range\": \"No filter\", \"y_axis_format\": \",d\", \"show_legend\": false, \"datasource\": \"4__table\", \"viz_type\": \"dist_bar\"}",
|
||||
"description": "Chart created automatically for dq_summary"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -122,18 +133,66 @@
|
||||
"database": "clickhouse_dwh",
|
||||
"description": "Полная обогащённая витрина событий (event + click)",
|
||||
"columns": [
|
||||
{"column_name": "event_id", "type": "UUID", "description": "UUID события"},
|
||||
{"column_name": "event_ts", "type": "DateTime64(6)", "description": "Время события"},
|
||||
{"column_name": "event_date", "type": "Date", "description": "Дата события"},
|
||||
{"column_name": "event_type", "type": "String", "description": "Тип события"},
|
||||
{"column_name": "click_id", "type": "UUID", "description": "ID сессии"},
|
||||
{"column_name": "user_domain_id", "type": "UUID", "description": "ID пользователя"},
|
||||
{"column_name": "device_type", "type": "String", "description": "Тип устройства"},
|
||||
{"column_name": "geo_country", "type": "String", "description": "Страна"},
|
||||
{"column_name": "browser_name", "type": "String", "description": "Браузер"},
|
||||
{"column_name": "utm_source", "type": "String", "description": "UTM Source"},
|
||||
{"column_name": "utm_medium", "type": "String", "description": "UTM Medium"},
|
||||
{"column_name": "page_url_path", "type": "String", "description": "Путь URL"}
|
||||
{
|
||||
"column_name": "event_id",
|
||||
"type": "UUID",
|
||||
"description": "UUID события"
|
||||
},
|
||||
{
|
||||
"column_name": "event_ts",
|
||||
"type": "DateTime64(6)",
|
||||
"description": "Время события"
|
||||
},
|
||||
{
|
||||
"column_name": "event_date",
|
||||
"type": "Date",
|
||||
"description": "Дата события"
|
||||
},
|
||||
{
|
||||
"column_name": "event_type",
|
||||
"type": "String",
|
||||
"description": "Тип события"
|
||||
},
|
||||
{
|
||||
"column_name": "click_id",
|
||||
"type": "UUID",
|
||||
"description": "ID сессии"
|
||||
},
|
||||
{
|
||||
"column_name": "user_domain_id",
|
||||
"type": "UUID",
|
||||
"description": "ID пользователя"
|
||||
},
|
||||
{
|
||||
"column_name": "device_type",
|
||||
"type": "String",
|
||||
"description": "Тип устройства"
|
||||
},
|
||||
{
|
||||
"column_name": "geo_country",
|
||||
"type": "String",
|
||||
"description": "Страна"
|
||||
},
|
||||
{
|
||||
"column_name": "browser_name",
|
||||
"type": "String",
|
||||
"description": "Браузер"
|
||||
},
|
||||
{
|
||||
"column_name": "utm_source",
|
||||
"type": "String",
|
||||
"description": "UTM Source"
|
||||
},
|
||||
{
|
||||
"column_name": "utm_medium",
|
||||
"type": "String",
|
||||
"description": "UTM Medium"
|
||||
},
|
||||
{
|
||||
"column_name": "page_url_path",
|
||||
"type": "String",
|
||||
"description": "Путь URL"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -144,13 +203,41 @@
|
||||
"database": "clickhouse_dwh",
|
||||
"description": "Эффективность UTM-кампаний",
|
||||
"columns": [
|
||||
{"column_name": "event_date", "type": "Date", "description": "Дата"},
|
||||
{"column_name": "utm_source", "type": "String", "description": "UTM Source"},
|
||||
{"column_name": "utm_medium", "type": "String", "description": "UTM Medium"},
|
||||
{"column_name": "utm_campaign", "type": "String", "description": "UTM Campaign"},
|
||||
{"column_name": "clicks", "type": "UInt64", "description": "Клики"},
|
||||
{"column_name": "uniq_users", "type": "UInt64", "description": "Уникальные пользователи"},
|
||||
{"column_name": "uniq_sessions", "type": "UInt64", "description": "Уникальные сессии"}
|
||||
{
|
||||
"column_name": "event_date",
|
||||
"type": "Date",
|
||||
"description": "Дата"
|
||||
},
|
||||
{
|
||||
"column_name": "utm_source",
|
||||
"type": "String",
|
||||
"description": "UTM Source"
|
||||
},
|
||||
{
|
||||
"column_name": "utm_medium",
|
||||
"type": "String",
|
||||
"description": "UTM Medium"
|
||||
},
|
||||
{
|
||||
"column_name": "utm_campaign",
|
||||
"type": "String",
|
||||
"description": "UTM Campaign"
|
||||
},
|
||||
{
|
||||
"column_name": "clicks",
|
||||
"type": "UInt64",
|
||||
"description": "Клики"
|
||||
},
|
||||
{
|
||||
"column_name": "uniq_users",
|
||||
"type": "UInt64",
|
||||
"description": "Уникальные пользователи"
|
||||
},
|
||||
{
|
||||
"column_name": "uniq_sessions",
|
||||
"type": "UInt64",
|
||||
"description": "Уникальные сессии"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -161,10 +248,26 @@
|
||||
"database": "clickhouse_dwh",
|
||||
"description": "Популярность страниц по дням",
|
||||
"columns": [
|
||||
{"column_name": "event_date", "type": "Date", "description": "Дата"},
|
||||
{"column_name": "page_url_path", "type": "String", "description": "Путь URL"},
|
||||
{"column_name": "pageviews", "type": "UInt64", "description": "Просмотры"},
|
||||
{"column_name": "uniq_clicks", "type": "UInt64", "description": "Уникальные клики"}
|
||||
{
|
||||
"column_name": "event_date",
|
||||
"type": "Date",
|
||||
"description": "Дата"
|
||||
},
|
||||
{
|
||||
"column_name": "page_url_path",
|
||||
"type": "String",
|
||||
"description": "Путь URL"
|
||||
},
|
||||
{
|
||||
"column_name": "pageviews",
|
||||
"type": "UInt64",
|
||||
"description": "Просмотры"
|
||||
},
|
||||
{
|
||||
"column_name": "uniq_clicks",
|
||||
"type": "UInt64",
|
||||
"description": "Уникальные клики"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -175,11 +278,31 @@
|
||||
"database": "clickhouse_dwh",
|
||||
"description": "Сводка по качеству данных",
|
||||
"columns": [
|
||||
{"column_name": "check_date", "type": "Date", "description": "Дата проверки"},
|
||||
{"column_name": "layer", "type": "String", "description": "Слой (stg/ods/dds)"},
|
||||
{"column_name": "table_name", "type": "String", "description": "Имя таблицы"},
|
||||
{"column_name": "check_name", "type": "String", "description": "Тип проверки"},
|
||||
{"column_name": "check_value", "type": "UInt64", "description": "Значение"}
|
||||
{
|
||||
"column_name": "check_date",
|
||||
"type": "Date",
|
||||
"description": "Дата проверки"
|
||||
},
|
||||
{
|
||||
"column_name": "layer",
|
||||
"type": "String",
|
||||
"description": "Слой (stg/ods/dds)"
|
||||
},
|
||||
{
|
||||
"column_name": "table_name",
|
||||
"type": "String",
|
||||
"description": "Имя таблицы"
|
||||
},
|
||||
{
|
||||
"column_name": "check_name",
|
||||
"type": "String",
|
||||
"description": "Тип проверки"
|
||||
},
|
||||
{
|
||||
"column_name": "check_value",
|
||||
"type": "UInt64",
|
||||
"description": "Значение"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user