2015-12-14 74 views
1

我有一些代碼,其中繪製了一定的數學函數,並使用戶能夠動態更改某些特定的功能參數,使用戶能夠看到它。約束滑塊jquery + callng JavaScript函數在頁面加載調用javascript函數

我有兩個問題,我需要一些幫助。

i)我正在使用提供slider的jQuery UI庫。我使用這個滑塊來使用戶能夠在一定範圍內改變特定的參數。通常對參數沒有限制。但是,在這種情況下,我需要以下等式成立min < = mode < = max。目前我已經用滑塊的slide事件中的一些代碼解決了這個問題。代碼基本上檢查相等性,如果違反,它將參數設置爲其最小或最大可能值。

然而,從視覺上可以進一步滑動。但是,在用戶鬆開滑塊後,將調用change事件,並將參數更改爲其最小或最大可能值。是否有可能確保滑塊在視覺上不違反約束?

ii)當我加載頁面時,頁面上還沒有可見的圖。這是因爲當頁面加載時,我似乎無法調用功能redraw(),請查看底部的代碼。爲什麼redraw()不被調用?

片段,見下文或http://jsfiddle.net/qraLt1p3/11/

<!DOCTYPE html> 
 
<html lang="en"> 
 
<head> 
 
<title>MPERT</title> 
 
<meta charset="utf-8"> 
 
<script src="//d3js.org/d3.v3.min.js"></script> 
 
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> 
 
<script src="//code.jquery.com/jquery-1.10.2.js"></script> 
 
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> 
 
<style type="text/css"> 
 
svg { 
 
    font: 10px sans-serif; 
 
    shape-rendering: crispEdges; 
 
} 
 
    
 
rect { 
 
    fill: transparent; 
 
} 
 
    
 
.axis path, 
 
.axis line { 
 
    fill: none; 
 
    stroke: #000; 
 
    shape-rendering: crispEdges; 
 
} 
 
    
 
.line { 
 
    fill: none; 
 
    stroke: steelblue; 
 
    stroke-width: 1.5px; 
 
    clip-path: url(#clip); 
 
} 
 
    
 
.grid .tick { 
 
    stroke: lightgrey; 
 
    opacity: 0.7; 
 
} 
 
    
 
.grid path { 
 
    stroke-width: 0; 
 
} 
 

 
#slider-pertmin, #slider-pertmode, #slider-pertmax { 
 
\t float: right; 
 
\t width: 120px; 
 
\t margin: 7px; 
 
} 
 

 
.ui-slider-horizontal { 
 
\t height: 8px; 
 
\t width: 200px; 
 
} 
 

 
.ui-slider .ui-slider-handle { 
 
\t height: 15px; 
 
\t width: 5px; 
 
\t padding-left: 5px; 
 
} 
 

 
#plot { 
 
    background-color:#f9f9f9; 
 
\t border:solid 1px #ddd; 
 
\t padding:10px; 
 
    width:250px; 
 
} 
 
\t 
 
#plotOptions { 
 
\t background-color:#f9f9f9; 
 
\t border:solid 1px #ddd; 
 
\t padding:10px; 
 
} 
 
\t 
 
.block label { 
 
\t display: inline-block; 
 
\t width: 60px; 
 
\t text-align: right; 
 
} 
 
</style> 
 
<script type="text/javascript"> 
 
\t // Log-gamma function 
 
\t gammaln = function gammaln(x) 
 
\t { 
 
\t \t var cof = [ 76.18009172947146, -86.50532032941677,  24.01409824083091, 
 
\t \t \t \t  -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5]; 
 

 
\t \t var j = 0; 
 
\t \t var ser = 1.000000000190015; 
 
\t \t var xx, y, tmp; 
 

 
\t \t tmp = (y = xx = x) + 5.5; 
 
\t \t tmp -= (xx + 0.5) * Math.log(tmp); 
 

 
\t \t for (; j < 6; j++) 
 
\t \t \t ser += cof[j]/++y; 
 

 
\t \t return Math.log(2.5066282746310005 * ser/xx) - tmp; 
 
\t }; 
 
\t 
 
\t // Gamma function 
 
\t gammafn = function gammafn(x) 
 
