From 6f0406125d9d656a4a9826b616f28ffda894ec8e Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 23 Oct 2018 14:40:27 -0230 Subject: Clean up gas chart code. --- .../gas-price-chart/gas-price-chart.utils.js | 307 +++++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js (limited to 'ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js') diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js new file mode 100644 index 000000000..43bbfd9ab --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -0,0 +1,307 @@ +import * as d3 from 'd3' +import c3 from 'c3' + +export function getCoordinateData (selector) { + return d3.select(selector).node().getBoundingClientRect() +} + +export function generateDataUIObj (x, index, value) { + return { + x, + value, + index, + id: 'data1', + name: 'data1', + } +} + +export function handleChartUpdate ({ chart, gasPrices, newPrice, cssId }) { + const { + closestLowerValueIndex, + closestLowerValue, + closestHigherValueIndex, + closestHigherValue, + } = getAdjacentGasPrices({ gasPrices, priceToPosition: newPrice }) + + if (closestLowerValue && closestHigherValue) { + setSelectedCircle({ + chart, + newPrice, + closestLowerValueIndex, + closestLowerValue, + closestHigherValueIndex, + closestHigherValue, + }) + } else { + hideDataUI(chart, cssId) + } +} + +export function getAdjacentGasPrices({ gasPrices, priceToPosition }) { + const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition) + const closestHigherValueIndex = gasPrices.findIndex((e, i, a) => e > priceToPosition) + return { + closestLowerValueIndex, + closestHigherValueIndex, + closestHigherValue: gasPrices[closestHigherValueIndex], + closestLowerValue: gasPrices[closestLowerValueIndex], + } +} + +export function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { + const slope = (higherY - lowerY) / (higherX - lowerX) + const newTimeEstimate = -1 * (slope * (higherX - xForExtrapolation) - higherY) + + return newTimeEstimate +} + + +export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) { + const chartMouseXPos = xMousePos - chartXStart + const posPercentile = chartMouseXPos / chartWidth + + const currentPosValue = (gasPrices[gasPrices.length - 1] - gasPrices[0]) * posPercentile + gasPrices[0] + + const { + closestLowerValueIndex, + closestLowerValue, + closestHigherValueIndex, + closestHigherValue, + } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentPosValue }) + + return !closestHigherValue || !closestLowerValue + ? { + currentPosValue: null, + newTimeEstimate: null, + } + : { + currentPosValue, + newTimeEstimate: extrapolateY ({ + higherY: estimatedTimes[closestHigherValueIndex], + lowerY: estimatedTimes[closestLowerValueIndex], + higherX: closestHigherValue, + lowerX: closestLowerValue, + xForExtrapolation: currentPosValue, + }), + } +} + +export function hideDataUI (chart, dataNodeId) { + const overLayedCircle = d3.select(dataNodeId) + if (!overLayedCircle.empty()) { + overLayedCircle.remove() + } + d3.select('.c3-tooltip-container').style('display', 'none !important') + chart.internal.hideXGridFocus() +} + +export function setTickPosition (axis, n, newPosition, secondNewPosition) { + const positionToShift = axis === 'y' ? 'x' : 'y' + const secondPositionToShift = axis === 'y' ? 'y' : 'x' + d3.select('#chart') + .select(`.c3-axis-${axis}`) + .selectAll('.tick') + .filter((d, i) => i === n) + .select('text') + .attr(positionToShift, 0) + .select('tspan') + .attr(positionToShift, newPosition) + .attr(secondPositionToShift, secondNewPosition || 0) + .style('visibility', 'visible') +} + +export function appendOrUpdateCircle ({ data, itemIndex, cx, cy, cssId, appendOnly }) { + const circle = this.main + .select('.' + 'c3-selected-circles' + this.getTargetSelectorSuffix(data.id)) + .selectAll('.' + 'c3-selected-circle' + '-' + itemIndex) + + if (appendOnly || circle.empty()) { + circle.data([data]) + .enter().append('circle') + .attr('class', () => this.generateClass('c3-selected-circle', itemIndex)) + .attr('id', cssId) + .attr('cx', cx) + .attr('cy', cy) + .attr('stroke', () => this.color(data)) + .attr('r', 6) + } else { + circle.data([data]) + .attr('cx', cx) + .attr('cy', cy) + } +} + +export function setSelectedCircle ({ + chart, + newPrice, + closestLowerValueIndex, + closestLowerValue, + closestHigherValueIndex, + closestHigherValue, +}) { + const numberOfValues = chart.internal.data.xs.data1.length + const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) + const { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + + const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) + const newTimeEstimate = extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) + + chart.internal.selectPoint( + generateDataUIObj(currentX, numberOfValues, newTimeEstimate), + numberOfValues + ) +} + + +export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimatedTimesMax) { + const chart = c3.generate({ + size: { + height: 165, + }, + transition: { + duration: 0, + }, + padding: {left: 20, right: 15, top: 6, bottom: 10}, + data: { + x: 'x', + columns: [ + ['x', ...gasPrices], + ['data1', ...estimatedTimes], + ], + types: { + data1: 'area', + }, + selection: { + enabled: false, + }, + }, + color: { + data1: '#259de5', + }, + axis: { + x: { + min: gasPrices[0], + max: gasPricesMax, + tick: { + values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], + outer: false, + format: function (val) { return val + ' GWEI' }, + }, + padding: {left: gasPricesMax / 50, right: gasPricesMax / 50}, + label: { + text: 'Gas Price ($)', + position: 'outer-center', + }, + }, + y: { + padding: {top: 7, bottom: 7}, + tick: { + values: [Math.floor(estimatedTimesMax * 0.05), Math.ceil(estimatedTimesMax * 0.97)], + outer: false, + }, + label: { + text: 'Confirmation time (sec)', + position: 'outer-middle', + }, + min: 0, + }, + }, + legend: { + show: false, + }, + grid: { + x: {}, + lines: { + front: false, + }, + }, + point: { + focus: { + expand: { + enabled: false, + r: 3.5, + }, + }, + }, + tooltip: { + format: { + title: (v) => v.toPrecision(4), + }, + contents: function (d) { + const titleFormat = this.config.tooltip_format_title + let text + d.forEach(el => { + if (el && (el.value || el.value === 0) && !text) { + text = "" + "' + } + }) + return text + '
" + titleFormat(el.x) + '
' + "
" + }, + position: function (data) { + if (d3.select('#overlayed-circle').empty()) { + return { top: -100, left: -100 } + } + + const { x: circleX, y: circleY, width: circleWidth } = getCoordinateData('#overlayed-circle') + const { x: chartXStart, y: chartYStart } = getCoordinateData('.c3-chart') + + // TODO: Confirm the below constants work with all data sets and screen sizes + const flipTooltip = circleY - circleWidth < chartYStart + 5 + + d3 + .select('.tooltip-arrow') + .style('margin-top', flipTooltip ? '-16px' : '4px') + + return { + top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0), + left: circleX - chartXStart + circleWidth - (gasPricesMax / 50), + } + }, + show: true, + }, + }) + + chart.internal.selectPoint = function (data, itemIndex = (data.index || 0)) { + const { x: chartXStart, y: chartYStart } = getCoordinateData('.c3-areas-data1') + + d3.select('#set-circle').remove() + + appendOrUpdateCircle.bind(this)({ + data, + itemIndex, + cx: () => data.x - chartXStart + 11, + cy: () => data.value - chartYStart + 10, + cssId: 'set-circle', + appendOnly: true, + }) + } + + chart.internal.overlayPoint = function (data, itemIndex) { + appendOrUpdateCircle.bind(this)({ + data, + itemIndex, + cx: this.circleX.bind(this), + cy: this.circleY.bind(this), + cssId: 'overlayed-circle', + }) + } + + chart.internal.showTooltip = function (selectedData, element) { + const dataToShow = selectedData.filter((d) => d && (d.value || d.value === 0)) + + if (dataToShow.length) { + this.tooltip.html( + this.config.tooltip_contents.call(this, selectedData, this.axis.getXAxisTickFormat(), this.getYFormat(), this.color) + ).style('display', 'flex') + + // Get tooltip dimensions + const tWidth = this.tooltip.property('offsetWidth') + const tHeight = this.tooltip.property('offsetHeight') + const position = this.config.tooltip_position.call(this, dataToShow, tWidth, tHeight, element) + // Set tooltip + this.tooltip.style('top', position.top + 'px').style('left', position.left + 'px') + } + } + + return chart +} -- cgit From d0619b024fb092182e77e16c6742e157c89b2dc9 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 23 Oct 2018 20:06:36 -0230 Subject: Update tests, plus some lint fixes, for gas-price-chart --- .../gas-price-chart/gas-price-chart.utils.js | 29 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js') diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index 43bbfd9ab..ffd8056b0 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -1,6 +1,27 @@ import * as d3 from 'd3' import c3 from 'c3' +export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) { + const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ + xMousePos, + chartXStart, + chartWidth, + gasPrices, + estimatedTimes, + }) + + if (currentPosValue === null && newTimeEstimate === null) { + hideDataUI(chart, '#overlayed-circle') + } + + const indexOfNewCircle = estimatedTimes.length + 1 + const dataUIObj = generateDataUIObj(currentPosValue, indexOfNewCircle, newTimeEstimate) + + chart.internal.overlayPoint(dataUIObj, indexOfNewCircle) + chart.internal.showTooltip([dataUIObj], d3.select('.c3-areas-data1')._groups[0]) + chart.internal.showXGridFocus([dataUIObj]) +} + export function getCoordinateData (selector) { return d3.select(selector).node().getBoundingClientRect() } @@ -37,7 +58,7 @@ export function handleChartUpdate ({ chart, gasPrices, newPrice, cssId }) { } } -export function getAdjacentGasPrices({ gasPrices, priceToPosition }) { +export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) { const closestLowerValueIndex = gasPrices.findIndex((e, i, a) => e <= priceToPosition && a[i + 1] >= priceToPosition) const closestHigherValueIndex = gasPrices.findIndex((e, i, a) => e > priceToPosition) return { @@ -69,14 +90,14 @@ export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, ga closestHigherValue, } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentPosValue }) - return !closestHigherValue || !closestLowerValue + return !closestHigherValue || !closestLowerValue ? { currentPosValue: null, newTimeEstimate: null, } : { currentPosValue, - newTimeEstimate: extrapolateY ({ + newTimeEstimate: extrapolateY({ higherY: estimatedTimes[closestHigherValueIndex], lowerY: estimatedTimes[closestLowerValueIndex], higherX: closestHigherValue, @@ -144,7 +165,7 @@ export function setSelectedCircle ({ const { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) - const newTimeEstimate = extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) + const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) chart.internal.selectPoint( generateDataUIObj(currentX, numberOfValues, newTimeEstimate), -- cgit From 3ced3c9b2ab75038163f82eb77fbf97ea78d2342 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 24 Oct 2018 22:23:12 -0230 Subject: Clean up for mmui-i11-custom-gas-price-chart branch --- .../gas-price-chart/gas-price-chart.utils.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js') diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index ffd8056b0..67508703f 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -133,8 +133,8 @@ export function setTickPosition (axis, n, newPosition, secondNewPosition) { export function appendOrUpdateCircle ({ data, itemIndex, cx, cy, cssId, appendOnly }) { const circle = this.main - .select('.' + 'c3-selected-circles' + this.getTargetSelectorSuffix(data.id)) - .selectAll('.' + 'c3-selected-circle' + '-' + itemIndex) + .select('.c3-selected-circles' + this.getTargetSelectorSuffix(data.id)) + .selectAll(`.c3-selected-circle-${itemIndex}`) if (appendOnly || circle.empty()) { circle.data([data]) @@ -175,6 +175,7 @@ export function setSelectedCircle ({ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimatedTimesMax) { + const gasPricesMaxPadded = gasPricesMax + 1 const chart = c3.generate({ size: { height: 165, @@ -202,13 +203,13 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate axis: { x: { min: gasPrices[0], - max: gasPricesMax, + max: gasPricesMaxPadded, tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], + values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMaxPadded)], outer: false, format: function (val) { return val + ' GWEI' }, }, - padding: {left: gasPricesMax / 50, right: gasPricesMax / 50}, + padding: {left: gasPricesMaxPadded / 50, right: gasPricesMaxPadded / 50}, label: { text: 'Gas Price ($)', position: 'outer-center', @@ -275,7 +276,7 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate return { top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0), - left: circleX - chartXStart + circleWidth - (gasPricesMax / 50), + left: circleX - chartXStart + circleWidth - (gasPricesMaxPadded / 50), } }, show: true, -- cgit From f8ffdaedc9a8fac631deafbc1d377430c980af94 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 14:06:35 -0330 Subject: Modify results of API data to better fit gas chart: remove outliers, pad data --- .../gas-price-chart/gas-price-chart.utils.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js') diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index 67508703f..0b9dfbd11 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -12,6 +12,7 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices if (currentPosValue === null && newTimeEstimate === null) { hideDataUI(chart, '#overlayed-circle') + return } const indexOfNewCircle = estimatedTimes.length + 1 @@ -162,7 +163,13 @@ export function setSelectedCircle ({ }) { const numberOfValues = chart.internal.data.xs.data1.length const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) - const { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + + if (lowerX === higherX) { + const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`) + higherY = higherYAdjusted + higherX = higherXAdjusted + } const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) @@ -203,13 +210,13 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate axis: { x: { min: gasPrices[0], - max: gasPricesMaxPadded, + max: gasPricesMax, tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMaxPadded)], + values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], outer: false, format: function (val) { return val + ' GWEI' }, }, - padding: {left: gasPricesMaxPadded / 50, right: gasPricesMaxPadded / 50}, + padding: {left: gasPricesMax / 50, right: gasPricesMax / 50}, label: { text: 'Gas Price ($)', position: 'outer-center', -- cgit From d8e41a6aa5a4c64538063c6dde7afdf77b0e5793 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 27 Nov 2018 14:00:41 -0330 Subject: Final gas customization fixes --- .../gas-price-chart/gas-price-chart.utils.js | 54 ++++++++++++++-------- 1 file changed, 36 insertions(+), 18 deletions(-) (limited to 'ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js') diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index 0b9dfbd11..f19dafcc1 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -1,5 +1,11 @@ import * as d3 from 'd3' import c3 from 'c3' +import BigNumber from 'bignumber.js' + +const newBigSigDig = n => (new BigNumber(n.toPrecision(15))) +const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b)) +const bigNumMinus = (a = 0, b = 0) => createOp(a, b, 'minus') +const bigNumDiv = (a = 0, b = 1) => createOp(a, b, 'div') export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) { const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ @@ -24,7 +30,8 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices } export function getCoordinateData (selector) { - return d3.select(selector).node().getBoundingClientRect() + const node = d3.select(selector).node() + return node ? node.getBoundingClientRect() : {} } export function generateDataUIObj (x, index, value) { @@ -70,19 +77,22 @@ export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) { } } -export function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { - const slope = (higherY - lowerY) / (higherX - lowerX) - const newTimeEstimate = -1 * (slope * (higherX - xForExtrapolation) - higherY) +export function extrapolateY ({ higherY = 0, lowerY = 0, higherX = 0, lowerX = 0, xForExtrapolation = 0 }) { + const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX)) + const newTimeEstimate = slope.times(bigNumMinus(higherX, xForExtrapolation)).minus(newBigSigDig(higherY)).negated() - return newTimeEstimate + return newTimeEstimate.toNumber() } export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) { - const chartMouseXPos = xMousePos - chartXStart - const posPercentile = chartMouseXPos / chartWidth + const chartMouseXPos = bigNumMinus(xMousePos, chartXStart) + const posPercentile = bigNumDiv(chartMouseXPos, chartWidth) - const currentPosValue = (gasPrices[gasPrices.length - 1] - gasPrices[0]) * posPercentile + gasPrices[0] + const currentPosValue = (bigNumMinus(gasPrices[gasPrices.length - 1], gasPrices[0])) + .times(newBigSigDig(posPercentile)) + .plus(newBigSigDig(gasPrices[0])) + .toNumber() const { closestLowerValueIndex, @@ -162,20 +172,28 @@ export function setSelectedCircle ({ closestHigherValue, }) { const numberOfValues = chart.internal.data.xs.data1.length + const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + let count = closestHigherValueIndex + 1 - if (lowerX === higherX) { - const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`) - higherY = higherYAdjusted - higherX = higherXAdjusted + if (lowerX && higherX) { + while (lowerX === higherX) { + higherX = getCoordinateData(`.c3-circle-${count}`).x + higherY = getCoordinateData(`.c3-circle-${count}`).y + count++ + } } - const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) + const currentX = bigNumMinus(higherX, lowerX) + .times(bigNumMinus(newPrice, closestLowerValue)) + .div(bigNumMinus(closestHigherValue, closestLowerValue)) + .plus(newBigSigDig(lowerX)) + const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) chart.internal.selectPoint( - generateDataUIObj(currentX, numberOfValues, newTimeEstimate), + generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate), numberOfValues ) } @@ -282,8 +300,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate .style('margin-top', flipTooltip ? '-16px' : '4px') return { - top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0), - left: circleX - chartXStart + circleWidth - (gasPricesMaxPadded / 50), + top: bigNumMinus(circleY, chartYStart).minus(19).plus(flipTooltip ? circleWidth + 38 : 0).toNumber(), + left: bigNumMinus(circleX, chartXStart).plus(newBigSigDig(circleWidth)).minus(bigNumDiv(gasPricesMaxPadded, 50)).toNumber(), } }, show: true, @@ -298,8 +316,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate appendOrUpdateCircle.bind(this)({ data, itemIndex, - cx: () => data.x - chartXStart + 11, - cy: () => data.value - chartYStart + 10, + cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(), + cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(), cssId: 'set-circle', appendOnly: true, }) -- cgit