我有一些代碼,其中繪製了一定的數學函數,並使用戶能夠動態更改某些特定的功能參數,使用戶能夠看到它。約束滑塊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>
謝謝你的解釋,你的例子。你創建的代碼確實是我正在尋找的。然而,我並不是那種對d3有經驗的人,並且想要一致的佈局。出於這個原因,我將嘗試編輯jQuery滑塊,使其能夠使用三個參數(最小值,最大值和最大值)來設置範圍。 –