\t { 
 
\t \t var p = [ -1.716185138865495, 24.76565080557592, -379.80425647094563, 
 
\t \t \t \t  629.3311553128184,  866.9662027904133, -31451.272968848367, 
 
\t \t \t  -36144.413418691176, 66456.14382024054]; 
 

 
\t \t var q = [ -30.8402300119739,  315.35062697960416, -1015.1563674902192, 
 
\t \t \t \t -3107.771671572311, 22538.118420980151, 4755.8462775278811, 
 
\t \t \t \t -134659.9598649693, -115132.2596755535]; 
 
\t 
 
\t \t var fact = false, 
 
\t \t \t n = 0, 
 
\t \t \t xden = 0, 
 
\t \t \t xnum = 0, 
 
\t \t \t y = x, 
 
\t \t \t i, 
 
\t \t \t z, 
 
\t \t \t yi, 
 
\t \t \t res, 
 
\t \t \t sum, 
 
\t \t \t ysq; 
 

 
\t \t if (y <= 0) { 
 
\t \t \t res = y % 1 + 3.6e-16; 
 
\t \t \t 
 
\t \t \t if (res) { 
 
\t \t \t \t fact = (!(y & 1) ? 1 : -1) * Math.PI/Math.sin(Math.PI * res); 
 
\t \t \t \t y = 1 - y; 
 
\t \t \t } else 
 
\t \t \t \t return Infinity; 
 
\t \t } 
 

 
\t \t yi = y; 
 

 
\t \t if (y < 1) 
 
\t \t \t z = y++; 
 
\t \t else 
 
\t \t \t z = (y -= n = (y | 0) - 1) - 1; 
 

 
\t \t for (i = 0; i < 8; ++i) { 
 
\t \t \t xnum = (xnum + p[i]) * z; 
 
\t \t \t xden = xden * z + q[i]; 
 
\t \t } 
 

 
\t \t res = xnum/xden + 1; 
 

 
\t \t if (yi < y) 
 
\t \t \t res /= yi; 
 
\t \t else if (yi > y) { 
 
\t \t \t for (i = 0; i < n; ++i) { 
 
\t \t \t \t res *= y; 
 
\t \t \t \t y++; 
 
\t \t \t } 
 
\t \t } 
 

 
\t \t if (fact) 
 
\t \t \t res = fact/res; 
 

 
\t \t return res; 
 
\t }; 
 

 
\t // Beta function 
 
\t betafn = function betafn(x,y) 
 
\t { 
 
\t \t // ensure arguments are positive 
 
\t \t if (x <= 0 || y <= 0) 
 
\t \t \t return undefined; 
 

 
\t \t // make sure x + y doesn't exceed the upper limit of usable values 
 
\t \t return (x + y > 170) 
 
\t \t \t ? Math.exp(betaln(x, y)) 
 
\t \t \t : gammafn(x) * gammafn(y)/gammafn(x + y); 
 
\t }; 
 
\t 
 
\t // Natural logarithm of Beta function 
 
\t betaln = function betaln(x, y) 
 
\t { 
 
\t \t return gammaln(x) + gammaln(y) - gammaln(x + y); 
 
\t }; 
 
\t 
 
