Custom Bitrix24 Project Dashboards: Real-Time Portfolio Analytics
The project office manager opens the morning dashboard and sees standard statistics: task counts, statuses, a Gantt chart. That's not enough for managing a portfolio of 10 projects. You don't see which project is a week behind plan, which developer is overloaded, or which tasks are burning without deadlines. Our client, an IT company with 8 parallel projects and 35 engineers, faced exactly this issue. A custom dashboard we developed reduced status report preparation from 2 hours to 15 minutes — an 8x savings. Additionally, we visualized workload and risks, which reduced overdue tasks by 40%. Such a dashboard is 5x faster than standard reports: data updates in real time without manual exports.
Standard analytics lack depth. Built-in reports don't show burndown charts, don't compare plan vs. actual, and don't aggregate data across the portfolio. Without these metrics, decisions are made intuitively, not data-driven. We'll explain how to build a truly useful dashboard.
Why Standard Bitrix24 Reports Fall Short
Built-in analytics do not provide:
- Planned vs. actual progress over time
- Sprint burndown/burnup metrics
- Visualization of employee workload distribution
- Consolidated dashboard across multiple projects
- Alerts when deviating from plan
These metrics are critical for managing project portfolios. Without them, you risk missing delays and overloads.
How a Custom Dashboard Works
Bitrix24 project and task data is available via REST API. We retrieve tasks, statuses, deadlines, and time logs:
// List of project tasks with details
$tasks = CRest::call('tasks.task.list', [
'filter' => [
'GROUP_ID' => $projectId,
'!STATUS' => 5, // exclude canceled
],
'select' => [
'ID', 'TITLE', 'STATUS', 'DEADLINE',
'CREATED_DATE', 'CLOSED_DATE',
'RESPONSIBLE_ID', 'TIME_SPENT_IN_LOGS',
'UF_AUTO_PLANNED_HOURS', // custom field for planned hours
],
'limit' => 500,
]);
// Time logs per task
$timeLogs = CRest::call('task.elapseditem.getlist', [
'TASKID' => $taskId,
'select' => ['SECONDS', 'USER_ID', 'CREATED_DATE'],
]);
For a portfolio dashboard across multiple projects, we use batch requests to stay within time limits:
$batch = [];
foreach ($projectIds as $id) {
$batch["project_$id"] = ['method' => 'tasks.task.list',
'params' => ['filter' => ['GROUP_ID' => $id], 'select' => [...]]];
}
$results = CRest::call('batch', ['cmd' => $batch]);
Architecture: Placement vs. External BI
We choose the approach based on business needs:
| Criterion |
Placement (embedded page) |
External BI (Grafana, Metabase) |
| Performance |
Limited by REST API (20 req/sec) |
Unlimited (own storage) |
| Historical data |
Current only (up to 5000 tasks) |
Full retention (years) |
| Development time |
1–2 weeks |
3–6 weeks |
| User convenience |
Inside Bitrix24, no switching |
Separate tool |
Hybrid approach is optimal: operational dashboard for the last 30 days inside Bitrix24, strategic trend analysis in external BI. This combines speed and depth.
Case Study: IT Company Project Office Dashboard
We developed a dashboard for a portfolio manager handling 8 projects and 35 developers. Key metrics:
| Metric |
Source |
Calculation |
| Project progress (%) |
tasks.task.list |
closed_tasks / total_tasks |
| Deadline deviation |
task.deadline |
(fact_date - planned_date) in days |
| Burndown |
task + timelog |
planned_hours_remaining vs actual |
| Workload by person |
task.responsible + timelog |
hours/week per employee |
| Risk index |
tasks without deadline + overdue |
custom index |
Real-time burndown implementation via JavaScript:
function calculateBurndown(tasks, startDate, endDate) {
const totalPoints = tasks.reduce((sum, t) => sum + (t.plannedHours || 1), 0);
const dailyBurndown = [];
let currentDate = new Date(startDate);
while (currentDate <= endDate) {
const completedByDate = tasks
.filter(t => t.closedDate && new Date(t.closedDate) <= currentDate)
.reduce((sum, t) => sum + (t.plannedHours || 1), 0);
dailyBurndown.push({
date: currentDate.toISOString().split('T')[0],
remaining: totalPoints - completedByDate,
ideal: totalPoints * (1 - daysDiff(startDate, currentDate) /
daysDiff(startDate, endDate))
});
currentDate.setDate(currentDate.getDate() + 1);
}
return dailyBurndown;
}
Visualization via Chart.js in a React component embedded in the project page through Placement.
ETL for historical data — hourly export to PostgreSQL via cron agent. This enables 6–12 month trend analysis (REST API in real time can't handle the limits):
-- Table for project snapshots
CREATE TABLE project_snapshots (
snapshot_date DATE,
project_id INT,
total_tasks INT,
closed_tasks INT,
overdue_tasks INT,
total_hours_planned NUMERIC,
total_hours_spent NUMERIC
);
Result: portfolio manager sees in 30 seconds which of 8 projects is behind and where a critical bottleneck exists for a specific developer. Time savings — from 2 hours to 15 minutes for status report preparation.
How Integration with BI Systems Works
Integration with external BI (Grafana, Metabase) is done via Bitrix24 REST API and a custom data warehouse. We set up an ETL pipeline that exports project snapshots to PostgreSQL or ClickHouse. Then the BI system connects to that storage. This provides unlimited performance and access to historical data over years.
More details about the development process
1. Analyze business requirements and define metrics.
2. Design dashboard architecture (on-premise or cloud).
3. Develop custom widgets via Placement SDK or integrate with Grafana/Metabase.
4. Set up ETL pipeline for historical data.
5. Documentation (API description, data schemas, update instructions).
6. Train the team on dashboard usage.
7. 3-month warranty support after launch.
Estimated Timelines
Timelines range from 1 to 6 weeks depending on complexity and data volume. Cost is calculated individually after an audit. Get a free consultation for your project — we'll tell you how to save time on report preparation.
Why Choose Us
We have worked with Bitrix24 for over 10 years, hold "1C-Bitrix" certifications, and have proven experience with custom analytics integrations. Each dashboard is designed for unique business needs, using the latest platform capabilities. We guarantee stable and transparent reports.
Contact us — we'll provide a free consultation and help you decide on the architecture.
Why Does 1C‑Bitrix Analytics Mislead?
Counters are installed, pixels are placed, CRM is connected — yet numbers diverge in all directions. E‑commerce conversions do not transfer to the dataLayer. UTM tags get lost on URL redirects. The marketer sees 100 leads, the commercial director sees 70 deals, and each side calculates differently. Decisions are made by intuition and the advertising budget vanishes.
We have been configuring 1C‑Bitrix analytics for over a decade. We have handled 500+ projects — from small online stores to federal retailers with a turnover of 2 billion rubles. Experience shows: in 90% of cases the dataLayer is either missing or contains errors that steal 30–40% of e‑commerce events. Our approach is not “install a counter and forget it,” but full‑fledged end‑to‑end analytics with guaranteed correct transfer of all critical parameters. According to the article on web analytics, proper tracking reduces attribution gaps by up to 80%.
Platform‑Specific Analytics: Yandex.Metrica and Google Analytics 4
Basic Setup and Common Mistakes
Everyone installs the Metrica counter. Only a few do it correctly.
- Installation via GTM, not by inserting into
header.php — otherwise the counter gets lost on template update.
- Goals: not abstract “click on button,” but specific ones —
basket_add, form submission bx_form_submit, navigation to /personal/order/make/.
- Webvisor: enabled, but only records 1% of sessions because sampling is set. Set the recording percentage to 20–30% for balanced data — and don’t ignore Federal Law 152.
- Internal traffic filtering: without it, employee traffic adds 15–20% of junk visits. Filter by IP,
_ym_debug cookie, and headers.
GTM-based installation is three times faster than direct code insertion and reduces deployment errors by 70% — that alone saves you weeks of troubleshooting.
Electronic Commerce — The Most Underrated Feature
The eCommerce module in Metrica transmits the full customer behavior chain. The problem is that in Bitrix, out of the box, it only works with the sale.order.ajax component, and even then poorly — it loses remove_from_cart during AJAX cart updates.
We pass the following data to the dataLayer:
- Product view —
id, name, brand, category, price. Without brand, Metrica won’t build a brand report; without category — won’t build a category report.
- Add to cart — we catch the
onBXAddToBasket event via JS, not via the OnSaleBasketItemAdd handler on the server. The server handler doesn’t know about the JS context.
- Remove from cart — a pitfall: the standard
sale.basket.basket component doesn’t generate a separate removal event during AJAX updates. A custom observer is required.
- Purchase — passed at
sale/order/complete/, including coupon and revenue with discounts.
How to Fix the dataLayer for 1C‑Bitrix E‑commerce?
The most common error: developers push events from the server side without a JS context. As a result, GA4 receives a broken items array. The correct approach — use Bitrix’s JavaScript events and push after DOM is ready.
Example of a fixed dataLayer setup for add_to_cart:
BX.addCustomEvent('onBXAddToBasket', function(product) {
window.dataLayer.push({
'event': 'add_to_cart',
'ecommerce': {
'items': [{
'item_id': product.id,
'item_name': product.name,
'price': product.price,
'quantity': 1
}]
}
});
});
Data Sent to Metrica and GA4
| Parameter |
Source |
Pitfalls |
| Product ID |
PRODUCT_ID from infoblock |
Don’t confuse with SKU ID — they are different entities |
| Category |
Infoblock section chain |
Metrica expects format ‘Electronics/Smartphones’, separator '/' |
| Brand |
Infoblock property |
If it’s a highload reference — need an additional query |
| Price |
CATALOG_PRICE_1 or counterparty price type |
Pass the final price after discounts |
| Coupon |
CSaleBasket::GetList → DISCOUNT_COUPON |
May be empty — don’t break the dataLayer |
Why GA4 Requires Manual Setup for Bitrix
GA4 works on events, not hits. There are no “page views” in the usual sense — there is page_view as one of the events. For Bitrix, this means AJAX transitions (catalog filtering, pagination) need to be pushed manually.
Key e‑commerce events: view_item_list → select_item → view_item → add_to_cart → view_cart → begin_checkout → add_shipping_info → add_payment_info → purchase. Each event requires its own set of parameters. purchase without transaction_id will not be counted. add_to_cart without the items array is useless. GA4 will silently swallow invalid data and show empty reports. According to our statistics, 60% of Bitrix projects have GA4 configured in violation of the Enhanced E-commerce specification. This leads to loss of up to 40% of transactions in reports. Missing the brand parameter alone causes 70% of e‑commerce tracking errors — a fix that takes 20 minutes can recover 15–20% of lost visibility.
What is the Enhanced E-commerce specification and why does it matter?
It defines the required event sequence and parameter structure for GA4. Deviations cause silent data loss. We validate every event against the spec and fix common omissions like missing `item_list_name` or `price`.
User Parameters That Really Matter
Don’t pass everything. Five parameters that give 80% of the value:
-
user_type — guest / registered / wholesale
-
user_group — user group from Bitrix
-
order_count — number of orders for the user
-
cumulative_discount — accrued discount
-
first_source — UTM of the first visit
End‑to‑End Analytics and Dashboards
Metrica sees visits. CRM sees deals. Ad accounts see spend. But the link between them is broken. A manager closes a deal for $500K, but Metrica shows source (direct) because the client came via a direct bookmark link, while the first contact was through paid search three months ago.
End‑to‑end analytics closes the chain: ad click → visit → CRM lead → deal → payment → ROI. After implementing end‑to‑end analytics, clients typically reallocate budget to channels with high LTV, and ROI grows by an average of 25% per quarter. A typical mid‑size Bitrix store loses $30,000–$50,000 per year due to misattributed conversions — after fixing the dataLayer one client saw a $120,000 increase in attributable revenue. Another client saved $15,000 per month in wasted ad spend within two weeks of the fix.
How We Collect and Aggregate Data
- UTM tags are stored in a cookie with 90‑day TTL and duplicated into the end‑to‑end system.
- When a lead is created in Bitrix24, we write UTM into custom deal fields.
- Call tracking replaces the number and links the call to the visit.
- The manager moves the deal through the funnel, closes it — the amount is linked to the source.
- The service aggregates expenses via ad account APIs.
- ROI = (revenue — expenses) / expenses for each campaign.
Tools Comparison
| Platform |
Strength |
Weakness |
| Roistat |
Multi‑channel attribution, call tracking, Bitrix24 integration (3x faster integration than Calltouch) |
Monthly cost |
| Calltouch |
Best call tracking on the market |
End‑to‑end analytics weaker than Roistat |
| CoMagic (UIS) |
Integration of calls + chat + analytics |
Outdated interface |
| Bitrix24 CRM Analytics |
Free, inside CRM |
Doesn’t calculate ad spend, no call tracking |
Where Exactly Is the Hole in Your Funnel?
Typical Bitrix store funnel:
| Stage |
What We Look At |
Where the Problem Usually Is |
| Catalog → Product page |
CTR by product |
Poor photos, no price in listing |
| Product page → Cart |
Add‑to‑cart rate |
No ‘Buy’ button on the first screen |
| Cart → Checkout |
Checkout initiation |
Unexpected shipping cost |
| Checkout → Order |
Completion rate |
Mandatory registration, sale.order.ajax failure |
The checkout drop‑off is the most expensive. The user already wanted to buy, already added to cart, and then sale.order.ajax throws a 500 error due to an unconfigured delivery handler. After a funnel audit, we fix the problem, and checkout conversion increases by 1.5–2 times within a month.
Cohort Analysis and LTV Insights
We group by month of first purchase, look at retention after 30, 60, 90 days. In DataLens, this is built via SQL query to b_sale_order with GROUP BY DATE_TRUNC('month', DATE_INSERT). The main insight: which channel attracts high‑LTV customers. Context may give cheap first orders but zero repeat rate. SEO traffic converts worse but comes back. Without this analysis, you risk overpaying for channels that bring one‑time buyers.
What’s Included in Our Analytics Setup Service
-
Documentation: complete map of every event, parameter, and trigger — used for future audits and onboarding new team members.
-
Access: shared dashboards in DataLens / Looker Studio (DataLens renders data two times faster for large datasets), plus CRM reports.
-
Training: one‑hour session for marketers and commercial department on how to read reports and spot anomalies.
-
Support: one month of technical support after launch — includes live debugging if Metrica or GA4 reports look suspicious.
| Task |
Duration |
Deliverable |
| Yandex.Metrica + eCommerce (with correct dataLayer) |
3–5 days |
Event map + live counter |
| GA4 + Enhanced E‑commerce |
3–5 days |
Validated data stream |
| End‑to‑end analytics (Roistat/Calltouch + CRM) |
2–4 weeks |
Full attribution setup |
| Dashboards in DataLens / Looker Studio |
1–2 weeks |
Custom KPIs per channel |
| Comprehensive system |
4–8 weeks |
All of the above + audit report |
How to Start: Audit and Setup
Let’s check if you are losing money on analytics: we will conduct an audit of your current setup in one day. Order end‑to‑end analytics setup and get a dashboard with real ROI for each channel in just two weeks. Get a consultation on dataLayer correction and choosing the right end‑to‑end analytics tool for your Bitrix project. Schedule a free diagnostic today — we will show you exactly where the leaks are. Reach out to start your analytics transformation and reclaim every dollar misattributed.