feat: Add in fulcrum feature and get it working, but now it's time to really start to make this page look good now that all the pieces are there.

This commit is contained in:
Mr. Dummy Tester 2020-12-26 17:32:50 -06:00
parent bda95affc2
commit 3b3ad80dd0
4 changed files with 269 additions and 0 deletions

35
package-lock.json generated
View File

@ -4311,6 +4311,32 @@
"resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
},
"chart.js": {
"version": "2.9.4",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz",
"integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==",
"requires": {
"chartjs-color": "^2.1.0",
"moment": "^2.10.2"
}
},
"chartjs-color": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
"integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
"requires": {
"chartjs-color-string": "^0.6.0",
"color-convert": "^1.9.3"
}
},
"chartjs-color-string": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
"integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"requires": {
"color-name": "^1.0.0"
}
},
"cheerio": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
@ -12566,6 +12592,15 @@
"whatwg-fetch": "^3.0.0"
}
},
"react-chartjs-2": {
"version": "2.11.1",
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-2.11.1.tgz",
"integrity": "sha512-G7cNq/n2Bkh/v4vcI+GKx7Q1xwZexKYhOSj2HmrFXlvNeaURWXun6KlOUpEQwi1cv9Tgs4H3kGywDWMrX2kxfA==",
"requires": {
"lodash": "^4.17.19",
"prop-types": "^15.7.2"
}
},
"react-copy-to-clipboard": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.2.tgz",

View File

@ -19,12 +19,14 @@
"bn.js": "^5.1.3",
"bs58": "^4.0.1",
"buffer-layout": "^1.2.0",
"chart.js": "^2.9.4",
"craco-less": "^1.17.0",
"echarts": "^4.9.0",
"eventemitter3": "^4.0.7",
"identicon.js": "^2.3.3",
"jazzicon": "^1.5.0",
"react": "^16.13.1",
"react-chartjs-2": "^2.11.1",
"react-dom": "^16.13.1",
"react-github-btn": "^1.2.0",
"react-intl": "^5.10.2",

View File

