Skip to content

Commit

Permalink
Merge pull request #545 from brucebinary/chunk-chartiq
Browse files Browse the repository at this point in the history
Dynamically import ChartIQ
  • Loading branch information
bruce-binary authored Oct 18, 2018
2 parents e05f2a1 + 5a644d9 commit 4198b6d
Show file tree
Hide file tree
Showing 15 changed files with 118 additions and 141 deletions.
1 change: 1 addition & 0 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }],
["@babel/plugin-syntax-dynamic-import"],
["@babel/plugin-proposal-class-properties", { "loose" : true }],
["inline-react-svg", {
"svgo": {
Expand Down
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,25 @@ The job of loading the active symbols or trading times or stream data from cache

Some important notes on your webpack.config.js (refer to `app/webpack.config.js`):

- The ChartIQ library and the smartcharts CSS file will need to be copied from the npm library (remember to include in your `index.html`). In the example we use the `copy-webpack-plugin` webpack plugin to do this:
- smartcharts CSS file will need to be copied from the npm library (remember to include in your `index.html`).
- smartcharts consist of a few chunks (which has filenames `*.smartcharts.*`), which it downloads asynchronously during runtime. Therefore, it needs to know where the library user places its chunks via the `setSmartChartsPublicPath` function:

```js
import { setSmartChartsPublicPath } from '@binary-com/smartcharts';

// SmartCharts chunk are deployed to https://mysite.com/dist/*
setSmartChartsPublicPath('/dist/');
```

We can use the `copy-webpack-plugin` webpack plugin to copy over SmartCharts chunks:

```js
new CopyWebpackPlugin([
{ from: './node_modules/@binary-com/smartcharts/dist/chartiq.min.js' },
{ from: './node_modules/@binary-com/smartcharts/dist/*.smartcharts.*' },
{ from: './node_modules/@binary-com/smartcharts/dist/smartcharts.css' },
])
```

- You need to expose `CIQ` (the ChartIQ library) as a global object:

```js
externals: {
CIQ: 'CIQ'
}
```

### API

Expand Down
22 changes: 14 additions & 8 deletions app/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { // eslint-disable-line import/no-extraneous-dependencies,import/no-unre
DrawTools,
ChartSetting,
createObjectFromLocalStorage,
setSmartChartsPublicPath,
Share,
ChartTitle,
AssetInformation,
Expand All @@ -25,10 +26,15 @@ import { ConnectionManager, StreamManager } from './connection';
import Notification from './Notification.jsx';
import ChartNotifier from './ChartNotifier.js';

setSmartChartsPublicPath('./dist/');

const isMobile = window.navigator.userAgent.toLowerCase().includes('mobi');

if (process.env.NODE_ENV !== 'production') {
whyDidYouUpdate(React, { exclude: [/^RenderInsideChart$/, /^inject-/] });
}


if (window.location.host.endsWith('binary.com')) {
window._trackJs = { token: '346262e7ffef497d85874322fff3bbf8', application: 'smartcharts' };
const s = document.createElement('script');
Expand All @@ -52,7 +58,7 @@ configure({ enforceActions: 'observed' });
function getLanguageStorage() {
const default_language = 'en';
try {
const setting_string = CIQ.localStorage.getItem('smartchart-setting'),
const setting_string = localStorage.getItem('smartchart-setting'),
setting = JSON.parse(setting_string !== '' ? setting_string : '{}');

return setting.language || default_language;
Expand All @@ -62,12 +68,12 @@ function getLanguageStorage() {
}

function getServerUrl() {
const local = CIQ.localStorage.getItem('config.server_url');
const local = localStorage.getItem('config.server_url');
return `wss://${local || 'ws.binaryws.com'}/websockets/v3`;
}

const chartId = '1';
const appId = CIQ.localStorage.getItem('config.app_id') || 12812;
const appId = localStorage.getItem('config.app_id') || 12812;
const serverUrl = getServerUrl();

const connectionManager = new ConnectionManager({
Expand Down Expand Up @@ -111,7 +117,7 @@ class App extends Component {

saveSettings = (settings) => {
console.log('settings updated:', settings);
CIQ.localStorageSetItem('smartchart-setting', JSON.stringify(settings));
localStorage.setItem('smartchart-setting', JSON.stringify(settings));

this.setState({ settings });
if (this.startingLanguage !== settings.language) {
Expand All @@ -132,32 +138,32 @@ class App extends Component {

renderControls = () => (
<>
{CIQ.isMobile ? '' : <CrosshairToggle />}
{isMobile ? '' : <CrosshairToggle />}
<ChartTypes />
<Timeperiod />
<StudyLegend />
<Comparison />
<DrawTools />
<Views />
<Share />
{CIQ.isMobile ? '' : <ChartSize />}
{isMobile ? '' : <ChartSize />}
<ChartSetting />
</>
);

onMessage = (e) => {
this.notifier.notify(e);
}

render() {
const { settings, isConnectionOpened, symbol } = this.state;

return (
<SmartChart
id={chartId}
symbol={symbol}
isMobile={isMobile}
onMessage={this.onMessage}
isMobile={CIQ.isMobile}
enableRouting
topWidgets={this.renderTopWidgets}
chartControlsWidgets={this.renderControls}
Expand Down
1 change: 0 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
<div id="root" role="main"></div>
<script src="./dist/browser-detection.js"></script>
<script src="./dist/babel-polyfill.min.js"></script>
<script src="./dist/chartiq.min.js"></script>
<script src="./dist/react.js"></script>
<script src="./dist/react-dom.js"></script>
<script src="./dist/react-transition-group.js"></script>
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{
"name": "@binary-com/smartcharts",
"version": "0.2.7",
"version": "0.3.0",
"main": "dist/smartcharts.js",
"author": "amin@binary.com",
"contributors": [
"Lee Zhen Yong <bruce@binary.com>",
"Mahboobeh Mohammadi <mahboobeh@binary.com>",
"Shayan Yazdanpanah <shayan@binary.com>"
],
"license": "ISC",
"repository": {
"type": "git",
Expand Down Expand Up @@ -37,6 +42,7 @@
"@babel/core": "^7.1.0",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/polyfill": "^7.0.0",
"@babel/preset-env": "^7.1.0",
"@babel/preset-react": "^7.0.0",
Expand Down Expand Up @@ -102,13 +108,11 @@
"stylelint": "^9.3.0",
"stylelint-webpack-plugin": "^0.10.5",
"svg-url-loader": "^2.3.1",
"uglify-js": "^3.4.7",
"url-loader": "^1.0.1",
"webpack": "^4.17.1",
"webpack-bundle-analyzer": "^3.0.2",
"webpack-cli": "^3.0.6",
"webpack-dev-server": "^3.1.4",
"write": "^1.0.3"
"webpack-dev-server": "^3.1.4"
},
"dependencies": {
"event-emitter-es6": "^1.1.5",
Expand Down
36 changes: 18 additions & 18 deletions src/SplinePlotter.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable no-restricted-properties,no-restricted-globals,prefer-const */
/* eslint-disable no-restricted-globals,no-restricted-properties */

window.SplinePlotter.plotSpline = function (points, tension, context, colorPatternChanges) {
export default function plotSpline(points, tension, context, colorPatternChanges) {
function getControlPoints(i) {
let x0 = points[i];
let y0 = points[i + 1];
let x1 = points[i + 2];
let y1 = points[i + 3];
let x2 = points[i + 4];
let y2 = points[i + 5];
const x0 = points[i];
const y0 = points[i + 1];
const x1 = points[i + 2];
const y1 = points[i + 3];
const x2 = points[i + 4];
const y2 = points[i + 5];

if (isNaN(x0) || isNaN(x1) || isNaN(x2) || isNaN(y0) || isNaN(y1) || isNaN(y2)) {
return null;
Expand All @@ -20,24 +20,24 @@ window.SplinePlotter.plotSpline = function (points, tension, context, colorPatte
// tension controls how far the control points spread.

// Scaling factors: distances from this knot to the previous and following knots.
let d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
let d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
const d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
const d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

let fa = tension * d01 / (d01 + d12);
let fb = tension - fa;
const fa = tension * d01 / (d01 + d12);
const fb = tension - fa;

let p1x = x1 + fa * (x0 - x2);
let p1y = y1 + fa * (y0 - y2);
const p1x = x1 + fa * (x0 - x2);
const p1y = y1 + fa * (y0 - y2);

let p2x = x1 - fb * (x0 - x2);
let p2y = y1 - fb * (y0 - y2);
const p2x = x1 - fb * (x0 - x2);
const p2y = y1 - fb * (y0 - y2);

return [p1x, p1y, p2x, p2y];
}

if (!tension || tension < 0) { tension = 0; }
let cp = []; // array of control points, as x0,y0,x1,y1,...
let n = points.length;
const n = points.length;
// Draw an open curve, not connected at the ends
for (let i = 0; i < n - 4; i += 2) {
cp = cp.concat(getControlPoints(i));
Expand All @@ -48,7 +48,7 @@ window.SplinePlotter.plotSpline = function (points, tension, context, colorPatte

function seeIfStrokeNeeded(i) {
if (colorPatternIndex === colorPatternChanges.length) { return; }
let colorPatternChange = colorPatternChanges[colorPatternIndex];
const colorPatternChange = colorPatternChanges[colorPatternIndex];
if (colorPatternChange.coord[0] === points[i] && colorPatternChange.coord[1] === points[i + 1]) {
context.stroke();
context.strokeStyle = colorPatternChange.color;
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/Animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* new CIQ.Animation(stxx, {tension:0.3}); //Default animation with splining tension of 0.3
*
*/
CIQ.Animation = function (stx, animationParameters, easeMachine) {
export default function animateChart(stx, animationParameters, easeMachine) {
let params = {
stayPut: false,
ticksFromEdgeOfScreen: 5,
Expand Down
2 changes: 0 additions & 2 deletions src/components/ui/Keystroke.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import CIQ from 'chartiq';

/**
* UI Helper for capturing and handling keystrokes. cb to capture the key. Developer is responsible
* for calling e.preventDefault() and/or e.stopPropagation();
Expand Down
1 change: 0 additions & 1 deletion src/components/ui/KeystrokeHub.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* eslint-disable prefer-destructuring */
import CIQ from 'chartiq';
import Helper from './Helper';
import Keystroke from './Keystroke';
import { claims } from '.';
Expand Down
6 changes: 5 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import Marker from './components/Marker.jsx';
import CurrentSpot from './components/CurrentSpot.jsx';
import { createObjectFromLocalStorage } from './utils';

import './SplinePlotter';
function setSmartChartsPublicPath(path) {
__webpack_public_path__ = path; // eslint-disable-line
}

export {
AssetInformation,
Expand All @@ -37,6 +39,7 @@ export {
DrawTools,
Marker,
PendingPromise,
setSmartChartsPublicPath,
Share,
SmartChart,
StudyLegend,
Expand All @@ -59,6 +62,7 @@ export default {
DrawTools,
Marker,
PendingPromise,
setSmartChartsPublicPath,
Share,
SmartChart,
StudyLegend,
Expand Down
40 changes: 32 additions & 8 deletions src/store/ChartStore.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import ResizeObserver from 'resize-observer-polyfill';
import { action, observable, reaction, computed } from 'mobx';
import PendingPromise from '../utils/PendingPromise';
import Context from '../components/ui/Context';
import KeystrokeHub from '../components/ui/KeystrokeHub';
import '../components/ui/Animation';
import animateChart from '../components/ui/Animation';
import plotSpline from '../SplinePlotter';
import { Feed } from '../feed';
import { ActiveSymbols, BinaryAPI, TradingTimes } from '../binaryapi';
import { calculateTimeUnitInterval, getUTCDate, cloneCategories } from '../utils';

CIQ.ChartEngine.prototype.createYAxisLabel = function (panel, txt, y, backgroundColor, color, ctx, yAxis) {
function myCreateYAxisLabel(panel, txt, y, backgroundColor, color, ctx, yAxis) {
if (panel.yAxis.drawPriceLabels === false || panel.yAxis.noDraw) return;
const yax = yAxis || panel.yAxis;
if (yax.noDraw || !yax.width) return;
Expand Down Expand Up @@ -65,7 +65,7 @@ CIQ.ChartEngine.prototype.createYAxisLabel = function (panel, txt, y, background
color,
};
CIQ[yaxisLabelStyle](params);
};
}

class ChartStore {
static keystrokeHub;
Expand Down Expand Up @@ -139,7 +139,21 @@ class ChartStore {
setTimeout(this.updateCanvas, this.isMobile ? 500 : 100);
}

@action.bound init(rootNode, modalNode, props) {
init = (rootNode, modalNode, props) => {
if (window.CIQ) {
this._initChart(rootNode, modalNode, props);
} else {
import(/* webpackChunkName: "chartiq" */ 'chartiq').then(action(({ CIQ, SplinePlotter }) => {
window.CIQ = CIQ;
SplinePlotter.plotSpline = plotSpline;
this._initChart(rootNode, modalNode, props);
}));
}
};

@action.bound _initChart(rootNode, modalNode, props) {
CIQ.ChartEngine.prototype.createYAxisLabel = myCreateYAxisLabel;

this.rootNode = rootNode;
this.modalNode = modalNode;
this.chartNode = this.rootNode.querySelector('.ciq-chart-area');
Expand Down Expand Up @@ -211,7 +225,7 @@ class ChartStore {
deleteElement.textConent = t.translate('right-click to delete');
manageElement.textConent = t.translate('right-click to manage');

CIQ.Animation(stxx, { stayPut: true });
animateChart(stxx, { stayPut: true });

// connect chart to data
this.feed = new Feed(this.api, stxx, this.mainStore, this.tradingTimes);
Expand Down Expand Up @@ -283,8 +297,17 @@ class ChartStore {
}));
});

this.resizeObserver = new ResizeObserver(this.resizeScreen);
this.resizeObserver.observe(modalNode);
if ('ResizeObserver' in window) {
this.resizeObserver = new ResizeObserver(this.resizeScreen);
this.resizeObserver.observe(modalNode);
} else {
import(/* webpackChunkName: "resize-observer-polyfill" */ 'resize-observer-polyfill').then(({ default: ResizeObserver }) => {
window.ResizeObserver = ResizeObserver;
if (stxx.isDestroyed || !modalNode) { return; }
this.resizeObserver = new ResizeObserver(this.resizeScreen);
this.resizeObserver.observe(modalNode);
});
}
}

onMarketOpenClosedChange = (changes) => {
Expand Down Expand Up @@ -428,6 +451,7 @@ class ChartStore {
@action.bound destroy() {
if (this.resizeObserver) { this.resizeObserver.disconnect(); }
if (this.tradingTimes) { this.tradingTimes.destructor(); }

// Destroying the chart does not unsubscribe the streams;
// we need to manually unsubscribe them.
if (this.feed) {
Expand Down
Loading

0 comments on commit 4198b6d

Please sign in to comment.