\t $(function() { 
 
\t \t $("#slider-pertmin").slider({ 
 
\t \t \t range: "min", 
 
\t \t \t value: 1, 
 
\t \t \t min: 1, 
 
\t \t \t max: 20, 
 
\t \t \t step: 0.1, 
 
\t \t \t slide: function(event,ui) { 
 
\t \t \t \t if (ui.value > $("#slider-pertmode").slider("value")) { 
 
\t \t \t \t \t $("#pertmin").val($("#slider-pertmode").slider("value") - 0.1); 
 
\t \t \t \t \t $("#slider-pertmin").slider("value",$("#slider-pertmode").slider("value") - 0.1) 
 
\t \t \t \t } else 
 
\t \t \t \t \t $("#pertmin").val(ui.value); 
 

 
\t \t \t \t redraw(); \t 
 
\t \t \t }, 
 
\t \t \t change: function(event,ui) { 
 
\t \t \t $("#slider-pertmin").slider("value",$("#pertmin").val()); 
 
\t \t \t } 
 
\t \t }); 
 

 
\t \t $("#slider-pertmode").slider({ 
 
\t \t \t range: "min", 
 
\t \t \t value: 3, 
 
\t \t \t min: 1, 
 
\t \t \t max: 20, 
 
\t \t \t step: 0.1, 
 
\t \t \t slide: function(event,ui) { 
 
\t \t \t \t if (ui.value < $("#slider-pertmin").slider("value")) { 
 
\t \t \t \t \t $("#pertmode").val($("#slider-pertmin").slider("value") + 0.1); 
 
\t \t \t \t \t $("#slider-pertmode").slider("value",$("#slider-pertmin").slider("value") + 0.1); 
 
\t \t \t \t } else if (ui.value > $("#slider-pertmax").slider("value")) { 
 
\t \t \t \t \t $("#pertmode").val($("#slider-pertmax").slider("value") - 0.1); 
 
\t \t \t \t \t $("#slider-pertmode").slider("value",$("#slider-pertmax").slider("value") - 0.1); 
 
\t \t \t \t } else 
 
\t \t \t \t \t $("#pertmode").val(ui.value); 
 

 
\t \t \t \t redraw(); 
 
\t \t \t }, 
 
\t \t \t change: function(event,ui) { 
 
\t \t \t $("#slider-pertmode").slider("value",$("#pertmode").val()); 
 
\t \t \t } 
 
\t \t }); 
 

 
\t \t $("#slider-pertmax").slider({ 
 
\t \t \t range: "min", 
 
\t \t \t value: 6, 
 
\t \t \t min: 1, 
 
\t \t \t max: 20, 
 
\t \t \t step: 0.1, 
 
\t \t \t slide: function(event,ui) { 
 
\t \t \t \t if (ui.value < $("#slider-pertmode").slider("value")) { 
 
\t \t \t \t \t $("#pertmax").val($("#slider-pertmode").slider("value") + 0.1); 
 
\t \t \t \t \t $("#slider-pertmax").slider("value",$("#slider-pertmode").slider("value") + 0.1); 
 
\t \t \t \t } else 
 
\t \t \t \t \t $("#pertmax").val(ui.value); 
 

 
\t \t \t \t redraw(); 
 
\t \t \t }, 
 
\t \t \t change: function(event,ui) { 
 
     $("#slider-pertmax").slider("value",$("#pertmax").val()); 
 
\t \t \t } 
 
\t \t }); 
 

 
\t \t $("#pertmin").val($("#slider-pertmin").slider("value")); 
 
\t \t $("#pertmode").val($("#slider-pertmode").slider("value")); 
 
\t \t $("#pertmax").val($("#slider-pertmax").slider("value")); 
 
\t }); 
 
</script> 
 
</head> 
 
<body> 
 
<div id="plot"></div> 
 
<div id="plotOptions" class="ui-widget" style="width:250px"> 
 
\t <div class="block"> 
 
\t \t <label for="pertmin">min:</label> <input type="value" id="pertmin" style="border:none; background: transparent; width:40px;" /> 
 
\t \t <div class="ui-slider" id="slider-pertmin" /> 
 
\t </div> 
 
\t <div class="block"> 
 
\t \t <label for="pertmode">mode:</label> <input type="value" id="pertmode" style="border:none; background: transparent; width:40px;" /> 
 
\t \t <div class="ui-slider" id="slider-pertmode" /> 
 
\t </div> 
 
\t <div class="block"> 
 
\t \t <label for="pertmax">max:</label> <input type="value" id="pertmax" style="border:none; background: transparent; width:40px;" /> 
 
\t \t <div class="ui-slider" id="slider-pertmax" /> 
 
\t </div> 
 
</div> 
 
<script type="text/javascript"> 
 
\t var pert = { 
 
\t \t min: 2, 
 
\t \t mode: 4, 
 
\t \t max: 9 
 
\t }; 
 

 
\t pert.mu = (pert.min + 4*pert.mode + pert.max)/6; 
 
\t pert.a1 = 6*(pert.mu - pert.min)/(pert.max - pert.min); 
 
\t pert.a2 = 6*(pert.max - pert.mu)/(pert.max - pert.min); 
 
