Skip to content

Commit

Permalink
Akmal / feat: remove relative indicator if it's blocking current price (
Browse files Browse the repository at this point in the history
#1387)

* feat: remove relative indicator if it's blocking current price

* chore: refactor code

* feat: parse the decimal

* feat: new UI for strike overlap

* feat: interim solution

* feature: updated UI and overlap behaviour for strike and barrier

* fix stylint issues

* fix: stylelint formatting

* fix broken styles in vercel development bundle

* feat: remove overlay from barrier

* fix: overlay style

* feat: trigger vercel

* chore: remove unused styles

* chore: apply review suggestion

* fix: add missing comma

* fix: inherit colors from deriv app for turbos

* feat: move div to a separate component
  • Loading branch information
akmal-deriv authored Nov 21, 2023
1 parent 0c2553b commit add9d41
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 50 deletions.
66 changes: 48 additions & 18 deletions sass/components/_barrier.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
width: 100%;
margin-left: -10px;
position: relative;
border-top-width: 0;
border-top-width: 1px;
border-top-color: $color-blue;
}
.title-wrapper {
$title-height: 24px;
Expand Down Expand Up @@ -74,12 +75,13 @@
}

.drag-price {
display: block;
display: flex;
height: 24px;
top: -11px;
top: -12px;
position: absolute;
right: -1px;
border: 1px solid inherit;
background-color: $color-blue;
justify-content: space-between;

.arrow-icon {
height: 41px;
Expand Down Expand Up @@ -123,26 +125,54 @@
/*hover*/

.price {
display: block;
font-size: 12px;
font-weight: bold;
display: block;
padding: 3px 1px;
line-height: 18px;
overflow: hidden;
overflow: unset;
padding: 3px 1px;
position: relative;
right: 45px;
text-align: center;
}
width: max-content;

.draggable .price {
padding-left: 16px;
&--zero {
color: $color-blue;
@include themify($themes) {
background-color: themed('DefaultBg');
}
}
&-overlay {
background-color: $color-blue;
height: 24px;
opacity: 0.3;
position: relative;
right: -10px;
top: -12px;
}
}

&:after {
font-weight: normal;
content: '';
font-size: 25px;
position: absolute;
left: 1px;
top: 1px;
transform: scaleX(0.8);
.draggable {
&-area-wrapper {
display: flex;
}
.price {
overflow: unset;
position: relative;
right: 55px;
}
.drag-icon {
display: flex;
flex-direction: column;
justify-content: center;
margin-left: 3px;

div {
background-color: $color-white;
height: 1px;
margin: 1px;
width: 8px;
}
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/components/Barrier.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ const Barrier = ({ store, ...props }: TBarrierBaseProps) => {
aboveShadeStore,
belowShadeStore,
betweenShadeStore,
shadeColor = '#39b19d',
color = '#39b19d',
foregroundColor = '#ffffff',
hideBarrierLine,
hideOffscreenBarrier,
hideOffscreenLine,
hideBarrierLine,
hidePriceLines,
lineStyle,
isInitialized,
priceLabelWidth,
isSingleBarrier,
lineStyle,
opacityOnOverlap,
overlappedBarrierWidth,
shadeColor = '#39b19d',
} = store;

if (!isInitialized) return null;
Expand All @@ -41,7 +41,7 @@ const Barrier = ({ store, ...props }: TBarrierBaseProps) => {
>
<PriceLine
store={_high_barrier}
width={priceLabelWidth}
width={overlappedBarrierWidth}
lineStyle={lineStyle}
color={color}
foregroundColor={foregroundColor}
Expand All @@ -55,7 +55,7 @@ const Barrier = ({ store, ...props }: TBarrierBaseProps) => {
<>
<PriceLine
store={_low_barrier}
width={priceLabelWidth}
width={overlappedBarrierWidth}
lineStyle={lineStyle}
color={color}
foregroundColor={foregroundColor}
Expand Down
11 changes: 11 additions & 0 deletions src/components/HamburgerDragIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';

const HamburgerDragIcon = () => (
<div className='drag-icon'>
<div></div>
<div></div>
<div></div>
</div>
);

export default HamburgerDragIcon;
74 changes: 58 additions & 16 deletions src/components/PriceLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import classNames from 'classnames';
import PriceLineStore from 'src/store/PriceLineStore';
import PriceLineArrow from './PriceLineArrow';
import PriceLineTitle from './PriceLineTitle';
import HamburgerDragIcon from './HamburgerDragIcon';

type TPriceLineProps = {
store: PriceLineStore;
lineStyle?: string;
lineStyle?: React.CSSProperties['borderStyle'];
hideOffscreenBarrier?: boolean;
hideOffscreenLine?: boolean;
hideBarrierLine?: boolean;
Expand All @@ -29,18 +30,19 @@ const PriceLine = ({
store,
}: TPriceLineProps) => {
const {
priceDisplay,
visible,
setDragLine,
className,
draggable,
isDragging,
init,
title,
yAxiswidth,
isDragging,
isOverlapping,
isOverlappingWithPriceLine,
offScreen,
offScreenDirection,
isOverlapping,
priceDisplay,
setDragLine,
title,
visible,
yAxiswidth,
} = store;

const showBarrier = React.useMemo(() => !(hideOffscreenBarrier && offScreen), [hideOffscreenBarrier, offScreen]);
Expand All @@ -57,26 +59,66 @@ const PriceLine = ({
if (!showBarrier) return null;

return (
<div className='barrier-area' style={{ top: 0 }} ref={setDragLine} hidden={!visible}>
<div
className={classNames('barrier-area', { 'barrier-area--zero': isOverlappingWithPriceLine })}
style={{ top: 0 }}
ref={setDragLine}
hidden={!visible}
>
<div
className={classNames('chart-line', 'horizontal', className || '', {
draggable,
dragging: isDragging,
})}
style={{
color: foregroundColor,
backgroundImage:
lineStyle && lineStyle !== 'solid' ? '' : `linear-gradient(to left, ${color} 90%, ${color}00`,
}}
>
{showBarrierDragLine && (
<div className='drag-line' style={{ borderTop: `${lineStyle} ${color} 1px` }} />
<div
className={classNames('drag-line', { 'drag-line--zero': isOverlappingWithPriceLine })}
style={{
borderTopColor: color,
borderTopStyle: lineStyle as React.CSSProperties['borderTopStyle'],
width: `calc(100% - ${yAxiswidth}px + ${width}px)`,
}}
/>
)}
<div className='draggable-area' />
<div className='drag-price' style={{ backgroundColor: color, width, opacity }}>
<div className='price'>{priceDisplay}</div>
{offScreen && offScreenDirection && (
<PriceLineArrow offScreenDirection={offScreenDirection} color={color} />
<div className='draggable-area-wrapper'>
<div
className={'drag-price'}
style={{
backgroundColor: color,
width: isOverlappingWithPriceLine ? width : yAxiswidth,
opacity,
right: isOverlappingWithPriceLine ? yAxiswidth - width : 0,
}}
>
<HamburgerDragIcon />
<div
className={classNames('price', { 'price--zero': isOverlappingWithPriceLine })}
style={{
color: isOverlappingWithPriceLine ? color : '',
right: isOverlappingWithPriceLine
? width + priceDisplay.length * 8 - (!draggable ? 16 : 0)
: 0,
}}
>
{priceDisplay}
</div>
<div />
{offScreen && offScreenDirection && (
<PriceLineArrow offScreenDirection={offScreenDirection} color={color} />
)}
</div>
{isOverlappingWithPriceLine && (
<div>
<div
className='price-overlay'
style={{ backgroundColor: color, width: yAxiswidth - width }}
/>
</div>
)}
</div>
{title && <PriceLineTitle color={color} title={title} yAxiswidth={yAxiswidth} opacity={opacity} />}
Expand Down
15 changes: 8 additions & 7 deletions src/store/BarrierStore.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CSSProperties } from 'react';
import { action, computed, observable, makeObservable } from 'mobx';
import MainStore from '.';
import Context from '../components/ui/Context';
Expand Down Expand Up @@ -47,7 +48,7 @@ export default class BarrierStore {
isTopShadeVisible = false;
isBottomShadeVisible = false;
hidePriceLines = false;
lineStyle?: string;
lineStyle?: CSSProperties['borderStyle'];
isInitialized = false;
initializePromise = PendingPromise<void, void>();
hideBarrierLine = false;
Expand All @@ -63,8 +64,8 @@ export default class BarrierStore {
get yAxisWidth(): number {
return this.mainStore.chart.yAxiswidth;
}
get priceLabelWidth(): number {
return this.yAxisWidth + 1;
get overlappedBarrierWidth(): number {
return 16;
}

constructor(mainStore: MainStore) {
Expand All @@ -83,12 +84,12 @@ export default class BarrierStore {
hideOffscreenLine: observable,
hideOffscreenBarrier: observable,
isSingleBarrier: observable,
pip: computed,
yAxisWidth: computed,
priceLabelWidth: computed,
destructor: action.bound,
init: action.bound,
overlappedBarrierWidth: computed,
pip: computed,
updateProps: action.bound,
destructor: action.bound
yAxisWidth: computed,
});

this.mainStore = mainStore;
Expand Down
2 changes: 1 addition & 1 deletion src/store/ChartStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1061,7 +1061,7 @@ class ChartStore {

const { context } = this.context?.stx.chart;
// barrier price can be wider than current tick price for 1 decimal digit
const priceWidth = context.measureText(price.toFixed((this.pip as number) + 1)).width + 20;
const priceWidth = context.measureText(price.toFixed((this.pip as number) + 1)).width + 26;
if (priceWidth > this.yAxiswidth) {
this.yAxiswidth = priceWidth;

Expand Down
11 changes: 9 additions & 2 deletions src/store/PriceLineStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default class PriceLineStore {
offScreen = false;
title?: string;
isOverlapping = false;
isOverlappingWithPriceLine = false;
offScreenDirection: keyof typeof DIRECTIONS | null = null;

set zIndex(value: string | number | null) {
Expand All @@ -51,6 +52,7 @@ export default class PriceLineStore {
offScreen: observable,
title: observable,
isOverlapping: observable,
isOverlappingWithPriceLine: observable,
offScreenDirection: observable,
pip: computed,
priceDisplay: computed,
Expand Down Expand Up @@ -225,6 +227,10 @@ export default class PriceLineStore {
return price;
}

_distanceFromCurrentPrice() {
return Math.abs(this._locationFromPrice(+this.realPrice) - this._locationFromPrice(+this.realPrice - +this._price));
}

_calculateTop = () => {
if (this.stx.currentQuote() === null) {
return;
Expand Down Expand Up @@ -265,10 +271,12 @@ export default class PriceLineStore {
this.isOverlapping = this.overlapCheck(top);
}

this.isOverlappingWithPriceLine = this._distanceFromCurrentPrice() < 25;

return Math.round(top) | 0;
};

// Mantually update the top to improve performance.
// Manually update the top to improve performance.
// We don't pay for react reconciler and mobx observable tracking in animation frames.
set top(v) {
this.__top = v;
Expand Down Expand Up @@ -304,7 +312,6 @@ export default class PriceLineStore {
if (i === current_barrier_idx) {
continue;
}

const barrier = filtered_barriers[i];
const diffTop = barrier._high_barrier.top && Math.abs(barrier._high_barrier.top - top);

Expand Down

2 comments on commit add9d41

@vercel
Copy link

@vercel vercel bot commented on add9d41 Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

smart-charts – ./

smart-charts-git-master.binary.sx
smart-charts.binary.sx

@vercel
Copy link

@vercel vercel bot commented on add9d41 Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

smart-charts-deriv-app-integration – ./

smart-charts-deriv-app-integration.binary.sx
smart-charts-deriv-app-integration-git-master.binary.sx

Please sign in to comment.