├── .babelrc
├── .gitignore
├── .npmignore
├── README.md
├── demo_dist
├── bundle.js
└── index.html
├── example
└── src
│ ├── index.html
│ └── index.jsx
├── npm_dist
├── css
│ └── main.css
├── img
│ ├── clear_333.png
│ ├── clear_ccc.png
│ ├── dropdown_b.png
│ ├── dropdown_w.png
│ ├── dropup_b.png
│ ├── dropup_w.png
│ ├── size.png
│ ├── size_d.png
│ ├── size_l.png
│ ├── tool_d_normal.png
│ ├── tool_d_push.png
│ ├── tool_l_normal.png
│ └── tool_l_push.png
├── index.js
└── js
│ ├── areas.js
│ ├── chart.js
│ ├── chart_manager.js
│ ├── chart_settings.js
│ ├── cname.js
│ ├── control.js
│ ├── cpoint.js
│ ├── ctool_manager.js
│ ├── ctools.js
│ ├── data_providers.js
│ ├── data_sources.js
│ ├── exprs.js
│ ├── indicators.js
│ ├── kline.js
│ ├── layouts.js
│ ├── mevent.js
│ ├── named_object.js
│ ├── plotters.js
│ ├── ranges.js
│ ├── templates.js
│ ├── themes.js
│ ├── timeline.js
│ └── util.js
├── package-lock.json
├── package.json
├── src
├── css
│ └── main.css
├── img
│ ├── clear_333.png
│ ├── clear_ccc.png
│ ├── dropdown_b.png
│ ├── dropdown_w.png
│ ├── dropup_b.png
│ ├── dropup_w.png
│ ├── size.png
│ ├── size_d.png
│ ├── size_l.png
│ ├── tool_d_normal.png
│ ├── tool_d_push.png
│ ├── tool_l_normal.png
│ └── tool_l_push.png
├── index.jsx
└── js
│ ├── areas.js
│ ├── chart.js
│ ├── chart_manager.js
│ ├── chart_settings.js
│ ├── cname.js
│ ├── control.js
│ ├── cpoint.js
│ ├── ctool_manager.js
│ ├── ctools.js
│ ├── data_providers.js
│ ├── data_sources.js
│ ├── exprs.js
│ ├── indicators.js
│ ├── kline.js
│ ├── layouts.js
│ ├── mevent.js
│ ├── named_object.js
│ ├── plotters.js
│ ├── ranges.js
│ ├── templates.js
│ ├── themes.js
│ ├── timeline.js
│ └── util.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react"]
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea
2 | /.git
3 | /node_modules
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .git
3 | src
4 | examples
5 | node_modules
6 | .babelrc
7 | .gitignore
8 | .npmignore
9 | webpack.config.js
10 | demo_dist
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-kline [](https://badge.fury.io/js/react-kline)
2 |
3 | [](https://www.npmjs.com/package/react-kline)
4 |
5 | > 基于React的K线图组件
6 |
7 | ### 演示地址
8 |
9 | * [Demo](https://lindakai2016.github.io/react-kline/index.html)
10 |
11 | ### 安装和使用
12 |
13 | 安装
14 |
15 | ```bash
16 | $ npm install react-kline
17 | ```
18 |
19 | * 使用
20 |
21 | ```html
22 | import React from 'react';
23 | import ReactDOM from 'react-dom';
24 | import ReactKline from 'react-kline';
25 |
26 | class App extends React.Component {
27 |
28 | onRequestData(param,callback){
29 | let data={};
30 | //请求数据
31 | //...
32 | callback(data);
33 | }
34 |
35 | render() {
36 | return (
37 |
47 | );
48 | }
49 | }
50 |
51 | ReactDOM.render(
52 | ,
53 | document.getElementById('root')
54 | );
55 | ```
56 |
57 | ### 构建选项
58 |
59 | | 参数名称 | 参数说明 | 默认值
60 | |:---------|:-----------------|:------------
61 | |`width` | 宽度 (px) | 600
62 | |`height` | 高度度 (px) | 400
63 | |`theme` | 主题 dark(暗色)/light(亮色)| dark
64 | |`language` | 语言 zh-cn(简体中文)/en-us(英文)/zh-tw(繁体中文)| zh-cn
65 | |`ranges` | 聚合选项 1w/1d/12h/6h/4h/2h/1h/30m/15m/5m/3m/1m/line (w:周, d:天, h:小时, m:分钟, line:分时数据)| ["1w", "1d", "1h", "30m", "15m", "5m", "1m", "line"]
66 | |`symbol` | 交易代号|
67 | |`symbolName` | 交易名称 |
68 | |`limit` | 分页大小 | 1000
69 | |`intervalTime` | 请求间隔时间(ms) | 3000
70 | |`debug` | 是否开启调试模式 true/false | true
71 | |`depthWidth` | 深度图宽度 | 最小50,小于50则取50,默认50
72 |
73 |
74 | ### 方法
75 |
76 | * resize(int width, int height)
77 |
78 | 设置画布大小
79 |
80 | ```javascript
81 | resize(1200, 550);
82 | ```
83 |
84 | * setSymbol(string symbol, string symbolName)
85 |
86 | 设置交易品种
87 |
88 | ```javascript
89 | setSymbol('usd/btc', 'USD/BTC');
90 | ```
91 |
92 | * setTheme(string style)
93 |
94 | 设置主题
95 |
96 | ```javascript
97 | setTheme('dark'); // dark/light
98 | ```
99 |
100 | * setLanguage(string lang)
101 |
102 | 设置语言
103 |
104 | ```javascript
105 | setLanguage('en-us'); // en-us/zh-ch/zh-tw
106 | ```
107 |
108 | * setIntervalTime: function (intervalTime)
109 |
110 | 设置请求间隔时间(ms)
111 |
112 | ```javascript
113 | setIntervalTime(5000);
114 | ```
115 |
116 | * setDepthWidth: function (width)
117 |
118 | 设置深度图宽度
119 |
120 | ```javascript
121 | setDepthWidth(100);
122 | ```
123 |
124 |
125 | ### 事件
126 |
127 | | 事件函数 | 说明
128 | |:-----------------------|:------------
129 | | `onResize: function(width, height)` | 画布尺寸改变时触发
130 | | `onLangChange: function(lang)` | 语言改变时触发
131 | | `onSymbolChange: function(symbol, symbolName)` | 交易品种改变时触发
132 | | `onThemeChange: function(theme)` | 主题改变时触发
133 | | `onRangeChange: function(range)` | 聚合时间改变时触发
134 | | `onRequestData: function(param,callback)`| 请求数据时触发,触发时间间隔由`intervalTime`指定,`param`请求参数,`callback(res)`结果回调函数。无论请求是否成功,必须在`onRequestData`里调用`callback`,否则会中断数据请求。
135 |
136 | ### 数据请求param格式
137 |
138 | ```json
139 | {
140 | "symbol": "BTC", // 交易品种
141 | "range": 900000, // range类型,毫秒
142 | "limit": 1000,
143 | "since": "1512205140000" // 时间
144 | }
145 | ```
146 |
147 | ### 回调函数res格式
148 |
149 | > 数据请求成功
150 |
151 | 当success为true,请求成功。
152 |
153 | ```json
154 | {
155 | "success": true,
156 | "data": {
157 | "lines": [
158 | [
159 | 1.50790476E12,
160 | 99.30597249871,
161 | 99.30597249871,
162 | 99.30597249871,
163 | 99.30597249871,
164 | 66.9905449283
165 | ]
166 | ],
167 | "depths": {
168 | "asks": [
169 | [
170 | 500654.27,
171 | 0.5
172 | ]
173 | ],
174 | "bids": [
175 | [
176 | 5798.79,
177 | 0.013
178 | ]
179 | ]
180 | }
181 | }
182 | }
183 | ```
184 |
185 | > 数据请求失败
186 |
187 | 当res为空,或者success为false,请求失败。
188 |
189 | ```json
190 | {
191 | "success": false,
192 | "data": null, // success为false,则忽略data
193 | }
194 | ```
195 |
196 |
197 | * res参数说明:
198 |
199 | * `lines`: K线图, 依次是: 时间(ms), 开盘价, 最高价, 最低价, 收盘价, 成交量
200 | * `depths`深度图数据,`asks`: 一定比例的卖单列表, `bids`:一定比例的买单列表, 其中每项的值依次是 : 成交价, 成交量
--------------------------------------------------------------------------------
/demo_dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | react kline Demo
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/example/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | react kline Demo
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/npm_dist/img/clear_333.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/clear_333.png
--------------------------------------------------------------------------------
/npm_dist/img/clear_ccc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/clear_ccc.png
--------------------------------------------------------------------------------
/npm_dist/img/dropdown_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/dropdown_b.png
--------------------------------------------------------------------------------
/npm_dist/img/dropdown_w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/dropdown_w.png
--------------------------------------------------------------------------------
/npm_dist/img/dropup_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/dropup_b.png
--------------------------------------------------------------------------------
/npm_dist/img/dropup_w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/dropup_w.png
--------------------------------------------------------------------------------
/npm_dist/img/size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/size.png
--------------------------------------------------------------------------------
/npm_dist/img/size_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/size_d.png
--------------------------------------------------------------------------------
/npm_dist/img/size_l.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/size_l.png
--------------------------------------------------------------------------------
/npm_dist/img/tool_d_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/tool_d_normal.png
--------------------------------------------------------------------------------
/npm_dist/img/tool_d_push.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/tool_d_push.png
--------------------------------------------------------------------------------
/npm_dist/img/tool_l_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/tool_l_normal.png
--------------------------------------------------------------------------------
/npm_dist/img/tool_l_push.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/npm_dist/img/tool_l_push.png
--------------------------------------------------------------------------------
/npm_dist/js/chart.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.Chart = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _chart_manager = require('./chart_manager');
11 |
12 | var _control = require('./control');
13 |
14 | var _kline = require('./kline');
15 |
16 | var _kline2 = _interopRequireDefault(_kline);
17 |
18 | var _templates = require('./templates');
19 |
20 | var _jquery = require('jquery');
21 |
22 | var _jquery2 = _interopRequireDefault(_jquery);
23 |
24 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25 |
26 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
27 |
28 | var Chart = exports.Chart = function () {
29 | function Chart() {
30 | _classCallCheck(this, Chart);
31 |
32 | this._data = null;
33 | this._charStyle = "CandleStick";
34 | this._depthData = {
35 | array: null,
36 | asks_count: 0,
37 | bids_count: 0,
38 | asks_si: 0,
39 | asks_ei: 0,
40 | bids_si: 0,
41 | bids_ei: 0
42 | };
43 | this.strIsLine = false;
44 | this._range = _kline2.default.instance.range;
45 | this._symbol = _kline2.default.instance.symbol;
46 | }
47 |
48 | _createClass(Chart, [{
49 | key: 'setTitle',
50 | value: function setTitle() {
51 | var lang = _chart_manager.ChartManager.instance.getLanguage();
52 | var title = _kline2.default.instance.symbolName;
53 | title += ' ';
54 | title += this.strIsLine ? Chart.strPeriod[lang]['line'] : Chart.strPeriod[lang][this._range];
55 | title += (this._contract_unit + '/' + this._money_type).toUpperCase();
56 | _chart_manager.ChartManager.instance.setTitle('frame0.k0', title);
57 | }
58 | }, {
59 | key: 'setSymbol',
60 | value: function setSymbol(symbol) {
61 | this._symbol = symbol;
62 | this.updateDataAndDisplay();
63 | }
64 | }, {
65 | key: 'updateDataAndDisplay',
66 | value: function updateDataAndDisplay() {
67 | _kline2.default.instance.symbol = this._symbol;
68 | _kline2.default.instance.range = this._range;
69 | _chart_manager.ChartManager.instance.setCurrentDataSource('frame0.k0', this._symbol + '.' + this._range);
70 | _chart_manager.ChartManager.instance.setNormalMode();
71 | var f = _kline2.default.instance.chartMgr.getDataSource("frame0.k0").getLastDate();
72 | if (f === -1) {
73 | _kline2.default.instance.requestParam = _control.Control.setHttpRequestParam(_kline2.default.instance.symbol, _kline2.default.instance.range, _kline2.default.instance.limit, null);
74 | _control.Control.requestData(true);
75 | } else {
76 | _kline2.default.instance.requestParam = _control.Control.setHttpRequestParam(_kline2.default.instance.symbol, _kline2.default.instance.range, null, f.toString());
77 | _control.Control.requestData();
78 | }
79 | _chart_manager.ChartManager.instance.redraw('All', false);
80 | }
81 | }, {
82 | key: 'setCurrentContractUnit',
83 | value: function setCurrentContractUnit(contractUnit) {
84 | this._contract_unit = contractUnit;
85 | this.updateDataAndDisplay();
86 | }
87 | }, {
88 | key: 'setCurrentMoneyType',
89 | value: function setCurrentMoneyType(moneyType) {
90 | this._money_type = moneyType;
91 | this.updateDataAndDisplay();
92 | }
93 | }, {
94 | key: 'setCurrentPeriod',
95 | value: function setCurrentPeriod(period) {
96 | this._range = _kline2.default.instance.periodMap[period];
97 | if (_kline2.default.instance.type === "stomp" && _kline2.default.instance.stompClient.ws.readyState === 1) {
98 | _kline2.default.instance.subscribed.unsubscribe();
99 | _kline2.default.instance.subscribed = _kline2.default.instance.stompClient.subscribe(_kline2.default.instance.subscribePath + '/' + _kline2.default.instance.symbol + '/' + this._range, _control.Control.subscribeCallback);
100 | }
101 | this.updateDataAndDisplay();
102 | _kline2.default.instance.onRangeChangeFunc(this._range);
103 | }
104 | }, {
105 | key: 'updateDataSource',
106 | value: function updateDataSource(data) {
107 | this._data = data;
108 | _chart_manager.ChartManager.instance.updateData("frame0.k0", this._data);
109 | }
110 | }, {
111 | key: 'updateDepth',
112 | value: function updateDepth(array) {
113 | if (array == null) {
114 | this._depthData.array = [];
115 | _chart_manager.ChartManager.instance.redraw('All', false);
116 | return;
117 | }
118 | if (!array.asks || !array.bids || array.asks === '' || array.bids === '') return;
119 | var _data = this._depthData;
120 | _data.array = [];
121 | for (var i = 0; i < array.asks.length; i++) {
122 | var data = {};
123 | data.rate = array.asks[i][0];
124 | data.amount = array.asks[i][1];
125 | _data.array.push(data);
126 | }
127 | for (var _i = 0; _i < array.bids.length; _i++) {
128 | var _data2 = {};
129 | _data2.rate = array.bids[_i][0];
130 | _data2.amount = array.bids[_i][1];
131 | _data.array.push(_data2);
132 | }
133 | _data.asks_count = array.asks.length;
134 | _data.bids_count = array.bids.length;
135 | _data.asks_si = _data.asks_count - 1;
136 | _data.asks_ei = 0;
137 | _data.bids_si = _data.asks_count - 1;
138 | _data.bids_ei = _data.asks_count + _data.bids_count - 2;
139 | for (var _i2 = _data.asks_si; _i2 >= _data.asks_ei; _i2--) {
140 | if (_i2 === _data.asks_si && _data.array[_i2] !== undefined) {
141 | _data.array[_i2].amounts = _data.array[_i2].amount;
142 | } else if (_data.array[_i2 + 1] !== undefined) {
143 | _data.array[_i2].amounts = _data.array[_i2 + 1].amounts + _data.array[_i2].amount;
144 | }
145 | }
146 | for (var _i3 = _data.bids_si; _i3 <= _data.bids_ei; _i3++) {
147 | if (_i3 === _data.bids_si && _data.array[_i3] !== undefined) {
148 | _data.array[_i3].amounts = _data.array[_i3].amount;
149 | } else if (_data.array[_i3 - 1] !== undefined) {
150 | _data.array[_i3].amounts = _data.array[_i3 - 1].amounts + _data.array[_i3].amount;
151 | }
152 | }
153 | _chart_manager.ChartManager.instance.redraw('All', false);
154 | }
155 | }, {
156 | key: 'setMainIndicator',
157 | value: function setMainIndicator(indicName) {
158 | this._mainIndicator = indicName;
159 | if (indicName === 'NONE') {
160 | _chart_manager.ChartManager.instance.removeMainIndicator('frame0.k0');
161 | } else {
162 | _chart_manager.ChartManager.instance.setMainIndicator('frame0.k0', indicName);
163 | }
164 | _chart_manager.ChartManager.instance.redraw('All', true);
165 | }
166 | }, {
167 | key: 'setIndicator',
168 | value: function setIndicator(index, indicName) {
169 | if (indicName === 'NONE') {
170 | /*
171 | let index = 2;
172 | if (Template.displayVolume === false)
173 | index = 1;
174 | */
175 | var _index = 1;
176 | var areaName = _chart_manager.ChartManager.instance.getIndicatorAreaName('frame0.k0', _index);
177 | if (areaName !== '') _chart_manager.ChartManager.instance.removeIndicator(areaName);
178 | } else {
179 | /*
180 | let index = 2;
181 | if (Template.displayVolume === false)
182 | index = 1;
183 | */
184 | var _index2 = 1;
185 | var _areaName = _chart_manager.ChartManager.instance.getIndicatorAreaName('frame0.k0', _index2);
186 | if (_areaName === '') {
187 | _templates.Template.createIndicatorChartComps('frame0.k0', indicName);
188 | } else {
189 | _chart_manager.ChartManager.instance.setIndicator(_areaName, indicName);
190 | }
191 | }
192 | _chart_manager.ChartManager.instance.redraw('All', true);
193 | }
194 | }, {
195 | key: 'addIndicator',
196 | value: function addIndicator(indicName) {
197 | _chart_manager.ChartManager.instance.addIndicator(indicName);
198 | _chart_manager.ChartManager.instance.redraw('All', true);
199 | }
200 | }, {
201 | key: 'removeIndicator',
202 | value: function removeIndicator(indicName) {
203 | var areaName = _chart_manager.ChartManager.instance.getIndicatorAreaName(2);
204 | _chart_manager.ChartManager.instance.removeIndicator(areaName);
205 | _chart_manager.ChartManager.instance.redraw('All', true);
206 | }
207 | }]);
208 |
209 | return Chart;
210 | }();
211 |
212 | Chart.strPeriod = {
213 | 'zh-cn': {
214 | 'line': '(分时)',
215 | '1min': '(1分钟)',
216 | '5min': '(5分钟)',
217 | '15min': '(15分钟)',
218 | '30min': '(30分钟)',
219 | '1hour': '(1小时)',
220 | '1day': '(日线)',
221 | '1week': '(周线)',
222 | '3min': '(3分钟)',
223 | '2hour': '(2小时)',
224 | '4hour': '(4小时)',
225 | '6hour': '(6小时)',
226 | '12hour': '(12小时)',
227 | '3day': '(3天)'
228 | },
229 | 'en-us': {
230 | 'line': '(Line)',
231 | '1min': '(1m)',
232 | '5min': '(5m)',
233 | '15min': '(15m)',
234 | '30min': '(30m)',
235 | '1hour': '(1h)',
236 | '1day': '(1d)',
237 | '1week': '(1w)',
238 | '3min': '(3m)',
239 | '2hour': '(2h)',
240 | '4hour': '(4h)',
241 | '6hour': '(6h)',
242 | '12hour': '(12h)',
243 | '3day': '(3d)'
244 | },
245 | 'zh-tw': {
246 | 'line': '(分時)',
247 | '1min': '(1分鐘)',
248 | '5min': '(5分鐘)',
249 | '15min': '(15分鐘)',
250 | '30min': '(30分鐘)',
251 | '1hour': '(1小時)',
252 | '1day': '(日線)',
253 | '1week': '(周線)',
254 | '3min': '(3分鐘)',
255 | '2hour': '(2小時)',
256 | '4hour': '(4小時)',
257 | '6hour': '(6小時)',
258 | '12hour': '(12小時)',
259 | '3day': '(3天)'
260 | }
261 | };
--------------------------------------------------------------------------------
/npm_dist/js/chart_settings.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.ChartSettings = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _chart_manager = require('./chart_manager');
11 |
12 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13 |
14 | var ChartSettings = exports.ChartSettings = function () {
15 | function ChartSettings() {
16 | _classCallCheck(this, ChartSettings);
17 | }
18 |
19 | _createClass(ChartSettings, null, [{
20 | key: 'checkVersion',
21 | value: function checkVersion() {
22 | if (ChartSettings._data.ver < 2) {
23 | ChartSettings._data.ver = 2;
24 | var charts = ChartSettings._data.charts;
25 | charts.period_weight = {};
26 | charts.period_weight['line'] = 8;
27 | charts.period_weight['1min'] = 7;
28 | charts.period_weight['5min'] = 6;
29 | charts.period_weight['15min'] = 5;
30 | charts.period_weight['30min'] = 4;
31 | charts.period_weight['1hour'] = 3;
32 | charts.period_weight['1day'] = 2;
33 | charts.period_weight['1week'] = 1;
34 | charts.period_weight['3min'] = 0;
35 | charts.period_weight['2hour'] = 0;
36 | charts.period_weight['4hour'] = 0;
37 | charts.period_weight['6hour'] = 0;
38 | charts.period_weight['12hour'] = 0;
39 | charts.period_weight['3day'] = 0;
40 | }
41 | if (ChartSettings._data.ver < 3) {
42 | ChartSettings._data.ver = 3;
43 | var _charts = ChartSettings._data.charts;
44 | _charts.areaHeight = [];
45 | }
46 | }
47 | }, {
48 | key: 'get',
49 | value: function get() {
50 | if (ChartSettings._data === undefined) {
51 | ChartSettings.init();
52 | ChartSettings.load();
53 | ChartSettings.checkVersion();
54 | }
55 | return ChartSettings._data;
56 | }
57 | }, {
58 | key: 'init',
59 | value: function init() {
60 | var _indic_param = {};
61 | var _name = ['MA', 'EMA', 'VOLUME', 'MACD', 'KDJ', 'StochRSI', 'RSI', 'DMI', 'OBV', 'BOLL', 'DMA', 'TRIX', 'BRAR', 'VR', 'EMV', 'WR', 'ROC', 'MTM', 'PSY'];
62 | for (var i = 0; i < _name.length; i++) {
63 | var _value = _chart_manager.ChartManager.instance.createIndicatorAndRange('', _name[i], true);
64 | if (_value === null) continue;
65 | _indic_param[_name[i]] = [];
66 | var param = _value.indic.getParameters();
67 | for (var j = 0; j < param.length; j++) {
68 | _indic_param[_name[i]].push(param[j]);
69 | }
70 | }
71 | var _chart_style = 'CandleStick';
72 | var _m_indic = 'MA';
73 | var _indic = ['VOLUME', 'VOLUME'];
74 | var _range = '15m';
75 | var _frame = {};
76 | _frame.chartStyle = _chart_style;
77 | _frame.mIndic = _m_indic;
78 | _frame.indics = _indic;
79 | _frame.indicsStatus = 'open';
80 | _frame.period = _range;
81 | _frame.depthStatus = 'close';
82 | ChartSettings._data = {
83 | ver: 1,
84 | charts: _frame,
85 | indics: _indic_param,
86 | theme: "Dark"
87 | };
88 | ChartSettings.checkVersion();
89 | }
90 | }, {
91 | key: 'load',
92 | value: function load() {
93 | if (document.cookie.length <= 0) return;
94 | var start = document.cookie.indexOf("chartSettings=");
95 | if (start < 0) return;
96 | start += "chartSettings=".length;
97 | var end = document.cookie.indexOf(";", start);
98 | if (end < 0) end = document.cookie.length;
99 | var json = unescape(document.cookie.substring(start, end));
100 | ChartSettings._data = JSON.parse(json);
101 | }
102 | }, {
103 | key: 'save',
104 | value: function save() {
105 | var exdate = new Date();
106 | exdate.setDate(exdate.getDate() + 2);
107 | document.cookie = "chartSettings=" + escape(JSON.stringify(ChartSettings._data)) + ";expires=" + exdate.toGMTString();
108 | }
109 | }]);
110 |
111 | return ChartSettings;
112 | }();
--------------------------------------------------------------------------------
/npm_dist/js/cname.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10 |
11 | var CName = exports.CName = function () {
12 | function CName(name) {
13 | _classCallCheck(this, CName);
14 |
15 | this._names = [];
16 | this._comps = [];
17 | if (name instanceof CName) {
18 | this._names = name._names;
19 | this._comps = name._comps;
20 | } else {
21 | var comps = name.split(".");
22 | var dotNum = comps.length - 1;
23 | if (dotNum > 0) {
24 | this._comps = comps;
25 | this._names.push(comps[0]);
26 | for (var i = 1; i <= dotNum; i++) {
27 | this._names.push(this._names[i - 1] + "." + comps[i]);
28 | }
29 | } else {
30 | this._comps.push(name);
31 | this._names.push(name);
32 | }
33 | }
34 | }
35 |
36 | _createClass(CName, [{
37 | key: "getCompAt",
38 | value: function getCompAt(index) {
39 | if (index >= 0 && index < this._comps.length) return this._comps[index];
40 | return "";
41 | }
42 | }, {
43 | key: "getName",
44 | value: function getName(index) {
45 | if (index < 0) {
46 | if (this._names.length > 0) return this._names[this._names.length - 1];
47 | } else if (index < this._names.length) {
48 | return this._names[index];
49 | }
50 | return "";
51 | }
52 | }]);
53 |
54 | return CName;
55 | }();
--------------------------------------------------------------------------------
/npm_dist/js/cpoint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.CPoint = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _chart_manager = require('./chart_manager');
11 |
12 | var _named_object = require('./named_object');
13 |
14 | var _data_sources = require('./data_sources');
15 |
16 | var data_sources = _interopRequireWildcard(_data_sources);
17 |
18 | var _util = require('./util');
19 |
20 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
21 |
22 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
23 |
24 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
25 |
26 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
27 |
28 | var CPoint = exports.CPoint = function (_NamedObject) {
29 | _inherits(CPoint, _NamedObject);
30 |
31 | function CPoint(name) {
32 | _classCallCheck(this, CPoint);
33 |
34 | var _this = _possibleConstructorReturn(this, (CPoint.__proto__ || Object.getPrototypeOf(CPoint)).call(this, name));
35 |
36 | _this.pos = { index: -1, value: -1 };
37 |
38 | _this.state = CPoint.state.Hide;
39 | return _this;
40 | }
41 |
42 | _createClass(CPoint, [{
43 | key: 'getChartObjects',
44 | value: function getChartObjects() {
45 | var ppMgr = _chart_manager.ChartManager.instance;
46 | var ppCDS = ppMgr.getDataSource("frame0.k0");
47 | if (ppCDS === null || !_util.Util.isInstance(ppCDS, data_sources.MainDataSource)) return null;
48 | var ppTimeline = ppMgr.getTimeline("frame0.k0");
49 | if (ppTimeline === null) return null;
50 | var ppRange = ppMgr.getRange("frame0.k0.main");
51 | if (ppRange === null) return null;
52 | return { pMgr: ppMgr, pCDS: ppCDS, pTimeline: ppTimeline, pRange: ppRange };
53 | }
54 | }, {
55 | key: 'setPosXY',
56 | value: function setPosXY(x, y) {
57 | var pObj = this.getChartObjects();
58 | var i = pObj.pTimeline.toIndex(x);
59 | var v = pObj.pRange.toValue(y);
60 | var result = this.snapValue(i, v);
61 | if (result !== null) v = result;
62 | this.setPosIV(i, v);
63 | }
64 | }, {
65 | key: 'setPosXYNoSnap',
66 | value: function setPosXYNoSnap(x, y) {
67 | var pObj = this.getChartObjects();
68 | var i = pObj.pTimeline.toIndex(x);
69 | var v = pObj.pRange.toValue(y);
70 | this.setPosIV(i, v);
71 | }
72 | }, {
73 | key: 'setPosIV',
74 | value: function setPosIV(i, v) {
75 | this.pos = { index: i, value: v };
76 | }
77 | }, {
78 | key: 'getPosXY',
79 | value: function getPosXY() {
80 | var pObj = this.getChartObjects();
81 | var _x = pObj.pTimeline.toItemCenter(this.pos.index);
82 | var _y = pObj.pRange.toY(this.pos.value);
83 | return { x: _x, y: _y };
84 | }
85 | }, {
86 | key: 'getPosIV',
87 | value: function getPosIV() {
88 | return { i: this.pos.index, v: this.pos.value };
89 | }
90 | }, {
91 | key: 'setState',
92 | value: function setState(s) {
93 | this.state = s;
94 | }
95 | }, {
96 | key: 'getState',
97 | value: function getState() {
98 | return this.state;
99 | }
100 | }, {
101 | key: 'isSelected',
102 | value: function isSelected(x, y) {
103 | var xy = this.getPosXY();
104 | if (x < xy.x - 4 || x > xy.x + 4 || y < xy.y - 4 || y > xy.y + 4) return false;
105 | this.setState(CPoint.state.Highlight);
106 | return true;
107 | }
108 | }, {
109 | key: 'snapValue',
110 | value: function snapValue(i, v) {
111 | var pObj = this.getChartObjects();
112 | var result = null;
113 | var first = Math.floor(pObj.pTimeline.getFirstIndex());
114 | var last = Math.floor(pObj.pTimeline.getLastIndex());
115 | if (i < first || i > last) return result;
116 | var y = pObj.pRange.toY(v);
117 | var pData = pObj.pCDS.getDataAt(i);
118 | if (pData === null || pData === undefined) return result;
119 | var pDataPre = null;
120 | if (i > 0) pDataPre = pObj.pCDS.getDataAt(i - 1);else pDataPre = pObj.pCDS.getDataAt(i);
121 | var candleStickStyle = pObj.pMgr.getChartStyle(pObj.pCDS.getFrameName());
122 | var open = pObj.pRange.toY(pData.open);
123 | var high = pObj.pRange.toY(pData.high);
124 | var low = pObj.pRange.toY(pData.low);
125 | var close = pObj.pRange.toY(pData.close);
126 | if (candleStickStyle === "CandleStickHLC") {
127 | open = pObj.pRange.toY(pDataPre.close);
128 | }
129 | var dif_open = Math.abs(open - y);
130 | var dif_high = Math.abs(high - y);
131 | var dif_low = Math.abs(low - y);
132 | var dif_close = Math.abs(close - y);
133 | if (dif_open <= dif_high && dif_open <= dif_low && dif_open <= dif_close) {
134 | if (dif_open < 6) result = pData.open;
135 | }
136 | if (dif_high <= dif_open && dif_high <= dif_low && dif_high <= dif_close) {
137 | if (dif_high < 6) result = pData.high;
138 | }
139 | if (dif_low <= dif_open && dif_low <= dif_high && dif_low <= dif_close) {
140 | if (dif_low < 6) result = pData.low;
141 | }
142 | if (dif_close <= dif_open && dif_close <= dif_high && dif_close <= dif_low) {
143 | if (dif_close < 6) result = pData.close;
144 | }
145 | return result;
146 | }
147 | }]);
148 |
149 | return CPoint;
150 | }(_named_object.NamedObject);
151 |
152 | CPoint.state = {
153 | Hide: 0,
154 | Show: 1,
155 | Highlight: 2
156 | };
--------------------------------------------------------------------------------
/npm_dist/js/ctool_manager.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.CToolManager = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _named_object = require('./named_object');
11 |
12 | var _cpoint = require('./cpoint');
13 |
14 | var _ctools = require('./ctools');
15 |
16 | var ctools = _interopRequireWildcard(_ctools);
17 |
18 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
19 |
20 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21 |
22 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
23 |
24 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
25 |
26 | var CToolManager = exports.CToolManager = function (_NamedObject) {
27 | _inherits(CToolManager, _NamedObject);
28 |
29 | function CToolManager(name) {
30 | _classCallCheck(this, CToolManager);
31 |
32 | var _this = _possibleConstructorReturn(this, (CToolManager.__proto__ || Object.getPrototypeOf(CToolManager)).call(this, name));
33 |
34 | _this.selectedObject = -1;
35 | _this.toolObjects = [];
36 | return _this;
37 | }
38 |
39 | _createClass(CToolManager, [{
40 | key: 'getToolObjectCount',
41 | value: function getToolObjectCount() {
42 | return this.toolObjects.length;
43 | }
44 | }, {
45 | key: 'addToolObject',
46 | value: function addToolObject(o) {
47 | this.toolObjects.push(o);
48 | }
49 | }, {
50 | key: 'getToolObject',
51 | value: function getToolObject(i) {
52 | if (i < this.toolObjects.length && i >= 0) {
53 | return this.toolObjects[i];
54 | }
55 | return null;
56 | }
57 | }, {
58 | key: 'getCurrentObject',
59 | value: function getCurrentObject() {
60 | return this.getToolObject(this.getToolObjectCount() - 1);
61 | }
62 | }, {
63 | key: 'getSelectedObject',
64 | value: function getSelectedObject() {
65 | return this.getToolObject(this.selectedObject);
66 | }
67 | }, {
68 | key: 'delCurrentObject',
69 | value: function delCurrentObject() {
70 | this.toolObjects.splice(this.getToolObjectCount() - 1, 1);
71 | }
72 | }, {
73 | key: 'delSelectedObject',
74 | value: function delSelectedObject() {
75 | this.toolObjects.splice(this.selectedObject, 1);
76 | this.selectedObject = -1;
77 | }
78 | }, {
79 | key: 'acceptMouseMoveEvent',
80 | value: function acceptMouseMoveEvent(x, y) {
81 | if (this.selectedObject === -1) {
82 | var curr = this.toolObjects[this.getToolObjectCount() - 1];
83 | if (curr !== null && curr !== undefined && curr.getState() !== ctools.CToolObject.state.AfterDraw) return curr.acceptMouseMoveEvent(x, y);
84 | } else {
85 | var sel = this.toolObjects[this.selectedObject];
86 | if (sel.getState() === ctools.CToolObject.state.Draw) {
87 | return sel.acceptMouseMoveEvent(x, y);
88 | }
89 | sel.unselect();
90 | this.selectedObject = -1;
91 | }
92 | for (var index in this.toolObjects) {
93 | if (this.toolObjects[index].isSelected(x, y)) {
94 | this.selectedObject = index;
95 | return false;
96 | }
97 | }
98 | return false;
99 | }
100 | }, {
101 | key: 'acceptMouseDownEvent',
102 | value: function acceptMouseDownEvent(x, y) {
103 | this.mouseDownMove = false;
104 | if (this.selectedObject === -1) {
105 | var curr = this.toolObjects[this.getToolObjectCount() - 1];
106 | if (curr !== null && curr !== undefined && curr.getState() !== ctools.CToolObject.state.AfterDraw) return curr.acceptMouseDownEvent(x, y);
107 | } else {
108 | var sel = this.toolObjects[this.selectedObject];
109 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw) return sel.acceptMouseDownEvent(x, y);
110 | }
111 | return false;
112 | }
113 | }, {
114 | key: 'acceptMouseDownMoveEvent',
115 | value: function acceptMouseDownMoveEvent(x, y) {
116 | this.mouseDownMove = true;
117 | if (this.selectedObject === -1) {
118 | var curr = this.toolObjects[this.getToolObjectCount() - 1];
119 | if (curr !== null && curr !== undefined && curr.getState() === ctools.CToolObject.state.Draw) return curr.acceptMouseDownMoveEvent(x, y);
120 | return false;
121 | } else {
122 | var sel = this.toolObjects[this.selectedObject];
123 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw) {
124 | if (sel.acceptMouseDownMoveEvent(x, y) === true) {
125 | var point = this.toolObjects[this.selectedObject].points;
126 | for (var i = 0; i < point.length; i++) {
127 | if (point[i].state === _cpoint.CPoint.state.Highlight || point[i].state === _cpoint.CPoint.state.Show) {
128 | return true;
129 | }
130 | }
131 | }
132 | return true;
133 | }
134 | }
135 | }
136 | }, {
137 | key: 'acceptMouseUpEvent',
138 | value: function acceptMouseUpEvent(x, y) {
139 | if (this.mouseDownMove === true) {
140 | if (this.selectedObject === -1) {
141 | var _curr = this.toolObjects[this.getToolObjectCount() - 1];
142 | if (_curr !== null && _curr !== undefined && _curr.getState() === ctools.CToolObject.state.Draw) return _curr.acceptMouseUpEvent(x, y);
143 | return true;
144 | } else {
145 | var sel = this.toolObjects[this.selectedObject];
146 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw) return sel.acceptMouseUpEvent(x, y);
147 | }
148 | }
149 | if (this.selectedObject !== -1) {
150 | return true;
151 | }
152 | var curr = this.toolObjects[this.getToolObjectCount() - 1];
153 | if (curr !== null && curr !== undefined) {
154 | if (curr.getState() === ctools.CToolObject.state.Draw) return true;
155 | if (!curr.isValidMouseXY(x, y)) {
156 | return false;
157 | }
158 | if (curr.isSelected(x, y)) {
159 | return true;
160 | }
161 | }
162 | return false;
163 | }
164 | }]);
165 |
166 | return CToolManager;
167 | }(_named_object.NamedObject);
--------------------------------------------------------------------------------
/npm_dist/js/data_providers.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.IndicatorDataProvider = exports.MainDataProvider = exports.DataProvider = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _named_object = require('./named_object');
11 |
12 | var _chart_manager = require('./chart_manager');
13 |
14 | var _util = require('./util');
15 |
16 | var _data_sources = require('./data_sources');
17 |
18 | var data_sources = _interopRequireWildcard(_data_sources);
19 |
20 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
21 |
22 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
23 |
24 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
25 |
26 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
27 |
28 | var DataProvider = exports.DataProvider = function (_NamedObject) {
29 | _inherits(DataProvider, _NamedObject);
30 |
31 | function DataProvider(name) {
32 | _classCallCheck(this, DataProvider);
33 |
34 | var _this = _possibleConstructorReturn(this, (DataProvider.__proto__ || Object.getPrototypeOf(DataProvider)).call(this, name));
35 |
36 | _this._minValue = 0;
37 | _this._maxValue = 0;
38 | _this._minValueIndex = -1;
39 | _this._maxValueIndex = -1;
40 | return _this;
41 | }
42 |
43 | _createClass(DataProvider, [{
44 | key: 'getMinValue',
45 | value: function getMinValue() {
46 | return this._minValue;
47 | }
48 | }, {
49 | key: 'getMaxValue',
50 | value: function getMaxValue() {
51 | return this._maxValue;
52 | }
53 | }, {
54 | key: 'getMinValueIndex',
55 | value: function getMinValueIndex() {
56 | return this._minValueIndex;
57 | }
58 | }, {
59 | key: 'getMaxValueIndex',
60 | value: function getMaxValueIndex() {
61 | return this._maxValueIndex;
62 | }
63 | }, {
64 | key: 'getMinMaxAt',
65 | value: function getMinMaxAt(index, minmax) {
66 | return true;
67 | }
68 | }, {
69 | key: 'calcRange',
70 | value: function calcRange(firstIndexes, lastIndex, minmaxes, indexes) {
71 | var min = Number.MAX_VALUE;
72 | var max = -Number.MAX_VALUE;
73 | var minIndex = -1;
74 | var maxIndex = -1;
75 | var minmax = {};
76 | var i = lastIndex - 1;
77 | var n = firstIndexes.length - 1;
78 | for (; n >= 0; n--) {
79 | var first = firstIndexes[n];
80 | if (i < first) {
81 | minmaxes[n] = { "min": min, "max": max };
82 | } else {
83 | for (; i >= first; i--) {
84 | if (this.getMinMaxAt(i, minmax) === false) {
85 | continue;
86 | }
87 | if (min > minmax.min) {
88 | min = minmax.min;
89 | minIndex = i;
90 | }
91 | if (max < minmax.max) {
92 | max = minmax.max;
93 | maxIndex = i;
94 | }
95 | }
96 | minmaxes[n] = { "min": min, "max": max };
97 | }
98 | if (indexes !== null && indexes !== undefined) {
99 | indexes[n] = { "minIndex": minIndex, "maxIndex": maxIndex };
100 | }
101 | }
102 | }
103 | }, {
104 | key: 'updateRange',
105 | value: function updateRange() {
106 | var mgr = _chart_manager.ChartManager.instance;
107 | var timeline = mgr.getTimeline(this.getDataSourceName());
108 | var firstIndexes = [timeline.getFirstIndex()];
109 | var minmaxes = [{}];
110 | var indexes = [{}];
111 | this.calcRange(firstIndexes, timeline.getLastIndex(), minmaxes, indexes);
112 | this._minValue = minmaxes[0].min;
113 | this._maxValue = minmaxes[0].max;
114 | this._minValueIndex = indexes[0].minIndex;
115 | this._maxValueIndex = indexes[0].maxIndex;
116 | }
117 | }]);
118 |
119 | return DataProvider;
120 | }(_named_object.NamedObject);
121 |
122 | var MainDataProvider = exports.MainDataProvider = function (_DataProvider) {
123 | _inherits(MainDataProvider, _DataProvider);
124 |
125 | function MainDataProvider(name) {
126 | _classCallCheck(this, MainDataProvider);
127 |
128 | var _this2 = _possibleConstructorReturn(this, (MainDataProvider.__proto__ || Object.getPrototypeOf(MainDataProvider)).call(this, name));
129 |
130 | _this2._candlestickDS = null;
131 | return _this2;
132 | }
133 |
134 | _createClass(MainDataProvider, [{
135 | key: 'updateData',
136 | value: function updateData() {
137 | var mgr = _chart_manager.ChartManager.instance;
138 | var ds = mgr.getDataSource(this.getDataSourceName());
139 | if (!_util.Util.isInstance(ds, data_sources.MainDataSource)) {
140 | return;
141 | }
142 | this._candlestickDS = ds;
143 | }
144 | }, {
145 | key: 'getMinMaxAt',
146 | value: function getMinMaxAt(index, minmax) {
147 | var data = this._candlestickDS.getDataAt(index);
148 | minmax.min = data.low;
149 | minmax.max = data.high;
150 | return true;
151 | }
152 | }]);
153 |
154 | return MainDataProvider;
155 | }(DataProvider);
156 |
157 | var IndicatorDataProvider = exports.IndicatorDataProvider = function (_DataProvider2) {
158 | _inherits(IndicatorDataProvider, _DataProvider2);
159 |
160 | function IndicatorDataProvider() {
161 | _classCallCheck(this, IndicatorDataProvider);
162 |
163 | return _possibleConstructorReturn(this, (IndicatorDataProvider.__proto__ || Object.getPrototypeOf(IndicatorDataProvider)).apply(this, arguments));
164 | }
165 |
166 | _createClass(IndicatorDataProvider, [{
167 | key: 'getIndicator',
168 | value: function getIndicator() {
169 | return this._indicator;
170 | }
171 | }, {
172 | key: 'setIndicator',
173 | value: function setIndicator(v) {
174 | this._indicator = v;
175 | this.refresh();
176 | }
177 | }, {
178 | key: 'refresh',
179 | value: function refresh() {
180 | var mgr = _chart_manager.ChartManager.instance;
181 | var ds = mgr.getDataSource(this.getDataSourceName());
182 | if (ds.getDataCount() < 1) {
183 | return;
184 | }
185 | var indic = this._indicator;
186 | var i = void 0,
187 | last = ds.getDataCount();
188 | indic.clear();
189 | indic.reserve(last);
190 | for (i = 0; i < last; i++) {
191 | indic.execute(ds, i);
192 | }
193 | }
194 | }, {
195 | key: 'updateData',
196 | value: function updateData() {
197 | var mgr = _chart_manager.ChartManager.instance;
198 | var ds = mgr.getDataSource(this.getDataSourceName());
199 | if (ds.getDataCount() < 1) {
200 | return;
201 | }
202 | var indic = this._indicator;
203 | var mode = ds.getUpdateMode();
204 | switch (mode) {
205 | case data_sources.DataSource.UpdateMode.Refresh:
206 | {
207 | this.refresh();
208 | break;
209 | }
210 | case data_sources.DataSource.UpdateMode.Append:
211 | {
212 | indic.reserve(ds.getAppendedCount());
213 | break;
214 | }
215 | case data_sources.DataSource.UpdateMode.Update:
216 | {
217 | var i = void 0,
218 | last = ds.getDataCount();
219 | var cnt = ds.getUpdatedCount() + ds.getAppendedCount();
220 | for (i = last - cnt; i < last; i++) {
221 | indic.execute(ds, i);
222 | }
223 | break;
224 | }
225 | }
226 | }
227 | }, {
228 | key: 'getMinMaxAt',
229 | value: function getMinMaxAt(index, minmax) {
230 | minmax.min = Number.MAX_VALUE;
231 | minmax.max = -Number.MAX_VALUE;
232 | var result = void 0,
233 | valid = false;
234 | var i = void 0,
235 | cnt = this._indicator.getOutputCount();
236 | for (i = 0; i < cnt; i++) {
237 | result = this._indicator.getOutputAt(i).execute(index);
238 | if (isNaN(result) === false) {
239 | valid = true;
240 | if (minmax.min > result) {
241 | minmax.min = result;
242 | }
243 | if (minmax.max < result) {
244 | minmax.max = result;
245 | }
246 | }
247 | }
248 | return valid;
249 | }
250 | }]);
251 |
252 | return IndicatorDataProvider;
253 | }(DataProvider);
--------------------------------------------------------------------------------
/npm_dist/js/data_sources.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.MainDataSource = exports.DataSource = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _named_object = require('./named_object');
11 |
12 | var _ctool_manager = require('./ctool_manager');
13 |
14 | var _kline = require('./kline');
15 |
16 | var _kline2 = _interopRequireDefault(_kline);
17 |
18 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19 |
20 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21 |
22 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
23 |
24 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
25 |
26 | var DataSource = exports.DataSource = function (_NamedObject) {
27 | _inherits(DataSource, _NamedObject);
28 |
29 | function DataSource(name) {
30 | _classCallCheck(this, DataSource);
31 |
32 | return _possibleConstructorReturn(this, (DataSource.__proto__ || Object.getPrototypeOf(DataSource)).call(this, name));
33 | }
34 |
35 | _createClass(DataSource, [{
36 | key: 'getUpdateMode',
37 | value: function getUpdateMode() {
38 | return this._updateMode;
39 | }
40 | }, {
41 | key: 'setUpdateMode',
42 | value: function setUpdateMode(mode) {
43 | this._updateMode = mode;
44 | }
45 | }, {
46 | key: 'getCacheSize',
47 | value: function getCacheSize() {
48 | return 0;
49 | }
50 | }, {
51 | key: 'getDataCount',
52 | value: function getDataCount() {
53 | return 0;
54 | }
55 | }, {
56 | key: 'getDataAt',
57 | value: function getDataAt(index) {
58 | return this._dataItems[index];
59 | }
60 | }]);
61 |
62 | return DataSource;
63 | }(_named_object.NamedObject);
64 |
65 | DataSource.UpdateMode = {
66 | DoNothing: 0,
67 | Refresh: 1,
68 | Update: 2,
69 | Append: 3
70 | };
71 |
72 | var MainDataSource = exports.MainDataSource = function (_DataSource) {
73 | _inherits(MainDataSource, _DataSource);
74 |
75 | function MainDataSource(name) {
76 | _classCallCheck(this, MainDataSource);
77 |
78 | var _this2 = _possibleConstructorReturn(this, (MainDataSource.__proto__ || Object.getPrototypeOf(MainDataSource)).call(this, name));
79 |
80 | _this2._erasedCount = 0;
81 | _this2._dataItems = [];
82 | _this2._decimalDigits = 0;
83 | _this2.toolManager = new _ctool_manager.CToolManager(name);
84 | return _this2;
85 | }
86 |
87 | _createClass(MainDataSource, [{
88 | key: 'getCacheSize',
89 | value: function getCacheSize() {
90 | return this._dataItems.length;
91 | }
92 | }, {
93 | key: 'getDataCount',
94 | value: function getDataCount() {
95 | return this._dataItems.length;
96 | }
97 | }, {
98 | key: 'getUpdatedCount',
99 | value: function getUpdatedCount() {
100 | return this._updatedCount;
101 | }
102 | }, {
103 | key: 'getAppendedCount',
104 | value: function getAppendedCount() {
105 | return this._appendedCount;
106 | }
107 | }, {
108 | key: 'getErasedCount',
109 | value: function getErasedCount() {
110 | return this._erasedCount;
111 | }
112 | }, {
113 | key: 'getDecimalDigits',
114 | value: function getDecimalDigits() {
115 | return this._decimalDigits;
116 | }
117 | }, {
118 | key: 'calcDecimalDigits',
119 | value: function calcDecimalDigits(v) {
120 | var str = "" + v;
121 | var i = str.indexOf('.');
122 | if (i < 0) {
123 | return 0;
124 | }
125 | return str.length - 1 - i;
126 | }
127 | }, {
128 | key: 'getLastDate',
129 | value: function getLastDate() {
130 | var count = this.getDataCount();
131 | if (count < 1) {
132 | return -1;
133 | }
134 | return this.getDataAt(count - 1).date;
135 | }
136 | }, {
137 | key: 'getDataAt',
138 | value: function getDataAt(index) {
139 | return this._dataItems[index];
140 | }
141 | }, {
142 | key: 'update',
143 | value: function update(data) {
144 | this._updatedCount = 0;
145 | this._appendedCount = 0;
146 | this._erasedCount = 0;
147 | var len = this._dataItems.length;
148 | if (len > 0) {
149 | var lastIndex = len - 1;
150 | var lastItem = this._dataItems[lastIndex];
151 | var _e = void 0,
152 | _i = void 0,
153 | _cnt = data.length;
154 | for (_i = 0; _i < _cnt; _i++) {
155 | _e = data[_i];
156 | if (_e[0] === lastItem.date) {
157 | if (lastItem.open === _e[1] && lastItem.high === _e[2] && lastItem.low === _e[3] && lastItem.close === _e[4] && lastItem.volume === _e[5]) {
158 | this.setUpdateMode(DataSource.UpdateMode.DoNothing);
159 | } else {
160 | this.setUpdateMode(DataSource.UpdateMode.Update);
161 | this._dataItems[lastIndex] = {
162 | date: _e[0],
163 | open: _e[1],
164 | high: _e[2],
165 | low: _e[3],
166 | close: _e[4],
167 | volume: _e[5]
168 | };
169 | this._updatedCount++;
170 | }
171 | _i++;
172 | if (_i < _cnt) {
173 | this.setUpdateMode(DataSource.UpdateMode.Append);
174 | for (; _i < _cnt; _i++, this._appendedCount++) {
175 | _e = data[_i];
176 | this._dataItems.push({
177 | date: _e[0],
178 | open: _e[1],
179 | high: _e[2],
180 | low: _e[3],
181 | close: _e[4],
182 | volume: _e[5]
183 | });
184 | }
185 | }
186 | return true;
187 | }
188 | }
189 | if (_cnt < _kline2.default.instance.limit) {
190 | this.setUpdateMode(DataSource.UpdateMode.DoNothing);
191 | return false;
192 | }
193 | }
194 | this.setUpdateMode(DataSource.UpdateMode.Refresh);
195 | this._dataItems = [];
196 | var d = void 0,
197 | n = void 0,
198 | e = void 0,
199 | i = void 0,
200 | cnt = data.length;
201 | for (i = 0; i < cnt; i++) {
202 | e = data[i];
203 | for (n = 1; n <= 4; n++) {
204 | d = this.calcDecimalDigits(e[n]);
205 | if (this._decimalDigits < d) this._decimalDigits = d;
206 | }
207 | this._dataItems.push({
208 | date: e[0],
209 | open: e[1],
210 | high: e[2],
211 | low: e[3],
212 | close: e[4],
213 | volume: e[5]
214 | });
215 | }
216 | return true;
217 | }
218 | }, {
219 | key: 'select',
220 | value: function select(id) {
221 | this.toolManager.selecedObject = id;
222 | }
223 | }, {
224 | key: 'unselect',
225 | value: function unselect() {
226 | this.toolManager.selecedObject = -1;
227 | }
228 | }, {
229 | key: 'addToolObject',
230 | value: function addToolObject(toolObject) {
231 | this.toolManager.addToolObject(toolObject);
232 | }
233 | }, {
234 | key: 'delToolObject',
235 | value: function delToolObject() {
236 | this.toolManager.delCurrentObject();
237 | }
238 | }, {
239 | key: 'getToolObject',
240 | value: function getToolObject(index) {
241 | return this.toolManager.getToolObject(index);
242 | }
243 | }, {
244 | key: 'getToolObjectCount',
245 | value: function getToolObjectCount() {
246 | return this.toolManager.toolObjects.length;
247 | }
248 | }, {
249 | key: 'getCurrentToolObject',
250 | value: function getCurrentToolObject() {
251 | return this.toolManager.getCurrentObject();
252 | }
253 | }, {
254 | key: 'getSelectToolObjcet',
255 | value: function getSelectToolObjcet() {
256 | return this.toolManager.getSelectedObject();
257 | }
258 | }, {
259 | key: 'delSelectToolObject',
260 | value: function delSelectToolObject() {
261 | this.toolManager.delSelectedObject();
262 | }
263 | }]);
264 |
265 | return MainDataSource;
266 | }(DataSource);
--------------------------------------------------------------------------------
/npm_dist/js/mevent.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10 |
11 | var MEvent = exports.MEvent = function () {
12 | function MEvent() {
13 | _classCallCheck(this, MEvent);
14 |
15 | this._handlers = [];
16 | }
17 |
18 | _createClass(MEvent, [{
19 | key: "addHandler",
20 | value: function addHandler(o, f) {
21 | if (this.indexOf(o, f) < 0) this._handlers.push({ obj: o, func: f });
22 | }
23 | }, {
24 | key: "removeHandler",
25 | value: function removeHandler(o, f) {
26 | var i = this.indexOf(o, f);
27 | if (i >= 0) this._handlers.splice(i, 1);
28 | }
29 | }, {
30 | key: "raise",
31 | value: function raise(s, g) {
32 | var a = this._handlers;
33 | var e = void 0,
34 | i = void 0,
35 | c = a.length;
36 | for (i = 0; i < c; i++) {
37 | e = a[i];
38 | e.func(s, g);
39 | }
40 | }
41 | }, {
42 | key: "indexOf",
43 | value: function indexOf(o, f) {
44 | var a = this._handlers;
45 | var e = void 0,
46 | i = void 0,
47 | c = a.length;
48 | for (i = 0; i < c; i++) {
49 | e = a[i];
50 | if (o === e.obj && f === e.func) return i;
51 | }
52 | return -1;
53 | }
54 | }]);
55 |
56 | return MEvent;
57 | }();
--------------------------------------------------------------------------------
/npm_dist/js/named_object.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.NamedObject = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _cname = require('./cname');
11 |
12 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
13 |
14 | var NamedObject = exports.NamedObject = function () {
15 | function NamedObject(name) {
16 | _classCallCheck(this, NamedObject);
17 |
18 | this._name = name;
19 | this._nameObj = new _cname.CName(name);
20 | }
21 |
22 | _createClass(NamedObject, [{
23 | key: 'getFrameName',
24 | value: function getFrameName() {
25 | return this._nameObj.getName(0);
26 | }
27 | }, {
28 | key: 'getDataSourceName',
29 | value: function getDataSourceName() {
30 | return this._nameObj.getName(1);
31 | }
32 | }, {
33 | key: 'getAreaName',
34 | value: function getAreaName() {
35 | return this._nameObj.getName(2);
36 | }
37 | }, {
38 | key: 'getName',
39 | value: function getName() {
40 | return this._nameObj.getName(-1);
41 | }
42 | }, {
43 | key: 'getNameObject',
44 | value: function getNameObject() {
45 | return this._nameObj;
46 | }
47 | }, {
48 | key: 'getRectCrossPt',
49 | value: function getRectCrossPt(rect, startPt, endPt) {
50 | var crossPt = void 0;
51 | var firstPt = { x: -1, y: -1 };
52 | var secondPt = { x: -1, y: -1 };
53 | var xdiff = endPt.x - startPt.x;
54 | var ydiff = endPt.y - startPt.y;
55 | if (Math.abs(xdiff) < 2) {
56 | firstPt = { x: startPt.x, y: rect.top };
57 | secondPt = { x: endPt.x, y: rect.bottom };
58 | crossPt = [firstPt, secondPt];
59 | return crossPt;
60 | }
61 | var k = ydiff / xdiff;
62 | secondPt.x = rect.right;
63 | secondPt.y = startPt.y + (rect.right - startPt.x) * k;
64 | firstPt.x = rect.left;
65 | firstPt.y = startPt.y + (rect.left - startPt.x) * k;
66 | crossPt = [firstPt, secondPt];
67 | return crossPt;
68 | }
69 | }]);
70 |
71 | return NamedObject;
72 | }();
--------------------------------------------------------------------------------
/npm_dist/js/templates.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.TemplateMeasuringHandler = exports.DefaultTemplate = exports.Template = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _chart_manager = require('./chart_manager');
11 |
12 | var _chart_settings = require('./chart_settings');
13 |
14 | var _data_sources = require('./data_sources');
15 |
16 | var data_sources = _interopRequireWildcard(_data_sources);
17 |
18 | var _data_providers = require('./data_providers');
19 |
20 | var data_providers = _interopRequireWildcard(_data_providers);
21 |
22 | var _areas = require('./areas');
23 |
24 | var areas = _interopRequireWildcard(_areas);
25 |
26 | var _plotters = require('./plotters');
27 |
28 | var plotters = _interopRequireWildcard(_plotters);
29 |
30 | var _timeline = require('./timeline');
31 |
32 | var _cname = require('./cname');
33 |
34 | var _layouts = require('./layouts');
35 |
36 | var layouts = _interopRequireWildcard(_layouts);
37 |
38 | var _themes = require('./themes');
39 |
40 | var themes = _interopRequireWildcard(_themes);
41 |
42 | var _ranges = require('./ranges');
43 |
44 | var ranges = _interopRequireWildcard(_ranges);
45 |
46 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
47 |
48 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
49 |
50 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
51 |
52 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
53 |
54 | var Template = exports.Template = function () {
55 | function Template() {
56 | _classCallCheck(this, Template);
57 | }
58 |
59 | _createClass(Template, null, [{
60 | key: 'createCandlestickDataSource',
61 | value: function createCandlestickDataSource(dsAlias) {
62 | return new data_sources.MainDataSource(dsAlias);
63 | }
64 | }, {
65 | key: 'createDataSource',
66 | value: function createDataSource(dsName, dsAlias, createFunc) {
67 | var mgr = _chart_manager.ChartManager.instance;
68 | if (mgr.getCachedDataSource(dsAlias) === null) mgr.setCachedDataSource(dsAlias, createFunc(dsAlias));
69 | mgr.setCurrentDataSource(dsName, dsAlias);
70 | mgr.updateData(dsName, null);
71 | }
72 | }, {
73 | key: 'createTableComps',
74 | value: function createTableComps(dsName) {
75 | this.createMainChartComps(dsName);
76 | this.createTimelineComps(dsName);
77 | }
78 | }, {
79 | key: 'createMainChartComps',
80 | value: function createMainChartComps(dsName) {
81 | var mgr = _chart_manager.ChartManager.instance;
82 | var tableLayout = mgr.getArea(dsName + ".charts");
83 | var areaName = dsName + ".main";
84 | var rangeAreaName = areaName + "Range";
85 | var area = new areas.MainArea(areaName);
86 | mgr.setArea(areaName, area);
87 | tableLayout.addArea(area);
88 | var rangeArea = new areas.MainRangeArea(rangeAreaName);
89 | mgr.setArea(rangeAreaName, rangeArea);
90 | tableLayout.addArea(rangeArea);
91 | var dp = new data_providers.MainDataProvider(areaName + ".main");
92 | mgr.setDataProvider(dp.getName(), dp);
93 | mgr.setMainIndicator(dsName, "MA");
94 | var range = new ranges.MainRange(areaName);
95 | mgr.setRange(range.getName(), range);
96 | range.setPaddingTop(28);
97 | range.setPaddingBottom(12);
98 | var plotter = new plotters.MainAreaBackgroundPlotter(areaName + ".background");
99 | mgr.setPlotter(plotter.getName(), plotter);
100 | plotter = new plotters.CGridPlotter(areaName + ".grid");
101 | mgr.setPlotter(plotter.getName(), plotter);
102 | plotter = new plotters.CandlestickPlotter(areaName + ".main");
103 | mgr.setPlotter(plotter.getName(), plotter);
104 | plotter = new plotters.MinMaxPlotter(areaName + ".decoration");
105 | mgr.setPlotter(plotter.getName(), plotter);
106 | plotter = new plotters.MainInfoPlotter(areaName + ".info");
107 | mgr.setPlotter(plotter.getName(), plotter);
108 | plotter = new plotters.SelectionPlotter(areaName + ".selection");
109 | mgr.setPlotter(plotter.getName(), plotter);
110 | plotter = new plotters.CDynamicLinePlotter(areaName + ".tool");
111 | mgr.setPlotter(plotter.getName(), plotter);
112 | plotter = new plotters.RangeAreaBackgroundPlotter(areaName + "Range.background");
113 | mgr.setPlotter(plotter.getName(), plotter);
114 | plotter = new plotters.COrderGraphPlotter(areaName + "Range.grid");
115 | mgr.setPlotter(plotter.getName(), plotter);
116 | plotter = new plotters.RangePlotter(areaName + "Range.main");
117 | mgr.setPlotter(plotter.getName(), plotter);
118 | plotter = new plotters.RangeSelectionPlotter(areaName + "Range.selection");
119 | mgr.setPlotter(plotter.getName(), plotter);
120 | plotter = new plotters.LastClosePlotter(areaName + "Range.decoration");
121 | mgr.setPlotter(plotter.getName(), plotter);
122 | }
123 | }, {
124 | key: 'createIndicatorChartComps',
125 | value: function createIndicatorChartComps(dsName, indicName) {
126 | var mgr = _chart_manager.ChartManager.instance;
127 | var tableLayout = mgr.getArea(dsName + ".charts");
128 | var areaName = dsName + ".indic" + tableLayout.getNextRowId();
129 | var rangeAreaName = areaName + "Range";
130 | var area = new areas.IndicatorArea(areaName);
131 | mgr.setArea(areaName, area);
132 | tableLayout.addArea(area);
133 | var rowIndex = tableLayout.getAreaCount() >> 1;
134 | var heights = _chart_settings.ChartSettings.get().charts.areaHeight;
135 | if (heights.length > rowIndex) {
136 | var a = void 0,
137 | i = void 0;
138 | for (i = 0; i < rowIndex; i++) {
139 | a = tableLayout.getAreaAt(i << 1);
140 | a.setTop(0);
141 | a.setBottom(heights[i]);
142 | }
143 | area.setTop(0);
144 | area.setBottom(heights[rowIndex]);
145 | }
146 | var rangeArea = new areas.IndicatorRangeArea(rangeAreaName);
147 | mgr.setArea(rangeAreaName, rangeArea);
148 | tableLayout.addArea(rangeArea);
149 | var dp = new data_providers.IndicatorDataProvider(areaName + ".secondary");
150 | mgr.setDataProvider(dp.getName(), dp);
151 | if (mgr.setIndicator(areaName, indicName) === false) {
152 | mgr.removeIndicator(areaName);
153 | return;
154 | }
155 | var plotter = new plotters.MainAreaBackgroundPlotter(areaName + ".background");
156 | mgr.setPlotter(plotter.getName(), plotter);
157 | plotter = new plotters.CGridPlotter(areaName + ".grid");
158 | mgr.setPlotter(plotter.getName(), plotter);
159 | plotter = new plotters.IndicatorPlotter(areaName + ".secondary");
160 | mgr.setPlotter(plotter.getName(), plotter);
161 | plotter = new plotters.IndicatorInfoPlotter(areaName + ".info");
162 | mgr.setPlotter(plotter.getName(), plotter);
163 | plotter = new plotters.SelectionPlotter(areaName + ".selection");
164 | mgr.setPlotter(plotter.getName(), plotter);
165 | plotter = new plotters.RangeAreaBackgroundPlotter(areaName + "Range.background");
166 | mgr.setPlotter(plotter.getName(), plotter);
167 | plotter = new plotters.RangePlotter(areaName + "Range.main");
168 | mgr.setPlotter(plotter.getName(), plotter);
169 | plotter = new plotters.RangeSelectionPlotter(areaName + "Range.selection");
170 | mgr.setPlotter(plotter.getName(), plotter);
171 | }
172 | }, {
173 | key: 'createTimelineComps',
174 | value: function createTimelineComps(dsName) {
175 | var mgr = _chart_manager.ChartManager.instance;
176 | var plotter = void 0;
177 | var timeline = new _timeline.Timeline(dsName);
178 | mgr.setTimeline(timeline.getName(), timeline);
179 | plotter = new plotters.TimelineAreaBackgroundPlotter(dsName + ".timeline.background");
180 | mgr.setPlotter(plotter.getName(), plotter);
181 | plotter = new plotters.TimelinePlotter(dsName + ".timeline.main");
182 | mgr.setPlotter(plotter.getName(), plotter);
183 | plotter = new plotters.TimelineSelectionPlotter(dsName + ".timeline.selection");
184 | mgr.setPlotter(plotter.getName(), plotter);
185 | }
186 | }, {
187 | key: 'createLiveOrderComps',
188 | value: function createLiveOrderComps(dsName) {
189 | var mgr = _chart_manager.ChartManager.instance;
190 | var plotter = void 0;
191 | plotter = new plotters.BackgroundPlotter(dsName + ".main.background");
192 | mgr.setPlotter(plotter.getName(), plotter);
193 | plotter = new plotters.CLiveOrderPlotter(dsName + ".main.main");
194 | mgr.setPlotter(plotter.getName(), plotter);
195 | }
196 | }, {
197 | key: 'createLiveTradeComps',
198 | value: function createLiveTradeComps(dsName) {
199 | var mgr = _chart_manager.ChartManager.instance;
200 | var plotter = void 0;
201 | plotter = new plotters.BackgroundPlotter(dsName + ".main.background");
202 | mgr.setPlotter(plotter.getName(), plotter);
203 | plotter = new plotters.CLiveTradePlotter(dsName + ".main.main");
204 | mgr.setPlotter(plotter.getName(), plotter);
205 | }
206 | }]);
207 |
208 | return Template;
209 | }();
210 |
211 | var DefaultTemplate = exports.DefaultTemplate = function (_Template) {
212 | _inherits(DefaultTemplate, _Template);
213 |
214 | function DefaultTemplate() {
215 | _classCallCheck(this, DefaultTemplate);
216 |
217 | return _possibleConstructorReturn(this, (DefaultTemplate.__proto__ || Object.getPrototypeOf(DefaultTemplate)).apply(this, arguments));
218 | }
219 |
220 | _createClass(DefaultTemplate, null, [{
221 | key: 'loadTemplate',
222 | value: function loadTemplate(dsName, dsAlias) {
223 | var mgr = _chart_manager.ChartManager.instance;
224 | var settings = _chart_settings.ChartSettings.get();
225 | var frameName = new _cname.CName(dsName).getCompAt(0);
226 | mgr.unloadTemplate(frameName);
227 | this.createDataSource(dsName, dsAlias, this.createCandlestickDataSource);
228 | var frame = new layouts.DockableLayout(frameName);
229 | mgr.setFrame(frame.getName(), frame);
230 | mgr.setArea(frame.getName(), frame);
231 | frame.setGridColor(themes.Theme.Color.Grid1);
232 | var area = new areas.TimelineArea(dsName + ".timeline");
233 | mgr.setArea(area.getName(), area);
234 | frame.addArea(area);
235 | area.setDockStyle(areas.ChartArea.DockStyle.Bottom);
236 | area.Measuring.addHandler(area, TemplateMeasuringHandler.onMeasuring);
237 | var tableLayout = new layouts.TableLayout(dsName + ".charts");
238 | mgr.setArea(tableLayout.getName(), tableLayout);
239 | tableLayout.setDockStyle(areas.ChartArea.DockStyle.Fill);
240 | frame.addArea(tableLayout);
241 | this.createTableComps(dsName);
242 | mgr.setThemeName(frameName, settings.theme);
243 | return mgr;
244 | }
245 | }]);
246 |
247 | return DefaultTemplate;
248 | }(Template);
249 |
250 | var TemplateMeasuringHandler = exports.TemplateMeasuringHandler = function () {
251 | function TemplateMeasuringHandler() {
252 | _classCallCheck(this, TemplateMeasuringHandler);
253 | }
254 |
255 | _createClass(TemplateMeasuringHandler, null, [{
256 | key: 'onMeasuring',
257 | value: function onMeasuring(sender, args) {
258 | var width = args.Width;
259 | var height = args.Height;
260 | var areaName = sender.getNameObject().getCompAt(2);
261 | if (areaName === "timeline") {
262 | sender.setMeasuredDimension(width, 22);
263 | }
264 | }
265 | }]);
266 |
267 | return TemplateMeasuringHandler;
268 | }();
--------------------------------------------------------------------------------
/npm_dist/js/themes.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.LightTheme = exports.DarkTheme = exports.Theme = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _kline = require("./kline");
11 |
12 | var _kline2 = _interopRequireDefault(_kline);
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
17 |
18 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
19 |
20 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21 |
22 | var Theme = exports.Theme = function () {
23 | function Theme() {
24 | _classCallCheck(this, Theme);
25 |
26 | this._colors = [];
27 | this._fonts = [];
28 | }
29 |
30 | _createClass(Theme, [{
31 | key: "getColor",
32 | value: function getColor(which) {
33 | return this._colors[which];
34 | }
35 | }, {
36 | key: "getFont",
37 | value: function getFont(which) {
38 | return this._fonts[which];
39 | }
40 | }]);
41 |
42 | return Theme;
43 | }();
44 |
45 | Theme.theme_color_id = 0;
46 | Theme.theme_font_id = 0;
47 | Theme.Color = {
48 | Positive: Theme.theme_color_id++,
49 | Negative: Theme.theme_color_id++,
50 | PositiveDark: Theme.theme_color_id++,
51 | NegativeDark: Theme.theme_color_id++,
52 | Unchanged: Theme.theme_color_id++,
53 | Background: Theme.theme_color_id++,
54 | Cursor: Theme.theme_color_id++,
55 | RangeMark: Theme.theme_color_id++,
56 | Indicator0: Theme.theme_color_id++,
57 | Indicator1: Theme.theme_color_id++,
58 | Indicator2: Theme.theme_color_id++,
59 | Indicator3: Theme.theme_color_id++,
60 | Indicator4: Theme.theme_color_id++,
61 | Indicator5: Theme.theme_color_id++,
62 | Grid0: Theme.theme_color_id++,
63 | Grid1: Theme.theme_color_id++,
64 | Grid2: Theme.theme_color_id++,
65 | Grid3: Theme.theme_color_id++,
66 | Grid4: Theme.theme_color_id++,
67 | TextPositive: Theme.theme_color_id++,
68 | TextNegative: Theme.theme_color_id++,
69 | Text0: Theme.theme_color_id++,
70 | Text1: Theme.theme_color_id++,
71 | Text2: Theme.theme_color_id++,
72 | Text3: Theme.theme_color_id++,
73 | Text4: Theme.theme_color_id++,
74 | LineColorNormal: Theme.theme_color_id++,
75 | LineColorSelected: Theme.theme_color_id++,
76 | CircleColorFill: Theme.theme_color_id++,
77 | CircleColorStroke: Theme.theme_color_id++
78 | };
79 | Theme.Font = {
80 | Default: Theme.theme_font_id++
81 | };
82 |
83 | var DarkTheme = exports.DarkTheme = function (_Theme) {
84 | _inherits(DarkTheme, _Theme);
85 |
86 | function DarkTheme() {
87 | _classCallCheck(this, DarkTheme);
88 |
89 | var _this = _possibleConstructorReturn(this, (DarkTheme.__proto__ || Object.getPrototypeOf(DarkTheme)).call(this));
90 |
91 | _this._colors = [];
92 |
93 | _this._colors[Theme.Color.Positive] = "#19b34c";
94 | _this._colors[Theme.Color.Negative] = "#990e0e";
95 | _this._colors[Theme.Color.PositiveDark] = "#004718";
96 | _this._colors[Theme.Color.NegativeDark] = "#3b0e08";
97 |
98 | _this._colors[Theme.Color.Unchanged] = "#fff";
99 | _this._colors[Theme.Color.Background] = "#161616";
100 | _this._colors[Theme.Color.Cursor] = "#aaa";
101 | _this._colors[Theme.Color.RangeMark] = "#f9ee30";
102 | _this._colors[Theme.Color.Indicator0] = "#ddd";
103 | _this._colors[Theme.Color.Indicator1] = "#f9ee30";
104 | _this._colors[Theme.Color.Indicator2] = "#f600ff";
105 | _this._colors[Theme.Color.Indicator3] = "#6bf";
106 | _this._colors[Theme.Color.Indicator4] = "#a5cf81";
107 | _this._colors[Theme.Color.Indicator5] = "#e18b89";
108 | _this._colors[Theme.Color.Grid0] = "#555";
109 | _this._colors[Theme.Color.Grid1] = "#555";
110 | _this._colors[Theme.Color.Grid3] = "#888";
111 | _this._colors[Theme.Color.Grid4] = "#aaa";
112 | _this._colors[Theme.Color.TextPositive] = "#1bd357";
113 | _this._colors[Theme.Color.TextNegative] = "#ff6f5e";
114 | _this._colors[Theme.Color.Text0] = "#444";
115 | _this._colors[Theme.Color.Text1] = "#666";
116 | _this._colors[Theme.Color.Text2] = "#888";
117 | _this._colors[Theme.Color.Text3] = "#aaa";
118 | _this._colors[Theme.Color.Text4] = "#ccc";
119 | _this._colors[Theme.Color.LineColorNormal] = "#a6a6a6";
120 | _this._colors[Theme.Color.LineColorSelected] = "#ffffff";
121 | _this._colors[Theme.Color.CircleColorFill] = "#161616";
122 | _this._colors[Theme.Color.CircleColorStroke] = "#ffffff";
123 | _this._fonts = [];
124 | _this._fonts[Theme.Font.Default] = "12px Tahoma";
125 | return _this;
126 | }
127 |
128 | return DarkTheme;
129 | }(Theme);
130 |
131 | var LightTheme = exports.LightTheme = function (_Theme2) {
132 | _inherits(LightTheme, _Theme2);
133 |
134 | function LightTheme() {
135 | _classCallCheck(this, LightTheme);
136 |
137 | var _this2 = _possibleConstructorReturn(this, (LightTheme.__proto__ || Object.getPrototypeOf(LightTheme)).call(this));
138 |
139 | _this2._colors = [];
140 |
141 | _this2._colors[Theme.Color.Positive] = "#53b37b";
142 | _this2._colors[Theme.Color.Negative] = "#db5542";
143 | _this2._colors[Theme.Color.PositiveDark] = "#66d293";
144 | _this2._colors[Theme.Color.NegativeDark] = "#ffadaa";
145 |
146 | _this2._colors[Theme.Color.Unchanged] = "#fff";
147 | _this2._colors[Theme.Color.Background] = "#f6f6f6";
148 | _this2._colors[Theme.Color.Cursor] = "#aaa";
149 | _this2._colors[Theme.Color.RangeMark] = "#f27935";
150 | _this2._colors[Theme.Color.Indicator0] = "#d27972";
151 | _this2._colors[Theme.Color.Indicator1] = "#ffb400";
152 | _this2._colors[Theme.Color.Indicator2] = "#e849b9";
153 | _this2._colors[Theme.Color.Indicator3] = "#1478c8";
154 | _this2._colors[Theme.Color.Grid0] = "#aaa";
155 | _this2._colors[Theme.Color.Grid1] = "#aaa";
156 | _this2._colors[Theme.Color.Grid3] = "#bbb";
157 | _this2._colors[Theme.Color.Grid4] = "#aaa";
158 | _this2._colors[Theme.Color.TextPositive] = "#53b37b";
159 | _this2._colors[Theme.Color.TextNegative] = "#db5542";
160 | _this2._colors[Theme.Color.Text0] = "#ccc";
161 | _this2._colors[Theme.Color.Text1] = "#aaa";
162 | _this2._colors[Theme.Color.Text2] = "#888";
163 | _this2._colors[Theme.Color.Text3] = "#666";
164 | _this2._colors[Theme.Color.Text4] = "#444";
165 | _this2._colors[Theme.Color.LineColorNormal] = "#8c8c8c";
166 | _this2._colors[Theme.Color.LineColorSelected] = "#393c40";
167 | _this2._colors[Theme.Color.CircleColorFill] = "#f6f6f6";
168 | _this2._colors[Theme.Color.CircleColorStroke] = "#393c40";
169 | _this2._fonts = [];
170 | _this2._fonts[Theme.Font.Default] = "12px Tahoma";
171 | return _this2;
172 | }
173 |
174 | return LightTheme;
175 | }(Theme);
--------------------------------------------------------------------------------
/npm_dist/js/timeline.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.Timeline = undefined;
7 |
8 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
9 |
10 | var _named_object = require('./named_object');
11 |
12 | var _chart_manager = require('./chart_manager');
13 |
14 | var _data_sources = require('./data_sources');
15 |
16 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
17 |
18 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
19 |
20 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
21 |
22 | var Timeline = exports.Timeline = function (_NamedObject) {
23 | _inherits(Timeline, _NamedObject);
24 |
25 | function Timeline(name) {
26 | _classCallCheck(this, Timeline);
27 |
28 | var _this = _possibleConstructorReturn(this, (Timeline.__proto__ || Object.getPrototypeOf(Timeline)).call(this, name));
29 |
30 | _this._updated = false;
31 | _this._innerLeft = 0;
32 | _this._innerWidth = 0;
33 | _this._firstColumnLeft = 0;
34 | _this._scale = 3;
35 | _this._lastScale = -1;
36 | _this._maxItemCount = 0;
37 | _this._maxIndex = 0;
38 | _this._firstIndex = -1;
39 | _this._selectedIndex = -1;
40 | _this._savedFirstIndex = -1;
41 | return _this;
42 | }
43 |
44 | _createClass(Timeline, [{
45 | key: 'isLatestShown',
46 | value: function isLatestShown() {
47 | return this.getLastIndex() === this._maxIndex;
48 | }
49 | }, {
50 | key: 'isUpdated',
51 | value: function isUpdated() {
52 | return this._updated;
53 | }
54 | }, {
55 | key: 'setUpdated',
56 | value: function setUpdated(v) {
57 | this._updated = v;
58 | }
59 | }, {
60 | key: 'getItemWidth',
61 | value: function getItemWidth() {
62 | return Timeline.itemWidth[this._scale];
63 | }
64 | }, {
65 | key: 'getSpaceWidth',
66 | value: function getSpaceWidth() {
67 | return Timeline.spaceWidth[this._scale];
68 | }
69 | }, {
70 | key: 'getColumnWidth',
71 | value: function getColumnWidth() {
72 | return this.getSpaceWidth() + this.getItemWidth();
73 | }
74 | }, {
75 | key: 'getInnerWidth',
76 | value: function getInnerWidth() {
77 | return this._innerWidth;
78 | }
79 | }, {
80 | key: 'getItemLeftOffset',
81 | value: function getItemLeftOffset() {
82 | return this.getSpaceWidth();
83 | }
84 | }, {
85 | key: 'getItemCenterOffset',
86 | value: function getItemCenterOffset() {
87 | return this.getSpaceWidth() + (this.getItemWidth() >> 1);
88 | }
89 | }, {
90 | key: 'getFirstColumnLeft',
91 | value: function getFirstColumnLeft() {
92 | return this._firstColumnLeft;
93 | }
94 | }, {
95 | key: 'getMaxItemCount',
96 | value: function getMaxItemCount() {
97 | return this._maxItemCount;
98 | }
99 | }, {
100 | key: 'getFirstIndex',
101 | value: function getFirstIndex() {
102 | return this._firstIndex;
103 | }
104 | }, {
105 | key: 'getLastIndex',
106 | value: function getLastIndex() {
107 | return Math.min(this._firstIndex + this._maxItemCount, this._maxIndex);
108 | }
109 | }, {
110 | key: 'getSelectedIndex',
111 | value: function getSelectedIndex() {
112 | return this._selectedIndex;
113 | }
114 | }, {
115 | key: 'getMaxIndex',
116 | value: function getMaxIndex() {
117 | return this._maxIndex;
118 | }
119 | }, {
120 | key: 'calcColumnCount',
121 | value: function calcColumnCount(w) {
122 | return Math.floor(w / this.getColumnWidth()) << 0;
123 | }
124 | }, {
125 | key: 'calcFirstColumnLeft',
126 | value: function calcFirstColumnLeft(maxItemCount) {
127 | return this._innerLeft + this._innerWidth - this.getColumnWidth() * maxItemCount;
128 | }
129 | }, {
130 | key: 'calcFirstIndexAlignRight',
131 | value: function calcFirstIndexAlignRight(oldFirstIndex, oldMaxItemCount, newMaxItemCount) {
132 | return Math.max(0, oldFirstIndex + Math.max(oldMaxItemCount, 1) - Math.max(newMaxItemCount, 1));
133 | }
134 | }, {
135 | key: 'calcFirstIndex',
136 | value: function calcFirstIndex(newMaxItemCount) {
137 | return this.validateFirstIndex(this.calcFirstIndexAlignRight(this._firstIndex, this._maxItemCount, newMaxItemCount), newMaxItemCount);
138 | }
139 | }, {
140 | key: 'updateMaxItemCount',
141 | value: function updateMaxItemCount() {
142 | var newMaxItemCount = this.calcColumnCount(this._innerWidth);
143 | var newFirstIndex = void 0;
144 | if (this._maxItemCount < 1) {
145 | newFirstIndex = this.calcFirstIndex(newMaxItemCount);
146 | } else if (this._lastScale === this._scale) {
147 | newFirstIndex = this.validateFirstIndex(this._firstIndex - (newMaxItemCount - this._maxItemCount));
148 | } else {
149 | var focusedIndex = this._selectedIndex >= 0 ? this._selectedIndex : this.getLastIndex() - 1;
150 | newFirstIndex = this.validateFirstIndex(focusedIndex - Math.round((focusedIndex - this._firstIndex) * newMaxItemCount / this._maxItemCount));
151 | }
152 | this._lastScale = this._scale;
153 | if (this._firstIndex !== newFirstIndex) {
154 | if (this._selectedIndex === this._firstIndex) this._selectedIndex = newFirstIndex;
155 | this._firstIndex = newFirstIndex;
156 | this._updated = true;
157 | }
158 | if (this._maxItemCount !== newMaxItemCount) {
159 | this._maxItemCount = newMaxItemCount;
160 | this._updated = true;
161 | }
162 | this._firstColumnLeft = this.calcFirstColumnLeft(newMaxItemCount);
163 | }
164 | }, {
165 | key: 'validateFirstIndex',
166 | value: function validateFirstIndex(firstIndex, maxItemCount) {
167 | if (this._maxIndex < 1) {
168 | return -1;
169 | }
170 | if (firstIndex < 0) {
171 | return 0;
172 | }
173 | var lastFirst = Math.max(0, this._maxIndex - 1 /*maxItemCount*/);
174 | if (firstIndex > lastFirst) {
175 | return lastFirst;
176 | }
177 | return firstIndex;
178 | }
179 | }, {
180 | key: 'validateSelectedIndex',
181 | value: function validateSelectedIndex() {
182 | if (this._selectedIndex < this._firstIndex) this._selectedIndex = -1;else if (this._selectedIndex >= this.getLastIndex()) this._selectedIndex = -1;
183 | }
184 | }, {
185 | key: 'onLayout',
186 | value: function onLayout() {
187 | var mgr = _chart_manager.ChartManager.instance;
188 | var area = mgr.getArea(this.getDataSourceName() + ".main");
189 | if (area !== null) {
190 | this._innerLeft = area.getLeft() + Timeline.PADDING_LEFT;
191 | var w = Math.max(0, area.getWidth() - (Timeline.PADDING_LEFT + Timeline.PADDING_RIGHT));
192 | if (this._innerWidth !== w) {
193 | this._innerWidth = w;
194 | this.updateMaxItemCount();
195 | }
196 | }
197 | }
198 | }, {
199 | key: 'toIndex',
200 | value: function toIndex(x) {
201 | return this._firstIndex + this.calcColumnCount(x - this._firstColumnLeft);
202 | }
203 | }, {
204 | key: 'toColumnLeft',
205 | value: function toColumnLeft(index) {
206 | return this._firstColumnLeft + this.getColumnWidth() * (index - this._firstIndex);
207 | }
208 | }, {
209 | key: 'toItemLeft',
210 | value: function toItemLeft(index) {
211 | return this.toColumnLeft(index) + this.getItemLeftOffset();
212 | }
213 | }, {
214 | key: 'toItemCenter',
215 | value: function toItemCenter(index) {
216 | return this.toColumnLeft(index) + this.getItemCenterOffset();
217 | }
218 | }, {
219 | key: 'selectAt',
220 | value: function selectAt(x) {
221 | this._selectedIndex = this.toIndex(x);
222 | this.validateSelectedIndex();
223 | return this._selectedIndex >= 0;
224 | }
225 | }, {
226 | key: 'unselect',
227 | value: function unselect() {
228 | this._selectedIndex = -1;
229 | }
230 | }, {
231 | key: 'update',
232 | value: function update() {
233 | var mgr = _chart_manager.ChartManager.instance;
234 | var ds = mgr.getDataSource(this.getDataSourceName());
235 | var oldMaxIndex = this._maxIndex;
236 | this._maxIndex = ds.getDataCount();
237 | switch (ds.getUpdateMode()) {
238 | case _data_sources.DataSource.UpdateMode.Refresh:
239 | if (this._maxIndex < 1) this._firstIndex = -1;else this._firstIndex = Math.max(this._maxIndex - this._maxItemCount, 0);
240 | this._selectedIndex = -1;
241 | this._updated = true;
242 | break;
243 | case _data_sources.DataSource.UpdateMode.Append:
244 | var lastIndex = this.getLastIndex();
245 | var erasedCount = ds.getErasedCount();
246 | if (lastIndex < oldMaxIndex) {
247 | if (erasedCount > 0) {
248 | this._firstIndex = Math.max(this._firstIndex - erasedCount, 0);
249 | if (this._selectedIndex >= 0) {
250 | this._selectedIndex -= erasedCount;
251 | this.validateSelectedIndex();
252 | }
253 | this._updated = true;
254 | }
255 | } else if (lastIndex === oldMaxIndex) {
256 | this._firstIndex += this._maxIndex - oldMaxIndex;
257 | if (this._selectedIndex >= 0) {
258 | this._selectedIndex -= erasedCount;
259 | this.validateSelectedIndex();
260 | }
261 | this._updated = true;
262 | }
263 | break;
264 | }
265 | }
266 | }, {
267 | key: 'move',
268 | value: function move(x) {
269 | if (this.isLatestShown()) {
270 | _chart_manager.ChartManager.instance.getArea(this.getDataSourceName() + ".mainRange").setChanged(true);
271 | }
272 | this._firstIndex = this.validateFirstIndex(this._savedFirstIndex - this.calcColumnCount(x), this._maxItemCount);
273 | this._updated = true;
274 | if (this._selectedIndex >= 0) this.validateSelectedIndex();
275 | }
276 | }, {
277 | key: 'startMove',
278 | value: function startMove() {
279 | this._savedFirstIndex = this._firstIndex;
280 | }
281 | }, {
282 | key: 'scale',
283 | value: function scale(s) {
284 | this._scale += s;
285 | if (this._scale < 0) {
286 | this._scale = 0;
287 | } else if (this._scale >= Timeline.itemWidth.length) {
288 | this._scale = Timeline.itemWidth.length - 1;
289 | }
290 | this.updateMaxItemCount();
291 | if (this._selectedIndex >= 0) {
292 | this.validateSelectedIndex();
293 | }
294 | }
295 | }]);
296 |
297 | return Timeline;
298 | }(_named_object.NamedObject);
299 |
300 | Timeline.itemWidth = [1, 3, 3, 5, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29];
301 | Timeline.spaceWidth = [1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 7, 7, 7];
302 | Timeline.PADDING_LEFT = 4;
303 | Timeline.PADDING_RIGHT = 8;
--------------------------------------------------------------------------------
/npm_dist/js/util.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
10 |
11 | var Util = exports.Util = function () {
12 | function Util() {
13 | _classCallCheck(this, Util);
14 | }
15 |
16 | _createClass(Util, null, [{
17 | key: 'fromFloat',
18 | value: function fromFloat(v, fractionDigits) {
19 | var text = v.toFixed(fractionDigits);
20 | for (var i = text.length - 1; i >= 0; i--) {
21 | if (text[i] === '.') return text.substring(0, i);
22 | if (text[i] !== '0') return text.substring(0, i + 1);
23 | }
24 | }
25 | }, {
26 | key: 'formatTime',
27 | value: function formatTime(v) {
28 | return v < 10 ? "0" + v.toString() : v.toString();
29 | }
30 | }, {
31 | key: 'isInstance',
32 | value: function isInstance(obj, clazz) {
33 | if (obj === null || obj === undefined) {
34 | return false;
35 | }
36 | return obj instanceof clazz;
37 | }
38 | }]);
39 |
40 | return Util;
41 | }();
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-kline",
3 | "version": "1.2.3",
4 | "description": "",
5 | "main": "npm_dist/index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "dev": "webpack-dev-server --inline --progress --mode development",
9 | "build-npm": "babel src -d npm_dist --copy-files",
10 | "build-demo": "webpack --mode production",
11 | "deploy-demo": "gh-pages -d demo_dist",
12 | "publish-demo": "npm run build-demo && npm run deploy-demo"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "dependencies": {
18 | "jquery": "^3.3.1",
19 | "jquery-mousewheel": "^3.1.13",
20 | "react": "^16.4.1",
21 | "react-dom": "^16.4.1"
22 | },
23 | "devDependencies": {
24 | "babel-cli": "^6.26.0",
25 | "babel-core": "^6.26.3",
26 | "babel-loader": "^7.1.4",
27 | "babel-plugin-transform-class-properties": "^6.24.1",
28 | "babel-preset-env": "^1.7.0",
29 | "babel-preset-react": "^6.24.1",
30 | "compression-webpack-plugin": "^1.1.11",
31 | "css-loader": "^0.28.11",
32 | "gh-pages": "^1.2.0",
33 | "html-loader": "^0.5.1",
34 | "html-webpack-plugin": "^3.2.0",
35 | "style-loader": "^0.21.0",
36 | "uglifyjs-webpack-plugin": "^1.1.6",
37 | "url-loader": "^0.6.2",
38 | "webpack": "^4.12.0",
39 | "webpack-bundle-analyzer": "^2.13.1",
40 | "webpack-cli": "^3.0.8",
41 | "webpack-dev-server": "^3.1.4",
42 | "webpack-node-externals": "^1.7.2"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/img/clear_333.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/clear_333.png
--------------------------------------------------------------------------------
/src/img/clear_ccc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/clear_ccc.png
--------------------------------------------------------------------------------
/src/img/dropdown_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/dropdown_b.png
--------------------------------------------------------------------------------
/src/img/dropdown_w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/dropdown_w.png
--------------------------------------------------------------------------------
/src/img/dropup_b.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/dropup_b.png
--------------------------------------------------------------------------------
/src/img/dropup_w.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/dropup_w.png
--------------------------------------------------------------------------------
/src/img/size.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/size.png
--------------------------------------------------------------------------------
/src/img/size_d.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/size_d.png
--------------------------------------------------------------------------------
/src/img/size_l.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/size_l.png
--------------------------------------------------------------------------------
/src/img/tool_d_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/tool_d_normal.png
--------------------------------------------------------------------------------
/src/img/tool_d_push.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/tool_d_push.png
--------------------------------------------------------------------------------
/src/img/tool_l_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/tool_l_normal.png
--------------------------------------------------------------------------------
/src/img/tool_l_push.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangcj-github/react-kline/90f3fe68fcc9d0715331e89986f3c730b2026ced/src/img/tool_l_push.png
--------------------------------------------------------------------------------
/src/js/areas.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {ChartManager} from './chart_manager'
3 | import {MEvent} from './mevent'
4 |
5 | export class ChartArea extends NamedObject {
6 |
7 | constructor(name) {
8 | super(name);
9 | this._left = 0;
10 | this._top = 0;
11 | this._right = 0;
12 | this._bottom = 0;
13 | this._changed = false;
14 | this._highlighted = false;
15 | this._pressed = false;
16 | this._selected = false;
17 | this.Measuring = new MEvent();
18 | }
19 |
20 | getDockStyle() {
21 | return this._dockStyle;
22 | }
23 |
24 | setDockStyle(dockStyle) {
25 | this._dockStyle = dockStyle;
26 | }
27 |
28 | getLeft() {
29 | return this._left;
30 | }
31 |
32 |
33 | getTop() {
34 | return this._top;
35 | }
36 |
37 |
38 | setTop(v) {
39 | if (this._top !== v) {
40 | this._top = v;
41 | this._changed = true;
42 | }
43 | }
44 |
45 |
46 | getRight() {
47 | return this._right;
48 | }
49 |
50 |
51 | getBottom() {
52 | return this._bottom;
53 | }
54 |
55 | setBottom(v) {
56 | if (this._bottom !== v) {
57 | this._bottom = v;
58 | this._changed = true;
59 | }
60 | }
61 |
62 | getCenter() {
63 | return (this._left + this._right) >> 1;
64 | }
65 |
66 | getMiddle() {
67 | return (this._top + this._bottom) >> 1;
68 | }
69 |
70 | getWidth() {
71 | return this._right - this._left;
72 | }
73 |
74 | getHeight() {
75 | return this._bottom - this._top;
76 | }
77 |
78 | getRect() {
79 | return {
80 | X: this._left,
81 | Y: this._top,
82 | Width: this._right - this._left,
83 | Height: this._bottom - this._top
84 | };
85 | }
86 |
87 | contains(x, y) {
88 | if (x >= this._left && x < this._right)
89 | if (y >= this._top && y < this._bottom)
90 | return [this];
91 | return null;
92 | }
93 |
94 | getMeasuredWidth() {
95 | return this._measuredWidth;
96 | }
97 |
98 | getMeasuredHeight() {
99 | return this._measuredHeight;
100 | }
101 |
102 | setMeasuredDimension(width, height) {
103 | this._measuredWidth = width;
104 | this._measuredHeight = height;
105 | }
106 |
107 | measure(context, width, height) {
108 | this._measuredWidth = 0;
109 | this._measuredHeight = 0;
110 | this.Measuring.raise(this, {Width: width, Height: height});
111 | if (this._measuredWidth === 0 && this._measuredHeight === 0)
112 | this.setMeasuredDimension(width, height);
113 | }
114 |
115 | layout(left, top, right, bottom, forceChange) {
116 | left <<= 0;
117 | if (this._left !== left) {
118 | this._left = left;
119 | this._changed = true;
120 | }
121 | top <<= 0;
122 | if (this._top !== top) {
123 | this._top = top;
124 | this._changed = true;
125 | }
126 | right <<= 0;
127 | if (this._right !== right) {
128 | this._right = right;
129 | this._changed = true;
130 | }
131 | bottom <<= 0;
132 | if (this._bottom !== bottom) {
133 | this._bottom = bottom;
134 | this._changed = true;
135 | }
136 | if (forceChange)
137 | this._changed = true;
138 | }
139 |
140 | isChanged() {
141 | return this._changed;
142 | }
143 |
144 | setChanged(v) {
145 | this._changed = v;
146 | }
147 |
148 | isHighlighted() {
149 | return this._highlighted;
150 | }
151 |
152 | getHighlightedArea() {
153 | return this._highlighted ? this : null;
154 | }
155 |
156 |
157 | highlight(area) {
158 | this._highlighted = (this === area);
159 | return this._highlighted ? this : null;
160 | }
161 |
162 | isPressed() {
163 | return this._pressed;
164 | }
165 |
166 |
167 | setPressed(v) {
168 | this._pressed = v;
169 | }
170 |
171 | isSelected() {
172 | return this._selected;
173 | }
174 |
175 | getSelectedArea() {
176 | return this._selected ? this : null;
177 | }
178 |
179 | select(area) {
180 | this._selected = (this === area);
181 | return this._selected ? this : null;
182 | }
183 |
184 | onMouseMove(x, y) {
185 | return null;
186 | }
187 |
188 | onMouseLeave(x, y) {
189 | }
190 |
191 | onMouseDown(x, y) {
192 | return null;
193 | }
194 |
195 | onMouseUp(x, y) {
196 | return null;
197 | }
198 |
199 | }
200 | ChartArea.DockStyle = {
201 | Left: 0,
202 | Top: 1,
203 | Right: 2,
204 | Bottom: 3,
205 | Fill: 4
206 | };
207 |
208 | export class MainArea extends ChartArea {
209 |
210 | constructor(name) {
211 | super(name);
212 | this._dragStarted = false;
213 | this._oldX = 0;
214 | this._oldY = 0;
215 | this._passMoveEventToToolManager = true;
216 | }
217 |
218 | onMouseMove(x, y) {
219 | let mgr = ChartManager.instance;
220 | if (mgr._capturingMouseArea === this)
221 | if (this._dragStarted === false)
222 | if (Math.abs(this._oldX - x) > 1 || Math.abs(this._oldY - y) > 1)
223 | this._dragStarted = true;
224 | if (this._dragStarted) {
225 | mgr.hideCursor();
226 | if (mgr.onToolMouseDrag(this.getFrameName(), x, y))
227 | return this;
228 | mgr.getTimeline(this.getDataSourceName()).move(x - this._oldX);
229 | return this;
230 | }
231 | if (this._passMoveEventToToolManager && mgr.onToolMouseMove(this.getFrameName(), x, y)) {
232 | mgr.hideCursor();
233 | return this;
234 | }
235 | switch (mgr._drawingTool) {
236 | case ChartManager.DrawingTool.Cursor:
237 | mgr.showCursor();
238 | break;
239 | case ChartManager.DrawingTool.CrossCursor:
240 | if (mgr.showCrossCursor(this, x, y))
241 | mgr.hideCursor();
242 | else
243 | mgr.showCursor();
244 | break;
245 | default:
246 | mgr.hideCursor();
247 | break;
248 | }
249 | return this;
250 | }
251 |
252 | onMouseLeave(x, y) {
253 | this._dragStarted = false;
254 | this._passMoveEventToToolManager = true;
255 | }
256 |
257 | onMouseDown(x, y) {
258 | let mgr = ChartManager.instance;
259 | mgr.getTimeline(this.getDataSourceName()).startMove();
260 | this._oldX = x;
261 | this._oldY = y;
262 | this._dragStarted = false;
263 | if (mgr.onToolMouseDown(this.getFrameName(), x, y))
264 | this._passMoveEventToToolManager = false;
265 | return this;
266 | }
267 |
268 | onMouseUp(x, y) {
269 | let mgr = ChartManager.instance;
270 | let ret = null;
271 | if (this._dragStarted) {
272 | this._dragStarted = false;
273 | ret = this;
274 | }
275 | if (mgr.onToolMouseUp(this.getFrameName(), x, y))
276 | ret = this;
277 | this._passMoveEventToToolManager = true;
278 | return ret;
279 | }
280 | }
281 |
282 | export class IndicatorArea extends ChartArea {
283 |
284 | constructor(name) {
285 | super(name);
286 | this._dragStarted = false;
287 | this._oldX = 0;
288 | this._oldY = 0;
289 | }
290 |
291 | onMouseMove(x, y) {
292 | let mgr = ChartManager.instance;
293 | if (mgr._capturingMouseArea === this) {
294 | if (this._dragStarted === false) {
295 | if (this._oldX !== x || this._oldY !== y) {
296 | this._dragStarted = true;
297 | }
298 | }
299 | }
300 | if (this._dragStarted) {
301 | mgr.hideCursor();
302 | mgr.getTimeline(this.getDataSourceName()).move(x - this._oldX);
303 | return this;
304 | }
305 | switch (mgr._drawingTool) {
306 | case ChartManager.DrawingTool.CrossCursor:
307 | if (mgr.showCrossCursor(this, x, y))
308 | mgr.hideCursor();
309 | else
310 | mgr.showCursor();
311 | break;
312 | default:
313 | mgr.showCursor();
314 | break;
315 | }
316 | return this;
317 | }
318 |
319 | onMouseLeave(x, y) {
320 | this._dragStarted = false;
321 | }
322 |
323 |
324 | onMouseDown(x, y) {
325 | let mgr = ChartManager.instance;
326 | mgr.getTimeline(this.getDataSourceName()).startMove();
327 | this._oldX = x;
328 | this._oldY = y;
329 | this._dragStarted = false;
330 | return this;
331 | }
332 |
333 | onMouseUp(x, y) {
334 | if (this._dragStarted) {
335 | this._dragStarted = false;
336 | return this;
337 | }
338 | return null;
339 | }
340 |
341 | }
342 |
343 | export class MainRangeArea extends ChartArea {
344 |
345 | constructor(name) {
346 | super(name);
347 | }
348 |
349 | onMouseMove(x, y) {
350 | ChartManager.instance.showCursor();
351 | return this;
352 | }
353 |
354 | }
355 |
356 | export class IndicatorRangeArea extends ChartArea {
357 |
358 | constructor(name) {
359 | super(name);
360 | }
361 |
362 | onMouseMove(x, y) {
363 | ChartManager.instance.showCursor();
364 | return this;
365 | }
366 |
367 | }
368 |
369 | export class TimelineArea extends ChartArea {
370 |
371 | constructor(name) {
372 | super(name);
373 | }
374 |
375 | onMouseMove(x, y) {
376 | ChartManager.instance.showCursor();
377 | return this;
378 | }
379 |
380 | }
381 |
382 | export class ChartAreaGroup extends ChartArea {
383 |
384 | constructor(name) {
385 | super(name);
386 | this._areas = [];
387 | this._highlightedArea = null;
388 | this._selectedArea = null;
389 | }
390 |
391 | contains(x, y) {
392 | let areas;
393 | let a, i, cnt = this._areas.length;
394 | for (i = 0; i < cnt; i++) {
395 | a = this._areas[i];
396 | areas = a.contains(x, y);
397 | if (areas !== null) {
398 | areas.push(this);
399 | return areas;
400 | }
401 | }
402 | return super.contains(x, y);
403 | }
404 |
405 | getAreaCount() {
406 | return this._areas.length;
407 | }
408 |
409 | getAreaAt(index) {
410 | if (index < 0 || index >= this._areas.length) {
411 | return null;
412 | }
413 | return this._areas[index];
414 | }
415 |
416 |
417 | addArea(area) {
418 | this._areas.push(area);
419 | }
420 |
421 | removeArea(area) {
422 | let i, cnt = this._areas.length;
423 | for (i = 0; i < cnt; i++) {
424 | if (area === this._areas[i]) {
425 | this._areas.splice(i);
426 | this.setChanged(true);
427 | break;
428 | }
429 | }
430 | }
431 |
432 | getGridColor() {
433 | return this._gridColor;
434 | }
435 |
436 | setGridColor(c) {
437 | this._gridColor = c;
438 | }
439 |
440 | getHighlightedArea() {
441 | if (this._highlightedArea !== null) {
442 | return this._highlightedArea.getHighlightedArea();
443 | }
444 | return null;
445 | }
446 |
447 | highlight(area) {
448 | this._highlightedArea = null;
449 | let e, i, cnt = this._areas.length;
450 | for (i = 0; i < cnt; i++) {
451 | e = this._areas[i].highlight(area);
452 | if (e !== null) {
453 | this._highlightedArea = e;
454 | return this;
455 | }
456 | }
457 | return null;
458 | }
459 |
460 | getSelectedArea() {
461 | if (this._selectedArea !== null) {
462 | return this._selectedArea.getSelectedArea();
463 | }
464 | return null;
465 | }
466 |
467 | select(area) {
468 | this._selectedArea = null;
469 | let e, i, cnt = this._areas.length;
470 | for (i = 0; i < cnt; i++) {
471 | e = this._areas[i].select(area);
472 | if (e !== null) {
473 | this._selectedArea = e;
474 | return this;
475 | }
476 | }
477 | return null;
478 | }
479 |
480 | onMouseLeave(x, y) {
481 | let i, cnt = this._areas.length;
482 | for (i = 0; i < cnt; i++)
483 | this._areas[i].onMouseLeave(x, y);
484 | }
485 |
486 | onMouseUp(x, y) {
487 | let a, i, cnt = this._areas.length;
488 | for (i = 0; i < cnt; i++) {
489 | a = this._areas[i].onMouseUp(x, y);
490 | if (a !== null)
491 | return a;
492 | }
493 | return null;
494 | }
495 |
496 | }
497 |
498 |
--------------------------------------------------------------------------------
/src/js/chart.js:
--------------------------------------------------------------------------------
1 | import {ChartManager} from './chart_manager'
2 | import {Control} from './control'
3 | import Kline from './kline'
4 | import {Template} from './templates'
5 | import $ from 'jquery'
6 |
7 | export class Chart {
8 | constructor() {
9 | this._data = null;
10 | this._charStyle = "CandleStick";
11 | this._depthData = {
12 | array: null,
13 | asks_count: 0,
14 | bids_count: 0,
15 | asks_si: 0,
16 | asks_ei: 0,
17 | bids_si: 0,
18 | bids_ei: 0
19 | };
20 | this.strIsLine = false;
21 | this._range = Kline.instance.range;
22 | this._symbol = Kline.instance.symbol;
23 | }
24 |
25 | setTitle() {
26 | let lang = ChartManager.instance.getLanguage();
27 | let title = Kline.instance.symbolName;
28 | title += ' ';
29 | title += this.strIsLine ? Chart.strPeriod[lang]['line'] : Chart.strPeriod[lang][this._range];
30 | title += (this._contract_unit + '/' + this._money_type).toUpperCase();
31 | ChartManager.instance.setTitle('frame0.k0', title);
32 | }
33 |
34 |
35 | setSymbol(symbol) {
36 | this._symbol = symbol;
37 | this.updateDataAndDisplay();
38 | }
39 |
40 | updateDataAndDisplay() {
41 | Kline.instance.symbol = this._symbol;
42 | Kline.instance.range = this._range;
43 | ChartManager.instance.setCurrentDataSource('frame0.k0', this._symbol + '.' + this._range);
44 | ChartManager.instance.setNormalMode();
45 | let f = Kline.instance.chartMgr.getDataSource("frame0.k0").getLastDate();
46 | if (f === -1) {
47 | Kline.instance.requestParam = Control.setHttpRequestParam(Kline.instance.symbol, Kline.instance.range, Kline.instance.limit, null);
48 | Control.requestData(true);
49 | } else {
50 | Kline.instance.requestParam = Control.setHttpRequestParam(Kline.instance.symbol, Kline.instance.range, null, f.toString());
51 | Control.requestData();
52 | }
53 | ChartManager.instance.redraw('All', false);
54 | }
55 |
56 |
57 | setCurrentContractUnit(contractUnit) {
58 | this._contract_unit = contractUnit;
59 | this.updateDataAndDisplay();
60 | }
61 |
62 | setCurrentMoneyType(moneyType) {
63 | this._money_type = moneyType;
64 | this.updateDataAndDisplay();
65 | }
66 |
67 | setCurrentPeriod(period) {
68 | this._range = Kline.instance.periodMap[period];
69 | if (Kline.instance.type === "stomp" && Kline.instance.stompClient.ws.readyState === 1) {
70 | Kline.instance.subscribed.unsubscribe();
71 | Kline.instance.subscribed = Kline.instance.stompClient.subscribe(Kline.instance.subscribePath + '/' + Kline.instance.symbol + '/' + this._range, Control.subscribeCallback);
72 | }
73 | this.updateDataAndDisplay();
74 | Kline.instance.onRangeChangeFunc(this._range);
75 | }
76 |
77 | updateDataSource(data) {
78 | this._data = data;
79 | ChartManager.instance.updateData("frame0.k0", this._data);
80 | }
81 |
82 | updateDepth(array) {
83 | if (array == null) {
84 | this._depthData.array = [];
85 | ChartManager.instance.redraw('All', false);
86 | return;
87 | }
88 | if (!array.asks || !array.bids || array.asks === '' || array.bids === '')
89 | return;
90 | let _data = this._depthData;
91 | _data.array = [];
92 | for (let i = 0; i < array.asks.length; i++) {
93 | let data = {};
94 | data.rate = array.asks[i][0];
95 | data.amount = array.asks[i][1];
96 | _data.array.push(data);
97 | }
98 | for (let i = 0; i < array.bids.length; i++) {
99 | let data = {};
100 | data.rate = array.bids[i][0];
101 | data.amount = array.bids[i][1];
102 | _data.array.push(data);
103 | }
104 | _data.asks_count = array.asks.length;
105 | _data.bids_count = array.bids.length;
106 | _data.asks_si = _data.asks_count - 1;
107 | _data.asks_ei = 0;
108 | _data.bids_si = _data.asks_count - 1;
109 | _data.bids_ei = _data.asks_count + _data.bids_count - 2;
110 | for (let i = _data.asks_si; i >= _data.asks_ei; i--) {
111 | if (i === _data.asks_si && _data.array[i] !== undefined) {
112 | _data.array[i].amounts = _data.array[i].amount;
113 | } else if(_data.array[i + 1] !== undefined) {
114 | _data.array[i].amounts = _data.array[i + 1].amounts + _data.array[i].amount;
115 | }
116 | }
117 | for (let i = _data.bids_si; i <= _data.bids_ei; i++) {
118 | if (i === _data.bids_si && _data.array[i] !== undefined) {
119 | _data.array[i].amounts = _data.array[i].amount;
120 | } else if (_data.array[i - 1] !== undefined) {
121 | _data.array[i].amounts = _data.array[i - 1].amounts + _data.array[i].amount;
122 | }
123 | }
124 | ChartManager.instance.redraw('All', false);
125 | }
126 |
127 | setMainIndicator(indicName) {
128 | this._mainIndicator = indicName;
129 | if (indicName === 'NONE') {
130 | ChartManager.instance.removeMainIndicator('frame0.k0');
131 | } else {
132 | ChartManager.instance.setMainIndicator('frame0.k0', indicName);
133 | }
134 | ChartManager.instance.redraw('All', true);
135 | }
136 |
137 | setIndicator(index, indicName) {
138 | if (indicName === 'NONE') {
139 | /*
140 | let index = 2;
141 | if (Template.displayVolume === false)
142 | index = 1;
143 | */
144 | let index=1;
145 | let areaName = ChartManager.instance.getIndicatorAreaName('frame0.k0', index);
146 | if (areaName !== '')
147 | ChartManager.instance.removeIndicator(areaName);
148 | } else {
149 | /*
150 | let index = 2;
151 | if (Template.displayVolume === false)
152 | index = 1;
153 | */
154 | let index=1;
155 | let areaName = ChartManager.instance.getIndicatorAreaName('frame0.k0', index);
156 | if (areaName === '') {
157 | Template.createIndicatorChartComps('frame0.k0', indicName);
158 | } else {
159 | ChartManager.instance.setIndicator(areaName, indicName);
160 | }
161 | }
162 | ChartManager.instance.redraw('All', true);
163 | }
164 |
165 | addIndicator(indicName) {
166 | ChartManager.instance.addIndicator(indicName);
167 | ChartManager.instance.redraw('All', true);
168 | }
169 |
170 | removeIndicator(indicName) {
171 | let areaName = ChartManager.instance.getIndicatorAreaName(2);
172 | ChartManager.instance.removeIndicator(areaName);
173 | ChartManager.instance.redraw('All', true);
174 | };
175 |
176 | }
177 | Chart.strPeriod = {
178 | 'zh-cn': {
179 | 'line': '(分时)',
180 | '1min': '(1分钟)',
181 | '5min': '(5分钟)',
182 | '15min': '(15分钟)',
183 | '30min': '(30分钟)',
184 | '1hour': '(1小时)',
185 | '1day': '(日线)',
186 | '1week': '(周线)',
187 | '3min': '(3分钟)',
188 | '2hour': '(2小时)',
189 | '4hour': '(4小时)',
190 | '6hour': '(6小时)',
191 | '12hour': '(12小时)',
192 | '3day': '(3天)'
193 | },
194 | 'en-us': {
195 | 'line': '(Line)',
196 | '1min': '(1m)',
197 | '5min': '(5m)',
198 | '15min': '(15m)',
199 | '30min': '(30m)',
200 | '1hour': '(1h)',
201 | '1day': '(1d)',
202 | '1week': '(1w)',
203 | '3min': '(3m)',
204 | '2hour': '(2h)',
205 | '4hour': '(4h)',
206 | '6hour': '(6h)',
207 | '12hour': '(12h)',
208 | '3day': '(3d)'
209 | },
210 | 'zh-tw': {
211 | 'line': '(分時)',
212 | '1min': '(1分鐘)',
213 | '5min': '(5分鐘)',
214 | '15min': '(15分鐘)',
215 | '30min': '(30分鐘)',
216 | '1hour': '(1小時)',
217 | '1day': '(日線)',
218 | '1week': '(周線)',
219 | '3min': '(3分鐘)',
220 | '2hour': '(2小時)',
221 | '4hour': '(4小時)',
222 | '6hour': '(6小時)',
223 | '12hour': '(12小時)',
224 | '3day': '(3天)'
225 | }
226 | };
--------------------------------------------------------------------------------
/src/js/chart_settings.js:
--------------------------------------------------------------------------------
1 | import {ChartManager} from './chart_manager'
2 |
3 | export class ChartSettings {
4 |
5 | static checkVersion() {
6 | if (ChartSettings._data.ver < 2) {
7 | ChartSettings._data.ver = 2;
8 | let charts = ChartSettings._data.charts;
9 | charts.period_weight = {};
10 | charts.period_weight['line'] = 8;
11 | charts.period_weight['1min'] = 7;
12 | charts.period_weight['5min'] = 6;
13 | charts.period_weight['15min'] = 5;
14 | charts.period_weight['30min'] = 4;
15 | charts.period_weight['1hour'] = 3;
16 | charts.period_weight['1day'] = 2;
17 | charts.period_weight['1week'] = 1;
18 | charts.period_weight['3min'] = 0;
19 | charts.period_weight['2hour'] = 0;
20 | charts.period_weight['4hour'] = 0;
21 | charts.period_weight['6hour'] = 0;
22 | charts.period_weight['12hour'] = 0;
23 | charts.period_weight['3day'] = 0;
24 | }
25 | if (ChartSettings._data.ver < 3) {
26 | ChartSettings._data.ver = 3;
27 | let charts = ChartSettings._data.charts;
28 | charts.areaHeight = [];
29 | }
30 | }
31 |
32 | static get () {
33 | if (ChartSettings._data === undefined) {
34 | ChartSettings.init();
35 | ChartSettings.load();
36 | ChartSettings.checkVersion();
37 | }
38 | return ChartSettings._data;
39 | };
40 |
41 | static init() {
42 | let _indic_param = {};
43 | let _name = ['MA', 'EMA', 'VOLUME', 'MACD', 'KDJ', 'StochRSI', 'RSI', 'DMI', 'OBV', 'BOLL', 'DMA', 'TRIX', 'BRAR', 'VR', 'EMV', 'WR', 'ROC', 'MTM', 'PSY'];
44 | for (let i = 0; i < _name.length; i++) {
45 | let _value = ChartManager.instance.createIndicatorAndRange('', _name[i], true);
46 | if (_value === null) continue;
47 | _indic_param[_name[i]] = [];
48 | let param = _value.indic.getParameters();
49 | for (let j = 0; j < param.length; j++) {
50 | _indic_param[_name[i]].push(param[j]);
51 | }
52 | }
53 | let _chart_style = 'CandleStick';
54 | let _m_indic = 'MA';
55 | let _indic = ['VOLUME', 'VOLUME'];
56 | let _range = '15m';
57 | let _frame = {};
58 | _frame.chartStyle = _chart_style;
59 | _frame.mIndic = _m_indic;
60 | _frame.indics = _indic;
61 | _frame.indicsStatus = 'open';
62 | _frame.period = _range;
63 | _frame.depthStatus = 'close';
64 | ChartSettings._data = {
65 | ver: 1,
66 | charts: _frame,
67 | indics: _indic_param,
68 | theme: "Dark"
69 | };
70 | ChartSettings.checkVersion();
71 | }
72 |
73 | static load() {
74 | if (document.cookie.length <= 0)
75 | return;
76 | let start = document.cookie.indexOf("chartSettings=");
77 | if (start < 0)
78 | return;
79 | start += "chartSettings=".length;
80 | let end = document.cookie.indexOf(";", start);
81 | if (end < 0)
82 | end = document.cookie.length;
83 | let json = unescape(document.cookie.substring(start, end));
84 | ChartSettings._data = JSON.parse(json);
85 | }
86 |
87 | static save() {
88 | let exdate = new Date();
89 | exdate.setDate(exdate.getDate() + 2);
90 | document.cookie = "chartSettings=" + escape(JSON.stringify(ChartSettings._data)) +
91 | ";expires=" + exdate.toGMTString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/js/cname.js:
--------------------------------------------------------------------------------
1 | export class CName {
2 |
3 | constructor(name) {
4 | this._names = [];
5 | this._comps = [];
6 | if (name instanceof CName) {
7 | this._names = name._names;
8 | this._comps = name._comps;
9 | } else {
10 | let comps = name.split(".");
11 | let dotNum = comps.length - 1;
12 | if (dotNum > 0) {
13 | this._comps = comps;
14 | this._names.push(comps[0]);
15 | for (let i = 1; i <= dotNum; i++) {
16 | this._names.push(this._names[i - 1] + "." + comps[i]);
17 | }
18 | } else {
19 | this._comps.push(name);
20 | this._names.push(name);
21 | }
22 | }
23 | }
24 |
25 | getCompAt(index) {
26 | if (index >= 0 && index < this._comps.length)
27 | return this._comps[index];
28 | return "";
29 | }
30 |
31 | getName(index) {
32 | if (index < 0) {
33 | if (this._names.length > 0)
34 | return this._names[this._names.length - 1];
35 | } else if (index < this._names.length) {
36 | return this._names[index];
37 | }
38 | return "";
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/js/cpoint.js:
--------------------------------------------------------------------------------
1 | import {ChartManager} from './chart_manager'
2 | import {NamedObject} from './named_object'
3 | import * as data_sources from './data_sources'
4 | import {Util} from './util'
5 |
6 | export class CPoint extends NamedObject {
7 |
8 | constructor(name) {
9 | super(name);
10 | this.pos = {index: -1, value: -1};
11 |
12 | this.state = CPoint.state.Hide;
13 | }
14 |
15 | getChartObjects() {
16 | let ppMgr = ChartManager.instance;
17 | let ppCDS = ppMgr.getDataSource("frame0.k0");
18 | if (ppCDS === null || !Util.isInstance(ppCDS, data_sources.MainDataSource))
19 | return null;
20 | let ppTimeline = ppMgr.getTimeline("frame0.k0");
21 | if (ppTimeline === null)
22 | return null;
23 | let ppRange = ppMgr.getRange("frame0.k0.main");
24 | if (ppRange === null)
25 | return null;
26 | return {pMgr: ppMgr, pCDS: ppCDS, pTimeline: ppTimeline, pRange: ppRange};
27 | }
28 |
29 | setPosXY(x, y) {
30 | let pObj = this.getChartObjects();
31 | let i = pObj.pTimeline.toIndex(x);
32 | let v = pObj.pRange.toValue(y);
33 | let result = this.snapValue(i, v);
34 | if (result !== null)
35 | v = result;
36 | this.setPosIV(i, v);
37 | }
38 |
39 | setPosXYNoSnap(x, y) {
40 | let pObj = this.getChartObjects();
41 | let i = pObj.pTimeline.toIndex(x);
42 | let v = pObj.pRange.toValue(y);
43 | this.setPosIV(i, v);
44 | }
45 |
46 | setPosIV(i, v) {
47 | this.pos = {index: i, value: v};
48 | }
49 |
50 | getPosXY() {
51 | let pObj = this.getChartObjects();
52 | let _x = pObj.pTimeline.toItemCenter(this.pos.index);
53 | let _y = pObj.pRange.toY(this.pos.value);
54 | return {x: _x, y: _y};
55 | }
56 |
57 | getPosIV() {
58 | return {i: this.pos.index, v: this.pos.value};
59 | }
60 |
61 | setState(s) {
62 | this.state = s;
63 | }
64 |
65 | getState() {
66 | return this.state;
67 | }
68 |
69 | isSelected(x, y) {
70 | let xy = this.getPosXY();
71 | if (x < xy.x - 4 || x > xy.x + 4 || y < xy.y - 4 || y > xy.y + 4)
72 | return false;
73 | this.setState(CPoint.state.Highlight);
74 | return true;
75 | }
76 |
77 | snapValue(i, v) {
78 | let pObj = this.getChartObjects();
79 | let result = null;
80 | let first = Math.floor(pObj.pTimeline.getFirstIndex());
81 | let last = Math.floor(pObj.pTimeline.getLastIndex());
82 | if (i < first || i > last)
83 | return result;
84 | let y = pObj.pRange.toY(v);
85 | let pData = pObj.pCDS.getDataAt(i);
86 | if (pData === null || pData === undefined)
87 | return result;
88 | let pDataPre = null;
89 | if (i > 0)
90 | pDataPre = pObj.pCDS.getDataAt(i - 1);
91 | else
92 | pDataPre = pObj.pCDS.getDataAt(i);
93 | let candleStickStyle = pObj.pMgr.getChartStyle(pObj.pCDS.getFrameName());
94 | let open = pObj.pRange.toY(pData.open);
95 | let high = pObj.pRange.toY(pData.high);
96 | let low = pObj.pRange.toY(pData.low);
97 | let close = pObj.pRange.toY(pData.close);
98 | if (candleStickStyle === "CandleStickHLC") {
99 | open = pObj.pRange.toY(pDataPre.close);
100 | }
101 | let dif_open = Math.abs(open - y);
102 | let dif_high = Math.abs(high - y);
103 | let dif_low = Math.abs(low - y);
104 | let dif_close = Math.abs(close - y);
105 | if (dif_open <= dif_high && dif_open <= dif_low && dif_open <= dif_close) {
106 | if (dif_open < 6)
107 | result = pData.open;
108 | }
109 | if (dif_high <= dif_open && dif_high <= dif_low && dif_high <= dif_close) {
110 | if (dif_high < 6)
111 | result = pData.high;
112 | }
113 | if (dif_low <= dif_open && dif_low <= dif_high && dif_low <= dif_close) {
114 | if (dif_low < 6)
115 | result = pData.low;
116 | }
117 | if (dif_close <= dif_open && dif_close <= dif_high && dif_close <= dif_low) {
118 | if (dif_close < 6)
119 | result = pData.close;
120 | }
121 | return result;
122 | }
123 |
124 | }
125 |
126 | CPoint.state = {
127 | Hide: 0,
128 | Show: 1,
129 | Highlight: 2
130 | };
--------------------------------------------------------------------------------
/src/js/ctool_manager.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {CPoint} from './cpoint'
3 | import * as ctools from './ctools'
4 |
5 | export class CToolManager extends NamedObject {
6 |
7 | constructor(name) {
8 | super(name);
9 | this.selectedObject = -1;
10 | this.toolObjects = [];
11 | }
12 |
13 | getToolObjectCount() {
14 | return this.toolObjects.length;
15 | }
16 |
17 | addToolObject(o) {
18 | this.toolObjects.push(o);
19 | }
20 |
21 | getToolObject(i) {
22 | if (i < this.toolObjects.length && i >= 0) {
23 | return this.toolObjects[i];
24 | }
25 | return null;
26 | }
27 |
28 | getCurrentObject() {
29 | return this.getToolObject(this.getToolObjectCount() - 1);
30 | }
31 |
32 | getSelectedObject() {
33 | return this.getToolObject(this.selectedObject);
34 | }
35 |
36 | delCurrentObject() {
37 | this.toolObjects.splice(this.getToolObjectCount() - 1, 1);
38 | }
39 |
40 | delSelectedObject() {
41 | this.toolObjects.splice(this.selectedObject, 1);
42 | this.selectedObject = -1;
43 | }
44 |
45 | acceptMouseMoveEvent(x, y) {
46 | if (this.selectedObject === -1) {
47 | let curr = this.toolObjects[this.getToolObjectCount() - 1];
48 | if (curr !== null && curr !== undefined && curr.getState() !== ctools.CToolObject.state.AfterDraw)
49 | return curr.acceptMouseMoveEvent(x, y);
50 | } else {
51 | let sel = this.toolObjects[this.selectedObject];
52 | if (sel.getState() === ctools.CToolObject.state.Draw) {
53 | return sel.acceptMouseMoveEvent(x, y);
54 | }
55 | sel.unselect();
56 | this.selectedObject = -1;
57 | }
58 | for (let index in this.toolObjects) {
59 | if (this.toolObjects[index].isSelected(x, y)) {
60 | this.selectedObject = index;
61 | return false;
62 | }
63 | }
64 | return false;
65 | }
66 |
67 | acceptMouseDownEvent(x, y) {
68 | this.mouseDownMove = false;
69 | if (this.selectedObject === -1) {
70 | let curr = this.toolObjects[this.getToolObjectCount() - 1];
71 | if (curr !== null && curr !== undefined && curr.getState() !== ctools.CToolObject.state.AfterDraw)
72 | return curr.acceptMouseDownEvent(x, y);
73 | } else {
74 | let sel = this.toolObjects[this.selectedObject];
75 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw)
76 | return sel.acceptMouseDownEvent(x, y);
77 | }
78 | return false;
79 | }
80 |
81 | acceptMouseDownMoveEvent(x, y) {
82 | this.mouseDownMove = true;
83 | if (this.selectedObject === -1) {
84 | let curr = this.toolObjects[this.getToolObjectCount() - 1];
85 | if (curr !== null && curr !== undefined && curr.getState() === ctools.CToolObject.state.Draw)
86 | return curr.acceptMouseDownMoveEvent(x, y);
87 | return false;
88 | } else {
89 | let sel = this.toolObjects[this.selectedObject];
90 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw) {
91 | if (sel.acceptMouseDownMoveEvent(x, y) === true) {
92 | let point = this.toolObjects[this.selectedObject].points;
93 | for (let i = 0; i < point.length; i++) {
94 | if (point[i].state === CPoint.state.Highlight || point[i].state === CPoint.state.Show) {
95 | return true;
96 | }
97 | }
98 | }
99 | return true;
100 | }
101 | }
102 | }
103 |
104 | acceptMouseUpEvent(x, y) {
105 | if (this.mouseDownMove === true) {
106 | if (this.selectedObject === -1) {
107 | let curr = this.toolObjects[this.getToolObjectCount() - 1];
108 | if (curr !== null && curr !== undefined && curr.getState() === ctools.CToolObject.state.Draw)
109 | return curr.acceptMouseUpEvent(x, y);
110 | return true;
111 | } else {
112 | let sel = this.toolObjects[this.selectedObject];
113 | if (sel.getState() !== ctools.CToolObject.state.BeforeDraw)
114 | return sel.acceptMouseUpEvent(x, y);
115 | }
116 | }
117 | if (this.selectedObject !== -1) {
118 | return true;
119 | }
120 | let curr = this.toolObjects[this.getToolObjectCount() - 1];
121 | if (curr !== null && curr !== undefined) {
122 | if (curr.getState() === ctools.CToolObject.state.Draw)
123 | return true;
124 | if (!curr.isValidMouseXY(x, y)) {
125 | return false;
126 | }
127 | if (curr.isSelected(x, y)) {
128 | return true;
129 | }
130 | }
131 | return false;
132 | }
133 |
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/src/js/data_providers.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {ChartManager} from './chart_manager'
3 | import {Util} from './util'
4 | import * as data_sources from './data_sources'
5 |
6 |
7 | export class DataProvider extends NamedObject {
8 |
9 | constructor(name) {
10 | super(name);
11 | this._minValue = 0;
12 | this._maxValue = 0;
13 | this._minValueIndex = -1;
14 | this._maxValueIndex = -1;
15 | }
16 |
17 | getMinValue() {
18 | return this._minValue;
19 | }
20 |
21 | getMaxValue() {
22 | return this._maxValue;
23 | }
24 |
25 | getMinValueIndex() {
26 | return this._minValueIndex;
27 | }
28 |
29 | getMaxValueIndex() {
30 | return this._maxValueIndex;
31 | }
32 |
33 | getMinMaxAt(index, minmax) {
34 | return true;
35 | }
36 |
37 | calcRange(firstIndexes, lastIndex, minmaxes, indexes) {
38 | let min = Number.MAX_VALUE;
39 | let max = -Number.MAX_VALUE;
40 | let minIndex = -1;
41 | let maxIndex = -1;
42 | let minmax = {};
43 | let i = lastIndex - 1;
44 | let n = firstIndexes.length - 1;
45 | for (; n >= 0; n--) {
46 | let first = firstIndexes[n];
47 | if (i < first) {
48 | minmaxes[n] = {"min": min, "max": max};
49 | } else {
50 | for (; i >= first; i--) {
51 | if (this.getMinMaxAt(i, minmax) === false) {
52 | continue;
53 | }
54 | if (min > minmax.min) {
55 | min = minmax.min;
56 | minIndex = i;
57 | }
58 | if (max < minmax.max) {
59 | max = minmax.max;
60 | maxIndex = i;
61 | }
62 | }
63 | minmaxes[n] = {"min": min, "max": max};
64 | }
65 | if (indexes !== null && indexes !== undefined) {
66 | indexes[n] = {"minIndex": minIndex, "maxIndex": maxIndex};
67 | }
68 | }
69 | }
70 |
71 | updateRange() {
72 | let mgr = ChartManager.instance;
73 | let timeline = mgr.getTimeline(this.getDataSourceName());
74 | let firstIndexes = [timeline.getFirstIndex()];
75 | let minmaxes = [{}];
76 | let indexes = [{}];
77 | this.calcRange(firstIndexes, timeline.getLastIndex(), minmaxes, indexes);
78 | this._minValue = minmaxes[0].min;
79 | this._maxValue = minmaxes[0].max;
80 | this._minValueIndex = indexes[0].minIndex;
81 | this._maxValueIndex = indexes[0].maxIndex;
82 | }
83 |
84 | }
85 |
86 |
87 | export class MainDataProvider extends DataProvider {
88 |
89 | constructor(name) {
90 | super(name);
91 | this._candlestickDS = null;
92 | }
93 |
94 | updateData() {
95 | let mgr = ChartManager.instance;
96 | let ds = mgr.getDataSource(this.getDataSourceName());
97 | if (!Util.isInstance(ds, data_sources.MainDataSource)) {
98 | return;
99 | }
100 | this._candlestickDS = ds;
101 | }
102 |
103 | getMinMaxAt(index, minmax) {
104 | let data = this._candlestickDS.getDataAt(index);
105 | minmax.min = data.low;
106 | minmax.max = data.high;
107 | return true;
108 | }
109 |
110 | }
111 |
112 |
113 | export class IndicatorDataProvider extends DataProvider {
114 |
115 | getIndicator() {
116 | return this._indicator;
117 | }
118 |
119 | setIndicator(v) {
120 | this._indicator = v;
121 | this.refresh();
122 | }
123 |
124 | refresh() {
125 | let mgr = ChartManager.instance;
126 | let ds = mgr.getDataSource(this.getDataSourceName());
127 | if (ds.getDataCount() < 1) {
128 | return;
129 | }
130 | let indic = this._indicator;
131 | let i, last = ds.getDataCount();
132 | indic.clear();
133 | indic.reserve(last);
134 | for (i = 0; i < last; i++) {
135 | indic.execute(ds, i);
136 | }
137 | }
138 |
139 | updateData() {
140 | let mgr = ChartManager.instance;
141 | let ds = mgr.getDataSource(this.getDataSourceName());
142 | if (ds.getDataCount() < 1) {
143 | return;
144 | }
145 | let indic = this._indicator;
146 | let mode = ds.getUpdateMode();
147 | switch (mode) {
148 | case data_sources.DataSource.UpdateMode.Refresh: {
149 | this.refresh();
150 | break;
151 | }
152 | case data_sources.DataSource.UpdateMode.Append: {
153 | indic.reserve(ds.getAppendedCount());
154 | break;
155 | }
156 | case data_sources.DataSource.UpdateMode.Update: {
157 | let i, last = ds.getDataCount();
158 | let cnt = ds.getUpdatedCount() + ds.getAppendedCount();
159 | for (i = last - cnt; i < last; i++) {
160 | indic.execute(ds, i);
161 | }
162 | break;
163 | }
164 | }
165 | }
166 |
167 | getMinMaxAt(index, minmax) {
168 | minmax.min = Number.MAX_VALUE;
169 | minmax.max = -Number.MAX_VALUE;
170 | let result, valid = false;
171 | let i, cnt = this._indicator.getOutputCount();
172 | for (i = 0; i < cnt; i++) {
173 | result = this._indicator.getOutputAt(i).execute(index);
174 | if (isNaN(result) === false) {
175 | valid = true;
176 | if (minmax.min > result) {
177 | minmax.min = result;
178 | }
179 | if (minmax.max < result) {
180 | minmax.max = result;
181 | }
182 | }
183 | }
184 | return valid;
185 | }
186 |
187 | }
188 |
189 |
--------------------------------------------------------------------------------
/src/js/data_sources.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {CToolManager} from './ctool_manager'
3 | import Kline from './kline'
4 |
5 |
6 |
7 | export class DataSource extends NamedObject {
8 |
9 | constructor(name) {
10 | super(name);
11 | }
12 |
13 | getUpdateMode() {
14 | return this._updateMode;
15 | }
16 |
17 | setUpdateMode(mode) {
18 | this._updateMode = mode;
19 | }
20 |
21 | getCacheSize() {
22 | return 0;
23 | }
24 |
25 | getDataCount() {
26 | return 0;
27 | }
28 |
29 | getDataAt(index) {
30 | return this._dataItems[index];
31 | }
32 |
33 | }
34 | DataSource.UpdateMode = {
35 | DoNothing: 0,
36 | Refresh: 1,
37 | Update: 2,
38 | Append: 3
39 | };
40 |
41 |
42 | export class MainDataSource extends DataSource {
43 |
44 | constructor(name) {
45 | super(name);
46 | this._erasedCount = 0;
47 | this._dataItems = [];
48 | this._decimalDigits = 0;
49 | this.toolManager = new CToolManager(name);
50 | }
51 |
52 | getCacheSize() {
53 | return this._dataItems.length;
54 | }
55 |
56 | getDataCount() {
57 | return this._dataItems.length;
58 | }
59 |
60 | getUpdatedCount() {
61 | return this._updatedCount;
62 | }
63 |
64 | getAppendedCount() {
65 | return this._appendedCount;
66 | }
67 |
68 | getErasedCount() {
69 | return this._erasedCount;
70 | }
71 |
72 | getDecimalDigits() {
73 | return this._decimalDigits;
74 | }
75 |
76 | calcDecimalDigits(v) {
77 | let str = "" + v;
78 | let i = str.indexOf('.');
79 | if (i < 0) {
80 | return 0;
81 | }
82 | return (str.length - 1) - i;
83 | }
84 |
85 | getLastDate() {
86 | let count = this.getDataCount();
87 | if (count < 1) {
88 | return -1;
89 | }
90 | return this.getDataAt(count - 1).date;
91 | }
92 |
93 | getDataAt(index) {
94 | return this._dataItems[index];
95 | }
96 |
97 | update(data) {
98 | this._updatedCount = 0;
99 | this._appendedCount = 0;
100 | this._erasedCount = 0;
101 | let len = this._dataItems.length;
102 | if (len > 0) {
103 | let lastIndex = len - 1;
104 | let lastItem = this._dataItems[lastIndex];
105 | let e, i, cnt = data.length;
106 | for (i = 0; i < cnt; i++) {
107 | e = data[i];
108 | if (e[0] === lastItem.date) {
109 | if (lastItem.open === e[1] &&
110 | lastItem.high === e[2] &&
111 | lastItem.low === e[3] &&
112 | lastItem.close === e[4] &&
113 | lastItem.volume === e[5]) {
114 | this.setUpdateMode(DataSource.UpdateMode.DoNothing);
115 | } else {
116 | this.setUpdateMode(DataSource.UpdateMode.Update);
117 | this._dataItems[lastIndex] = {
118 | date: e[0],
119 | open: e[1],
120 | high: e[2],
121 | low: e[3],
122 | close: e[4],
123 | volume: e[5]
124 | };
125 | this._updatedCount++;
126 | }
127 | i++;
128 | if (i < cnt) {
129 | this.setUpdateMode(DataSource.UpdateMode.Append);
130 | for (; i < cnt; i++, this._appendedCount++) {
131 | e = data[i];
132 | this._dataItems.push({
133 | date: e[0],
134 | open: e[1],
135 | high: e[2],
136 | low: e[3],
137 | close: e[4],
138 | volume: e[5]
139 | });
140 | }
141 | }
142 | return true;
143 | }
144 | }
145 | if (cnt < Kline.instance.limit) {
146 | this.setUpdateMode(DataSource.UpdateMode.DoNothing);
147 | return false;
148 | }
149 | }
150 | this.setUpdateMode(DataSource.UpdateMode.Refresh);
151 | this._dataItems = [];
152 | let d, n, e, i, cnt = data.length;
153 | for (i = 0; i < cnt; i++) {
154 | e = data[i];
155 | for (n = 1; n <= 4; n++) {
156 | d = this.calcDecimalDigits(e[n]);
157 | if (this._decimalDigits < d)
158 | this._decimalDigits = d;
159 | }
160 | this._dataItems.push({
161 | date: e[0],
162 | open: e[1],
163 | high: e[2],
164 | low: e[3],
165 | close: e[4],
166 | volume: e[5]
167 | });
168 | }
169 | return true;
170 | }
171 |
172 | select(id) {
173 | this.toolManager.selecedObject = id;
174 | }
175 |
176 | unselect() {
177 | this.toolManager.selecedObject = -1;
178 | }
179 |
180 | addToolObject(toolObject) {
181 | this.toolManager.addToolObject(toolObject);
182 | }
183 |
184 | delToolObject() {
185 | this.toolManager.delCurrentObject();
186 | }
187 |
188 | getToolObject(index) {
189 | return this.toolManager.getToolObject(index);
190 | }
191 |
192 | getToolObjectCount() {
193 | return this.toolManager.toolObjects.length;
194 | }
195 |
196 | getCurrentToolObject() {
197 | return this.toolManager.getCurrentObject();
198 | }
199 |
200 | getSelectToolObjcet() {
201 | return this.toolManager.getSelectedObject();
202 | }
203 |
204 | delSelectToolObject() {
205 | this.toolManager.delSelectedObject();
206 | }
207 |
208 | }
209 |
210 |
--------------------------------------------------------------------------------
/src/js/layouts.js:
--------------------------------------------------------------------------------
1 | import * as areas from './areas'
2 | import {ChartManager} from './chart_manager'
3 | import * as themes from './themes'
4 | import {ChartSettings} from './chart_settings'
5 | import Kline from "./kline";
6 |
7 | export class TableLayout extends areas.ChartAreaGroup {
8 |
9 | constructor(name) {
10 | super(name);
11 | this._nextRowId = 0;
12 | this._focusedRowIndex = -1;
13 | }
14 |
15 | getNextRowId() {
16 | return this._nextRowId++;
17 | }
18 |
19 | measure(context, width, height) {
20 | this.setMeasuredDimension(width, height);
21 | let rowH, prevH = 0,
22 | totalH = 0;
23 | let h, rows;
24 | let rh = [];
25 | let i, cnt = this._areas.length;
26 | for (i = 0; i < cnt; i += 2) {
27 | rowH = this._areas[i].getHeight();
28 | if (rowH === 0) {
29 | if (i === 0) {
30 | rows = (cnt + 1) >> 1;
31 | let n = (rows * 2) + 5;
32 | let nh = ((height / n) * 2) << 0;
33 | h = height;
34 | for (i = rows - 1; i > 0; i--) {
35 | rh.unshift(nh);
36 | h -= nh;
37 | }
38 | rh.unshift(h);
39 | break;
40 | } else if (i === 2) {
41 | rowH = prevH / 3;
42 | } else {
43 | rowH = prevH;
44 | }
45 | }
46 | totalH += rowH;
47 | prevH = rowH;
48 | rh.push(rowH);
49 | }
50 | if (totalH > 0) {
51 | let rate = height / totalH;
52 | rows = (cnt + 1) >> 1;
53 | h = height;
54 | for (i = rows - 1; i > 0; i--) {
55 | rh[i] *= rate;
56 | h -= rh[i];
57 | }
58 | rh[0] = h;
59 | }
60 | let nw = 8;
61 | // chart depths sidebar (深度图侧边栏宽度)
62 | let tmp = ChartSettings.get();
63 | let minRW = tmp.charts.depthStatus==="open" ? Kline.instance.depthWidth : 50;
64 | let maxRW = Math.min(240, width >> 1);
65 | let rw = minRW;
66 | let mgr = ChartManager.instance;
67 | let timeline = mgr.getTimeline(this.getDataSourceName());
68 | if (timeline.getFirstIndex() >= 0) {
69 | let firstIndexes = [];
70 | for (rw = minRW; rw < maxRW; rw += nw) {
71 | firstIndexes.push(timeline.calcFirstIndex(timeline.calcColumnCount(width - rw)));
72 | }
73 | let lastIndex = timeline.getLastIndex();
74 | let dpNames = [".main", ".secondary"];
75 | let minmaxes = new Array(firstIndexes.length);
76 | let iArea, iIndex;
77 | for (iArea = 0, iIndex = 0, rw = minRW; iArea < this._areas.length && iIndex < firstIndexes.length; iArea += 2) {
78 | let area = this._areas[iArea];
79 | let plotter = mgr.getPlotter(area.getName() + "Range.main");
80 | for (let iDp in dpNames) {
81 | let dp = mgr.getDataProvider(area.getName() + dpNames[iDp]);
82 | if (dp === undefined) {
83 | continue;
84 | }
85 | dp.calcRange(firstIndexes, lastIndex, minmaxes, null);
86 | while (iIndex < firstIndexes.length) {
87 | let minW = plotter.getRequiredWidth(context, minmaxes[iIndex].min);
88 | let maxW = plotter.getRequiredWidth(context, minmaxes[iIndex].max);
89 | if (Math.max(minW, maxW) < rw) {
90 | break;
91 | }
92 | iIndex++;
93 | rw += nw;
94 | }
95 | }
96 | }
97 | }
98 | for (i = 1; i < this._areas.length; i += 2) {
99 | this._areas[i].measure(context, rw, rh[i >> 1]);
100 | }
101 | let lw = width - rw;
102 | for (i = 0; i < this._areas.length; i += 2) {
103 | this._areas[i].measure(context, lw, rh[i >> 1]);
104 | }
105 | }
106 |
107 | layout(left, top, right, bottom, forceChange) {
108 | super.layout(left, top, right, bottom, forceChange);
109 | if (this._areas.length < 1)
110 | return;
111 | let area;
112 | let center = left + this._areas[0].getMeasuredWidth();
113 | let t = top,
114 | b;
115 | if (!forceChange)
116 | forceChange = this.isChanged();
117 | let i, cnt = this._areas.length;
118 | for (i = 0; i < cnt; i++) {
119 | area = this._areas[i];
120 | b = t + area.getMeasuredHeight();
121 | area.layout(left, t, center, b, forceChange);
122 | i++;
123 | area = this._areas[i];
124 | area.layout(center, t, this.getRight(), b, forceChange);
125 | t = b;
126 | }
127 | this.setChanged(false);
128 | }
129 |
130 | drawGrid(context) {
131 | if (this._areas.length < 1) {
132 | return;
133 | }
134 | let mgr = ChartManager.instance;
135 | let theme = mgr.getTheme(this.getFrameName());
136 | context.fillStyle = theme.getColor(themes.Theme.Color.Grid1);
137 | context.fillRect(this._areas[0].getRight(), this.getTop(), 1, this.getHeight());
138 | let i, cnt = this._areas.length - 2;
139 | for (i = 0; i < cnt; i += 2)
140 | context.fillRect(this.getLeft(), this._areas[i].getBottom(), this.getWidth(), 1);
141 | if (!mgr.getCaptureMouseWheelDirectly()) {
142 | for (i = 0, cnt += 2; i < cnt; i += 2) {
143 | if (this._areas[i].isSelected()) {
144 | context.strokeStyle = theme.getColor(themes.Theme.Color.Indicator1);
145 | context.strokeRect(
146 | this.getLeft() + 0.5, this.getTop() + 0.5,
147 | this.getWidth() - 1, this.getHeight() - 1);
148 | break;
149 | }
150 | }
151 | }
152 | }
153 |
154 | highlight(area) {
155 | this._highlightedArea = null;
156 | let e, i, cnt = this._areas.length;
157 | for (i = 0; i < cnt; i++) {
158 | e = this._areas[i];
159 | if (e === area) {
160 | i &= ~1;
161 | e = this._areas[i];
162 | e.highlight(e);
163 | this._highlightedArea = e;
164 | i++;
165 | e = this._areas[i];
166 | e.highlight(null);
167 | e.highlight(e);
168 | } else {
169 | e.highlight(null);
170 | }
171 | }
172 | return this._highlightedArea !== null ? this : null;
173 | }
174 |
175 | select(area) {
176 | this._selectedArea = null;
177 | let e, i, cnt = this._areas.length;
178 | for (i = 0; i < cnt; i++) {
179 | e = this._areas[i];
180 | if (e === area) {
181 | i &= ~1;
182 | e = this._areas[i];
183 | e.select(e);
184 | this._selectedArea = e;
185 | i++;
186 | e = this._areas[i];
187 | e.select(e);
188 | } else {
189 | e.select(null);
190 | }
191 | }
192 | return this._selectedArea !== null ? this : null;
193 | }
194 |
195 | onMouseMove(x, y) {
196 | if (this._focusedRowIndex >= 0) {
197 | let upper = this._areas[this._focusedRowIndex];
198 | let lower = this._areas[this._focusedRowIndex + 2];
199 | let d = y - this._oldY;
200 | if (d === 0)
201 | return this;
202 | let upperBottom = this._oldUpperBottom + d;
203 | let lowerTop = this._oldLowerTop + d;
204 | if (upperBottom - upper.getTop() >= 60 && lower.getBottom() - lowerTop >= 60) {
205 | upper.setBottom(upperBottom);
206 | lower.setTop(lowerTop);
207 | }
208 | return this;
209 | }
210 | let i, cnt = this._areas.length - 2;
211 | for (i = 0; i < cnt; i += 2) {
212 | let b = this._areas[i].getBottom();
213 | if (y >= b - 4 && y < b + 4) {
214 | ChartManager.instance.showCursor('n-resize');
215 | return this;
216 | }
217 | }
218 | return null;
219 | }
220 |
221 | onMouseLeave(x, y) {
222 | this._focusedRowIndex = -1;
223 | }
224 |
225 | onMouseDown(x, y) {
226 | let i, cnt = this._areas.length - 2;
227 | for (i = 0; i < cnt; i += 2) {
228 | let b = this._areas[i].getBottom();
229 | if (y >= b - 4 && y < b + 4) {
230 | this._focusedRowIndex = i;
231 | this._oldY = y;
232 | this._oldUpperBottom = b;
233 | this._oldLowerTop = this._areas[i + 2].getTop();
234 | return this;
235 | }
236 | }
237 | return null;
238 | }
239 |
240 | onMouseUp(x, y) {
241 | if (this._focusedRowIndex >= 0) {
242 | this._focusedRowIndex = -1;
243 | let i, cnt = this._areas.length;
244 | let height = [];
245 | for (i = 0; i < cnt; i += 2) {
246 | height.push(this._areas[i].getHeight());
247 | }
248 | ChartSettings.get().charts.areaHeight = height;
249 | ChartSettings.save();
250 | }
251 | return this;
252 | }
253 |
254 | }
255 |
256 | export class DockableLayout extends areas.ChartAreaGroup {
257 |
258 | constructor(name) {
259 | super(name);
260 | }
261 |
262 | measure(context, width, height) {
263 | super.measure(context, width, height);
264 | width = this.getMeasuredWidth();
265 | height = this.getMeasuredHeight();
266 | for (let i in this._areas) {
267 | let area = this._areas[i];
268 | area.measure(context, width, height);
269 | switch (area.getDockStyle()) {
270 | case areas.ChartArea.DockStyle.left:
271 | case areas.ChartArea.DockStyle.Right:
272 | width -= area.getMeasuredWidth();
273 | break;
274 | case areas.ChartArea.DockStyle.Top:
275 | case areas.ChartArea.DockStyle.Bottom:
276 | height -= area.getMeasuredHeight();
277 | break;
278 | case areas.ChartArea.DockStyle.Fill:
279 | width = 0;
280 | height = 0;
281 | break;
282 | }
283 | }
284 | }
285 |
286 | layout(left, top, right, bottom, forceChange) {
287 | super.layout(left, top, right, bottom, forceChange);
288 | left = this.getLeft();
289 | top = this.getTop();
290 | right = this.getRight();
291 | bottom = this.getBottom();
292 | let w, h;
293 | if (!forceChange) {
294 | forceChange = this.isChanged();
295 | }
296 | for (let i in this._areas) {
297 | let area = this._areas[i];
298 | switch (area.getDockStyle()) {
299 | case areas.ChartArea.DockStyle.left:
300 | w = area.getMeasuredWidth();
301 | area.layout(left, top, left + w, bottom, forceChange);
302 | left += w;
303 | break;
304 | case areas.ChartArea.DockStyle.Top:
305 | h = area.getMeasuredHeight();
306 | area.layout(left, top, right, top + h, forceChange);
307 | top += h;
308 | break;
309 | case areas.ChartArea.DockStyle.Right:
310 | w = area.getMeasuredWidth();
311 | area.layout(right - w, top, right, bottom, forceChange);
312 | right -= w;
313 | break;
314 | case areas.ChartArea.DockStyle.Bottom:
315 | h = area.getMeasuredHeight();
316 | area.layout(left, bottom - h, right, bottom, forceChange);
317 | bottom -= h;
318 | break;
319 | case areas.ChartArea.DockStyle.Fill:
320 | area.layout(left, top, right, bottom, forceChange);
321 | left = right;
322 | top = bottom;
323 | break;
324 | }
325 | }
326 | this.setChanged(false);
327 | }
328 |
329 | drawGrid(context) {
330 | let mgr = ChartManager.instance;
331 | let theme = mgr.getTheme(this.getFrameName());
332 | let left = this.getLeft();
333 | let top = this.getTop();
334 | let right = this.getRight();
335 | let bottom = this.getBottom();
336 | context.fillStyle = theme.getColor(this._gridColor);
337 | for (let i in this._areas) {
338 | let area = this._areas[i];
339 | switch (area.getDockStyle()) {
340 | case areas.ChartArea.DockStyle.Left:
341 | context.fillRect(area.getRight(), top, 1, bottom - top);
342 | left += area.getWidth();
343 | break;
344 | case areas.ChartArea.DockStyle.Top:
345 | context.fillRect(left, area.getBottom(), right - left, 1);
346 | top += area.getHeight();
347 | break;
348 | case areas.ChartArea.DockStyle.Right:
349 | context.fillRect(area.getLeft(), top, 1, bottom - top);
350 | right -= area.getWidth();
351 | break;
352 | case areas.ChartArea.DockStyle.Bottom:
353 | context.fillRect(left, area.getTop(), right - left, 1);
354 | bottom -= area.getHeight();
355 | break;
356 | }
357 | }
358 | }
359 |
360 | }
361 |
--------------------------------------------------------------------------------
/src/js/mevent.js:
--------------------------------------------------------------------------------
1 | export class MEvent {
2 |
3 | constructor() {
4 | this._handlers = [];
5 | }
6 |
7 | addHandler(o, f) {
8 | if (this.indexOf(o, f) < 0)
9 | this._handlers.push({obj: o, func: f});
10 | }
11 |
12 | removeHandler(o, f) {
13 | let i = this.indexOf(o, f);
14 | if (i >= 0)
15 | this._handlers.splice(i, 1);
16 | }
17 |
18 | raise(s, g) {
19 | let a = this._handlers;
20 | let e, i, c = a.length;
21 | for (i = 0; i < c; i++) {
22 | e = a[i];
23 | e.func(s, g);
24 | }
25 | }
26 |
27 | indexOf(o, f) {
28 | let a = this._handlers;
29 | let e, i, c = a.length;
30 | for (i = 0; i < c; i++) {
31 | e = a[i];
32 | if (o === e.obj && f === e.func)
33 | return i;
34 | }
35 | return -1;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/js/named_object.js:
--------------------------------------------------------------------------------
1 | import {CName} from './cname'
2 |
3 | export class NamedObject {
4 |
5 | constructor(name) {
6 | this._name = name;
7 | this._nameObj = new CName(name);
8 | }
9 |
10 | getFrameName() {
11 | return this._nameObj.getName(0);
12 | }
13 |
14 | getDataSourceName() {
15 | return this._nameObj.getName(1);
16 | }
17 |
18 | getAreaName() {
19 | return this._nameObj.getName(2);
20 | }
21 |
22 | getName() {
23 | return this._nameObj.getName(-1);
24 | }
25 |
26 | getNameObject() {
27 | return this._nameObj;
28 | }
29 |
30 | getRectCrossPt(rect, startPt, endPt) {
31 | let crossPt;
32 | let firstPt = {x: -1, y: -1};
33 | let secondPt = {x: -1, y: -1};
34 | let xdiff = endPt.x - startPt.x;
35 | let ydiff = endPt.y - startPt.y;
36 | if (Math.abs(xdiff) < 2) {
37 | firstPt = {x: startPt.x, y: rect.top};
38 | secondPt = {x: endPt.x, y: rect.bottom};
39 | crossPt = [firstPt, secondPt];
40 | return crossPt;
41 | }
42 | let k = ydiff / xdiff;
43 | secondPt.x = rect.right;
44 | secondPt.y = startPt.y + (rect.right - startPt.x) * k;
45 | firstPt.x = rect.left;
46 | firstPt.y = startPt.y + (rect.left - startPt.x) * k;
47 | crossPt = [firstPt, secondPt];
48 | return crossPt;
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/js/ranges.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {ChartManager} from './chart_manager'
3 |
4 | export class Range extends NamedObject {
5 |
6 | constructor(name) {
7 | super(name);
8 | this._updated = true;
9 | this._minValue = Number.MAX_VALUE;
10 | this._maxValue = -Number.MAX_VALUE;
11 | this._outerMinValue = Number.MAX_VALUE;
12 | this._outerMaxValue = -Number.MAX_VALUE;
13 | this._ratio = 0;
14 | this._top = 0;
15 | this._bottom = 0;
16 | this._paddingTop = 0;
17 | this._paddingBottom = 0;
18 | this._minInterval = 36;
19 | this._selectedPosition = -1;
20 | this._selectedValue = -Number.MAX_VALUE;
21 | this._gradations = [];
22 | }
23 |
24 | isUpdated() {
25 | return this._updated;
26 | }
27 |
28 | setUpdated(v) {
29 | this._updated = v;
30 | }
31 |
32 | getMinValue() {
33 | return this._minValue;
34 | }
35 |
36 | getMaxValue() {
37 | return this._maxValue;
38 | }
39 |
40 | getRange() {
41 | return this._maxValue - this._minValue;
42 | }
43 |
44 | getOuterMinValue() {
45 | return this._outerMinValue;
46 | }
47 |
48 | getOuterMaxValue() {
49 | return this._outerMaxValue;
50 | }
51 |
52 | getOuterRange() {
53 | return this._outerMaxValue - this._outerMinValue;
54 | }
55 |
56 | getHeight() {
57 | return Math.max(0, this._bottom - this._top);
58 | }
59 |
60 | getGradations() {
61 | return this._gradations;
62 | }
63 |
64 | getMinInterval() {
65 | return this._minInterval;
66 | }
67 |
68 | setMinInterval(v) {
69 | this._minInterval = v;
70 | }
71 |
72 | getSelectedPosition() {
73 | if (this._selectedPosition >= 0) {
74 | return this._selectedPosition;
75 | }
76 | if (this._selectedValue > -Number.MAX_VALUE) {
77 | return this.toY(this._selectedValue);
78 | }
79 | return -1;
80 | }
81 |
82 | getSelectedValue() {
83 | if (this._selectedValue > -Number.MAX_VALUE) {
84 | return this._selectedValue;
85 | }
86 | let mgr = ChartManager.instance;
87 | let area = mgr.getArea(this.getAreaName());
88 | if (area === null) {
89 | return -Number.MAX_VALUE;
90 | }
91 | if (this._selectedPosition < area.getTop() + 12 || this._selectedPosition >= area.getBottom() - 4) {
92 | return -Number.MAX_VALUE;
93 | }
94 | return this.toValue(this._selectedPosition);
95 | }
96 |
97 | setPaddingTop(p) {
98 | this._paddingTop = p;
99 | }
100 |
101 | setPaddingBottom(p) {
102 | this._paddingBottom = p;
103 | }
104 |
105 | toValue(y) {
106 | return this._maxValue - (y - this._top) / this._ratio;
107 | }
108 |
109 | toY(value) {
110 | if (this._ratio > 0) {
111 | return this._top + Math.floor((this._maxValue - value) * this._ratio + 0.5);
112 | }
113 | return this._top;
114 | }
115 |
116 | toHeight(value) {
117 | if (value == Infinity || this._ratio == 0) {
118 | return 1.5;
119 | }
120 | return Math.floor(value * this._ratio + 1.5);
121 | }
122 |
123 | update() {
124 | let min = Number.MAX_VALUE;
125 | let max = -Number.MAX_VALUE;
126 | let mgr = ChartManager.instance;
127 | let dp, dpNames = [".main", ".secondary"];
128 | for (let i = 0; i < dpNames.length; i++) {
129 | dp = mgr.getDataProvider(this.getName() + dpNames[i]);
130 | if (dp !== null && dp !== undefined) {
131 | min = Math.min(min, dp.getMinValue());
132 | max = Math.max(max, dp.getMaxValue());
133 | }
134 | }
135 | let r = {"min": min, "max": max};
136 | this.preSetRange(r);
137 | this.setRange(r.min, r.max);
138 | }
139 |
140 | select(v) {
141 | this._selectedValue = v;
142 | this._selectedPosition = -1;
143 | }
144 |
145 | selectAt(y) {
146 | this._selectedPosition = y;
147 | this._selectedValue = -Number.MAX_VALUE;
148 | }
149 |
150 | unselect() {
151 | this._selectedPosition = -1;
152 | this._selectedValue = -Number.MAX_VALUE;
153 | }
154 |
155 | preSetRange(r) {
156 | if (r.min === r.max) {
157 | r.min = -1.0;
158 | r.max = 1.0;
159 | }
160 | }
161 |
162 | setRange(minValue, maxValue) {
163 | let mgr = ChartManager.instance;
164 | let area = mgr.getArea(this.getAreaName());
165 | if (this._minValue === minValue && this._maxValue === maxValue && !area.isChanged()) {
166 | return;
167 | }
168 | this._updated = true;
169 | this._minValue = minValue;
170 | this._maxValue = maxValue;
171 | this._gradations = [];
172 | let top = area.getTop() + this._paddingTop;
173 | let bottom = area.getBottom() - (this._paddingBottom + 1);
174 | if (top >= bottom) {
175 | this._minValue = this._maxValue;
176 | return;
177 | }
178 | this._top = top;
179 | this._bottom = bottom;
180 | if (this._maxValue > this._minValue)
181 | this._ratio = (bottom - top) / (this._maxValue - this._minValue);
182 | else {
183 | this._ratio = 1;
184 | }
185 | this._outerMinValue = this.toValue(area.getBottom());
186 | this._outerMaxValue = this.toValue(area.getTop());
187 | this.updateGradations();
188 | }
189 |
190 | calcInterval() {
191 | let H = this.getHeight();
192 | let h = this.getMinInterval();
193 | if ((H / h) <= 1) {
194 | h = H >> 1;
195 | }
196 | let d = this.getRange();
197 | let i = 0;
198 | while (i > -2 && Math.floor(d) < d) {
199 | d *= 10.0;
200 | i--;
201 | }
202 | let m, c;
203 | for (; ; i++) {
204 | c = Math.pow(10.0, i);
205 | m = c;
206 | if (this.toHeight(m) > h)
207 | break;
208 | m = 2.0 * c;
209 | if (this.toHeight(m) > h)
210 | break;
211 | m = 5.0 * c;
212 | if (this.toHeight(m) > h)
213 | break;
214 | }
215 | return m;
216 | }
217 |
218 | updateGradations() {
219 | this._gradations = [];
220 | let interval = this.calcInterval();
221 | if (interval <= 0.0) {
222 | return;
223 | }
224 | let v = Math.floor(this.getMaxValue() / interval) * interval;
225 | do {
226 | this._gradations.push(v);
227 | v -= interval;
228 | } while (v > this.getMinValue());
229 | }
230 |
231 | }
232 |
233 |
234 | export class PositiveRange extends Range {
235 |
236 | constructor(name) {
237 | super(name);
238 | }
239 |
240 | preSetRange(r) {
241 | if (r.min < 0) r.min = 0;
242 | if (r.max < 0) r.max = 0;
243 | }
244 |
245 | }
246 |
247 |
248 | export class ZeroBasedPositiveRange extends Range {
249 |
250 | constructor(name) {
251 | super(name);
252 | }
253 |
254 | preSetRange(r) {
255 | r.min = 0;
256 | if (r.max < 0) r.max = 0;
257 | }
258 |
259 | }
260 |
261 |
262 | export class MainRange extends Range {
263 |
264 | constructor(name) {
265 | super(name);
266 | }
267 |
268 | preSetRange(r) {
269 | let mgr = ChartManager.instance;
270 |
271 | let timeline = mgr.getTimeline(this.getDataSourceName());
272 | let dIndex = timeline.getMaxIndex() - timeline.getLastIndex();
273 | if (dIndex < 25) {
274 | let ds = mgr.getDataSource(this.getDataSourceName());
275 |
276 | let data = ds.getDataAt(ds.getDataCount() - 1);
277 | let d = ((r.max - r.min) / 4) * (1 - (dIndex / 25));
278 |
279 | r.min = Math.min(r.min, Math.max(data.low - d, 0));
280 | r.max = Math.max(r.max, data.high + d);
281 | }
282 |
283 | if (r.min > 0) {
284 | let a = r.max / r.min;
285 |
286 | if (a < 1.016) {
287 | let m = (r.max + r.min) / 2.0;
288 | let c = (a - 1.0) * 1.5;
289 | r.max = m * (1.0 + c);
290 | r.min = m * (1.0 - c);
291 | } else if (a < 1.048) {
292 | let m = (r.max + r.min) / 2.0;
293 | r.max = m * 1.024;
294 | r.min = m * 0.976;
295 | }
296 | }
297 | if (r.min < 0) r.min = 0;
298 | if (r.max < 0) r.max = 0;
299 | }
300 |
301 | }
302 |
303 |
304 | export class ZeroCenteredRange extends Range {
305 |
306 | constructor(name) {
307 | super(name);
308 | }
309 |
310 | calcInterval(area) {
311 | let h = this.getMinInterval();
312 | if (area.getHeight() / h < 2) {
313 | return 0.0;
314 | }
315 | let r = this.getRange();
316 | let i;
317 | for (i = 3; ; i += 2) {
318 | if (this.toHeight(r / i) <= h)
319 | break;
320 | }
321 | i -= 2;
322 | return r / i;
323 | }
324 |
325 | updateGradations() {
326 | this._gradations = [];
327 | let mgr = ChartManager.instance;
328 | let area = mgr.getArea(this.getAreaName());
329 | let interval = this.calcInterval(area);
330 | if (interval <= 0.0) {
331 | return;
332 | }
333 | let v = interval / 2.0;
334 | do {
335 | this._gradations.push(v);
336 | this._gradations.push(-v);
337 | v += interval;
338 | } while (v <= this.getMaxValue());
339 | }
340 |
341 | preSetRange(r) {
342 | let abs = Math.max(Math.abs(r.min), Math.abs(r.max));
343 | r.min = -abs;
344 | r.max = abs;
345 | }
346 |
347 | }
348 |
349 |
350 | export class PercentageRange extends Range {
351 |
352 | constructor(name) {
353 | super(name);
354 | }
355 |
356 | updateGradations() {
357 | this._gradations = [];
358 | let mgr = ChartManager.instance;
359 | let area = mgr.getArea(this.getAreaName());
360 | let interval = 10.0;
361 | let h = Math.floor(this.toHeight(interval));
362 | if ((h << 2) > area.getHeight())
363 | return;
364 | let v = Math.ceil(this.getMinValue() / interval) * interval;
365 | if (v === 0.0)
366 | v = 0;
367 | if ((h << 2) < 24) {
368 | if ((h << 1) < 8)
369 | return;
370 | do {
371 | if (v === 20.0 || v === 80.0)
372 | this._gradations.push(v);
373 | v += interval;
374 | } while (v < this.getMaxValue());
375 | } else {
376 | do {
377 | if (h < 8) {
378 | if (v === 20.0 || v === 50.0 || v === 80.0)
379 | this._gradations.push(v);
380 | } else {
381 | if (v === 0.0 || v === 20.0 || v === 50.0 || v === 80.0 || v === 100.0)
382 | this._gradations.push(v);
383 | }
384 | v += interval;
385 | } while (v < this.getMaxValue());
386 | }
387 | }
388 |
389 | }
390 |
391 |
--------------------------------------------------------------------------------
/src/js/templates.js:
--------------------------------------------------------------------------------
1 | import {ChartManager} from './chart_manager'
2 | import {ChartSettings} from './chart_settings'
3 | import * as data_sources from './data_sources'
4 | import * as data_providers from './data_providers'
5 | import * as areas from './areas'
6 | import * as plotters from './plotters'
7 | import {Timeline} from './timeline'
8 | import {CName} from './cname'
9 | import * as layouts from './layouts'
10 | import * as themes from './themes'
11 | import * as ranges from './ranges'
12 |
13 | export class Template {
14 |
15 | static createCandlestickDataSource(dsAlias) {
16 | return new data_sources.MainDataSource(dsAlias);
17 | }
18 |
19 | static createDataSource(dsName, dsAlias, createFunc) {
20 | let mgr = ChartManager.instance;
21 | if (mgr.getCachedDataSource(dsAlias) === null)
22 | mgr.setCachedDataSource(dsAlias, createFunc(dsAlias));
23 | mgr.setCurrentDataSource(dsName, dsAlias);
24 | mgr.updateData(dsName, null);
25 | }
26 |
27 | static createTableComps(dsName) {
28 | this.createMainChartComps(dsName);
29 | this.createTimelineComps(dsName);
30 | }
31 |
32 | static createMainChartComps(dsName) {
33 | let mgr = ChartManager.instance;
34 | let tableLayout = mgr.getArea(dsName + ".charts");
35 | let areaName = dsName + ".main";
36 | let rangeAreaName = areaName + "Range";
37 | let area = new areas.MainArea(areaName);
38 | mgr.setArea(areaName, area);
39 | tableLayout.addArea(area);
40 | let rangeArea = new areas.MainRangeArea(rangeAreaName);
41 | mgr.setArea(rangeAreaName, rangeArea);
42 | tableLayout.addArea(rangeArea);
43 | let dp = new data_providers.MainDataProvider(areaName + ".main");
44 | mgr.setDataProvider(dp.getName(), dp);
45 | mgr.setMainIndicator(dsName, "MA");
46 | let range = new ranges.MainRange(areaName);
47 | mgr.setRange(range.getName(), range);
48 | range.setPaddingTop(28);
49 | range.setPaddingBottom(12);
50 | let plotter = new plotters.MainAreaBackgroundPlotter(areaName + ".background");
51 | mgr.setPlotter(plotter.getName(), plotter);
52 | plotter = new plotters.CGridPlotter(areaName + ".grid");
53 | mgr.setPlotter(plotter.getName(), plotter);
54 | plotter = new plotters.CandlestickPlotter(areaName + ".main");
55 | mgr.setPlotter(plotter.getName(), plotter);
56 | plotter = new plotters.MinMaxPlotter(areaName + ".decoration");
57 | mgr.setPlotter(plotter.getName(), plotter);
58 | plotter = new plotters.MainInfoPlotter(areaName + ".info");
59 | mgr.setPlotter(plotter.getName(), plotter);
60 | plotter = new plotters.SelectionPlotter(areaName + ".selection");
61 | mgr.setPlotter(plotter.getName(), plotter);
62 | plotter = new plotters.CDynamicLinePlotter(areaName + ".tool");
63 | mgr.setPlotter(plotter.getName(), plotter);
64 | plotter = new plotters.RangeAreaBackgroundPlotter(areaName + "Range.background");
65 | mgr.setPlotter(plotter.getName(), plotter);
66 | plotter = new plotters.COrderGraphPlotter(areaName + "Range.grid");
67 | mgr.setPlotter(plotter.getName(), plotter);
68 | plotter = new plotters.RangePlotter(areaName + "Range.main");
69 | mgr.setPlotter(plotter.getName(), plotter);
70 | plotter = new plotters.RangeSelectionPlotter(areaName + "Range.selection");
71 | mgr.setPlotter(plotter.getName(), plotter);
72 | plotter = new plotters.LastClosePlotter(areaName + "Range.decoration");
73 | mgr.setPlotter(plotter.getName(), plotter);
74 | }
75 |
76 | static createIndicatorChartComps(dsName, indicName) {
77 | let mgr = ChartManager.instance;
78 | let tableLayout = mgr.getArea(dsName + ".charts");
79 | let areaName = dsName + ".indic" + tableLayout.getNextRowId();
80 | let rangeAreaName = areaName + "Range";
81 | let area = new areas.IndicatorArea(areaName);
82 | mgr.setArea(areaName, area);
83 | tableLayout.addArea(area);
84 | let rowIndex = tableLayout.getAreaCount() >> 1;
85 | let heights = ChartSettings.get().charts.areaHeight;
86 | if (heights.length > rowIndex) {
87 | let a, i;
88 | for (i = 0; i < rowIndex; i++) {
89 | a = tableLayout.getAreaAt(i << 1);
90 | a.setTop(0);
91 | a.setBottom(heights[i]);
92 | }
93 | area.setTop(0);
94 | area.setBottom(heights[rowIndex]);
95 | }
96 | let rangeArea = new areas.IndicatorRangeArea(rangeAreaName);
97 | mgr.setArea(rangeAreaName, rangeArea);
98 | tableLayout.addArea(rangeArea);
99 | let dp = new data_providers.IndicatorDataProvider(areaName + ".secondary");
100 | mgr.setDataProvider(dp.getName(), dp);
101 | if (mgr.setIndicator(areaName, indicName) === false) {
102 | mgr.removeIndicator(areaName);
103 | return;
104 | }
105 | let plotter = new plotters.MainAreaBackgroundPlotter(areaName + ".background");
106 | mgr.setPlotter(plotter.getName(), plotter);
107 | plotter = new plotters.CGridPlotter(areaName + ".grid");
108 | mgr.setPlotter(plotter.getName(), plotter);
109 | plotter = new plotters.IndicatorPlotter(areaName + ".secondary");
110 | mgr.setPlotter(plotter.getName(), plotter);
111 | plotter = new plotters.IndicatorInfoPlotter(areaName + ".info");
112 | mgr.setPlotter(plotter.getName(), plotter);
113 | plotter = new plotters.SelectionPlotter(areaName + ".selection");
114 | mgr.setPlotter(plotter.getName(), plotter);
115 | plotter = new plotters.RangeAreaBackgroundPlotter(areaName + "Range.background");
116 | mgr.setPlotter(plotter.getName(), plotter);
117 | plotter = new plotters.RangePlotter(areaName + "Range.main");
118 | mgr.setPlotter(plotter.getName(), plotter);
119 | plotter = new plotters.RangeSelectionPlotter(areaName + "Range.selection");
120 | mgr.setPlotter(plotter.getName(), plotter);
121 | }
122 |
123 | static createTimelineComps(dsName) {
124 | let mgr = ChartManager.instance;
125 | let plotter;
126 | let timeline = new Timeline(dsName);
127 | mgr.setTimeline(timeline.getName(), timeline);
128 | plotter = new plotters.TimelineAreaBackgroundPlotter(dsName + ".timeline.background");
129 | mgr.setPlotter(plotter.getName(), plotter);
130 | plotter = new plotters.TimelinePlotter(dsName + ".timeline.main");
131 | mgr.setPlotter(plotter.getName(), plotter);
132 | plotter = new plotters.TimelineSelectionPlotter(dsName + ".timeline.selection");
133 | mgr.setPlotter(plotter.getName(), plotter);
134 | }
135 |
136 | static createLiveOrderComps(dsName) {
137 | let mgr = ChartManager.instance;
138 | let plotter;
139 | plotter = new plotters.BackgroundPlotter(dsName + ".main.background");
140 | mgr.setPlotter(plotter.getName(), plotter);
141 | plotter = new plotters.CLiveOrderPlotter(dsName + ".main.main");
142 | mgr.setPlotter(plotter.getName(), plotter);
143 | }
144 |
145 | static createLiveTradeComps(dsName) {
146 | let mgr = ChartManager.instance;
147 | let plotter;
148 | plotter = new plotters.BackgroundPlotter(dsName + ".main.background");
149 | mgr.setPlotter(plotter.getName(), plotter);
150 | plotter = new plotters.CLiveTradePlotter(dsName + ".main.main");
151 | mgr.setPlotter(plotter.getName(), plotter);
152 | }
153 |
154 | }
155 |
156 | export class DefaultTemplate extends Template {
157 |
158 | static loadTemplate(dsName, dsAlias) {
159 | let mgr = ChartManager.instance;
160 | let settings = ChartSettings.get();
161 | let frameName = (new CName(dsName)).getCompAt(0);
162 | mgr.unloadTemplate(frameName);
163 | this.createDataSource(dsName, dsAlias, this.createCandlestickDataSource);
164 | let frame = new layouts.DockableLayout(frameName);
165 | mgr.setFrame(frame.getName(), frame);
166 | mgr.setArea(frame.getName(), frame);
167 | frame.setGridColor(themes.Theme.Color.Grid1);
168 | let area = new areas.TimelineArea(dsName + ".timeline");
169 | mgr.setArea(area.getName(), area);
170 | frame.addArea(area);
171 | area.setDockStyle(areas.ChartArea.DockStyle.Bottom);
172 | area.Measuring.addHandler(area, TemplateMeasuringHandler.onMeasuring);
173 | let tableLayout = new layouts.TableLayout(dsName + ".charts");
174 | mgr.setArea(tableLayout.getName(), tableLayout);
175 | tableLayout.setDockStyle(areas.ChartArea.DockStyle.Fill);
176 | frame.addArea(tableLayout);
177 | this.createTableComps(dsName);
178 | mgr.setThemeName(frameName, settings.theme);
179 | return mgr;
180 | }
181 |
182 | }
183 |
184 | export class TemplateMeasuringHandler {
185 |
186 | static onMeasuring(sender, args) {
187 | let width = args.Width;
188 | let height = args.Height;
189 | let areaName = sender.getNameObject().getCompAt(2);
190 | if (areaName === "timeline") {
191 | sender.setMeasuredDimension(width, 22);
192 | }
193 | }
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/src/js/themes.js:
--------------------------------------------------------------------------------
1 | import Kline from './kline'
2 |
3 | export class Theme {
4 | constructor(){
5 | this._colors=[];
6 | this._fonts=[];
7 | }
8 | getColor(which) {
9 | return this._colors[which];
10 | }
11 | getFont(which) {
12 | return this._fonts[which];
13 | }
14 | }
15 | Theme.theme_color_id = 0;
16 | Theme.theme_font_id = 0;
17 | Theme.Color = {
18 | Positive: Theme.theme_color_id++,
19 | Negative: Theme.theme_color_id++,
20 | PositiveDark: Theme.theme_color_id++,
21 | NegativeDark: Theme.theme_color_id++,
22 | Unchanged: Theme.theme_color_id++,
23 | Background: Theme.theme_color_id++,
24 | Cursor: Theme.theme_color_id++,
25 | RangeMark: Theme.theme_color_id++,
26 | Indicator0: Theme.theme_color_id++,
27 | Indicator1: Theme.theme_color_id++,
28 | Indicator2: Theme.theme_color_id++,
29 | Indicator3: Theme.theme_color_id++,
30 | Indicator4: Theme.theme_color_id++,
31 | Indicator5: Theme.theme_color_id++,
32 | Grid0: Theme.theme_color_id++,
33 | Grid1: Theme.theme_color_id++,
34 | Grid2: Theme.theme_color_id++,
35 | Grid3: Theme.theme_color_id++,
36 | Grid4: Theme.theme_color_id++,
37 | TextPositive: Theme.theme_color_id++,
38 | TextNegative: Theme.theme_color_id++,
39 | Text0: Theme.theme_color_id++,
40 | Text1: Theme.theme_color_id++,
41 | Text2: Theme.theme_color_id++,
42 | Text3: Theme.theme_color_id++,
43 | Text4: Theme.theme_color_id++,
44 | LineColorNormal: Theme.theme_color_id++,
45 | LineColorSelected: Theme.theme_color_id++,
46 | CircleColorFill: Theme.theme_color_id++,
47 | CircleColorStroke: Theme.theme_color_id++
48 | };
49 | Theme.Font = {
50 | Default: Theme.theme_font_id++
51 | };
52 |
53 | export class DarkTheme extends Theme {
54 |
55 | constructor() {
56 | super();
57 | this._colors = [];
58 |
59 | this._colors[Theme.Color.Positive] = "#19b34c";
60 | this._colors[Theme.Color.Negative] = "#990e0e";
61 | this._colors[Theme.Color.PositiveDark] = "#004718";
62 | this._colors[Theme.Color.NegativeDark] = "#3b0e08";
63 |
64 | this._colors[Theme.Color.Unchanged] = "#fff";
65 | this._colors[Theme.Color.Background] = "#161616";
66 | this._colors[Theme.Color.Cursor] = "#aaa";
67 | this._colors[Theme.Color.RangeMark] = "#f9ee30";
68 | this._colors[Theme.Color.Indicator0] = "#ddd";
69 | this._colors[Theme.Color.Indicator1] = "#f9ee30";
70 | this._colors[Theme.Color.Indicator2] = "#f600ff";
71 | this._colors[Theme.Color.Indicator3] = "#6bf";
72 | this._colors[Theme.Color.Indicator4] = "#a5cf81";
73 | this._colors[Theme.Color.Indicator5] = "#e18b89";
74 | this._colors[Theme.Color.Grid0] = "#555";
75 | this._colors[Theme.Color.Grid1] = "#555";
76 | this._colors[Theme.Color.Grid3] = "#888";
77 | this._colors[Theme.Color.Grid4] = "#aaa";
78 | this._colors[Theme.Color.TextPositive] = "#1bd357";
79 | this._colors[Theme.Color.TextNegative] = "#ff6f5e";
80 | this._colors[Theme.Color.Text0] = "#444";
81 | this._colors[Theme.Color.Text1] = "#666";
82 | this._colors[Theme.Color.Text2] = "#888";
83 | this._colors[Theme.Color.Text3] = "#aaa";
84 | this._colors[Theme.Color.Text4] = "#ccc";
85 | this._colors[Theme.Color.LineColorNormal] = "#a6a6a6";
86 | this._colors[Theme.Color.LineColorSelected] = "#ffffff";
87 | this._colors[Theme.Color.CircleColorFill] = "#161616";
88 | this._colors[Theme.Color.CircleColorStroke] = "#ffffff";
89 | this._fonts = [];
90 | this._fonts[Theme.Font.Default] = "12px Tahoma";
91 | }
92 |
93 | }
94 |
95 |
96 | export class LightTheme extends Theme {
97 |
98 | constructor() {
99 | super();
100 | this._colors = [];
101 |
102 | this._colors[Theme.Color.Positive] = "#53b37b";
103 | this._colors[Theme.Color.Negative] = "#db5542";
104 | this._colors[Theme.Color.PositiveDark] = "#66d293";
105 | this._colors[Theme.Color.NegativeDark] = "#ffadaa";
106 |
107 | this._colors[Theme.Color.Unchanged] = "#fff";
108 | this._colors[Theme.Color.Background] = "#f6f6f6";
109 | this._colors[Theme.Color.Cursor] = "#aaa";
110 | this._colors[Theme.Color.RangeMark] = "#f27935";
111 | this._colors[Theme.Color.Indicator0] = "#d27972";
112 | this._colors[Theme.Color.Indicator1] = "#ffb400";
113 | this._colors[Theme.Color.Indicator2] = "#e849b9";
114 | this._colors[Theme.Color.Indicator3] = "#1478c8";
115 | this._colors[Theme.Color.Grid0] = "#aaa";
116 | this._colors[Theme.Color.Grid1] = "#aaa";
117 | this._colors[Theme.Color.Grid3] = "#bbb";
118 | this._colors[Theme.Color.Grid4] = "#aaa";
119 | this._colors[Theme.Color.TextPositive] = "#53b37b";
120 | this._colors[Theme.Color.TextNegative] = "#db5542";
121 | this._colors[Theme.Color.Text0] = "#ccc";
122 | this._colors[Theme.Color.Text1] = "#aaa";
123 | this._colors[Theme.Color.Text2] = "#888";
124 | this._colors[Theme.Color.Text3] = "#666";
125 | this._colors[Theme.Color.Text4] = "#444";
126 | this._colors[Theme.Color.LineColorNormal] = "#8c8c8c";
127 | this._colors[Theme.Color.LineColorSelected] = "#393c40";
128 | this._colors[Theme.Color.CircleColorFill] = "#f6f6f6";
129 | this._colors[Theme.Color.CircleColorStroke] = "#393c40";
130 | this._fonts = [];
131 | this._fonts[Theme.Font.Default] = "12px Tahoma";
132 | }
133 |
134 | }
135 |
--------------------------------------------------------------------------------
/src/js/timeline.js:
--------------------------------------------------------------------------------
1 | import {NamedObject} from './named_object'
2 | import {ChartManager} from './chart_manager'
3 | import {DataSource} from './data_sources'
4 |
5 | export class Timeline extends NamedObject {
6 |
7 | constructor(name) {
8 | super(name);
9 | this._updated = false;
10 | this._innerLeft = 0;
11 | this._innerWidth = 0;
12 | this._firstColumnLeft = 0;
13 | this._scale = 3;
14 | this._lastScale = -1;
15 | this._maxItemCount = 0;
16 | this._maxIndex = 0;
17 | this._firstIndex = -1;
18 | this._selectedIndex = -1;
19 | this._savedFirstIndex = -1;
20 | }
21 |
22 |
23 | isLatestShown() {
24 | return this.getLastIndex() === this._maxIndex;
25 | }
26 |
27 | isUpdated() {
28 | return this._updated;
29 | }
30 |
31 | setUpdated(v) {
32 | this._updated = v;
33 | }
34 |
35 | getItemWidth() {
36 | return Timeline.itemWidth[this._scale];
37 | }
38 |
39 | getSpaceWidth() {
40 | return Timeline.spaceWidth[this._scale];
41 | }
42 |
43 | getColumnWidth() {
44 | return this.getSpaceWidth() + this.getItemWidth();
45 | }
46 |
47 | getInnerWidth() {
48 | return this._innerWidth;
49 | }
50 |
51 | getItemLeftOffset() {
52 | return this.getSpaceWidth();
53 | }
54 |
55 | getItemCenterOffset() {
56 | return this.getSpaceWidth() + (this.getItemWidth() >> 1);
57 | }
58 |
59 | getFirstColumnLeft() {
60 | return this._firstColumnLeft;
61 | }
62 |
63 | getMaxItemCount() {
64 | return this._maxItemCount;
65 | }
66 |
67 | getFirstIndex() {
68 | return this._firstIndex;
69 | }
70 |
71 | getLastIndex() {
72 | return Math.min(this._firstIndex + this._maxItemCount, this._maxIndex);
73 | }
74 |
75 | getSelectedIndex() {
76 | return this._selectedIndex;
77 | }
78 |
79 | getMaxIndex() {
80 | return this._maxIndex;
81 | }
82 |
83 | calcColumnCount(w) {
84 | return Math.floor(w / this.getColumnWidth()) << 0;
85 | }
86 |
87 | calcFirstColumnLeft(maxItemCount) {
88 | return this._innerLeft + this._innerWidth - (this.getColumnWidth() * maxItemCount);
89 | }
90 |
91 | calcFirstIndexAlignRight(oldFirstIndex, oldMaxItemCount, newMaxItemCount) {
92 | return Math.max(0, oldFirstIndex + Math.max(oldMaxItemCount, 1) - Math.max(newMaxItemCount, 1));
93 | }
94 |
95 | calcFirstIndex(newMaxItemCount) {
96 | return this.validateFirstIndex(
97 | this.calcFirstIndexAlignRight(this._firstIndex, this._maxItemCount,
98 | newMaxItemCount), newMaxItemCount);
99 | }
100 |
101 | updateMaxItemCount() {
102 | let newMaxItemCount = this.calcColumnCount(this._innerWidth);
103 | let newFirstIndex;
104 | if (this._maxItemCount < 1) {
105 | newFirstIndex = this.calcFirstIndex(newMaxItemCount);
106 | } else if (this._lastScale === this._scale) {
107 | newFirstIndex = this.validateFirstIndex(this._firstIndex - (newMaxItemCount - this._maxItemCount));
108 | } else {
109 | let focusedIndex = (this._selectedIndex >= 0) ? this._selectedIndex : this.getLastIndex() - 1;
110 | newFirstIndex = this.validateFirstIndex(focusedIndex -
111 | Math.round((focusedIndex - this._firstIndex) * newMaxItemCount / this._maxItemCount));
112 | }
113 | this._lastScale = this._scale;
114 | if (this._firstIndex !== newFirstIndex) {
115 | if (this._selectedIndex === this._firstIndex)
116 | this._selectedIndex = newFirstIndex;
117 | this._firstIndex = newFirstIndex;
118 | this._updated = true;
119 | }
120 | if (this._maxItemCount !== newMaxItemCount) {
121 | this._maxItemCount = newMaxItemCount;
122 | this._updated = true;
123 | }
124 | this._firstColumnLeft = this.calcFirstColumnLeft(newMaxItemCount);
125 | }
126 |
127 | validateFirstIndex(firstIndex, maxItemCount) {
128 | if (this._maxIndex < 1) {
129 | return -1;
130 | }
131 | if (firstIndex < 0) {
132 | return 0;
133 | }
134 | let lastFirst = Math.max(0, this._maxIndex - 1 /*maxItemCount*/);
135 | if (firstIndex > lastFirst) {
136 | return lastFirst;
137 | }
138 | return firstIndex;
139 | }
140 |
141 | validateSelectedIndex() {
142 | if (this._selectedIndex < this._firstIndex)
143 | this._selectedIndex = -1;
144 | else if (this._selectedIndex >= this.getLastIndex())
145 | this._selectedIndex = -1;
146 | }
147 |
148 | onLayout() {
149 | let mgr = ChartManager.instance;
150 | let area = mgr.getArea(this.getDataSourceName() + ".main");
151 | if (area !== null) {
152 | this._innerLeft = area.getLeft() + Timeline.PADDING_LEFT;
153 | let w = Math.max(0, area.getWidth() - (Timeline.PADDING_LEFT + Timeline.PADDING_RIGHT));
154 | if (this._innerWidth !== w) {
155 | this._innerWidth = w;
156 | this.updateMaxItemCount();
157 | }
158 | }
159 | }
160 |
161 | toIndex(x) {
162 | return this._firstIndex + this.calcColumnCount(x - this._firstColumnLeft);
163 | }
164 |
165 | toColumnLeft(index) {
166 | return this._firstColumnLeft + (this.getColumnWidth() * (index - this._firstIndex));
167 | }
168 |
169 | toItemLeft(index) {
170 | return this.toColumnLeft(index) + this.getItemLeftOffset();
171 | }
172 |
173 | toItemCenter(index) {
174 | return this.toColumnLeft(index) + this.getItemCenterOffset();
175 | }
176 |
177 | selectAt(x) {
178 | this._selectedIndex = this.toIndex(x);
179 | this.validateSelectedIndex();
180 | return (this._selectedIndex >= 0);
181 | }
182 |
183 | unselect() {
184 | this._selectedIndex = -1;
185 | }
186 |
187 | update() {
188 | let mgr = ChartManager.instance;
189 | let ds = mgr.getDataSource(this.getDataSourceName());
190 | let oldMaxIndex = this._maxIndex;
191 | this._maxIndex = ds.getDataCount();
192 | switch (ds.getUpdateMode()) {
193 | case DataSource.UpdateMode.Refresh:
194 | if (this._maxIndex < 1)
195 | this._firstIndex = -1;
196 | else
197 | this._firstIndex = Math.max(this._maxIndex - this._maxItemCount, 0);
198 | this._selectedIndex = -1;
199 | this._updated = true;
200 | break;
201 | case DataSource.UpdateMode.Append:
202 | let lastIndex = this.getLastIndex();
203 | let erasedCount = ds.getErasedCount();
204 | if (lastIndex < oldMaxIndex) {
205 | if (erasedCount > 0) {
206 | this._firstIndex = Math.max(this._firstIndex - erasedCount, 0);
207 | if (this._selectedIndex >= 0) {
208 | this._selectedIndex -= erasedCount;
209 | this.validateSelectedIndex();
210 | }
211 | this._updated = true;
212 | }
213 | } else if (lastIndex === oldMaxIndex) {
214 | this._firstIndex += (this._maxIndex - oldMaxIndex);
215 | if (this._selectedIndex >= 0) {
216 | this._selectedIndex -= erasedCount;
217 | this.validateSelectedIndex();
218 | }
219 | this._updated = true;
220 | }
221 | break;
222 | }
223 | }
224 |
225 | move(x) {
226 | if (this.isLatestShown()) {
227 | ChartManager.instance.getArea(this.getDataSourceName() + ".mainRange").setChanged(true);
228 | }
229 | this._firstIndex = this.validateFirstIndex(
230 | this._savedFirstIndex - this.calcColumnCount(x), this._maxItemCount);
231 | this._updated = true;
232 | if (this._selectedIndex >= 0)
233 | this.validateSelectedIndex();
234 | }
235 |
236 | startMove() {
237 | this._savedFirstIndex = this._firstIndex;
238 | }
239 |
240 | scale(s) {
241 | this._scale += s;
242 | if (this._scale < 0) {
243 | this._scale = 0;
244 | } else if (this._scale >= Timeline.itemWidth.length) {
245 | this._scale = Timeline.itemWidth.length - 1;
246 | }
247 | this.updateMaxItemCount();
248 | if (this._selectedIndex >= 0) {
249 | this.validateSelectedIndex();
250 | }
251 | }
252 |
253 | }
254 | Timeline.itemWidth = [1, 3, 3, 5, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29];
255 | Timeline.spaceWidth = [1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 7, 7, 7];
256 | Timeline.PADDING_LEFT = 4;
257 | Timeline.PADDING_RIGHT = 8;
258 |
--------------------------------------------------------------------------------
/src/js/util.js:
--------------------------------------------------------------------------------
1 | export class Util {
2 |
3 | static fromFloat(v, fractionDigits) {
4 | let text = v.toFixed(fractionDigits);
5 | for (let i = text.length - 1; i >= 0; i--) {
6 | if (text[i] === '.')
7 | return text.substring(0, i);
8 | if (text[i] !== '0')
9 | return text.substring(0, i + 1);
10 | }
11 | };
12 |
13 | static formatTime(v) {
14 | return (v < 10) ? "0" + v.toString() : v.toString();
15 | }
16 |
17 | static isInstance(obj, clazz) {
18 | if (obj === null || obj === undefined) {
19 | return false;
20 | }
21 | return obj instanceof clazz;
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const HtmlWebpackPlugin = require("html-webpack-plugin");
3 | const htmlWebpackPlugin = new HtmlWebpackPlugin({
4 | template: path.join(__dirname, "example/src/index.html"),
5 | filename: "./index.html"
6 | });
7 | module.exports = [
8 | {
9 | entry: path.join(__dirname, "example/src/index.jsx"),
10 | output: {
11 | path: path.join(__dirname, "demo_dist"),
12 | filename: "bundle.js"
13 | },
14 | module: {
15 | rules: [
16 | {
17 | test: /\.(js|jsx)$/,
18 | use: "babel-loader",
19 | exclude: /node_modules/
20 | },
21 | {
22 | test: /\.css$/,
23 | use: ["style-loader", "css-loader"]
24 | },
25 | {
26 | test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
27 | loader: 'url-loader',
28 | options: {
29 | limit: 10000
30 | }
31 | },
32 | {
33 | test: /\.(html)$/,
34 | use: {
35 | loader: 'html-loader',
36 | options: {
37 | attrs: [':data-src']
38 | }
39 | }
40 | }
41 | ]
42 | },
43 | plugins: [htmlWebpackPlugin],
44 | resolve: {
45 | extensions: [".js", ".jsx"]
46 | },
47 | devServer: {
48 | port: 3001
49 | }
50 | },
51 | ];
52 |
--------------------------------------------------------------------------------