\t pert.beta = betafn(pert.a1,pert.a2); 
 

 
    var data = []; 
 

 
    for (var k = pert.min; k < pert.max; k += 0.1) { 
 
     data.push({ 
 
     x: k, 
 
     y: (1/pert.beta)*(Math.pow(k - pert.min,pert.a1 - 1) * 
 
\t \t     Math.pow(pert.max - k,pert.a2 - 1))/
 
\t \t \t \t \t \t Math.pow(pert.max - pert.min,pert.a1 + pert.a2 - 1) 
 
     }); 
 
    } 
 

 
\t var margin = { 
 
     top: 20, 
 
     right: 20, 
 
     bottom: 35, 
 
     left: 50 
 
    }, 
 
\t \t width = 250 - margin.left - margin.right, 
 
\t \t height = 250 - margin.top - margin.bottom; 
 

 
    var x = d3.scale.linear() 
 
     .domain([pert.min, pert.max]) 
 
     .range([0, width]); 
 

 
    var y = d3.scale.linear() 
 
     .domain([0, 1]) 
 
     .range([height, 0]); 
 

 
    var xAxis1 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var yAxis1 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var xAxis2 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("top") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .tickPadding(-20) 
 
     .outerTickSize(0) 
 
     .tickFormat(""); 
 

 
    var yAxis2 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(6) 
 
     .tickPadding(-20) 
 
     .outerTickSize(0) 
 
     .tickFormat(""); 
 

 
    var xGrid = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .tickSize(-height, -height, 0) 
 
     .tickFormat(""); 
 

 
    var yGrid = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .tickSize(-width, -width, 0) 
 
     .tickFormat(""); 
 
\t 
 
    var line = d3.svg.line() 
 
     .x(function(d) { 
 
     return x(d.x); 
 
     }) 
 
     .y(function(d) { 
 
     return y(d.y); 
 
     }) 
 
     .interpolate("linear"); 
 
\t 
 
    var zoom = d3.behavior.zoom() 
 
     .x(x) 
 
     .y(y) 
 
     .scaleExtent([1, 1]) 
 
     .on("zoom",redraw); 
 
     
 
    var svg = d3.select("#plot").append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
     .call(zoom); 
 
\t 
 
    // Add x grid 
 
    svg.append("g") 
 
     .attr("class", "x grid") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xGrid); 
 

 
    // Add y grid 
 
    svg.append("g") 
 
     .attr("class", "y grid") 
 
     .call(yGrid); 
 

 
    svg.append("g") 
 
     .attr("class", "x1 axis") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xAxis1); 
 

 
    svg.append("g") 
 
     .attr("class", "y1 axis") 
 
     .call(yAxis1); 
 

 
    /* append additional X axis */ 
 
    svg.append("g") 
 
     .attr("class", "x2 axis") 
 
     .attr("transform", "translate(" + [0, 0] + ")") 
 
     .call(xAxis2); 
 

 
    /* append additional y axis */ 
 
    svg.append("g") 
 
     .attr("class", "y2 axis") 
 
     .attr("transform", "translate(" + [width, 0] + ")") 
 
     .call(yAxis2); 
 

 
    // Add x axis label 
 
    svg.append("text") 
 
     .attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom) + ")") 
 
     .style("font-size","15") 
 
     .style("text-anchor", "middle") 
 
     .text("x axis"); 
 

 
    // Add y axis label 
 
    svg.append("text") 
 
     .attr("transform", "rotate(-90)") 
 
     .attr("y",0 - margin.left) 
 
     .attr("x",0 - (height/2)) 
 
     .attr("dy", "1em") 
 
     .style("font-size","15") 
 
     .style("text-anchor", "middle") 
 
     .text("y axis"); 
 

 
    svg.append("defs").append("clipPath") 
 
     .attr("id", "clip") 
 
     .append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 
     
 
    svg.append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    svg.append("path") 
 
     .attr("class", "line") 
 

 
    function redraw() { 
 
\t \t pert.min = $("#slider-pertmin").slider("value"); 
 
\t \t pert.mode = $("#slider-pertmode").slider("value"); 
 
\t \t pert.max = $("#slider-pertmax").slider("value"); 
 
\t \t pert.mu = (pert.min + 4*pert.mode + pert.max)/6; 
 
\t \t pert.a1 = 6*(pert.mu - pert.min)/(pert.max - pert.min); 
 
\t \t pert.a2 = 6*(pert.max - pert.mu)/(pert.max - pert.min); 
 
\t \t pert.beta = betafn(pert.a1,pert.a2); 
 
\t \t 
 
\t \t x.domain([pert.min, pert.max]); 
 
\t 
 
\t \t svg.select(".x1.axis").call(xAxis1); 
 
\t \t svg.select(".y1.axis").call(yAxis1); 
 
\t \t svg.select(".x2.axis").call(xAxis2); 
 
\t \t svg.select(".y2.axis").call(yAxis2); 
 
\t \t svg.select(".x.grid").call(xGrid); 
 
\t \t svg.select(".y.grid").call(yGrid); 
 
\t \t 
 
\t \t var data = []; 
 

 
\t \t for (var k = pert.min; k < pert.max; k += 0.1) { 
 
\t \t \t data.push({ 
 
\t \t \t \t x: k, 
 
\t \t \t \t y: (1/pert.beta)*(Math.pow(k - pert.min,pert.a1 - 1) * 
 
\t \t \t \t \t \t \t \t Math.pow(pert.max - k,pert.a2 - 1))/
 
\t \t \t \t \t \t \t \t Math.pow(pert.max - pert.min,pert.a1 + pert.a2 - 1) 
 
\t \t \t }); 
 
\t \t } 
 

 
\t \t d3.select(".line").attr("d",line(data)); 
 
    } 
 
    
 
    redraw(); 
 
