brush2.html 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <script src="esl.js"></script>
  5. <script src="config.js"></script>
  6. <script src="lib/jquery.min.js"></script>
  7. <link rel="stylesheet" href="reset.css" />
  8. </head>
  9. <body>
  10. <style>
  11. .split {
  12. line-height: 60px;
  13. height: 60px;
  14. background: #333;
  15. text-align: center;
  16. font-weight: bold;
  17. font-size: 20px;
  18. color: #fff;
  19. }
  20. .block {
  21. position: relative;
  22. }
  23. body {
  24. background: #555;
  25. }
  26. body .main {
  27. height: 550px;
  28. margin-right: 220px;
  29. margin-left: 20px;
  30. }
  31. .panel {
  32. position: absolute;
  33. top: 0;
  34. right: 0;
  35. bottom: 0;
  36. width: 200px;
  37. background: #555;
  38. color: #fff;
  39. font-size: 14px;
  40. font-weight: normal;
  41. padding: 10px;
  42. }
  43. ul.panel-desc {
  44. padding-left: 20px;
  45. padding-bottom: 10px;
  46. border-bottom: 1px solid #777;
  47. }
  48. ul.panel-desc li {
  49. margin-bottom: 5px;
  50. }
  51. h3 {
  52. font-size: 14px;
  53. }
  54. #main2 {
  55. height: 450px;
  56. }
  57. #main2-st {
  58. position: relative;
  59. height: 200px;
  60. margin-right: 220px;
  61. margin-left: 20px;
  62. }
  63. strong {
  64. background: yellow;
  65. padding: 0 2px;
  66. border-radius: 2px;
  67. color: #000;
  68. }
  69. #main1-st {
  70. position: absolute;
  71. top: 0;
  72. right: 300px;
  73. height: 550px;
  74. width: 400px;
  75. z-index: 999;
  76. }
  77. .sm-settings {
  78. border-bottom: 1px solid #777;
  79. padding-bottom: 15px;
  80. }
  81. .sm-settings input {
  82. max-width: 50px;
  83. }
  84. </style>
  85. <div class="split">Candlestick</div>
  86. <div class="block">
  87. <div id="main1" class="main"></div>
  88. <!-- <div id="main1-st"></div> -->
  89. <div class="panel">
  90. <ul class="panel-desc">
  91. <li><strong>CHECK</strong>: brush an area and drag dataZoom.</li>
  92. </ul>
  93. <div id="panel1"></div>
  94. </div>
  95. </div>
  96. <div class="split">Graph</div>
  97. <div class="block">
  98. <div id="main2" class="main"></div>
  99. <!-- <div id="main1-st"></div> -->
  100. <div class="panel">
  101. <ul class="panel-desc">
  102. <li><strong>CHECK</strong>: brush an area and drag dataZoom.</li>
  103. </ul>
  104. <div id="panel2"></div>
  105. </div>
  106. </div>
  107. <!-- =================== 1 ===================== -->
  108. <script>
  109. /**
  110. * @see <https://en.wikipedia.org/wiki/Michelson%E2%80%93Morley_experiment>
  111. * @see <http://bl.ocks.org/mbostock/4061502>
  112. */
  113. var chart;
  114. var data;
  115. var panel;
  116. require([
  117. 'echarts',
  118. 'data/stock-DJI.json',
  119. 'echarts/chart/candlestick',
  120. 'echarts/chart/line',
  121. 'echarts/chart/bar',
  122. 'echarts/component/title',
  123. 'echarts/component/legend',
  124. 'echarts/component/grid',
  125. 'echarts/component/tooltip',
  126. 'echarts/component/dataZoom',
  127. 'echarts/component/toolbox',
  128. 'echarts/component/brush',
  129. 'echarts/component/markPoint',
  130. 'echarts/component/markLine'
  131. ], function (echarts, rawData) {
  132. chart = echarts.init(document.getElementById('main1'), null, {
  133. renderer: 'canvas'
  134. });
  135. panel = document.getElementById('panel1');
  136. data = splitData(rawData);
  137. update();
  138. chart.on('click', function (info) {
  139. if (info.data && info.componentType === 'series') {
  140. alert([
  141. 'clicked on: ',
  142. 'DATA: ' + info.name,
  143. 'OPEN: ' + info.data[0],
  144. 'CLOSE: ' + info.data[1],
  145. 'LOWEST: ' + info.data[2],
  146. 'HIGHEST: ' + info.data[3],
  147. 'VOLUMN: ' + info.data[4]
  148. ].join('\n'));
  149. }
  150. });
  151. })
  152. function splitData(rawData) {
  153. var categoryData = [];
  154. var values = [];
  155. var volumns = [];
  156. for (var i = 0; i < rawData.length; i++) {
  157. categoryData.push(rawData[i].splice(0, 1)[0]);
  158. values.push(rawData[i])
  159. volumns.push(rawData[i][4]);
  160. }
  161. return {
  162. categoryData: categoryData,
  163. values: values,
  164. volumns: volumns
  165. };
  166. }
  167. function calculateMA(dayCount, data) {
  168. var result = [];
  169. for (var i = 0, len = data.values.length; i < len; i++) {
  170. if (i < dayCount) {
  171. result.push('-');
  172. continue;
  173. }
  174. var sum = 0;
  175. for (var j = 0; j < dayCount; j++) {
  176. sum += data.values[i - j][1];
  177. }
  178. result.push(+(sum / dayCount).toFixed(3));
  179. }
  180. return result;
  181. }
  182. function update() {
  183. chart.setOption({
  184. backgroundColor: '#eee',
  185. animation: false,
  186. legend: {
  187. left: 0,
  188. data: ['Dow-Jones index', 'MA5', 'MA10', 'MA20', 'MA30']
  189. },
  190. tooltip: {
  191. trigger: 'axis',
  192. axisPointer: {
  193. type: 'line'
  194. }
  195. },
  196. toolbox: {
  197. feature: {
  198. dataZoom: {
  199. yAxisIndex: false
  200. },
  201. brush: {
  202. type: ['polygon', 'rect', 'lineX', 'lineY', 'keep', 'clear']
  203. }
  204. }
  205. },
  206. brush: {
  207. xAxisIndex: 'all',
  208. brushLink: 'all',
  209. outOfBrush: {
  210. colorAlpha: 0.1
  211. }
  212. },
  213. grid: [
  214. {
  215. left: '10%',
  216. right: '10%',
  217. height: 300
  218. },
  219. {
  220. left: '10%',
  221. right: '10%',
  222. height: 70,
  223. bottom: 80
  224. }
  225. ],
  226. xAxis: [
  227. {
  228. type: 'category',
  229. data: data.categoryData,
  230. scale: true,
  231. boundaryGap : false,
  232. axisLine: {onZero: false},
  233. splitLine: {show: false},
  234. splitNumber: 20,
  235. min: 'dataMin',
  236. max: 'dataMax'
  237. },
  238. {
  239. type: 'category',
  240. gridIndex: 1,
  241. data: data.categoryData,
  242. scale: true,
  243. boundaryGap : false,
  244. axisLine: {onZero: false},
  245. axisTick: {show: false},
  246. splitLine: {show: false},
  247. axisLabel: {show: false},
  248. splitNumber: 20,
  249. min: 'dataMin',
  250. max: 'dataMax'
  251. }
  252. ],
  253. yAxis: [
  254. {
  255. scale: true,
  256. splitArea: {
  257. show: true
  258. }
  259. },
  260. {
  261. scale: true,
  262. gridIndex: 1,
  263. splitNumber: 2,
  264. axisLabel: {show: false},
  265. axisLine: {show: false},
  266. axisTick: {show: false},
  267. splitLine: {show: false}
  268. }
  269. ],
  270. dataZoom: [
  271. {
  272. type: 'inside',
  273. xAxisIndex: [0, 1],
  274. start: 98,
  275. end: 100
  276. },
  277. {
  278. show: true,
  279. xAxisIndex: [0, 1],
  280. type: 'slider',
  281. bottom: 10,
  282. start: 98,
  283. end: 100
  284. }
  285. ],
  286. series: [
  287. {
  288. name: 'Dow-Jones index',
  289. type: 'candlestick',
  290. data: data.values,
  291. itemStyle: {
  292. normal: {
  293. borderColor: null,
  294. borderColor0: null
  295. }
  296. },
  297. tooltip: {
  298. formatter: function (param) {
  299. var param = param[0];
  300. return [
  301. 'Date: ' + param.name + '<hr size=1 style="margin: 3px 0">',
  302. 'Open: ' + param.data[0] + '<br/>',
  303. 'Close: ' + param.data[1] + '<br/>',
  304. 'Lowest: ' + param.data[2] + '<br/>',
  305. 'Highest: ' + param.data[3] + '<br/>'
  306. ].join('')
  307. }
  308. }
  309. },
  310. {
  311. name: 'MA5',
  312. type: 'line',
  313. data: calculateMA(5, data),
  314. smooth: true,
  315. lineStyle: {
  316. normal: {opacity: 0.5}
  317. }
  318. },
  319. {
  320. name: 'MA10',
  321. type: 'line',
  322. data: calculateMA(10, data),
  323. smooth: true,
  324. lineStyle: {
  325. normal: {opacity: 0.5}
  326. }
  327. },
  328. {
  329. name: 'MA20',
  330. type: 'line',
  331. data: calculateMA(20, data),
  332. smooth: true,
  333. lineStyle: {
  334. normal: {opacity: 0.5}
  335. }
  336. },
  337. {
  338. name: 'MA30',
  339. type: 'line',
  340. data: calculateMA(30, data),
  341. smooth: true,
  342. lineStyle: {
  343. normal: {opacity: 0.5}
  344. }
  345. },
  346. {
  347. name: 'Volumn',
  348. type: 'bar',
  349. xAxisIndex: 1,
  350. yAxisIndex: 1,
  351. data: data.volumns
  352. }
  353. ]
  354. });
  355. chart.on('brushSelected', renderBrushed);
  356. function renderBrushed(params) {
  357. var sum = 0;
  358. var min = Infinity;
  359. var max = -Infinity;
  360. var countBySeries = [];
  361. var brushComponent = params.batch[0];
  362. var rawIndices = brushComponent.selected[0].dataIndex;
  363. for (var i = 0; i < rawIndices.length; i++) {
  364. var val = data.values[rawIndices[i]][1];
  365. sum += val;
  366. min = Math.min(val, min);
  367. max = Math.max(val, max);
  368. }
  369. panel.innerHTML = [
  370. '<h3>STATISTICS:</h3>',
  371. 'SUM of open: ' + (sum / rawIndices.length).toFixed(4) + '<br>',
  372. 'MIN of open: ' + min.toFixed(4) + '<br>',
  373. 'MAX of open: ' + max.toFixed(4) + '<br>'
  374. ].join(' ');
  375. }
  376. chart.dispatchAction({
  377. type: 'brush',
  378. areas: [
  379. {
  380. brushType: 'lineX',
  381. coordRange: ['2016-06-02', '2016-06-20'],
  382. xAxisIndex: 0
  383. }
  384. ]
  385. });
  386. }
  387. </script>
  388. <!-- =================== 2 ===================== -->
  389. <script>
  390. require([
  391. 'echarts',
  392. 'extension/dataTool/gexf',
  393. 'echarts/chart/graph',
  394. 'echarts/component/title',
  395. 'echarts/component/legend',
  396. 'echarts/component/geo',
  397. 'echarts/component/tooltip',
  398. 'echarts/component/visualMap',
  399. 'theme/vintage'
  400. ], function (echarts, gexf) {
  401. var chart = echarts.init(document.getElementById('main2'), 'vintage');
  402. $.get('./data/les-miserables.gexf', function (xml) {
  403. var graph = gexf.parse(xml);
  404. var categories = [];
  405. for (var i = 0; i < 9; i++) {
  406. categories[i] = {
  407. name: '类目' + i
  408. };
  409. }
  410. graph.nodes.forEach(function (node) {
  411. delete node.itemStyle;
  412. node.value = node.symbolSize;
  413. node.label = {
  414. normal: {
  415. show: node.symbolSize > 30
  416. },
  417. emphasis: {
  418. show: true
  419. }
  420. };
  421. node.category = node.attributes['modularity_class'];
  422. });
  423. graph.links.forEach(function (link) {
  424. delete link.lineStyle;
  425. });
  426. var option = {
  427. tooltip: {},
  428. legend: [{
  429. width: '70%',
  430. // selectedMode: 'single',
  431. data: categories.map(function (a) {
  432. return a.name;
  433. })
  434. }],
  435. animationDurationUpdate: 1500,
  436. animationEasingUpdate: 'quinticInOut',
  437. brush: {
  438. },
  439. series : [
  440. {
  441. name: 'Les Miserables',
  442. type: 'graph',
  443. layout: 'none',
  444. data: graph.nodes,
  445. links: graph.links,
  446. categories: categories,
  447. roam: true,
  448. draggable: true,
  449. itemStyle: {
  450. normal: {
  451. borderColor: '#fff',
  452. borderWidth: 2,
  453. shadowBlur: 10,
  454. shadowColor: 'rgba(0, 0, 0, 0.3)'
  455. }
  456. },
  457. focusNodeAdjacency: true,
  458. // edgeSymbol: ['none', 'arrow'],
  459. // scaleLimit: {
  460. // min: 1.5,
  461. // max: 2
  462. // },
  463. label: {
  464. normal: {
  465. position: 'right',
  466. formatter: '{b}'
  467. }
  468. },
  469. lineStyle: {
  470. normal: {
  471. color: 'source',
  472. curveness: 0.3
  473. }
  474. }
  475. }
  476. ]
  477. };
  478. chart.setOption(option);
  479. var config = {
  480. layout: 'none'
  481. };
  482. chart.on('click', function (params) {
  483. console.log(params, params.data);
  484. });
  485. });
  486. });
  487. </script>
  488. </body>
  489. </html>