Chart.js
上传用户:kimgenplus
上传日期:2016-06-05
资源大小:20877k
文件大小:19k
源码类别:

OA系统

开发平台:

Java

  1. /*
  2. Copyright (c) 2004-2006, The Dojo Foundation
  3. All Rights Reserved.
  4. Licensed under the Academic Free License version 2.1 or above OR the
  5. modified BSD license. For more information on Dojo licensing, see:
  6. http://dojotoolkit.org/community/licensing.shtml
  7. */
  8. dojo.provide("dojo.widget.vml.Chart");
  9. dojo.require("dojo.widget.HtmlWidget");
  10. dojo.require("dojo.widget.Chart");
  11. dojo.require("dojo.math");
  12. dojo.require("dojo.html.layout");
  13. dojo.require("dojo.gfx.color");
  14. dojo.widget.defineWidget("dojo.widget.vml.Chart", [dojo.widget.HtmlWidget, dojo.widget.Chart], function () {
  15. this.templatePath = null;
  16. this.templateCssPath = null;
  17. this._isInitialize = false;
  18. this.hasData = false;
  19. this.vectorNode = null;
  20. this.plotArea = null;
  21. this.dataGroup = null;
  22. this.axisGroup = null;
  23. this.properties = {height:0, width:0, defaultWidth:600, defaultHeight:400, plotType:null, padding:{top:10, bottom:2, left:60, right:30}, axes:{x:{plotAt:0, label:"", unitLabel:"", unitType:Number, nUnitsToShow:10, range:{min:0, max:200}}, y:{plotAt:0, label:"", unitLabel:"", unitType:Number, nUnitsToShow:10, range:{min:0, max:200}}}};
  24. }, {parseProperties:function (node) {
  25. var bRangeX = false;
  26. var bRangeY = false;
  27. if (node.getAttribute("width")) {
  28. this.properties.width = node.getAttribute("width");
  29. }
  30. if (node.getAttribute("height")) {
  31. this.properties.height = node.getAttribute("height");
  32. }
  33. if (node.getAttribute("plotType")) {
  34. this.properties.plotType = node.getAttribute("plotType");
  35. }
  36. if (node.getAttribute("padding")) {
  37. if (node.getAttribute("padding").indexOf(",") > -1) {
  38. var p = node.getAttribute("padding").split(",");
  39. } else {
  40. var p = node.getAttribute("padding").split(" ");
  41. }
  42. if (p.length == 1) {
  43. var pad = parseFloat(p[0]);
  44. this.properties.padding.top = pad;
  45. this.properties.padding.right = pad;
  46. this.properties.padding.bottom = pad;
  47. this.properties.padding.left = pad;
  48. } else {
  49. if (p.length == 2) {
  50. var padV = parseFloat(p[0]);
  51. var padH = parseFloat(p[1]);
  52. this.properties.padding.top = padV;
  53. this.properties.padding.right = padH;
  54. this.properties.padding.bottom = padV;
  55. this.properties.padding.left = padH;
  56. } else {
  57. if (p.length == 4) {
  58. this.properties.padding.top = parseFloat(p[0]);
  59. this.properties.padding.right = parseFloat(p[1]);
  60. this.properties.padding.bottom = parseFloat(p[2]);
  61. this.properties.padding.left = parseFloat(p[3]);
  62. }
  63. }
  64. }
  65. }
  66. if (node.getAttribute("rangeX")) {
  67. var p = node.getAttribute("rangeX");
  68. if (p.indexOf(",") > -1) {
  69. p = p.split(",");
  70. } else {
  71. p = p.split(" ");
  72. }
  73. this.properties.axes.x.range.min = parseFloat(p[0]);
  74. this.properties.axes.x.range.max = parseFloat(p[1]);
  75. bRangeX = true;
  76. }
  77. if (node.getAttribute("rangeY")) {
  78. var p = node.getAttribute("rangeY");
  79. if (p.indexOf(",") > -1) {
  80. p = p.split(",");
  81. } else {
  82. p = p.split(" ");
  83. }
  84. this.properties.axes.y.range.min = parseFloat(p[0]);
  85. this.properties.axes.y.range.max = parseFloat(p[1]);
  86. bRangeY = true;
  87. }
  88. return {rangeX:bRangeX, rangeY:bRangeY};
  89. }, setAxesPlot:function (table) {
  90. if (table.getAttribute("axisAt")) {
  91. var p = table.getAttribute("axisAt");
  92. if (p.indexOf(",") > -1) {
  93. p = p.split(",");
  94. } else {
  95. p = p.split(" ");
  96. }
  97. if (!isNaN(parseFloat(p[0]))) {
  98. this.properties.axes.x.plotAt = parseFloat(p[0]);
  99. } else {
  100. if (p[0].toLowerCase() == "ymin") {
  101. this.properties.axes.x.plotAt = this.properties.axes.y.range.min;
  102. } else {
  103. if (p[0].toLowerCase() == "ymax") {
  104. this.properties.axes.x.plotAt = this.properties.axes.y.range.max;
  105. }
  106. }
  107. }
  108. if (!isNaN(parseFloat(p[1]))) {
  109. this.properties.axes.y.plotAt = parseFloat(p[1]);
  110. } else {
  111. if (p[1].toLowerCase() == "xmin") {
  112. this.properties.axes.y.plotAt = this.properties.axes.x.range.min;
  113. } else {
  114. if (p[1].toLowerCase() == "xmax") {
  115. this.properties.axes.y.plotAt = this.properties.axes.x.range.max;
  116. }
  117. }
  118. }
  119. } else {
  120. this.properties.axes.x.plotAt = this.properties.axes.y.range.min;
  121. this.properties.axes.y.plotAt = this.properties.axes.x.range.min;
  122. }
  123. }, drawVectorNode:function () {
  124. if (this.vectorNode) {
  125. this.destroy();
  126. }
  127. this.vectorNode = document.createElement("div");
  128. this.vectorNode.style.width = this.properties.width + "px";
  129. this.vectorNode.style.height = this.properties.height + "px";
  130. this.vectorNode.style.position = "relative";
  131. this.domNode.appendChild(this.vectorNode);
  132. }, drawPlotArea:function () {
  133. var plotWidth = this.properties.width - this.properties.padding.left - this.properties.padding.right;
  134. var plotHeight = this.properties.height - this.properties.padding.top - this.properties.padding.bottom;
  135. if (this.plotArea) {
  136. this.plotArea.parentNode.removeChild(this.plotArea);
  137. this.plotArea = null;
  138. }
  139. this.plotArea = document.createElement("div");
  140. this.plotArea.style.position = "absolute";
  141. this.plotArea.style.backgroundColor = "#fff";
  142. this.plotArea.style.top = (this.properties.padding.top) - 2 + "px";
  143. this.plotArea.style.left = (this.properties.padding.left - 1) + "px";
  144. this.plotArea.style.width = plotWidth + "px";
  145. this.plotArea.style.height = plotHeight + "px";
  146. this.plotArea.style.clip = "rect(0 " + plotWidth + " " + plotHeight + " 0)";
  147. this.vectorNode.appendChild(this.plotArea);
  148. }, drawDataGroup:function () {
  149. var plotWidth = this.properties.width - this.properties.padding.left - this.properties.padding.right;
  150. var plotHeight = this.properties.height - this.properties.padding.top - this.properties.padding.bottom;
  151. if (this.dataGroup) {
  152. this.dataGroup.parentNode.removeChild(this.dataGroup);
  153. this.dataGroup = null;
  154. }
  155. this.dataGroup = document.createElement("div");
  156. this.dataGroup.style.position = "absolute";
  157. this.dataGroup.setAttribute("title", "Data Group");
  158. this.dataGroup.style.top = "0px";
  159. this.dataGroup.style.left = "0px";
  160. this.dataGroup.style.width = plotWidth + "px";
  161. this.dataGroup.style.height = plotHeight + "px";
  162. this.plotArea.appendChild(this.dataGroup);
  163. }, drawAxes:function () {
  164. var plotWidth = this.properties.width - this.properties.padding.left - this.properties.padding.right;
  165. var plotHeight = this.properties.height - this.properties.padding.top - this.properties.padding.bottom;
  166. if (this.axisGroup) {
  167. this.axisGroup.parentNode.removeChild(this.axisGroup);
  168. this.axisGroup = null;
  169. }
  170. this.axisGroup = document.createElement("div");
  171. this.axisGroup.style.position = "absolute";
  172. this.axisGroup.setAttribute("title", "Axis Group");
  173. this.axisGroup.style.top = "0px";
  174. this.axisGroup.style.left = "0px";
  175. this.axisGroup.style.width = plotWidth + "px";
  176. this.axisGroup.style.height = plotHeight + "px";
  177. this.plotArea.appendChild(this.axisGroup);
  178. var stroke = 1;
  179. var line = document.createElement("v:line");
  180. var y = dojo.widget.vml.Chart.Plotter.getY(this.properties.axes.x.plotAt, this);
  181. line.setAttribute("from", "0px," + y + "px");
  182. line.setAttribute("to", plotWidth + "px," + y + "px");
  183. line.style.position = "absolute";
  184. line.style.top = "0px";
  185. line.style.left = "0px";
  186. line.style.antialias = "false";
  187. line.setAttribute("strokecolor", "#666");
  188. line.setAttribute("strokeweight", stroke * 2 + "px");
  189. this.axisGroup.appendChild(line);
  190. var line = document.createElement("v:line");
  191. var x = dojo.widget.vml.Chart.Plotter.getX(this.properties.axes.y.plotAt, this);
  192. line.setAttribute("from", x + "px,0px");
  193. line.setAttribute("to", x + "px," + plotHeight + "px");
  194. line.style.position = "absolute";
  195. line.style.top = "0px";
  196. line.style.left = "0px";
  197. line.style.antialias = "false";
  198. line.setAttribute("strokecolor", "#666");
  199. line.setAttribute("strokeweight", stroke * 2 + "px");
  200. this.axisGroup.appendChild(line);
  201. var size = 10;
  202. var t = document.createElement("div");
  203. t.style.position = "absolute";
  204. t.style.top = (this.properties.height - this.properties.padding.bottom) + "px";
  205. t.style.left = this.properties.padding.left + "px";
  206. t.style.fontFamily = "sans-serif";
  207. t.style.fontSize = size + "px";
  208. t.innerHTML = dojo.math.round(parseFloat(this.properties.axes.x.range.min), 2);
  209. this.vectorNode.appendChild(t);
  210. t = document.createElement("div");
  211. t.style.position = "absolute";
  212. t.style.top = (this.properties.height - this.properties.padding.bottom) + "px";
  213. t.style.left = (this.properties.width - this.properties.padding.right - size) + "px";
  214. t.style.fontFamily = "sans-serif";
  215. t.style.fontSize = size + "px";
  216. t.innerHTML = dojo.math.round(parseFloat(this.properties.axes.x.range.max), 2);
  217. this.vectorNode.appendChild(t);
  218. t = document.createElement("div");
  219. t.style.position = "absolute";
  220. t.style.top = (size / 2) + "px";
  221. t.style.left = "0px";
  222. t.style.width = this.properties.padding.left + "px";
  223. t.style.textAlign = "right";
  224. t.style.paddingRight = "4px";
  225. t.style.fontFamily = "sans-serif";
  226. t.style.fontSize = size + "px";
  227. t.innerHTML = dojo.math.round(parseFloat(this.properties.axes.y.range.max), 2);
  228. this.vectorNode.appendChild(t);
  229. t = document.createElement("div");
  230. t.style.position = "absolute";
  231. t.style.top = (this.properties.height - this.properties.padding.bottom - size) + "px";
  232. t.style.left = "0px";
  233. t.style.width = this.properties.padding.left + "px";
  234. t.style.textAlign = "right";
  235. t.style.paddingRight = "4px";
  236. t.style.fontFamily = "sans-serif";
  237. t.style.fontSize = size + "px";
  238. t.innerHTML = dojo.math.round(parseFloat(this.properties.axes.y.range.min), 2);
  239. this.vectorNode.appendChild(t);
  240. }, init:function () {
  241. if (!this.properties.width || !this.properties.height) {
  242. var box = dojo.html.getContentBox(this.domNode);
  243. if (!this.properties.width) {
  244. this.properties.width = (box.width < 32) ? this.properties.defaultWidth : box.width;
  245. }
  246. if (!this.properties.height) {
  247. this.properties.height = (box.height < 32) ? this.properties.defaultHeight : box.height;
  248. }
  249. }
  250. this.drawVectorNode();
  251. this.drawPlotArea();
  252. this.drawDataGroup();
  253. this.drawAxes();
  254. this.assignColors();
  255. this._isInitialized = true;
  256. }, destroy:function () {
  257. while (this.domNode.childNodes.length > 0) {
  258. this.domNode.removeChild(this.domNode.childNodes[0]);
  259. }
  260. this.vectorNode = this.plotArea = this.dataGroup = this.axisGroup = null;
  261. }, render:function () {
  262. if (this.dataGroup) {
  263. while (this.dataGroup.childNodes.length > 0) {
  264. this.dataGroup.removeChild(this.dataGroup.childNodes[0]);
  265. }
  266. } else {
  267. this.init();
  268. }
  269. for (var i = 0; i < this.series.length; i++) {
  270. dojo.widget.vml.Chart.Plotter.plot(this.series[i], this);
  271. }
  272. }, postCreate:function () {
  273. var table = this.domNode.getElementsByTagName("table")[0];
  274. if (table) {
  275. var ranges = this.parseProperties(table);
  276. var bRangeX = false;
  277. var bRangeY = false;
  278. var axisValues = this.parseData(table);
  279. if (!bRangeX) {
  280. this.properties.axes.x.range = {min:axisValues.x.min, max:axisValues.x.max};
  281. }
  282. if (!bRangeY) {
  283. this.properties.axes.y.range = {min:axisValues.y.min, max:axisValues.y.max};
  284. }
  285. this.setAxesPlot(table);
  286. this.domNode.removeChild(table);
  287. }
  288. if (this.series.length > 0) {
  289. this.render();
  290. }
  291. }});
  292. dojo.widget.vml.Chart.Plotter = new function () {
  293. var self = this;
  294. var plotters = {};
  295. var types = dojo.widget.Chart.PlotTypes;
  296. this.getX = function (value, chart) {
  297. var v = parseFloat(value);
  298. var min = chart.properties.axes.x.range.min;
  299. var max = chart.properties.axes.x.range.max;
  300. var ofst = 0 - min;
  301. min += ofst;
  302. max += ofst;
  303. v += ofst;
  304. var xmin = 0;
  305. var xmax = chart.properties.width - chart.properties.padding.left - chart.properties.padding.right;
  306. var x = (v * ((xmax - xmin) / max)) + xmin;
  307. return x;
  308. };
  309. this.getY = function (value, chart) {
  310. var v = parseFloat(value);
  311. var max = chart.properties.axes.y.range.max;
  312. var min = chart.properties.axes.y.range.min;
  313. var ofst = 0;
  314. if (min < 0) {
  315. ofst += Math.abs(min);
  316. }
  317. min += ofst;
  318. max += ofst;
  319. v += ofst;
  320. var ymin = chart.properties.height - chart.properties.padding.top - chart.properties.padding.bottom;
  321. var ymax = 0;
  322. var y = (((ymin - ymax) / (max - min)) * (max - v)) + ymax;
  323. return y;
  324. };
  325. this.addPlotter = function (name, func) {
  326. plotters[name] = func;
  327. };
  328. this.plot = function (series, chart) {
  329. if (series.values.length == 0) {
  330. return;
  331. }
  332. if (series.plotType && plotters[series.plotType]) {
  333. return plotters[series.plotType](series, chart);
  334. } else {
  335. if (chart.plotType && plotters[chart.plotType]) {
  336. return plotters[chart.plotType](series, chart);
  337. }
  338. }
  339. };
  340. plotters["bar"] = function (series, chart) {
  341. var space = 1;
  342. var lastW = 0;
  343. var ys = [];
  344. var yAxis = self.getY(chart.properties.axes.x.plotAt, chart);
  345. var yA = yAxis;
  346. for (var i = 0; i < series.values.length; i++) {
  347. var x = self.getX(series.values[i].x, chart);
  348. var w;
  349. if (i == series.values.length - 1) {
  350. w = lastW;
  351. } else {
  352. w = self.getX(series.values[i + 1].x, chart) - x - space;
  353. lastW = w;
  354. }
  355. x -= (w / 2);
  356. var y = self.getY(series.values[i].value, chart);
  357. var h = Math.abs(yA - y);
  358. if (parseFloat(series.values[i].value) < chart.properties.axes.x.plotAt) {
  359. y = yA;
  360. }
  361. var bar = document.createElement("v:rect");
  362. bar.style.position = "absolute";
  363. bar.style.top = y + "px";
  364. bar.style.left = x + "px";
  365. bar.style.width = w + "px";
  366. bar.style.height = h + "px";
  367. bar.setAttribute("fillColor", series.color);
  368. bar.setAttribute("stroked", "false");
  369. bar.style.antialias = "false";
  370. bar.setAttribute("title", series.label + " (" + i + "): " + series.values[i].value);
  371. var fill = document.createElement("v:fill");
  372. fill.setAttribute("opacity", "0.9");
  373. bar.appendChild(fill);
  374. chart.dataGroup.appendChild(bar);
  375. }
  376. };
  377. plotters["line"] = function (series, chart) {
  378. var tension = 1.5;
  379. var line = document.createElement("v:shape");
  380. line.setAttribute("strokeweight", "2px");
  381. line.setAttribute("strokecolor", series.color);
  382. line.setAttribute("fillcolor", "none");
  383. line.setAttribute("filled", "false");
  384. line.setAttribute("title", series.label);
  385. line.setAttribute("coordsize", chart.properties.width + "," + chart.properties.height);
  386. line.style.position = "absolute";
  387. line.style.top = "0px";
  388. line.style.left = "0px";
  389. line.style.width = chart.properties.width + "px";
  390. line.style.height = chart.properties.height + "px";
  391. var stroke = document.createElement("v:stroke");
  392. stroke.setAttribute("opacity", "0.85");
  393. line.appendChild(stroke);
  394. var path = [];
  395. for (var i = 0; i < series.values.length; i++) {
  396. var x = Math.round(self.getX(series.values[i].x, chart));
  397. var y = Math.round(self.getY(series.values[i].value, chart));
  398. if (i == 0) {
  399. path.push("m");
  400. path.push(x + "," + y);
  401. } else {
  402. var lastx = Math.round(self.getX(series.values[i - 1].x, chart));
  403. var lasty = Math.round(self.getY(series.values[i - 1].value, chart));
  404. var dx = x - lastx;
  405. var dy = y - lasty;
  406. path.push("c");
  407. var cx = Math.round((x - (tension - 1) * (dx / tension)));
  408. path.push(cx + "," + lasty);
  409. cx = Math.round((x - (dx / tension)));
  410. path.push(cx + "," + y);
  411. path.push(x + "," + y);
  412. }
  413. }
  414. line.setAttribute("path", path.join(" ") + " e");
  415. chart.dataGroup.appendChild(line);
  416. };
  417. plotters["area"] = function (series, chart) {
  418. var tension = 1.5;
  419. var line = document.createElement("v:shape");
  420. line.setAttribute("strokeweight", "1px");
  421. line.setAttribute("strokecolor", series.color);
  422. line.setAttribute("fillcolor", series.color);
  423. line.setAttribute("title", series.label);
  424. line.setAttribute("coordsize", chart.properties.width + "," + chart.properties.height);
  425. line.style.position = "absolute";
  426. line.style.top = "0px";
  427. line.style.left = "0px";
  428. line.style.width = chart.properties.width + "px";
  429. line.style.height = chart.properties.height + "px";
  430. var stroke = document.createElement("v:stroke");
  431. stroke.setAttribute("opacity", "0.8");
  432. line.appendChild(stroke);
  433. var fill = document.createElement("v:fill");
  434. fill.setAttribute("opacity", "0.4");
  435. line.appendChild(fill);
  436. var path = [];
  437. for (var i = 0; i < series.values.length; i++) {
  438. var x = Math.round(self.getX(series.values[i].x, chart));
  439. var y = Math.round(self.getY(series.values[i].value, chart));
  440. if (i == 0) {
  441. path.push("m");
  442. path.push(x + "," + y);
  443. } else {
  444. var lastx = Math.round(self.getX(series.values[i - 1].x, chart));
  445. var lasty = Math.round(self.getY(series.values[i - 1].value, chart));
  446. var dx = x - lastx;
  447. var dy = y - lasty;
  448. path.push("c");
  449. var cx = Math.round((x - (tension - 1) * (dx / tension)));
  450. path.push(cx + "," + lasty);
  451. cx = Math.round((x - (dx / tension)));
  452. path.push(cx + "," + y);
  453. path.push(x + "," + y);
  454. }
  455. }
  456. path.push("l");
  457. path.push(x + "," + self.getY(0, chart));
  458. path.push("l");
  459. path.push(self.getX(0, chart) + "," + self.getY(0, chart));
  460. line.setAttribute("path", path.join(" ") + " x e");
  461. chart.dataGroup.appendChild(line);
  462. };
  463. plotters["scatter"] = function (series, chart) {
  464. var r = 6;
  465. for (var i = 0; i < series.values.length; i++) {
  466. var x = self.getX(series.values[i].x, chart);
  467. var y = self.getY(series.values[i].value, chart);
  468. var mod = r / 2;
  469. var point = document.createElement("v:rect");
  470. point.setAttribute("fillcolor", series.color);
  471. point.setAttribute("strokecolor", series.color);
  472. point.setAttribute("title", series.label + ": " + series.values[i].value);
  473. point.style.position = "absolute";
  474. point.style.rotation = "45";
  475. point.style.top = (y - mod) + "px";
  476. point.style.left = (x - mod) + "px";
  477. point.style.width = r + "px";
  478. point.style.height = r + "px";
  479. var fill = document.createElement("v:fill");
  480. fill.setAttribute("opacity", "0.6");
  481. point.appendChild(fill);
  482. chart.dataGroup.appendChild(point);
  483. }
  484. };
  485. plotters["bubble"] = function (series, chart) {
  486. var minR = 1;
  487. var min = chart.properties.axes.x.range.min;
  488. var max = chart.properties.axes.x.range.max;
  489. var ofst = 0 - min;
  490. min += ofst;
  491. max += ofst;
  492. var xmin = chart.properties.padding.left;
  493. var xmax = chart.properties.width - chart.properties.padding.right;
  494. var factor = (max - min) / (xmax - xmin) * 25;
  495. for (var i = 0; i < series.values.length; i++) {
  496. var size = series.values[i].size;
  497. if (isNaN(parseFloat(size))) {
  498. size = minR;
  499. }
  500. var radius = (parseFloat(size) * factor) / 2;
  501. var diameter = radius * 2;
  502. var cx = self.getX(series.values[i].x, chart);
  503. var cy = self.getY(series.values[i].value, chart);
  504. var top = cy - radius;
  505. var left = cx - radius;
  506. var point = document.createElement("v:oval");
  507. point.setAttribute("fillcolor", series.color);
  508. point.setAttribute("title", series.label + ": " + series.values[i].value + " (" + size + ")");
  509. point.setAttribute("stroked", "false");
  510. point.style.position = "absolute";
  511. point.style.top = top + "px";
  512. point.style.left = left + "px";
  513. point.style.width = diameter + "px";
  514. point.style.height = diameter + "px";
  515. var fill = document.createElement("v:fill");
  516. fill.setAttribute("opacity", "0.8");
  517. point.appendChild(fill);
  518. chart.dataGroup.appendChild(point);
  519. }
  520. };
  521. }();