import { METRIC_LABELS, METRIC_FORMATTER } from './visitor-graph' import { parseUTCDate, formatMonthYYYY, formatDay } from '../../util/date' export const dateFormatter = (interval, longForm) => { return function(isoDate, _index, _ticks) { let date = parseUTCDate(isoDate) if (interval === 'month') { return formatMonthYYYY(date); } else if (interval === 'date') { return formatDay(date); } else if (interval === 'hour') { const parts = isoDate.split(/[^0-9]/); date = new Date(parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5]) const dateFormat = Intl.DateTimeFormat(navigator.language, { hour: 'numeric' }) const twelveHourClock = dateFormat.resolvedOptions().hour12 const formattedHours = dateFormat.format(date) if (twelveHourClock) { return formattedHours.replace(' ', '').toLowerCase() } else { return formattedHours.replace(/[^0-9]/g, '').concat(":00") } } else if (interval === 'minute') { if (longForm) { const minutesAgo = Math.abs(isoDate) return minutesAgo === 1 ? '1 minute ago' : minutesAgo + ' minutes ago' } else { return isoDate + 'm' } } } } export const GraphTooltip = (graphData, metric) => { return (context) => { const tooltipModel = context.tooltip; const offset = document.getElementById("main-graph-canvas").getBoundingClientRect() // Tooltip Element let tooltipEl = document.getElementById('chartjs-tooltip'); // Create element on first render if (!tooltipEl) { tooltipEl = document.createElement('div'); tooltipEl.id = 'chartjs-tooltip'; tooltipEl.style.display = 'none'; tooltipEl.style.opacity = 0; document.body.appendChild(tooltipEl); } if (tooltipEl && offset && window.innerWidth < 768) { tooltipEl.style.top = offset.y + offset.height + window.scrollY + 15 + 'px' tooltipEl.style.left = offset.x + 'px' tooltipEl.style.right = null; tooltipEl.style.opacity = 1; } // Stop if no tooltip showing if (tooltipModel.opacity === 0) { tooltipEl.style.display = 'none'; return; } function getBody(bodyItem) { return bodyItem.lines; } function renderLabel(label, prev_label) { const formattedLabel = dateFormatter(graphData.interval, true)(label) const prev_formattedLabel = prev_label && dateFormatter(graphData.interval, true)(prev_label) if (graphData.interval === 'month') { return !prev_label ? formattedLabel : prev_formattedLabel } if (graphData.interval === 'date') { return !prev_label ? formattedLabel : prev_formattedLabel } if (graphData.interval === 'hour') { return !prev_label ? `${dateFormatter("date", true)(label)}, ${formattedLabel}` : `${dateFormatter("date", true)(prev_label)}, ${dateFormatter(graphData.interval, true)(prev_label)}` } return !prev_label ? formattedLabel : prev_formattedLabel } // function renderComparison(change) { // const formattedComparison = numberFormatter(Math.abs(change)) // if (change > 0) { // return `${formattedComparison}%` // } // if (change < 0) { // return `${formattedComparison}%` // } // if (change === 0) { // return `0%` // } // } // Set Tooltip Body if (tooltipModel.body) { var bodyLines = tooltipModel.body.map(getBody); // Remove duplicated line on overlap between dashed and normal if (bodyLines.length == 3) { bodyLines[1] = false } const data = tooltipModel.dataPoints[0] const label = graphData.labels[data.dataIndex] const point = data.raw || 0 // const prev_data = tooltipModel.dataPoints.slice(-1)[0] // const prev_label = graphData.prev_labels && graphData.prev_labels[prev_data.dataIndex] // const prev_point = prev_data.raw || 0 // const pct_change = point === prev_point ? 0 : prev_point === 0 ? 100 : Math.round(((point - prev_point) / prev_point * 100).toFixed(1)) let innerHtml = `