Created
January 2, 2014 04:48
-
-
Save e7h4n/8215173 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * DistributionChart.js, Jul 11, 2013 | |
| * | |
| * Copyright 2013 fenbi.com. All rights reserved. | |
| * FENBI.COM PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. | |
| */ | |
| /** | |
| * @author zhangyc <zhangyc@fenbi.com> | |
| */ | |
| /*jshint maxparams: 5*/ | |
| 'use strict'; | |
| var raphael = require('../lib/raphael'); | |
| var $ = require('../lib/jquery'); | |
| var DistributionChart = { | |
| axisFix: { | |
| left: 60, | |
| bottom: 20, | |
| right: 10, | |
| top: 10 | |
| }, | |
| axisWidth: 4, | |
| axisHeight: 6, | |
| paper: null, | |
| $scoreTip: null, | |
| draw: function (el, mu, sigma, fullMark, score) { | |
| mu = parseFloat(mu); | |
| sigma = parseFloat(sigma); | |
| var paper = DistributionChart.paper || raphael(el); | |
| paper.clear(); | |
| DistributionChart.paper = paper; | |
| DistributionChart.drawAxis(fullMark); | |
| var dottes = [{ | |
| x: 0, | |
| y: 0 | |
| }]; | |
| var yList = []; | |
| var total = 0; | |
| for (var x = 1; x < fullMark; x += 1) { | |
| var y = DistributionChart.normDist(fullMark - x, mu, sigma); | |
| var pos = { | |
| x: x / fullMark, | |
| y: y | |
| }; | |
| total += y; | |
| dottes.push(pos); | |
| yList.push(pos.y); | |
| } | |
| dottes.push({ | |
| x: 1, | |
| y: 0 | |
| }); | |
| var width = paper.width - DistributionChart.axisFix.left - DistributionChart.axisFix.right; | |
| var height = paper.height - DistributionChart.axisFix.top - DistributionChart.axisFix.bottom; | |
| var yMax = Math.max.apply(Math, yList) * width; | |
| var yFix = width * 0.7 / yMax; | |
| if (!isFinite(yFix)) { | |
| yFix = 1; | |
| } | |
| if (score && score > 0) { | |
| var $container = $(el).parent(); | |
| var $el = $(el); | |
| var posFix = { | |
| left: $el.offset().left - $container.offset().left, | |
| top: $el.offset().top - $container.offset().top | |
| }; | |
| var userScorePosition = { | |
| left: posFix.left + width * yFix * DistributionChart.normDist(score, mu, sigma) + DistributionChart.axisFix.left, | |
| top: posFix.top + (fullMark - score) / fullMark * height + DistributionChart.axisFix.top | |
| }; | |
| if(!DistributionChart.$scoreTip) { | |
| DistributionChart.$scoreTip = $('<div class="distribution-score-tip"></div>').appendTo($container); | |
| } | |
| DistributionChart.$scoreTip.css(userScorePosition).text(score + ' 分'); | |
| } | |
| var path = dottes.reduce(function (memo, dot) { | |
| memo.push([ | |
| memo.length === 0 ? 'M' : 'L', | |
| yFix * dot.y * width + DistributionChart.axisFix.left, | |
| dot.x * height + DistributionChart.axisFix.top | |
| ]); | |
| return memo; | |
| }, []); | |
| path.push('Z'); | |
| paper.path(path).attr({ | |
| fill: '270.0-#FF947D-#D83C48', | |
| stroke: 'none' | |
| }).glow({ | |
| offsetx: 1, | |
| offsety: 1, | |
| width: 4, | |
| color: '#CCC' | |
| }); | |
| }, | |
| normDist: function (x, mu, sigma) { | |
| if (mu === 0 || sigma === 0) { | |
| return 0; | |
| } | |
| return 1 / (sigma * Math.sqrt(2 * Math.PI)) * Math.exp(-(x - mu) * (x - mu) / (2 * sigma * sigma)); | |
| }, | |
| drawAxis: function (fullMark) { | |
| var paper = DistributionChart.paper; | |
| if (paper === null) { | |
| return; | |
| } | |
| var paths = [ | |
| ['M', DistributionChart.axisFix.left, DistributionChart.axisFix.top] | |
| ]; | |
| /* | |
| * Render axes | |
| * x1 x0 DistributionChart.axisFix.left | |
| * ^ ^ ^ | |
| * | | | | |
| * | | | - start point | |
| * | | | / | |
| * ^ ^ ^ / | |
| * y0 <--------> -----<-----<------ <-------> DistributionChart.axisFix.top | |
| * / | | |
| * / | | |
| * | ___ | | |
| * | | | |
| * \ ___ | | |
| * \ U | | |
| * y1 <--------> --->----| | | |
| * | | | |
| * | | | |
| * . . | |
| * . . | |
| * . . - finish point, 'Z' | | |
| * | | / / | |
| * | |/ / | |
| * ----<---| -----<-----...-------------<------| <---------> paper.height - DistributionChart.axisFix.bottom | |
| * / | | |
| * / | | |
| * | | | |
| * | ^ | |
| * \ | | |
| * \ | | |
| * ---->---| |--->----...---------| | <---------> y0 | |
| * | | | | | |
| * | | | | <---------> y1 | |
| * \ / \ / | |
| * \ / \ / | |
| * -->----- --->---- | |
| * ^ ^ ^ | |
| * | | | | |
| * | | | | |
| * | | | | |
| * | | | | |
| * ^ ^ ^ | |
| * x0 x1 paper.width - DistributionChart.axisFix.right | |
| * | |
| */ | |
| var width = paper.width - DistributionChart.axisFix.left - DistributionChart.axisFix.right; | |
| var height = paper.height - DistributionChart.axisFix.top - DistributionChart.axisFix.bottom; | |
| (function () { | |
| var yStops = Math.min(fullMark / 10, 10); | |
| for (var i = 0; i <= yStops; i++) { | |
| var x0 = DistributionChart.axisFix.left - DistributionChart.axisWidth; | |
| var x1 = x0 - DistributionChart.axisHeight; | |
| var y0 = DistributionChart.axisFix.top + i / yStops * height; | |
| var y1 = y0 + DistributionChart.axisWidth; | |
| paper.text(DistributionChart.axisFix.left / 2, (y0 + y1) / 2, fullMark * (yStops - i) / yStops).attr({ | |
| fill: '#3A8FFB', | |
| 'font-size': 14, | |
| 'font-family': 'Arial, Helvetica, sans-serif', | |
| 'text-anchor': 'middle' | |
| }); | |
| paths = paths.concat([ | |
| ['L', x0, y0], | |
| ['L', x1, y0], | |
| ['A', 2, 2, 0, 1, 0, x1, y1], | |
| ['L', x0, y1] | |
| ]); | |
| } | |
| })(); | |
| (function () { | |
| var xStops = 10; | |
| for (var i = 0; i <= xStops; i++) { | |
| var x0 = DistributionChart.axisFix.left - DistributionChart.axisWidth + width * (i / xStops); | |
| var x1 = x0 + DistributionChart.axisWidth; | |
| var y0 = DistributionChart.axisFix.top + height + DistributionChart.axisWidth; | |
| var y1 = y0 + DistributionChart.axisHeight; | |
| var path = [ | |
| ['L', x0, y1], | |
| ['A', 2, 2, 0, 1, 0, x1, y1], | |
| ['L', x1, y0] | |
| ]; | |
| if (i !== 0) { | |
| path.unshift(['L', x0, y0]); | |
| } | |
| paths = paths.concat(path); | |
| } | |
| })(); | |
| paths = paths.concat([ | |
| ['L', paper.width - DistributionChart.axisFix.right, DistributionChart.axisFix.top + height], | |
| ['L', DistributionChart.axisFix.left, DistributionChart.axisFix.top + height], | |
| 'Z' | |
| ]); | |
| var axisPaths = paper.path(paths); | |
| axisPaths.attr({ | |
| fill: '#FFF', | |
| stroke: 'none' | |
| }); | |
| if (!$.browser.msie || $.browser.version !== '7.0') { | |
| axisPaths.glow({ | |
| offsetx: -1, | |
| offsety: 1, | |
| width: 1, | |
| color: '#BBB' | |
| }); | |
| axisPaths.glow({ | |
| offsetx: 1, | |
| offsety: -1, | |
| width: 3, | |
| opacity: 0.3, | |
| color: '#CCC' | |
| }); | |
| } | |
| } | |
| }; | |
| module.exports = DistributionChart; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment