diff --git a/src/api/gramjs/apiBuilders/statistics.ts b/src/api/gramjs/apiBuilders/statistics.ts index f0af93198..0b9d2ce0a 100644 --- a/src/api/gramjs/apiBuilders/statistics.ts +++ b/src/api/gramjs/apiBuilders/statistics.ts @@ -57,7 +57,9 @@ export function buildChannelMonetizationStatistics( return { // Graphs topHoursGraph: stats.topHoursGraph ? buildGraph(stats.topHoursGraph) : undefined, - revenueGraph: buildGraph(stats.revenueGraph, undefined, true, stats.usdRate), + revenueGraph: buildGraph(stats.revenueGraph, undefined, { + label: 'USD ≈', multiplier: stats.usdRate, prefix: '$', + }), // Statistics overview balances: buildChannelMonetizationBalances(stats.status), @@ -156,7 +158,9 @@ export function buildStoryPublicForwards( } export function buildGraph( - result: GramJs.TypeStatsGraph, isPercentage?: boolean, isCurrency?: boolean, currencyRate?: number, + result: GramJs.TypeStatsGraph, isPercentage?: boolean, secondaryYAxis?: { + label: string; multiplier: number; prefix?: string; suffix?: string; + }, ): TypeStatisticsGraph { if (result instanceof GramJs.StatsGraphError) { return { @@ -187,15 +191,15 @@ export function buildGraph( hasSecondYAxis, isStacked: data.stacked && !hasSecondYAxis, isPercentage, - isCurrency, - currencyRate, + secondaryYAxis, datasets: y.map((item: any) => { const key = item[0]; + const values = item.slice(1); return { name: data.names[key], color: extractColor(data.colors[key]), - values: item.slice(1), + values: secondaryYAxis ? values.map((v: number) => v / 1e9) : values, }; }), ...calculateMinimapRange(data.subchart.defaultZoom, x.slice(1)), diff --git a/src/api/types/statistics.ts b/src/api/types/statistics.ts index 2fb63992d..57707e08c 100644 --- a/src/api/types/statistics.ts +++ b/src/api/types/statistics.ts @@ -91,8 +91,12 @@ export interface StatisticsGraph { labels: Array; isStacked: boolean; isPercentage?: boolean; - isCurrency?: boolean; - currencyRate?: number; + secondaryYAxis?: { + label: string; + multiplier: number; + prefix?: string; + suffix?: string; + }; hideCaption: boolean; hasSecondYAxis: boolean; minimapRange: { diff --git a/src/lib/lovely-chart/Axes.js b/src/lib/lovely-chart/Axes.js index ba29b3910..75bca5d11 100644 --- a/src/lib/lovely-chart/Axes.js +++ b/src/lib/lovely-chart/Axes.js @@ -1,5 +1,5 @@ import { GUTTER, AXES_FONT, X_AXIS_HEIGHT, X_AXIS_SHIFT_START, PLOT_TOP_PADDING } from './constants.js'; -import { formatCryptoValue, humanize } from './format.js'; +import { humanize } from './format.js'; import { getCssColor } from './skin.js'; import { applyXEdgeOpacity, applyYEdgeOpacity, xScaleLevelToStep, yScaleLevelToStep } from './formulas.js'; import { toPixels } from './Projection.js'; @@ -47,8 +47,25 @@ export function createAxes(context, data, plotSize, colors) { if (data.isPercentage) { _drawYAxisPercents(projection); - } else if (data.isCurrency) { - _drawYAxisCurrency(projection, data); + } else if (data.secondaryYAxis) { + _drawYAxisScaled( + state, + projection, + Math.round(yAxisScaleTo || yAxisScale), + yMinViewportTo !== undefined ? yMinViewportTo : yMinViewport, + yMaxViewportTo !== undefined ? yMaxViewportTo : yMaxViewport, + yAxisScaleFrom ? yAxisScaleProgress : 1, + ); + + _drawSecondaryYAxis( + state, + projection, + Math.round(yAxisScaleTo || yAxisScale), + yMinViewportTo !== undefined ? yMinViewportTo : yMinViewport, + yMaxViewportTo !== undefined ? yMaxViewportTo : yMaxViewport, + yAxisScaleFrom ? yAxisScaleProgress : 1, + data.secondaryYAxis, + ); } else { _drawYAxisScaled( state, @@ -125,10 +142,14 @@ export function createAxes(context, data, plotSize, colors) { ? getCssColor(colors, colorKey, textOpacity) : getCssColor(colors, 'y-axis-text', textOpacity); + const label = isSecondary + ? humanize(value) + : `${data.valuePrefix || ''}${humanize(value)}${data.valueSuffix || ''}`; + if (!isSecondary) { - context.fillText(humanize(value), GUTTER, yPx - GUTTER / 2); + context.fillText(label, GUTTER, yPx - GUTTER / 2); } else { - context.fillText(humanize(value), plotSize.width - GUTTER, yPx - GUTTER / 2); + context.fillText(label, plotSize.width - GUTTER, yPx - GUTTER / 2); } if (isSecondary) { @@ -171,48 +192,24 @@ export function createAxes(context, data, plotSize, colors) { context.stroke(); } - function _drawYAxisCurrency(projection, data) { - const formatValue = data.datasets[0].values.map(value => formatCryptoValue(value)); - - const total = formatValue.reduce((sum, value) => sum + value, 0); - const avg1 = total / formatValue.length; - const avg2 = total / (formatValue.length / 2); - const avg3 = total / (formatValue.length / 3); - - const averageRate1 = avg1 * data.currencyRate; - const averageRate2 = avg2 * data.currencyRate; - const averageRate3 = avg3 * data.currencyRate; - - const totalAvg = [0, avg1, avg2, avg3]; - const totalRate = [0, averageRate1, averageRate2, averageRate3]; - - const [, height] = projection.getSize(); + function _drawSecondaryYAxis(state, projection, scaleLevel, yMin, yMax, opacity = 1, secondaryYAxis) { + const { multiplier, prefix = '', suffix = '' } = secondaryYAxis; + const step = yScaleLevelToStep(scaleLevel); + const firstVisibleValue = Math.ceil(yMin / step) * step; + const lastVisibleValue = Math.floor(yMax / step) * step; context.font = AXES_FONT; - context.textAlign = 'left'; + context.textAlign = 'right'; context.textBaseline = 'bottom'; - context.lineWidth = 1; - context.beginPath(); + for (let value = firstVisibleValue; value <= lastVisibleValue; value += step) { + const [, yPx] = toPixels(projection, 0, value); + const textOpacity = applyXEdgeOpacity(opacity, yPx); + const secondaryValue = value * multiplier; - totalAvg.forEach((value, index) => { - const yPx = height - height * (value / Math.max(...formatValue)) + PLOT_TOP_PADDING; - - context.fillStyle = getCssColor(colors, 'y-axis-text', 1); - - context.fillText(`${value.toFixed(2)} TON`, GUTTER, yPx - GUTTER / 4); - - context.textAlign = 'right'; - context.fillText(`$${totalRate[index].toFixed(2)}`, plotSize.width - GUTTER, yPx - GUTTER / 4); - - context.textAlign = 'left'; - - context.moveTo(GUTTER, yPx); - context.strokeStyle = getCssColor(colors, 'grid-lines', 1); - context.lineTo(plotSize.width - GUTTER, yPx); - }); - - context.stroke(); + context.fillStyle = getCssColor(colors, 'y-axis-text', textOpacity); + context.fillText(`${prefix}${humanize(secondaryValue)}${suffix}`, plotSize.width - GUTTER, yPx - GUTTER / 2); + } } return { drawXAxis, drawYAxis }; diff --git a/src/lib/lovely-chart/Tools.js b/src/lib/lovely-chart/Tools.js index 9adfc3840..a0afef39c 100644 --- a/src/lib/lovely-chart/Tools.js +++ b/src/lib/lovely-chart/Tools.js @@ -1,5 +1,6 @@ import { createElement } from './minifiers.js'; import { captureEvents } from './captureEvents.js'; +import { isColorCloseToWhite } from './skin.js'; export function createTools(container, data, filterCallback) { let _element; @@ -35,7 +36,8 @@ export function createTools(container, data, filterCallback) { const control = createElement('a'); control.href = '#'; control.dataset.key = key; - control.className = `lovely-chart--button lovely-chart--color-${data.colors[key].slice(1)} lovely-chart--state-checked`; + const darkContent = isColorCloseToWhite(data.colors[key]) ? ' lovely-chart--dark-content' : ''; + control.className = `lovely-chart--button lovely-chart--color-${data.colors[key].slice(1)} lovely-chart--state-checked${darkContent}`; control.innerHTML = `${name}`; control.addEventListener('click', (e) => { diff --git a/src/lib/lovely-chart/Tooltip.js b/src/lib/lovely-chart/Tooltip.js index 6a452c040..ddb27453c 100644 --- a/src/lib/lovely-chart/Tooltip.js +++ b/src/lib/lovely-chart/Tooltip.js @@ -1,8 +1,8 @@ import { setupCanvas, clearCanvas } from './canvas.js'; -import { BALLOON_OFFSET, X_AXIS_HEIGHT } from './constants.js'; +import { BALLOON_OFFSET, X_AXIS_HEIGHT, MAX_TOOLTIP_ITEMS } from './constants.js'; import { getPieRadius } from './formulas.js'; -import {formatCryptoValue, formatInteger, getLabelDate, getLabelTime, statsFormatDayHourFull} from './format.js'; -import { getCssColor } from './skin.js'; +import { formatInteger, getLabelDate, getLabelTime, statsFormatDayHourFull } from './format.js'; +import { getCssColor, isColorCloseToBackground } from './skin.js'; import { throttle, throttleWithRaf } from './utils.js'; import { addEventListener, createElement } from './minifiers.js'; import { toPixels } from './Projection.js'; @@ -333,12 +333,14 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus } function _insertNewDataSet(dataSetContainer, { name, key, value }, totalValue) { - const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right lovely-chart--color-${data.colors[key].slice(1)}`; + const colorHex = data.colors[key]; + const colorClass = isColorCloseToBackground(colors, colorHex) ? '' : ` lovely-chart--color-${colorHex.slice(1)}`; + const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right${colorClass}`; const newDataSet = createElement(); newDataSet.className = 'lovely-chart--tooltip-dataset'; newDataSet.setAttribute('data-present', 'true'); newDataSet.setAttribute('data-name', name); - newDataSet.innerHTML = `${name}${formatInteger(value)}`; + newDataSet.innerHTML = `${name}${_formatValue(value)}`; _renderPercentageValue(newDataSet, value, totalValue); const totalText = dataSetContainer.querySelector(`[data-total="true"]`); @@ -352,17 +354,19 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus function _updateDataSet(currentDataSet, { key, value } = {}, totalValue) { currentDataSet.setAttribute('data-present', 'true'); - const valueElement = currentDataSet.querySelector(`.lovely-chart--tooltip-dataset-value.lovely-chart--color-${data.colors[key].slice(1)}:not(.lovely-chart--state-hidden)`); + const valueElement = currentDataSet.querySelector(`.lovely-chart--tooltip-dataset-value`); - if (data.isCurrency) { - valueElement.innerHTML = formatCryptoValue(value); - } else { - valueElement.innerHTML = formatInteger(value); + if (valueElement) { + valueElement.innerHTML = _formatValue(value); } _renderPercentageValue(currentDataSet, value, totalValue); } + function _formatValue(value) { + return `${data.valuePrefix || ''}${formatInteger(value)}${data.valueSuffix || ''}`; + } + function _renderPercentageValue(dataSet, value, totalValue) { if (!data.isPercentage) { return; @@ -402,7 +406,10 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus const totalValue = statistics.reduce((a, x) => a + x.value, 0); const pointerVector = getPointerVector(); - const finalStatistics = data.isPie ? statistics.filter(({ value }, index) => _isPieSectorSelected(statistics, value, totalValue, index, pointerVector)) : statistics; + const filteredStatistics = statistics.filter(({ value }) => value !== 0); + const sortedStatistics = filteredStatistics.sort((a, b) => b.value - a.value); + const limitedStatistics = sortedStatistics.slice(0, MAX_TOOLTIP_ITEMS); + const finalStatistics = data.isPie ? limitedStatistics.filter(({ value }, index) => _isPieSectorSelected(statistics, value, totalValue, index, pointerVector)) : limitedStatistics; finalStatistics.forEach((statItem) => { const currentDataSet = dataSetContainer.querySelector(`[data-name="${statItem.name}"]`); @@ -411,17 +418,22 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus _insertNewDataSet(dataSetContainer, statItem, totalValue); } else { _updateDataSet(currentDataSet, statItem, totalValue); + dataSetContainer.appendChild(currentDataSet); } }); - if ((data.isBars || data.isSteps) && data.isStacked) { - _renderTotal(dataSetContainer, formatInteger(totalValue)); + if ((data.isBars || data.isSteps || data.isAreas) && data.isStacked) { + _renderTotal(dataSetContainer, _formatValue(totalValue)); } - if (data.isCurrency) { - _renderCurrencyRate(dataSetContainer, formatCryptoValue(totalValue)); + if (data.secondaryYAxis) { + _renderSecondaryTotal(dataSetContainer, totalValue); } + // Re-append total rows to keep them at the bottom after sort reordering + Array.from(dataSetContainer.querySelectorAll('[data-total="true"]')) + .forEach((el) => dataSetContainer.appendChild(el)); + Array.from(dataSetContainer.querySelectorAll('[data-present="false"]')) .forEach((dataSet) => { dataSet.remove(); @@ -438,10 +450,10 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right`; if (!totalText) { const newTotalText = createElement(); - newTotalText.className = 'lovely-chart--tooltip-dataset'; + newTotalText.className = 'lovely-chart--tooltip-dataset lovely-chart--tooltip-dataset-total'; newTotalText.setAttribute('data-present', 'true'); newTotalText.setAttribute('data-total', 'true'); - newTotalText.innerHTML = `All${totalValue}`; + newTotalText.innerHTML = `Total${totalValue}`; dataSetContainer.appendChild(newTotalText); } else { totalText.setAttribute('data-present', 'true'); @@ -451,24 +463,25 @@ export function createTooltip(container, data, plotSize, colors, onZoom, onFocus } } - function _renderCurrencyRate(dataSetContainer, totalValue) { + function _renderSecondaryTotal(dataSetContainer, totalValue) { + const { label, multiplier, prefix = '', suffix = '' } = data.secondaryYAxis; const totalText = dataSetContainer.querySelector(`[data-total="true"]`); const className = `lovely-chart--tooltip-dataset-value lovely-chart--position-right`; - const totalUsd = (parseFloat(totalValue) * data.currencyRate).toFixed(2); + const secondaryValue = (totalValue * multiplier).toFixed(2); if (!totalText) { const newTotalText = createElement(); - newTotalText.className = 'lovely-chart--tooltip-dataset'; + newTotalText.className = 'lovely-chart--tooltip-dataset lovely-chart--tooltip-dataset-total'; newTotalText.setAttribute('data-present', 'true'); newTotalText.setAttribute('data-total', 'true'); - newTotalText.innerHTML = `USD ≈$${totalUsd}`; + newTotalText.innerHTML = `${label}${prefix}${secondaryValue}${suffix}`; dataSetContainer.appendChild(newTotalText); } else { totalText.setAttribute('data-present', 'true'); const valueElement = totalText.querySelector(`.lovely-chart--tooltip-dataset-value:not(.lovely-chart--state-hidden)`); - valueElement.innerHTML = `$${totalUsd}`; + valueElement.innerHTML = `${prefix}${secondaryValue}${suffix}`; } } diff --git a/src/lib/lovely-chart/constants.js b/src/lib/lovely-chart/constants.js index f9d98d60b..198ff37df 100644 --- a/src/lib/lovely-chart/constants.js +++ b/src/lib/lovely-chart/constants.js @@ -15,6 +15,7 @@ export const PLOT_BARS_WIDTH_SHIFT = 0.5; export const PIE_MINIMUM_VISIBLE_PERCENT = 0.02; export const BALLOON_OFFSET = 20; +export const MAX_TOOLTIP_ITEMS = 12; export const AXES_FONT = '300 10px Helvetica, Arial, sans-serif'; export const AXES_MAX_COLUMN_WIDTH = 45; diff --git a/src/lib/lovely-chart/data.js b/src/lib/lovely-chart/data.js index abcc04316..8cef5ccd4 100644 --- a/src/lib/lovely-chart/data.js +++ b/src/lib/lovely-chart/data.js @@ -1,8 +1,17 @@ import { getMaxMin } from './utils.js'; import { statsFormatDay, statsFormatDayHour, statsFormatText, statsFormatMin } from './format.js'; +const LABEL_TYPE_TO_FORMATTER = { + 'day': "statsFormat('day')", + 'hour': "statsFormat('hour')", + '5min': "statsFormat('5min')", + 'dayHour': 'statsFormatDayHour', + 'text': undefined, +}; + export function analyzeData(data) { - const { title, labelFormatter, tooltipFormatter, isStacked, isPercentage, isCurrency, currencyRate, hasSecondYAxis, onZoom, minimapRange, hideCaption, zoomOutLabel } = data; + const { title, labelFormatter: labelFormatterRaw, labelType, tooltipFormatter, isStacked, isPercentage, secondaryYAxis, hasSecondYAxis, onZoom, minimapRange, hideCaption, zoomOutLabel, valuePrefix, valueSuffix } = data; + const labelFormatter = labelFormatterRaw || (labelType && LABEL_TYPE_TO_FORMATTER[labelType]); const { datasets, labels } = prepareDatasets(data); const colors = {}; @@ -20,13 +29,8 @@ export function analyzeData(data) { } }); - let effectiveLabelFormatter = labelFormatter; - if (isCurrency) { - effectiveLabelFormatter = 'statsFormat(\'day\')'; - } - let xLabels; - switch (effectiveLabelFormatter) { + switch (labelFormatter) { case 'statsFormatDayHour': xLabels = statsFormatDayHour(labels); break; @@ -50,9 +54,10 @@ export function analyzeData(data) { datasets, isStacked, isPercentage, - isCurrency, - currencyRate, + secondaryYAxis, hasSecondYAxis, + valuePrefix, + valueSuffix, onZoom, isLines: data.type === 'line', isBars: data.type === 'bar', diff --git a/src/lib/lovely-chart/drawDatasets.js b/src/lib/lovely-chart/drawDatasets.js index c9e14847e..ce876c598 100644 --- a/src/lib/lovely-chart/drawDatasets.js +++ b/src/lib/lovely-chart/drawDatasets.js @@ -27,18 +27,14 @@ export function drawDatasets( let datasetProjection = hasOwnYAxis ? secondaryProjection : projection; if (datasetType === 'area') { - const { yMin, yMax } = projection.getParams(); - const yHeight = yMax - yMin; const bottomLine = [ { labelIndex: range.from, stackValue: 0 }, { labelIndex: range.to, stackValue: 0 }, ]; - const topLine = [ - { labelIndex: range.to, stackValue: yHeight }, - { labelIndex: range.from, stackValue: yHeight }, - ]; + const lowerBoundary = points[i - 1] || bottomLine; + const upperBoundary = points[i].slice().reverse(); - datasetPoints = mergeArrays([points[i - 1] || bottomLine, topLine]); + datasetPoints = mergeArrays([lowerBoundary, upperBoundary]); } if (datasetType === 'pie') { diff --git a/src/lib/lovely-chart/format.js b/src/lib/lovely-chart/format.js index 31dfb6bd1..1956802ec 100644 --- a/src/lib/lovely-chart/format.js +++ b/src/lib/lovely-chart/format.js @@ -59,11 +59,20 @@ function keepThreeDigits(value, decimals) { } export function formatInteger(n) { - return String(n).replace(/\d(?=(\d{3})+$)/g, '$& '); + if (!Number.isInteger(n)) { + const abs = Math.abs(n); + const decimals = (abs > 0 && abs < 1) + ? Math.max(2, -Math.floor(Math.log10(abs)) + 1) + : 2; + const [intPart, decPart] = n.toFixed(decimals).split('.'); + const trimmed = decPart.replace(/0+$/, ''); + return trimmed ? addThousandSeparators(intPart) + '.' + trimmed : addThousandSeparators(intPart); + } + return addThousandSeparators(String(n)); } -export function formatCryptoValue(n) { - return Number(n / 10 ** 9); +function addThousandSeparators(s) { + return s.replace(/\d(?=(\d{3})+$)/g, '$& '); } export function getFullLabelDate(label, { isShort = false } = {}) { diff --git a/src/lib/lovely-chart/skin.js b/src/lib/lovely-chart/skin.js index a8de5bd5d..7b7261d00 100644 --- a/src/lib/lovely-chart/skin.js +++ b/src/lib/lovely-chart/skin.js @@ -59,7 +59,9 @@ export function createColors(datasetColors) { addCssRule(styleSheet, `.lovely-chart--tooltip-dataset-value${baseClass}-${datasetColors[key].slice(1)}`, `color: ${datasetColors[key]}`); addCssRule(styleSheet, `.lovely-chart--button${baseClass}-${datasetColors[key].slice(1)}`, `border-color: ${datasetColors[key]}; color: ${datasetColors[key]}`); - addCssRule(styleSheet, `.lovely-chart--button.lovely-chart--state-checked${baseClass}-${datasetColors[key].slice(1)}`, `background-color: ${datasetColors[key]}`); + + const checkedBtnSelector = `.lovely-chart--button.lovely-chart--state-checked${baseClass}-${datasetColors[key].slice(1)}`; + addCssRule(styleSheet, checkedBtnSelector, `background-color: ${datasetColors[key]}`); }); }); @@ -85,6 +87,20 @@ function buildCssColor([r, g, b, a = 1], opacity = 1) { return `rgba(${r}, ${g}, ${b}, ${a * opacity})`; } +export function isColorCloseToBackground(colors, hex) { + const bg = colors[skin]['tooltip-background']; + const fg = hexToChannels(hex); + return colorDistance(bg, fg) < 70; +} + +export function isColorCloseToWhite(hex) { + return colorDistance(hexToChannels(hex), [255, 255, 255]) < 70; +} + +function colorDistance([r1, g1, b1], [r2, g2, b2]) { + return Math.sqrt((r1 - r2) ** 2 + (g1 - g2) ** 2 + (b1 - b2) ** 2); +} + function addCssRule(sheet, selector, rule) { sheet.insertRule(`${selector} { ${rule} }`, sheet.cssRules.length); } diff --git a/src/lib/lovely-chart/styles/_buttons.scss b/src/lib/lovely-chart/styles/_buttons.scss index ececd2105..3abae9d46 100644 --- a/src/lib/lovely-chart/styles/_buttons.scss +++ b/src/lib/lovely-chart/styles/_buttons.scss @@ -15,6 +15,11 @@ text-decoration: none; background-color: transparent; + transition: opacity 150ms ease; + + &:hover { + opacity: 0.85; + } &.lovely-chart--state-checked { background-color: var(--text-color); @@ -28,6 +33,14 @@ transform: translateX(6px); color: #ffffff; } + + &.lovely-chart--dark-content .lovely-chart--button-label { + color: #222222; + } + + &.lovely-chart--dark-content .lovely-chart--button-check::after { + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -256 1792 1792' version='1.1'%0A%3E%3Cg transform='matrix(1,0,0,-1,7.5932203,1217.0847)' id='g3003'%3E%3Cpath d='m 1671,970 q 0,-40 -28,-68 L 919,178 783,42 Q 755,14 715,14 675,14 647,42 L 511,178 149,540 q -28,28 -28,68 0,40 28,68 l 136,136 q 28,28 68,28 40,0 68,-28 l 294,-295 656,657 q 28,28 68,28 40,0 68,-28 l 136,-136 q 28,-28 28,-68 z' style='fill:%23222222'/%3E%3C/g%3E%3C/svg%3E"); + } } &.lovely-chart--state-shake { @@ -64,6 +77,7 @@ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 -256 1792 1792' version='1.1'%0A%3E%3Cg transform='matrix(1,0,0,-1,7.5932203,1217.0847)' id='g3003'%3E%3Cpath d='m 1671,970 q 0,-40 -28,-68 L 919,178 783,42 Q 755,14 715,14 675,14 647,42 L 511,178 149,540 q -28,28 -28,68 0,40 28,68 l 136,136 q 28,28 68,28 40,0 68,-28 l 294,-295 656,657 q 28,28 68,28 40,0 68,-28 l 136,-136 q 28,-28 28,-68 z' style='fill:white'/%3E%3C/g%3E%3C/svg%3E"); background-size: 100%; } + } .lovely-chart--button-label { diff --git a/src/lib/lovely-chart/styles/_common.scss b/src/lib/lovely-chart/styles/_common.scss index 294d6ae11..4dc40b352 100644 --- a/src/lib/lovely-chart/styles/_common.scss +++ b/src/lib/lovely-chart/styles/_common.scss @@ -1,7 +1,27 @@ .lovely-chart--container { + --background-color: #ffffff; + --text-color: #222222; + --minimap-mask: #{rgba(#E2EEF9, 0.6)}; + --minimap-slider: #C0D1E1; + --grid-lines: #{rgba(#182D3B, 0.1)}; + --zoom-out-text: #108BE3; + --tooltip-background: #ffffff; + --tooltip-arrow: #D2D5D7; + -webkit-user-select: none; user-select: none; + html.theme-dark & { + --background-color: #242F3E; + --text-color: #ffffff; + --minimap-mask: #{rgba(#304259, 0.6)}; + --minimap-slider: #56626D; + --grid-lines: #{rgba(#FFFFFF, 0.1)}; + --zoom-out-text: #48AAF0; + --tooltip-background: #1c2533; + --tooltip-arrow: #D2D5D7; + } + position: relative; overflow: hidden; diff --git a/src/lib/lovely-chart/styles/_header.scss b/src/lib/lovely-chart/styles/_header.scss index 8abc97f5b..338a6fa0c 100644 --- a/src/lib/lovely-chart/styles/_header.scss +++ b/src/lib/lovely-chart/styles/_header.scss @@ -16,13 +16,7 @@ &-title { float: left; - margin: 0 1rem; font-size: 16px; - text-transform: lowercase; - - &:first-letter { - text-transform: uppercase; - } } &-caption { diff --git a/src/lib/lovely-chart/styles/_tooltip.scss b/src/lib/lovely-chart/styles/_tooltip.scss index 08c842f6d..309e279e5 100644 --- a/src/lib/lovely-chart/styles/_tooltip.scss +++ b/src/lib/lovely-chart/styles/_tooltip.scss @@ -59,7 +59,7 @@ .lovely-chart--tooltip-title { position: relative; - padding-bottom: 5px; + padding-bottom: 6px; font-size: 12px; font-weight: bold; @@ -89,7 +89,12 @@ .lovely-chart--tooltip-dataset-value { float: right; - margin-left: 5px; + margin-left: 12px; + font-weight: bold; + } + + &.lovely-chart--tooltip-dataset-total { + margin-top: 6px; font-weight: bold; } } diff --git a/src/lib/lovely-chart/styles/_variables.scss b/src/lib/lovely-chart/styles/_variables.scss deleted file mode 100644 index 093fda324..000000000 --- a/src/lib/lovely-chart/styles/_variables.scss +++ /dev/null @@ -1,21 +0,0 @@ -.lovely-chart--container { - --background-color: #ffffff; - --text-color: #222222; - --minimap-mask: #{rgba(#E2EEF9, 0.6)}; - --minimap-slider: #C0D1E1; - --grid-lines: #{rgba(#182D3B, 0.1)}; - --zoom-out-text: #108BE3; - --tooltip-background: #ffffff; - --tooltip-arrow: #D2D5D7; -} - -html.theme-dark .lovely-chart--container { - --background-color: #242F3E; - --text-color: #ffffff; - --minimap-mask: #{rgba(#304259, 0.6)}; - --minimap-slider: #56626D; - --grid-lines: #{rgba(#FFFFFF, 0.1)}; - --zoom-out-text: #48AAF0; - --tooltip-background: #1c2533; - --tooltip-arrow: #D2D5D7; -} diff --git a/src/lib/lovely-chart/styles/index.scss b/src/lib/lovely-chart/styles/index.scss index 4ef5bcb25..868467691 100644 --- a/src/lib/lovely-chart/styles/index.scss +++ b/src/lib/lovely-chart/styles/index.scss @@ -1,4 +1,3 @@ -@use 'variables'; @use 'animations'; @use 'common'; @use 'header';