</script> 
 
</body> 
 
</html>

回答

1

1)在你的用戶界面的問題,我會用一個範圍滑塊來代表我的最小/最大。然後,我會有點想象,並更新我的模式滑塊的最小/最大(和寬度),以強制它始終在最小/最大值之間。

2.)在滑塊初始化之前,您正在調用您的初始redraw。這是因爲滑塊初始化在document.ready事件中完成,而您的初始redraw不是。一個簡單的解決方法是:

$(function() { 
    redraw(); 
}); 

要對我的回答擴展了一下,這裏有我將如何實現你的第一個問題一個粗略的例子。請注意,我用d3換出了jquery滑塊,其基於此example。我總是尋找一個基於d3的答案。

<!DOCTYPE html> 
 
<html lang="en"> 
 

 
<head> 
 
    <title>MPERT</title> 
 
    <meta charset="utf-8"> 
 
    <script src="//d3js.org/d3.v3.min.js"></script> 
 
    <style type="text/css"> 
 
    svg { 
 
     font: 10px sans-serif; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    
 
    rect { 
 
     fill: transparent; 
 
    } 
 
    
 
    .axis path, 
 
    .axis line { 
 
     fill: none; 
 
     stroke: #000; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    
 
    .line { 
 
     fill: none; 
 
     stroke: steelblue; 
 
     stroke-width: 1.5px; 
 
     clip-path: url(#clip); 
 
    } 
 
    
 
    .grid .tick { 
 
     stroke: lightgrey; 
 
     opacity: 0.7; 
 
    } 
 
    
 
    .grid path { 
 
     stroke-width: 0; 
 
    } 
 
    
 
    circle { 
 
     -webkit-transition: fill-opacity 250ms linear; 
 
    } 
 
    
 
    .selecting circle { 
 
     fill-opacity: .2; 
 
    } 
 
    
 
    .selecting circle.selected { 
 
     stroke: #f00; 
 
    } 
 
    
 
    .resize path { 
 
     fill: #666; 
 
     fill-opacity: .8; 
 
     stroke: #000; 
 
     stroke-width: 1.5px; 
 
    } 
 
    
 
    .brush .extent { 
 
     fill-opacity: .125; 
 
     shape-rendering: crispEdges; 
 
    } 
 
    
 
    #plot { 
 
     background-color: #f9f9f9; 
 
     border: solid 1px #ddd; 
 
     padding: 10px; 
 
     width: 250px; 
 
    } 
 
    
 
    #plotOptions { 
 
     background-color: #f9f9f9; 
 
     border: solid 1px #ddd; 
 
     padding: 10px; 
 
    } 
 
    
 
    .block label { 
 
     display: inline-block; 
 
     width: 60px; 
 
     text-align: right; 
 
    } 
 
    </style> 
 
    <script type="text/javascript"> 
 
    // Log-gamma function 
 
    gammaln = function gammaln(x) { 
 
     var cof = [76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5]; 
 

 
     var j = 0; 
 
     var ser = 1.000000000190015; 
 
     var xx, y, tmp; 
 

 
     tmp = (y = xx = x) + 5.5; 
 
     tmp -= (xx + 0.5) * Math.log(tmp); 
 

 
     for (; j < 6; j++) 
 
     ser += cof[j]/++y; 
 

 
     return Math.log(2.5066282746310005 * ser/xx) - tmp; 
 
    }; 
 

 
    // Gamma function 
 
    gammafn = function gammafn(x) { 
 
     var p = [-1.716185138865495, 24.76565080557592, -379.80425647094563, 
 
     629.3311553128184, 866.9662027904133, -31451.272968848367, -36144.413418691176, 66456.14382024054 
 
     ]; 
 

 
     var q = [-30.8402300119739, 315.35062697960416, -1015.1563674902192, -3107.771671572311, 22538.118420980151, 4755.8462775278811, -134659.9598649693, -115132.2596755535]; 
 

 
     var fact = false, 
 
     n = 0, 
 
     xden = 0, 
 
     xnum = 0, 
 
     y = x, 
 
     i, 
 
     z, 
 
     yi, 
 
     res, 
 
     sum, 
 
     ysq; 
 

 
     if (y <= 0) { 
 
     res = y % 1 + 3.6e-16; 
 

 
     if (res) { 
 
      fact = (!(y & 1) ? 1 : -1) * Math.PI/Math.sin(Math.PI * res); 
 
      y = 1 - y; 
 
     } else 
 
      return Infinity; 
 
     } 
 

 
     yi = y; 
 

 
     if (y < 1) 
 
     z = y++; 
 
     else 
 
     z = (y -= n = (y | 0) - 1) - 1; 
 

 
     for (i = 0; i < 8; ++i) { 
 
     xnum = (xnum + p[i]) * z; 
 
     xden = xden * z + q[i]; 
 
     } 
 

 
     res = xnum/xden + 1; 
 

 
     if (yi < y) 
 
     res /= yi; 
 
     else if (yi > y) { 
 
     for (i = 0; i < n; ++i) { 
 
      res *= y; 
 
      y++; 
 
     } 
 
     } 
 

 
     if (fact) 
 
     res = fact/res; 
 

 
     return res; 
 
    }; 
 

 
    // Beta function 
 
    betafn = function betafn(x, y) { 
 
     // ensure arguments are positive 
 
     if (x <= 0 || y <= 0) 
 
     return undefined; 
 

 
     // make sure x + y doesn't exceed the upper limit of usable values 
 
     return (x + y > 170) ? Math.exp(betaln(x, y)) : gammafn(x) * gammafn(y)/gammafn(x + y); 
 
    }; 
 

 
    // Natural logarithm of Beta function 
 
    betaln = function betaln(x, y) { 
 
     return gammaln(x) + gammaln(y) - gammaln(x + y); 
 
    }; 
 
    </script> 
 
</head> 
 

 
<body> 
 
    <div id="plot"></div> 
 
    <div id="plotOptions" class="ui-widget" style="width:250px"> 
 
    </div> 
 

 
    <script> 
 

 
var margin = {top: 5, right: 20, bottom: 5, left: 20}, 
 
    width = 250 - margin.left - margin.right, 
 
    height = 50 - margin.top - margin.bottom 
 
    min = 0, max = 20; 
 

 
var brushX = d3.scale.linear() 
 
    .range([0, width]) 
 
    .domain([min, max]); 
 

 
var brush = d3.svg.brush() 
 
    .x(brushX) 
 
    .extent([0, 20]) 
 
    .on("brush", brushmove); 
 

 
var arc = d3.svg.arc() 
 
    .outerRadius(height/3) 
 
    .startAngle(0) 
 
    .endAngle(function(d, i) { return i ? -Math.PI : Math.PI; }); 
 

 
var svg = d3.select("#plotOptions").append("svg") 
 
    .attr("width", width + margin.left + margin.right) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
svg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(0," + height/2 + ")") 
 
    .call(d3.svg.axis().scale(brushX).orient("bottom")); 
 

 
var brushg = svg.append("g") 
 
    .attr("class", "brush") 
 
    .call(brush); 
 

 
brushg.selectAll(".resize").append("path") 
 
    .attr("transform", "translate(0," + height/2 + ")") 
 
    .attr("d", arc); 
 

 
brushg.selectAll("rect") 
 
    .attr("height", height); 
 

 
var mode = 10; 
 
var modeRect = svg.append("rect") 
 
    .attr("height", height) 
 
    .attr("width", 10) 
 
    .attr("y", 0) 
 
    .attr("x", brushX(mode) - 5) 
 
    .style("fill", "steelblue") 
 
    .style("opacity", 0.5); 
 
    
 
var drag = d3.behavior.drag() 
 
    .on("drag", modeDrag); 
 

 
modeRect.call(drag); 
 

 

 
function modeDrag(modeX){ 
 
    var xPos = d3.mouse(this)[0], 
 
     tmp = brushX.invert(xPos); 
 
    if (tmp > min && tmp < max){ 
 
    mode = tmp; 
 
    modeRect 
 
    .attr('x', xPos); 
 
    redraw(); 
 
    } 
 
} 
 

 
function brushmove() { 
 
    console.log(d3.event) 
 
    var extent = brush.extent(); 
 
    min = extent[0]; 
 
    max = extent[1]; 
 
    if (min >= mode){ 
 
    mode = min; 
 
    modeRect.attr('x', brushX(mode) - 5); 
 
    } else if (max <= mode){ 
 
    mode = max; 
 
    modeRect.attr('x', brushX(mode) - 5); 
 
    } 
 
    
 
    redraw(); 
 
} 
 

 
    </script> 
 

 

 
    <script type="text/javascript"> 
 
    var pert = { 
 
     min: 2, 
 
     mode: 4, 
 
     max: 9 
 
    }; 
 

 
    pert.mu = (pert.min + 4 * pert.mode + pert.max)/6; 
 
    pert.a1 = 6 * (pert.mu - pert.min)/(pert.max - pert.min); 
 
    pert.a2 = 6 * (pert.max - pert.mu)/(pert.max - pert.min); 
 
    pert.beta = betafn(pert.a1, pert.a2); 
 

 
    var data = []; 
 

 
    for (var k = pert.min; k < pert.max; k += 0.1) { 
 
     data.push({ 
 
     x: k, 
 
     y: (1/pert.beta) * (Math.pow(k - pert.min, pert.a1 - 1) * 
 
      Math.pow(pert.max - k, pert.a2 - 1))/
 
      Math.pow(pert.max - pert.min, pert.a1 + pert.a2 - 1) 
 
     }); 
 
    } 
 

 
    var margin = { 
 
     top: 20, 
 
     right: 20, 
 
     bottom: 35, 
 
     left: 50 
 
     }, 
 
     width = 250 - margin.left - margin.right, 
 
     height = 250 - margin.top - margin.bottom; 
 

 
    var x = d3.scale.linear() 
 
     .domain([pert.min, pert.max]) 
 
     .range([0, width]); 
 

 
    var y = d3.scale.linear() 
 
     .domain([0, 1]) 
 
     .range([height, 0]); 
 

 
    var xAxis1 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var yAxis1 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .outerTickSize(0) 
 
     .tickPadding(7); 
 

 
    var xAxis2 = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("top") 
 
     .ticks(5) 
 
     .innerTickSize(-6) 
 
     .tickPadding(-20) 
 
     .outerTickSize(0) 
 
     .tickFormat(""); 
 

 
    var yAxis2 = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .innerTickSize(6) 
 
     .tickPadding(-20) 
 
     .outerTickSize(0) 
 
     .tickFormat(""); 
 

 
    var xGrid = d3.svg.axis() 
 
     .scale(x) 
 
     .orient("bottom") 
 
     .tickSize(-height, -height, 0) 
 
     .tickFormat(""); 
 

 
    var yGrid = d3.svg.axis() 
 
     .scale(y) 
 
     .orient("left") 
 
     .ticks(5) 
 
     .tickSize(-width, -width, 0) 
 
     .tickFormat(""); 
 

 
    var line = d3.svg.line() 
 
     .x(function(d) { 
 
     return x(d.x); 
 
     }) 
 
     .y(function(d) { 
 
     return y(d.y); 
 
     }) 
 
     .interpolate("linear"); 
 

 
    var zoom = d3.behavior.zoom() 
 
     .x(x) 
 
     .y(y) 
 
     .scaleExtent([1, 1]) 
 
     .on("zoom", redraw); 
 

 
    var svg = d3.select("#plot").append("svg") 
 
     .attr("width", width + margin.left + margin.right) 
 
     .attr("height", height + margin.top + margin.bottom) 
 
     .append("g") 
 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
 
     .call(zoom); 
 

 
    // Add x grid 
 
    svg.append("g") 
 
     .attr("class", "x grid") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xGrid); 
 

 
    // Add y grid 
 
    svg.append("g") 
 
     .attr("class", "y grid") 
 
     .call(yGrid); 
 

 
    svg.append("g") 
 
     .attr("class", "x1 axis") 
 
     .attr("transform", "translate(0," + height + ")") 
 
     .call(xAxis1); 
 

 
    svg.append("g") 
 
     .attr("class", "y1 axis") 
 
     .call(yAxis1); 
 

 
    /* append additional X axis */ 
 
    svg.append("g") 
 
     .attr("class", "x2 axis") 
 
     .attr("transform", "translate(" + [0, 0] + ")") 
 
     .call(xAxis2); 
 

 
    /* append additional y axis */ 
 
    svg.append("g") 
 
     .attr("class", "y2 axis") 
 
     .attr("transform", "translate(" + [width, 0] + ")") 
 
     .call(yAxis2); 
 

 
    // Add x axis label 
 
    svg.append("text") 
 
     .attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom) + ")") 
 
     .style("font-size", "15") 
 
     .style("text-anchor", "middle") 
 
     .text("x axis"); 
 

 
    // Add y axis label 
 
    svg.append("text") 
 
     .attr("transform", "rotate(-90)") 
 
     .attr("y", 0 - margin.left) 
 
     .attr("x", 0 - (height/2)) 
 
     .attr("dy", "1em") 
 
     .style("font-size", "15") 
 
     .style("text-anchor", "middle") 
 
     .text("y axis"); 
 

 
    svg.append("defs").append("clipPath") 
 
     .attr("id", "clip") 
 
     .append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    svg.append("rect") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    svg.append("path") 
 
     .attr("class", "line") 
 

 
    function redraw() { 
 
     pert.min = min - 0.001; 
 
     pert.mode = mode; 
 
     pert.max = max + 0.001; 
 
     pert.mu = (pert.min + 4 * pert.mode + pert.max)/6; 
 
     pert.a1 = 6 * (pert.mu - pert.min)/(pert.max - pert.min); 
 
     pert.a2 = 6 * (pert.max - pert.mu)/(pert.max - pert.min); 
 
     pert.beta = betafn(pert.a1, pert.a2); 
 

 
     x.domain([pert.min, pert.max]); 
 

 
     svg.select(".x1.axis").call(xAxis1); 
 
     svg.select(".y1.axis").call(yAxis1); 
 
     svg.select(".x2.axis").call(xAxis2); 
 
     svg.select(".y2.axis").call(yAxis2); 
 
     svg.select(".x.grid").call(xGrid); 
 
     svg.select(".y.grid").call(yGrid); 
 

 
     var data = []; 
 

 
     for (var k = pert.min; k < pert.max; k += 0.1) { 
 
     data.push({ 
 
      x: k, 
 
      y: (1/pert.beta) * (Math.pow(k - pert.min, pert.a1 - 1) * 
 
       Math.pow(pert.max - k, pert.a2 - 1))/
 
      Math.pow(pert.max - pert.min, pert.a1 + pert.a2 - 1) 
 
     }); 
 
     } 
 

 
     d3.select(".line").attr("d", line(data)); 
 
    } 
 

 
    redraw(); 
 
    </script> 
 
</body> 
 

 
</html>

+0

謝謝你的解釋,你的例子。你創建的代碼確實是我正在尋找的。然而,我並不是那種對d3有經驗的人,並且想要一致的佈局。出於這個原因,我將嘗試編輯jQuery滑塊,使其能夠使用三個參數(最小值,最大值和最大值)來設置範圍。 –

相關問題