boxplot.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <html>
  2. <head>
  3. <meta charset="utf-8">
  4. <meta name="viewport" content="width=device-width, initial-scale=1" />
  5. <link rel="stylesheet" href="reset.css"/>
  6. <script src="esl.js"></script>
  7. <script src="config.js"></script>
  8. <script src="lib/facePrint.js"></script>
  9. </head>
  10. <body>
  11. <style>
  12. #main {
  13. width: 900px;
  14. height: 650px;
  15. border: 9px solid #eee;
  16. }
  17. </style>
  18. <div id="info"></div>
  19. <div id="main"></div>
  20. <script>
  21. /**
  22. * @see <https://en.wikipedia.org/wiki/Michelson%E2%80%93Morley_experiment>
  23. * @see <http://bl.ocks.org/mbostock/4061502>
  24. */
  25. var chart;
  26. var data;
  27. var mean;
  28. require([
  29. 'echarts',
  30. 'data/Michelson-Morley.json',
  31. 'extension/dataTool/prepareBoxplotData',
  32. 'zrender/core/env',
  33. 'echarts/chart/boxplot',
  34. 'echarts/chart/scatter',
  35. 'echarts/component/title',
  36. 'echarts/component/legend',
  37. 'echarts/component/markLine',
  38. 'echarts/component/markPoint',
  39. 'echarts/component/grid',
  40. 'echarts/component/tooltip',
  41. 'zrender/vml/vml'
  42. ], function (echarts, rawData, prepareBoxplotData, env) {
  43. chart = echarts.init(document.getElementById('main'), null, {
  44. renderer: 'canvas'
  45. });
  46. update('horizontal');
  47. // update('vertical');
  48. initControlPanel(env);
  49. function update(layout) {
  50. data = prepareBoxplotData(rawData, {
  51. layout: layout
  52. });
  53. mean = calculateMean(rawData);
  54. var categoryAxis = {
  55. type: 'category',
  56. data: data.axisData,
  57. boundaryGap: true,
  58. nameGap: 30,
  59. splitArea: {
  60. show: false
  61. },
  62. axisLabel: {
  63. formatter: 'expr {value}'
  64. },
  65. splitLine: {
  66. show: false
  67. }
  68. };
  69. var valueAxis = {
  70. type: 'value',
  71. name: 'km/s minus 299,000',
  72. splitArea: {
  73. show: true
  74. }
  75. };
  76. chart.setOption({
  77. title: [
  78. {
  79. text: 'Michelson-Morley Experiment',
  80. left: 'center'
  81. },
  82. {
  83. text: 'upper: Q3 + 1.5 * IRQ \nlower: Q1 - 1.5 * IRQ',
  84. borderColor: '#999',
  85. borderWidth: 1,
  86. textStyle: {
  87. fontSize: 14
  88. },
  89. left: '10%',
  90. top: '90%'
  91. }
  92. ],
  93. legend: {
  94. data: ['line', 'line2', 'line3']
  95. },
  96. tooltip: {
  97. trigger: 'item',
  98. axisPointer: {
  99. type: 'shadow'
  100. }
  101. },
  102. grid: {
  103. left: '10%',
  104. right: '10%',
  105. bottom: '15%'
  106. },
  107. xAxis: layout === 'horizontal' ? categoryAxis : valueAxis,
  108. yAxis: layout === 'vertical' ? categoryAxis : valueAxis,
  109. series: [
  110. {
  111. name: 'boxplot',
  112. type: 'boxplot',
  113. data: data.boxData,
  114. tooltip: {
  115. formatter: function (param) {
  116. return [
  117. 'Experiment ' + param.name + ': ',
  118. 'upper: ' + param.data[0],
  119. 'Q1: ' + param.data[1],
  120. 'median: ' + param.data[2],
  121. 'Q3: ' + param.data[3],
  122. 'lower: ' + param.data[4]
  123. ].join('<br/>')
  124. }
  125. },
  126. markPoint: {
  127. data: [
  128. {
  129. name: '某个坐标',
  130. coord: [2, 300]
  131. },
  132. {
  133. name: '某个屏幕坐标',
  134. x: 100,
  135. y: 200,
  136. label: {
  137. normal: {
  138. show: false,
  139. formatter: 'asdf'
  140. },
  141. emphasis: {
  142. show: true,
  143. position: 'top',
  144. formatter: 'zxcv'
  145. }
  146. }
  147. },
  148. {
  149. name: 'max value (default)',
  150. type: 'max'
  151. },
  152. {
  153. name: 'min value (default)',
  154. type: 'min'
  155. },
  156. {
  157. name: 'max value (dim:Q1)',
  158. type: 'max',
  159. valueDim: 'Q1'
  160. },
  161. {
  162. name: 'average value (dim:Q1)',
  163. type: 'average',
  164. valueDim: 'Q1'
  165. }
  166. ]
  167. },
  168. markLine: {
  169. data: [
  170. [
  171. {name: '两个坐标之间的标线', coord: [1, 240]},
  172. {coord: [2, 260]}
  173. ],
  174. [
  175. {name: '两个屏幕坐标之间的标线', x: 50, y: 60},
  176. {x: 70, y: 90}
  177. ],
  178. [
  179. {name: 'max - min', type: 'max'},
  180. {type: 'min'}
  181. ],
  182. {
  183. name: 'min line',
  184. type: 'min'
  185. },
  186. {
  187. name: 'max line on dim:Q3',
  188. type: 'max',
  189. valueDim: 'Q3'
  190. }
  191. ]
  192. }
  193. },
  194. {
  195. name: 'outlier',
  196. type: 'scatter',
  197. data: data.outliers
  198. }
  199. ]
  200. });
  201. }
  202. function calculateMean(rawData) {
  203. var sum = 0;
  204. var count = 0;
  205. for (var i = 0, len = rawData.length; i < len; i++) {
  206. for (var j = 0, lenj = rawData[i].length; j < lenj; j++) {
  207. var value = rawData[i][j];
  208. count++;
  209. if (!isNaN(value) && value != null && value !== '') {
  210. sum += value;
  211. }
  212. }
  213. }
  214. return sum / count;
  215. };
  216. function initControlPanel(env) {
  217. if (!env.browser.ie || env.browser.ie.version > 8) {
  218. var scr = document.createElement('script');
  219. scr.src = 'lib/dat.gui.min.js';
  220. scr.onload = function () {
  221. var gui = new dat.GUI();
  222. var config = {
  223. layout: 'horizontal'
  224. };
  225. gui
  226. .add(config, 'layout', ['horizontal', 'vertical'])
  227. .onChange(update);
  228. };
  229. document.head.appendChild(scr);
  230. }
  231. }
  232. });
  233. </script>
  234. </body>
  235. </html>