Alter height of items in distribution based on their cluster and cluster position.

This commit is contained in:
Jim Myers 2019-01-21 18:49:33 -05:00
parent 83050b49f0
commit 604baaad0c
4 changed files with 128 additions and 32 deletions

View File

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>flipside.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src="flipside-v1.5.2.js"></script>
<script src="flipside-v1.5.4.js"></script>
<style>
body {
padding: 0;
@ -34,8 +34,10 @@
<div class="wrapper"><div id="widget-2"></div></div>
<script>
const flipside = new Flipside("<YOUR-API-KEY>");
flipside.createFCAS("widget-0", "btc");
const flipside = new Flipside("<YOUR_API_KEY>");
flipside.createFCAS("widget-0", "btc", {
highlights: ["EOS", "ETH", "QTUM", "ZRX", "BTC", "ZEC", "LTC"]
});
flipside.createFCAS("widget-1", "btc", {
logo: false,
mini: true,

View File

@ -1,6 +1,6 @@
{
"name": "flipside-js",
"version": "1.5.3",
"version": "1.5.4",
"description": "FlipsideJS provides a library embeddable widgets that display data from the Flipside Platform API, including FCAS.",
"main": "index.js",
"scripts": {

View File

@ -1,8 +1,11 @@
import { h, Component } from "preact";
import { sortObjectArray } from "../../utils";
import "./styles.scss";
const PLOT_WIDTH = 240;
const PLOT_SCALE = PLOT_WIDTH / 1000;
const DEFAULT_BUCKET_DISTANCE = 35;
const DEFAULT_LINE_DISTANCE = 25;
export default class Plot extends Component {
constructor() {
@ -26,7 +29,10 @@ export default class Plot extends Component {
}
if (data && data.length > 0) {
this.setState({ loading: false, distribution: data });
this.setState({
loading: false,
distribution: data
});
}
return success;
}
@ -59,7 +65,6 @@ export default class Plot extends Component {
_update() {
this.interval = setInterval(() => {
this._getData();
this._getHighlights();
}, 300000);
}
@ -68,17 +73,17 @@ export default class Plot extends Component {
}
async componentDidMount() {
this._getHighlights();
const success = await this._getData();
if (!success) {
this.setState({ loading: false, distribution: [] });
this.setState({
loading: false,
distribution: []
});
}
this._update();
}
componentWillMount() {
this._getHighlights();
}
getHighlights() {
let { symbol, opts } = this.props;
symbol = symbol.toLowerCase();
@ -94,6 +99,85 @@ export default class Plot extends Component {
return highlights;
}
getBuckets() {
if (this.state.highlights.length == 0) {
return [];
}
let { bucketDistance } = this.props.opts;
if (!bucketDistance) {
bucketDistance = DEFAULT_BUCKET_DISTANCE;
}
let buckets = [];
let currentBucketIndex = 0;
let anchorX = 0;
let scoresToBuckets = {};
let highlightLength = this.state.highlights.length;
let sortedHighLights = sortObjectArray(this.state.highlights, "value");
for (let i = 0; i < highlightLength; i++) {
let currentAsset = sortedHighLights[i];
// If first item
if (i === 0) {
buckets[currentBucketIndex] = [];
buckets[currentBucketIndex].push(currentAsset);
scoresToBuckets[currentAsset.value] = currentBucketIndex;
anchorX = currentAsset.value;
continue;
}
const nextAsset =
i !== highlightLength - 1 ? sortedHighLights[i + 1] : null;
// const prevDist = Math.abs(prevAsset.value - currentAsset.value);
const prevDist = Math.abs(anchorX - currentAsset.value);
const nextDist = nextAsset
? Math.abs(nextAsset.value - currentAsset.value)
: 1000000;
// Is closer to previous or next?
if (prevDist < nextDist && prevDist <= bucketDistance) {
buckets[currentBucketIndex].push(currentAsset);
scoresToBuckets[currentAsset.value] = currentBucketIndex;
} else {
currentBucketIndex++;
buckets[currentBucketIndex] = [];
buckets[currentBucketIndex].push(currentAsset);
scoresToBuckets[currentAsset.value] = currentBucketIndex;
anchorX = currentAsset.value;
}
}
return { buckets, scoresToBuckets };
}
getYCoords(asset, buckets, scoresToBuckets) {
let { lineDistance } = this.props.opts;
if (!lineDistance) {
lineDistance = DEFAULT_LINE_DISTANCE;
}
let bucketIndex = scoresToBuckets[asset.value];
let bucket = buckets[bucketIndex];
let index = 0;
let toClose = false;
for (let i = 0; i < bucket.length; i++) {
let ba = bucket[i];
if (ba.symbol == asset.symbol) {
index = i;
if (i === 0) {
break;
}
const prevAsset = bucket[i - 1];
if (prevAsset && Math.abs(prevAsset.value - ba.value) <= lineDistance) {
toClose = true;
}
break;
}
}
return { y: 44 - 10 * index, toClose };
}
render({ opts, metric, symbol }, { loading, distribution }) {
if (loading) return null;
@ -107,7 +191,7 @@ export default class Plot extends Component {
.filter(i => highlightedSymbols.indexOf(i.symbol) > -1)
.filter(i => i.symbol != symbol.toUpperCase());
let lastHighlightX, lastHighlightY;
const { buckets, scoresToBuckets } = this.getBuckets();
return (
<svg class="fs-plot" width="100%" height="104" overflow="visible">
@ -150,31 +234,24 @@ export default class Plot extends Component {
</text>
{highlightedAssets.map(a => {
let yOffset = 0;
const xPos = `${(a.value / 1000) * 100}%`;
if (lastHighlightX && xPos - lastHighlightX < 10) {
yOffset = 10;
}
lastHighlightX = xPos;
let { y, toClose } = this.getYCoords(a, buckets, scoresToBuckets);
return (
<g fill={opts.dark ? "#fff" : "#000"}>
<text
x={xPos}
y={44 - yOffset}
text-anchor="middle"
font-size="10"
>
<text x={xPos} y={y} text-anchor="middle" font-size="10">
{a.symbol}
</text>
<line
x1={xPos}
y1={47 - yOffset}
x2={xPos}
y2="60"
style={`stroke:rgb(${
opts.dark ? "255, 255, 255" : "0,0,0"
}); stroke-width:0.5`}
/>
{toClose === false && (
<line
x1={xPos}
y1={y + 3}
x2={xPos}
y2="60"
style={`stroke:rgb(${
opts.dark ? "255, 255, 255" : "0,0,0"
}); stroke-width:0.5`}
/>
)}
</g>
);
})}

17
src/utils.js Normal file
View File

@ -0,0 +1,17 @@
export const compare = key => {
return (a, b) => {
const valueA = a[key];
const valueB = b[key];
let comparison = 0;
if (valueA > valueB) {
comparison = 1;
} else if (valueA < valueB) {
comparison = -1;
}
return comparison;
};
};
export const sortObjectArray = (array, key) => {
return array.sort(compare(key));
};