@ -3,6 +3,7 @@ import React, { useState } from 'react';
import { Position } from './interfaces';
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
import tokens from '../../../config/tokens.json';
import GainsChart from './GainsChart';
export function Breakdown({ item }: { item: Position }) {
let myPart = parseFloat(item.asset?.value || '0') / item.leverage;
@ -89,6 +90,7 @@ export function Breakdown({ item }: { item: Position }) {
/>
</Card>
</div>
<GainsChart item={item} priceChange={myGain} />
{progressBar}
</div>
);

View File

@ -0,0 +1,230 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Line } from 'react-chartjs-2';
import { Position } from './interfaces';
// Special thanks to
// https://github.com/bZxNetwork/fulcrum_ui/blob/development/packages/fulcrum-website/assets/js/trading.js
// For the basis of this code - I copied it directly from there and then modified it for our needs.
// You guys are real heroes - that is beautifully done.
const baseData = [
{ x: 0, y: 65 },
{ x: 1, y: 80 },
{ x: 2, y: 60 },
{ x: 3, y: 30 },
{ x: 4, y: 20 },
{ x: 5, y: 35 },
{ x: 6, y: 25 },
{ x: 7, y: 40 },
{ x: 8, y: 36 },
{ x: 9, y: 34 },
{ x: 10, y: 50 },
{ x: 11, y: 33 },
{ x: 12, y: 37 },
{ x: 13, y: 45 },
{ x: 14, y: 35 },
{ x: 15, y: 37 },
{ x: 16, y: 50 },
{ x: 17, y: 43 },
{ x: 18, y: 50 },
{ x: 19, y: 45 },
{ x: 20, y: 55 },
{ x: 21, y: 50 },
{ x: 22, y: 45 },
{ x: 23, y: 50 },
{ x: 24, y: 45 },
{ x: 25, y: 40 },
{ x: 26, y: 35 },
{ x: 27, y: 40 },
{ x: 28, y: 37 },
{ x: 29, y: 45 },
{ x: 30, y: 50 },
{ x: 31, y: 60 },
{ x: 32, y: 55 },
{ x: 33, y: 50 },
{ x: 34, y: 53 },
{ x: 35, y: 55 },
{ x: 36, y: 50 },
{ x: 37, y: 45 },
{ x: 38, y: 40 },
{ x: 39, y: 45 },
{ x: 40, y: 50 },
{ x: 41, y: 55 },
{ x: 42, y: 65 },
{ x: 43, y: 62 },
{ x: 44, y: 54 },
{ x: 45, y: 65 },
{ x: 46, y: 48 },
{ x: 47, y: 55 },
{ x: 48, y: 60 },
{ x: 49, y: 63 },
{ x: 50, y: 65 },
];
function getChartData({ item, priceChange }: { item: Position; priceChange: number }) {
//the only way to create an immutable copy of array with objects inside.
const baseDashed = JSON.parse(JSON.stringify(baseData.slice(Math.floor(baseData.length) / 2)));
const baseSolid = JSON.parse(JSON.stringify(baseData.slice(0, Math.floor(baseData.length) / 2 + 1)));
const leverage = item.leverage;
baseDashed.forEach((item: { y: number; x: number }, index: number) => {
if (index !== 0) item.y += (item.y * priceChange) / 100;
});
var leverageData = baseDashed.map((item: { x: number; y: number }, index: number) => {
if (index === 0) {
return { x: item.x, y: item.y };
}
const gain = (priceChange * leverage) / 100;
return { x: item.x, y: item.y * (1 + gain) };
});
return {
datasets: [
{
backgroundColor: 'transparent',
borderColor: 'rgb(39, 107, 251)',
borderWidth: 4,
radius: 0,
data: baseSolid,
},
{
backgroundColor: 'transparent',
borderColor: priceChange >= 0 ? 'rgb(51, 223, 204)' : 'rgb(255,79,79)',
borderWidth: 4,
radius: 0,
data: leverageData,
borderDash: [15, 3],
label: 'LEVERAGE',
},
{
backgroundColor: 'transparent',
borderColor: 'rgb(86, 169, 255)',
borderWidth: 2,
radius: 0,
data: baseDashed,
borderDash: [8, 4],
label: 'HOLD',
},
],
};
}
function updateChartData({
item,
priceChange,
chartRef,
}: {
item: Position;
priceChange: number;
chartRef: React.RefObject<any>;
}) {
const data = getChartData({ item, priceChange });
chartRef.current.chartInstance.data = data;
chartRef.current.chartInstance.canvas.parentNode.style.width = '100%';
chartRef.current.chartInstance.canvas.parentNode.style.height = 'auto';
chartRef.current.chartInstance.update();
}
function drawLabels(t: any, ctx: any, leverage: number, priceChange: number) {
ctx.save();
ctx.font = 'normal normal bold 15px /1.5 Muli';
ctx.textBaseline = 'bottom';
const chartInstance = t.chart;
const datasets = chartInstance.config.data.datasets;
datasets.forEach(function (ds: { label: any; borderColor: any }, index: number) {
const label = ds.label;
ctx.fillStyle = ds.borderColor;
const meta = chartInstance.controller.getDatasetMeta(index);
const len = meta.data.length - 1;
const pointPostition = Math.floor(len / 2) - Math.floor(0.2 * len);
const x = meta.data[pointPostition]._model.x;
const xOffset = x;
const y = meta.data[pointPostition]._model.y;
let yOffset;
if (label === 'HOLD') {
yOffset = leverage * priceChange > 0 ? y * 1.2 : y * 0.8;
} else {
yOffset = leverage * priceChange > 0 ? y * 0.8 : y * 1.2;
}
if (yOffset > chartInstance.canvas.parentNode.offsetHeight) {
// yOffset = 295;
chartInstance.canvas.parentNode.style.height = `${yOffset * 1.3}px`;
}
if (yOffset < 0) yOffset = 5;
if (label) ctx.fillText(label, xOffset, yOffset);
});
ctx.restore();
}
export default function GainsChart({ item, priceChange }: { item: Position; priceChange: number }) {
const chartRef = useRef<any>();
useEffect(() => {
if (chartRef.current.chartInstance) updateChartData({ item, priceChange, chartRef });
}, [priceChange, item.leverage]);
return useMemo(
() => (
<Line
ref={chartRef}
data={(canvas: any) => {
const originalController = chartRef.current?.chartInstance?.controllers?.line;
if (originalController)
chartRef.current.chartInstance.controllers.line = chartRef.current.chartInstance.controllers.line.extend({
draw: function () {
originalController.prototype.draw.call(this, arguments);
drawLabels(this, canvas.getContext('2d'), item.leverage, priceChange);
},
});
return getChartData({ item, priceChange });
}}
options={{
responsive: true,
maintainAspectRatio: true,
scaleShowLabels: false,
layout: {
padding: {
top: 30,
bottom: 80,
},
},
labels: {
render: 'title',
fontColor: ['green', 'white', 'red'],
precision: 2,
},
animation: {
easing: 'easeOutExpo',
duration: 500,
},
scales: {
xAxes: [
{
display: false,
gridLines: {
display: false,
},
type: 'linear',
position: 'bottom',
},
],
yAxes: [
{
display: false,
gridLines: {
display: false,
},
},
],
},
legend: {
display: false,
},
}}
/>
),
[]
);
}