Skip to content

Commit

Permalink
Shayan / Fix issue of multiple chart store and context issues (deriv-…
Browse files Browse the repository at this point in the history
…com#1145)

* Fix issue of multiple chart store and cotext issues

* Add exception to ensure data is exist
  • Loading branch information
shayan-binary-2 authored Jan 25, 2021
1 parent fa46eb0 commit e644893
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 35 deletions.
4 changes: 4 additions & 0 deletions src/components/Chart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ const Chart = props => {
const defaultTopWidgets = () => <ChartTitle />;

const {
id,
chartId,
DrawToolsSettingsDialog,
StudySettingsDialog,
isCandle,
Expand Down Expand Up @@ -77,6 +79,7 @@ const Chart = props => {

return (
<div
id={id || chartId}
className={classNames('smartcharts', `smartcharts-${theme}`, {
'smartcharts--navigation-widget': enabledNavigationWidget,
'smartcharts--loading': isLoading,
Expand Down Expand Up @@ -151,6 +154,7 @@ const Chart = props => {
};

export default connect(({ chart, drawTools, studies, chartSetting, chartType, state, loader }) => ({
chartId: chart.chartId,
init: chart.init,
destroy: chart.destroy,
StudySettingsDialog: studies.StudySettingsDialog,
Expand Down
4 changes: 2 additions & 2 deletions src/components/ChartTitle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ const ChartTitle = props => {
return ChartTitleContainer;
};

export default connect(({ chartTitle: c, chart, state, chartSetting }) => ({
chartId: state.chartId,
export default connect(({ chartTitle: c, chart, chartSetting }) => ({
chartId: chart.chartId,
ChartTitleMenu: c.ChartTitleMenu,
currentSymbol: c.currentSymbol,
isMobile: chart.isMobile,
Expand Down
4 changes: 2 additions & 2 deletions src/components/ChartTypes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ const ChartTypes = ({
);
};

export default connect(({ chartType, state, chart }) => ({
chartId: state.chartId,
export default connect(({ chartType, chart }) => ({
chartId: chart.chartId,
ChartTypeMenu: chartType.ChartTypeMenu,
ChartTypeList: chartType.ChartTypeList,
menuOpen: chartType.menu.open,
Expand Down
2 changes: 1 addition & 1 deletion src/components/FastMarker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const FastMarker = props => {
injection_id_ref.current = stx_ref.current.append('draw', updateCSS);
updateCSS();
});
} else if (injection_id_ref.current) {
} else if (injection_id_ref.current && stx_ref.current) {
// remove the injection on unmount
stx_ref.current.removeInjection(injection_id_ref.current);
ctx_ref.current = null;
Expand Down
19 changes: 13 additions & 6 deletions src/components/SmartChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ import { Provider } from 'mobx-react';
import MainStore from '../store';
import Chart from './Chart.jsx';

const mainStore = new MainStore();
const SmartChart = ({ children, ...props }) => (
<Provider {...mainStore}>
<Chart {...props}>{children}</Chart>
</Provider>
);
const SmartChart = ({ children, ...props }) => {
const store = React.useRef();

if (!store.current) {
store.current = new MainStore();
}

return (
<Provider {...store.current}>
<Chart {...props}>{children}</Chart>
</Provider>
);
};

export default SmartChart;
4 changes: 2 additions & 2 deletions src/components/Timeperiod.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ const Timeperiod = ({
}
};

export default connect(({ timeperiod: s, state, chartType, loader }) => ({
chartId: state.chartId,
export default connect(({ timeperiod: s, chart, chartType, loader }) => ({
chartId: chart.chartId,
timeUnit: s.timeUnit,
interval: s.interval,
isMobile: s.mainStore.chart.isMobile,
Expand Down
1 change: 1 addition & 0 deletions src/store/BarrierStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export default class BarrierStore {
}

@action.bound destructor() {
if (!this.context) return;
this.stx.removeInjection(this._injectionId);
this.stx.removeEventListener(this._listenerId);
this._high_barrier.destructor();
Expand Down
37 changes: 22 additions & 15 deletions src/store/ChartState.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ class ChartState {
return this.mainStore.chart;
}

get rootElement() {
return this.chartStore.rootElement;
}

constructor(mainStore) {
this.mainStore = mainStore;
this.chartStore = mainStore.chart;
Expand All @@ -78,7 +82,6 @@ class ChartState {
this.stxx.append('zoomOut', this.setEnableScroll.bind(this));
this.stxx.append('zoomIn', this.setEnableScroll.bind(this));

this.rootNode = this.mainStore.chart.rootNode;
this.granularity = this.chartStore.granularity;
this.stxx.maxMasterDataSize = this.chartStore.getMaxMasterDataSize(this.granularity);
};
Expand All @@ -92,7 +95,6 @@ class ChartState {
chartType,
clearChart,
endEpoch,
id,
isAnimationEnabled = true,
isConnectionOpened,
isStaticChart,
Expand All @@ -117,7 +119,6 @@ class ChartState {
let isSymbolChanged = false;
let isGranularityChanged = false;

this.chartId = id;
this.chartStatusListener = chartStatusListener;
this.stateChangeListener = stateChangeListener;
this.isAnimationEnabled = isAnimationEnabled;
Expand Down Expand Up @@ -288,15 +289,14 @@ class ChartState {
}

setChartTheme(theme, isChartClosed = this.isChartClosed) {
if (!this.stxx) return;
this.stxx.clearStyles();
this.stxx.setStyle('stx_grid', 'color', Theme[`${theme}_chart_grid`]);
this.stxx.setStyle('stx_yaxis', 'color', Theme[`${theme}_chart_text`]);
this.stxx.setStyle('stx_xaxis', 'color', Theme[`${theme}_chart_text`]);
this.stxx.setStyle('stx_xaxis_dark', 'color', Theme[`${theme}_chart_text`]);
if (!this.rootNode) {
this.rootNode = this.mainStore.chart.rootNode;
}
this.rootNode.querySelector('.chartContainer').style.backgroundColor = Theme[`${theme}_chart_bg`];

this.rootElement.querySelector('.chartContainer').style.backgroundColor = Theme[`${theme}_chart_bg`];
// change chart colors to grey if the current market is closed and it is not a static chart
if (isChartClosed && !this.isStaticChart) {
this.stxx.setStyle('stx_mountain_chart', 'borderTopColor', Theme[`${theme}_chart_closed_mountain_border`]);
Expand Down Expand Up @@ -338,7 +338,11 @@ class ChartState {
@action.bound setChartIsReady(isChartReady) {
if (this.isChartReady !== isChartReady) {
this.isChartReady = isChartReady;
this.stateChange(STATE.READY);

if (isChartReady) {
this.stateChange(STATE.READY);
}

if (this.chartStatusListener && typeof this.chartStatusListener === 'function') {
this.chartStatusListener(isChartReady);
}
Expand Down Expand Up @@ -383,15 +387,15 @@ class ChartState {
}

saveLayout() {
if (!this.chartId || !this.stxx) return;
if (!this.chartStore.chartId || !this.stxx) return;
const layoutData = this.stxx.exportLayout(true);
const json = JSON.stringify(layoutData);
CIQ.localStorageSetItem(`layout-${this.chartId}`, json);
CIQ.localStorageSetItem(`layout-${this.chartStore.chartId}`, json);
}

// returns false if restoring layout fails
restoreLayout() {
let layoutData = createObjectFromLocalStorage(`layout-${this.chartId}`);
let layoutData = createObjectFromLocalStorage(`layout-${this.chartStore.chartId}`);

if (!layoutData || !layoutData.symbols.length) return false;

Expand Down Expand Up @@ -451,6 +455,7 @@ class ChartState {
this.stxx.importLayout(layoutData, {
managePeriodicity: true,
cb: () => {
if (!this.context) return;
if (layoutData.tension) {
this.stxx.chart.tension = layoutData.tension;
}
Expand All @@ -472,19 +477,19 @@ class ChartState {
}

saveDrawings() {
if (!this.chartId) return;
if (!this.chartStore.chartId) return;
const obj = this.stxx.exportDrawings();
const symbol = this.stxx.chart.symbol;
if (obj.length === 0) {
CIQ.localStorage.removeItem(`${symbol}-${this.chartId}`);
CIQ.localStorage.removeItem(`${symbol}-${this.chartStore.chartId}`);
} else {
CIQ.localStorageSetItem(`${symbol}-${this.chartId}`, JSON.stringify(obj));
CIQ.localStorageSetItem(`${symbol}-${this.chartStore.chartId}`, JSON.stringify(obj));
}
}

restoreDrawings() {
if (this.stxx && this.stxx.chart) {
const drawings = createObjectFromLocalStorage(`${this.stxx.chart.symbol}-${this.chartId}`);
const drawings = createObjectFromLocalStorage(`${this.stxx.chart.symbol}-${this.chartStore.chartId}`);
if (drawings) {
this.stxx.importDrawings(drawings);
this.stxx.draw();
Expand All @@ -496,6 +501,8 @@ class ChartState {
}

scrollChartToLeft = (leftTick, force) => {
if (!this.stxx?.chart) return;

const scrollToEpoch = this.scrollToEpoch || (leftTick && getUTCEpoch(leftTick.DT));
this.stxx.chart.entryTick = null;

Expand Down
35 changes: 33 additions & 2 deletions src/store/ChartStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ class ChartStore {
return this.currentActiveSymbol.decimal_places;
}

get rootElement() {
return document.getElementById(this.chartId);
}

currentCloseQuote = () => {
if (!this.stxx) {
return;
Expand Down Expand Up @@ -169,6 +173,7 @@ class ChartStore {
this.loader.show();
this.mainStore.state.setChartIsReady(false);
this.loader.setState('chart-engine');
this.chartId = props.id || 'base-chart';

if (window.CIQ) {
this._initChart(rootNode, props);
Expand Down Expand Up @@ -575,6 +580,29 @@ class ChartStore {
this.positionSticky(m);
}
};
// In some cases we faced some cases that color1 or color2 get undefined
// and this cause the application to crash, as a result, we we set below
// condition to slient that error
CIQ.colorsEqual = function (color1, color2) {
if (!color2 || !color1 || typeof color1 !== 'string' || typeof color2 !== 'string') {
return false;
} // Modified by SmartChart team
if (color1 === color2) return true;
if (!color1 && !color2) return true;
if (!color1 || !color2) return false;
if (color1 === 'transparent') color1 = 'rgba(0,0,0,0)';
if (color2 === 'transparent') color2 = 'rgba(0,0,0,0)';
const alpha = /^rgba\(.*,(.+)\)/;
let rgba1 = color1.match(alpha);
let rgba2 = color2.match(alpha);
rgba1 = rgba1 ? parseFloat(rgba1[1]) : 1;
rgba2 = rgba2 ? parseFloat(rgba2[1]) : 1;
if (rgba1 !== rgba2) return false;

const first = CIQ.colorToHex(color1);
const second = CIQ.colorToHex(color2);
return first.toLowerCase() === second.toLowerCase();
};

const {
symbol,
Expand Down Expand Up @@ -909,7 +937,6 @@ class ChartStore {
symbolObj = this.activeSymbols.getSymbolObj(symbolObj);
}
const isSymbolAvailable = symbolObj && this.currentActiveSymbol;

if (
isSymbolAvailable &&
symbolObj.symbol === this.currentActiveSymbol.symbol &&
Expand Down Expand Up @@ -1010,7 +1037,7 @@ class ChartStore {
loadChartWithInitalData(symbol, masterData) {
if (!masterData) return;

const layoutData = createObjectFromLocalStorage(`layout-${this.stateStore.chartId}`);
const layoutData = createObjectFromLocalStorage(`layout-${this.chartId}`);
if (!layoutData || !layoutData.symbols.length) return;
const layout_symbol = layoutData.symbols[0].symbol;

Expand Down Expand Up @@ -1131,6 +1158,10 @@ class ChartStore {
this.stxx.destroy();
this.stxx = null;
}

this.currentActiveSymbol = null;
this.contextPromise = null;
this.context = null;
}

@action.bound openFullscreen() {
Expand Down
2 changes: 1 addition & 1 deletion src/store/ChartTitleStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class ChartTitleStore {
return this.mainStore.chart.currentActiveSymbol;
}
@computed get isSymbolOpen() {
return this.currentSymbol.exchange_is_open;
return this.currentSymbol?.exchange_is_open;
}
@computed get decimalPlaces() {
return this.mainStore.chart.currentActiveSymbol.decimal_places;
Expand Down
2 changes: 2 additions & 0 deletions src/store/DrawToolsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ export default class DrawToolsStore {
}

@action.bound computeActiveDrawTools() {
if (!this.context) return;

const items = {};
const ignoreBarType = ['vertical', 'horizontal'];
const groups = {};
Expand Down
13 changes: 10 additions & 3 deletions src/store/LastDigitStatsStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export default class LastDigitStatsStore {
// TODO: call onMasterDataUpdate on symobl change.
this.mainStore.chart.feed.onMasterDataUpdate(this.onMasterDataUpdate);
this.mainStore.chart.feed.onMasterDataReinitialize(() => {
this.mainStore.chart.feed.offMasterDataUpdate(this.onMasterDataUpdate);
this.mainStore.chart.feed.onMasterDataUpdate(this.onMasterDataUpdate);
if (this.context && this.mainStore.chart.feed) {
this.mainStore.chart.feed.offMasterDataUpdate(this.onMasterDataUpdate);
this.mainStore.chart.feed.onMasterDataUpdate(this.onMasterDataUpdate);
}
});
}
);
Expand All @@ -40,7 +42,7 @@ export default class LastDigitStatsStore {
}

@computed get decimalPlaces() {
return this.mainStore.chart.currentActiveSymbol.decimal_places;
return this.mainStore.chart.currentActiveSymbol?.decimal_places || 2;
}

@computed get isVisible() {
Expand All @@ -56,6 +58,8 @@ export default class LastDigitStatsStore {
}

@action.bound async updateLastDigitStats() {
if (!this.context || !this.mainStore.chart.currentActiveSymbol) return;

this.digits = [];
this.bars = [];
this.latestData = [];
Expand All @@ -74,6 +78,7 @@ export default class LastDigitStatsStore {
});
this.latestData = tickHistory && tickHistory.history ? tickHistory.history.prices : [];
}
if (!this.context || !this.mainStore.chart.currentActiveSymbol) return;

this.latestData.forEach(price => {
const lastDigit = (+price).toFixed(this.decimalPlaces).slice(-1);
Expand All @@ -83,6 +88,8 @@ export default class LastDigitStatsStore {
}

@action.bound onMasterDataUpdate({ Close, tick }) {
if (!this.context || !this.mainStore.chart.currentActiveSymbol) return;

this.lastTick = tick;
if (this.marketDisplayName !== this.lastSymbol) {
this.lastSymbol = this.marketDisplayName;
Expand Down
2 changes: 1 addition & 1 deletion src/store/StudyLegendStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ export default class StudyLegendStore {
* Gets called continually in the draw animation loop.
* Be careful not to render unnecessarily. */
renderLegend = () => {
if (!this.shouldRenderLegend()) {
if (!this.context || !this.shouldRenderLegend()) {
return;
}

Expand Down
2 changes: 2 additions & 0 deletions src/store/TimeperiodStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export default class TimeperiodStore {
}

updateCountdown() {
if (!this.context) return;
const stx = this.context.stx;
this.remain = null;
this.clearCountdown();
Expand Down Expand Up @@ -167,6 +168,7 @@ export default class TimeperiodStore {
}

@action.bound updateDisplay() {
if (!this.context) return;
const stx = this.context.stx;
this.timeUnit = getTimeUnit(stx.layout);
this.interval = stx.layout.interval;
Expand Down

0 comments on commit e644893

Please sign in to comment.