charts.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /*
  2. * 图片转换对话框脚本
  3. **/
  4. var tableData = [],
  5. //编辑器页面table
  6. editorTable = null,
  7. chartsConfig = window.typeConfig,
  8. resizeTimer = null,
  9. //初始默认图表类型
  10. currentChartType = 0;
  11. window.onload = function () {
  12. editorTable = domUtils.findParentByTagName( editor.selection.getRange().startContainer, 'table', true);
  13. //未找到表格, 显示错误页面
  14. if ( !editorTable ) {
  15. document.body.innerHTML = "<div class='edui-charts-not-data'>未找到数据</div>";
  16. return;
  17. }
  18. //初始化图表类型选择
  19. initChartsTypeView();
  20. renderTable( editorTable );
  21. initEvent();
  22. initUserConfig( editorTable.getAttribute( "data-chart" ) );
  23. $( "#scrollBed .view-box:eq("+ currentChartType +")" ).trigger( "click" );
  24. updateViewType( currentChartType );
  25. dialog.addListener( "resize", function () {
  26. if ( resizeTimer != null ) {
  27. window.clearTimeout( resizeTimer );
  28. }
  29. resizeTimer = window.setTimeout( function () {
  30. resizeTimer = null;
  31. renderCharts();
  32. }, 500 );
  33. } );
  34. };
  35. function initChartsTypeView () {
  36. var contents = [];
  37. for ( var i = 0, len = chartsConfig.length; i<len; i++ ) {
  38. contents.push( '<div class="view-box" data-chart-type="'+ i +'"><img width="300" src="images/charts'+ i +'.png"></div>' );
  39. }
  40. $( "#scrollBed" ).html( contents.join( "" ) );
  41. }
  42. //渲染table, 以便用户修改数据
  43. function renderTable ( table ) {
  44. var tableHtml = [];
  45. //构造数据
  46. for ( var i = 0, row; row = table.rows[ i ]; i++ ) {
  47. tableData[ i ] = [];
  48. tableHtml[ i ] = [];
  49. for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) {
  50. var value = getCellValue( cell );
  51. if ( i > 0 && j > 0 ) {
  52. value = +value;
  53. }
  54. if ( i === 0 || j === 0 ) {
  55. tableHtml[ i ].push( '<th>'+ value +'</th>' );
  56. } else {
  57. tableHtml[ i ].push( '<td><input type="text" class="data-item" value="'+ value +'"></td>' );
  58. }
  59. tableData[ i ][ j ] = value;
  60. }
  61. tableHtml[ i ] = tableHtml[ i ].join( "" );
  62. }
  63. //draw 表格
  64. $( "#tableContainer" ).html( '<table id="showTable" border="1"><tbody><tr>'+ tableHtml.join( "</tr><tr>" ) +'</tr></tbody></table>' );
  65. }
  66. /*
  67. * 根据表格已有的图表属性初始化当前图表属性
  68. */
  69. function initUserConfig ( config ) {
  70. var parsedConfig = {};
  71. if ( !config ) {
  72. return;
  73. }
  74. config = config.split( ";" );
  75. $.each( config, function ( index, item ) {
  76. item = item.split( ":" );
  77. parsedConfig[ item[ 0 ] ] = item[ 1 ];
  78. } );
  79. setUserConfig( parsedConfig );
  80. }
  81. function initEvent () {
  82. var cacheValue = null,
  83. //图表类型数
  84. typeViewCount = chartsConfig.length- 1,
  85. $chartsTypeViewBox = $( '#scrollBed .view-box' );
  86. $( ".charts-format" ).delegate( ".format-ctrl", "change", function () {
  87. renderCharts();
  88. } )
  89. $( ".table-view" ).delegate( ".data-item", "focus", function () {
  90. cacheValue = this.value;
  91. } ).delegate( ".data-item", "blur", function () {
  92. if ( this.value !== cacheValue ) {
  93. renderCharts();
  94. }
  95. cacheValue = null;
  96. } );
  97. $( "#buttonContainer" ).delegate( "a", "click", function (e) {
  98. e.preventDefault();
  99. if ( this.getAttribute( "data-title" ) === 'prev' ) {
  100. if ( currentChartType > 0 ) {
  101. currentChartType--;
  102. updateViewType( currentChartType );
  103. }
  104. } else {
  105. if ( currentChartType < typeViewCount ) {
  106. currentChartType++;
  107. updateViewType( currentChartType );
  108. }
  109. }
  110. } );
  111. //图表类型变化
  112. $( '#scrollBed' ).delegate( ".view-box", "click", function (e) {
  113. var index = $( this ).attr( "data-chart-type" );
  114. $chartsTypeViewBox.removeClass( "selected" );
  115. $( $chartsTypeViewBox[ index ] ).addClass( "selected" );
  116. currentChartType = index | 0;
  117. //饼图, 禁用部分配置
  118. if ( currentChartType === chartsConfig.length - 1 ) {
  119. disableNotPieConfig();
  120. //启用完整配置
  121. } else {
  122. enableNotPieConfig();
  123. }
  124. renderCharts();
  125. } );
  126. }
  127. function renderCharts () {
  128. var data = collectData();
  129. $('#chartsContainer').highcharts( $.extend( {}, chartsConfig[ currentChartType ], {
  130. credits: {
  131. enabled: false
  132. },
  133. exporting: {
  134. enabled: false
  135. },
  136. title: {
  137. text: data.title,
  138. x: -20 //center
  139. },
  140. subtitle: {
  141. text: data.subTitle,
  142. x: -20
  143. },
  144. xAxis: {
  145. title: {
  146. text: data.xTitle
  147. },
  148. categories: data.categories
  149. },
  150. yAxis: {
  151. title: {
  152. text: data.yTitle
  153. },
  154. plotLines: [{
  155. value: 0,
  156. width: 1,
  157. color: '#808080'
  158. }]
  159. },
  160. tooltip: {
  161. enabled: true,
  162. valueSuffix: data.suffix
  163. },
  164. legend: {
  165. layout: 'vertical',
  166. align: 'right',
  167. verticalAlign: 'middle',
  168. borderWidth: 1
  169. },
  170. series: data.series
  171. } ));
  172. }
  173. function updateViewType ( index ) {
  174. $( "#scrollBed" ).css( 'marginLeft', -index*324+'px' );
  175. }
  176. function collectData () {
  177. var form = document.forms[ 'data-form' ],
  178. data = null;
  179. if ( currentChartType !== chartsConfig.length - 1 ) {
  180. data = getSeriesAndCategories();
  181. $.extend( data, getUserConfig() );
  182. //饼图数据格式
  183. } else {
  184. data = getSeriesForPieChart();
  185. data.title = form[ 'title' ].value;
  186. data.suffix = form[ 'unit' ].value;
  187. }
  188. return data;
  189. }
  190. /**
  191. * 获取用户配置信息
  192. */
  193. function getUserConfig () {
  194. var form = document.forms[ 'data-form' ],
  195. info = {
  196. title: form[ 'title' ].value,
  197. subTitle: form[ 'sub-title' ].value,
  198. xTitle: form[ 'x-title' ].value,
  199. yTitle: form[ 'y-title' ].value,
  200. suffix: form[ 'unit' ].value,
  201. //数据对齐方式
  202. tableDataFormat: getTableDataFormat (),
  203. //饼图提示文字
  204. tip: $( "#tipInput" ).val()
  205. };
  206. return info;
  207. }
  208. function setUserConfig ( config ) {
  209. var form = document.forms[ 'data-form' ];
  210. config.title && ( form[ 'title' ].value = config.title );
  211. config.subTitle && ( form[ 'sub-title' ].value = config.subTitle );
  212. config.xTitle && ( form[ 'x-title' ].value = config.xTitle );
  213. config.yTitle && ( form[ 'y-title' ].value = config.yTitle );
  214. config.suffix && ( form[ 'unit' ].value = config.suffix );
  215. config.dataFormat == "-1" && ( form[ 'charts-format' ][ 1 ].checked = true );
  216. config.tip && ( form[ 'tip' ].value = config.tip );
  217. currentChartType = config.chartType || 0;
  218. }
  219. function getSeriesAndCategories () {
  220. var form = document.forms[ 'data-form' ],
  221. series = [],
  222. categories = [],
  223. tmp = [],
  224. tableData = getTableData();
  225. //反转数据
  226. if ( getTableDataFormat() === "-1" ) {
  227. for ( var i = 0, len = tableData.length; i < len; i++ ) {
  228. for ( var j = 0, jlen = tableData[ i ].length; j < jlen; j++ ) {
  229. if ( !tmp[ j ] ) {
  230. tmp[ j ] = [];
  231. }
  232. tmp[ j ][ i ] = tableData[ i ][ j ];
  233. }
  234. }
  235. tableData = tmp;
  236. }
  237. categories = tableData[0].slice( 1 );
  238. for ( var i = 1, data; data = tableData[ i ]; i++ ) {
  239. series.push( {
  240. name: data[ 0 ],
  241. data: data.slice( 1 )
  242. } );
  243. }
  244. return {
  245. series: series,
  246. categories: categories
  247. };
  248. }
  249. /*
  250. * 获取数据源数据对齐方式
  251. */
  252. function getTableDataFormat () {
  253. var form = document.forms[ 'data-form' ],
  254. items = form['charts-format'];
  255. return items[ 0 ].checked ? items[ 0 ].value : items[ 1 ].value;
  256. }
  257. /*
  258. * 禁用非饼图类型的配置项
  259. */
  260. function disableNotPieConfig() {
  261. updateConfigItem( 'disable' );
  262. }
  263. /*
  264. * 启用非饼图类型的配置项
  265. */
  266. function enableNotPieConfig() {
  267. updateConfigItem( 'enable' );
  268. }
  269. function updateConfigItem ( value ) {
  270. var table = $( "#showTable" )[ 0 ],
  271. isDisable = value === 'disable' ? true : false;
  272. //table中的input处理
  273. for ( var i = 2 , row; row = table.rows[ i ]; i++ ) {
  274. for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
  275. $( "input", cell ).attr( "disabled", isDisable );
  276. }
  277. }
  278. //其他项处理
  279. $( "input.not-pie-item" ).attr( "disabled", isDisable );
  280. $( "#tipInput" ).attr( "disabled", !isDisable )
  281. }
  282. /*
  283. * 获取饼图数据
  284. * 饼图的数据只取第一行的
  285. **/
  286. function getSeriesForPieChart () {
  287. var series = {
  288. type: 'pie',
  289. name: $("#tipInput").val(),
  290. data: []
  291. },
  292. tableData = getTableData();
  293. for ( var j = 1, jlen = tableData[ 0 ].length; j < jlen; j++ ) {
  294. var title = tableData[ 0 ][ j ],
  295. val = tableData[ 1 ][ j ];
  296. series.data.push( [ title, val ] );
  297. }
  298. return {
  299. series: [ series ]
  300. };
  301. }
  302. function getTableData () {
  303. var table = document.getElementById( "showTable" ),
  304. xCount = table.rows[0].cells.length - 1,
  305. values = getTableInputValue();
  306. for ( var i = 0, value; value = values[ i ]; i++ ) {
  307. tableData[ Math.floor( i / xCount ) + 1 ][ i % xCount + 1 ] = values[ i ];
  308. }
  309. return tableData;
  310. }
  311. function getTableInputValue () {
  312. var table = document.getElementById( "showTable" ),
  313. inputs = table.getElementsByTagName( "input" ),
  314. values = [];
  315. for ( var i = 0, input; input = inputs[ i ]; i++ ) {
  316. values.push( input.value | 0 );
  317. }
  318. return values;
  319. }
  320. function getCellValue ( cell ) {
  321. var value = utils.trim( ( cell.innerText || cell.textContent || '' ) );
  322. return value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' );
  323. }
  324. //dialog确认事件
  325. dialog.onok = function () {
  326. //收集信息
  327. var form = document.forms[ 'data-form' ],
  328. info = getUserConfig();
  329. //添加图表类型
  330. info.chartType = currentChartType;
  331. //同步表格数据到编辑器
  332. syncTableData();
  333. //执行图表命令
  334. editor.execCommand( 'charts', info );
  335. };
  336. /*
  337. * 同步图表编辑视图的表格数据到编辑器里的原始表格
  338. */
  339. function syncTableData () {
  340. var tableData = getTableData();
  341. for ( var i = 1, row; row = editorTable.rows[ i ]; i++ ) {
  342. for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {
  343. cell.innerHTML = tableData[ i ] [ j ];
  344. }
  345. }
  346. }