我有一个缩放功能,可以更改条形图y轴的最小值和最大值。条形和数据标签似乎并没有使其自身适应新的比例。如何将其设置为y轴的新比例尺?
更改Y轴比例功能:
function changeYAxisScale() {
var min = document.getElementById("min").value;
var max = document.getElementById("max").value;
y.domain([min, max]);
innerChart.select(".y.axis").transition().duration(300).call(yAxis);
innerChart.selectAll(".bar").data(jsdata)
.transition()
.duration(500)
.attr("y", function (jsdata) {
return y(jsdata.value);
})
.attr("height", function (jsdata) {
return height - y(jsdata.value);
});
innerChart.selectAll(".label").data(jsdata)
.transition()
.duration(500)
.attr("y", function (jsdata) {
return y(jsdata.value) - 20;
})
.attr("dy", ".75em")
.attr("text-anchor", "middle")
.text(function (jsdata) {
return jsdata.value;
});
innerChart.select(".y.axis").transition().duration(300).call(yAxis);
innerChart.selectAll(".bar").data(jsObjectsArray)
.transition()
.duration(500)
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
innerChart.selectAll(".label").data(jsObjectsArray)
.transition()
.duration(500)
.attr("y", (function (d) {
return y(d.value) - 20;
}))
.attr("dy", ".75em")
.attr("text-anchor", "middle")
.text(function (d) {
return d.value;
});
}
基本上,我只是重设y域,然后重绘条形图和数据标签。如何设置数据标签像条一样经过x轴后消失。并且如果条形的高度大于y刻度的最大高度,如何将其高度设置为刻度的最大高度?
<!DOCTYPE html>
<body>
<style>
.bar {
font: 10px sans-serif;
text-align: right;
padding: 3px;
margin: 1px;
color: white;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.legend rect {
fill: white;
stroke: black;
opacity: 0.8;
}
.toolTip {
position: absolute;
display: none;
min-width: 80px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
border: 1px solid #6F257F;
padding: 14px;
text-align: center;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked+.slider {
background-color: #2196F3;
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
div {
display: inline-block;
position: relative;
}
#colorize {
position: relative;
bottom: 10px;
right: 81px;
}
#scale {
top: -119px;
height: 40px;
}
#userData {
top: -3px;
}
#submitData {
position: absolute;
bottom: 10px;
right: 10px;
}
#toggle {
width: 445px;
}
</style>
<svg class="chart"></svg>
<div class="row">
<div class="col-sm-6" id="toggle">
<h3>Toggle Data Label</h3>
<label class="switch">
<input type="checkbox" onclick="togglePressed(this)" id="dataLabel" checked>
<span class="slider round"></span>
</label>
<h3>Toggle Data Legend</h3>
<label class="switch">
<input type="checkbox" onclick="togglePressed(this)" id="dataLegend" checked>
<span class="slider round"></span>
</label>
<h3>Toggle Data Legend Position</h3>
<select id="legendpos" onchange="changeLegendPosition(this)">
<option value="right" selected>Right</option>
<option value="bottom">Bottom</option>
<option value="left">Left</option>
<option value="top">Top</option>
</select>
</div>
<div class="col-sm-6" id="scale">
<h3>Change Y-axis Scale</h3>
Min :
<input type="number" id="min"> Max :
<input type="number" id="max">
<button onclick="changeYAxisScale()">Change</button>
</div>
</div>
<div class="row" id="inputData">
<div class="col-sm-12">
<h3>Enter your desired colors in hexadecimal value</h3>
<textarea rows="6" cols="60" id="colorInput"></textarea>
<button id="colorize" onclick="colorize()">Colorize</button>
<h3>Enter your data in JSON Object Array format</h3>
X:
<input type="text" id="xvalue" required> Y:
<input type="text" id="yvalue" required>
<textarea rows="6" cols="60" id="jstextarea"></textarea>
<button id="submitData" onclick="addjsObjectArray()">Submit</button>
</div>
</div>
<script src="https://d3js.org/d3.v3.js"></script>
<script src="d3legend.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var jsdata = [{
name: "Locke",
value: 4
},
{
name: "Reyes",
value: 8
},
{
name: "Ford",
value: 15
},
{
name: "Jarrah",
value: 16
},
{
name: "Shephard",
value: 23
},
{
name: "Kwon",
value: 52
}
];
var jsObjectsArray;
var colorCodes = ["#6b486b", "#a05d56", "#d0743c", "#ff8c00"];
var color = d3.scale.ordinal().range(colorCodes);
//Set the margins for the bar chart.
var margin = {
top: 130,
right: 100,
bottom: 170,
left: 130
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
//Encoding ordinal data. rangeRoundBands is used to snap each position to the exact pixel boundary for crisp edges
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var y = d3.scale.linear()
.range([height, 0]);
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
//Adding the axes
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//Declaring the chart container
var mainChart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.data(jsdata)
.attr("height", height + margin.top + margin.bottom)
var innerChart = mainChart.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(jsdata.map(function (jsdata) {
return jsdata.name;
}));
y.domain([0, d3.max(jsdata, function (jsdata) {
return jsdata.value;
})]);
innerChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll(".tick text")
.call(wrap, x.rangeBand());
innerChart.append("text") // text label for the x axis
.attr("x", width / 2)
.attr("y", height + 30)
.attr("id", "xAxistext")
.style("text-anchor", "middle")
.text(function (jsdata) {
return Object.keys(jsdata)[0];
});
innerChart.append("g")
.attr("class", "y axis")
.call(yAxis);
innerChart.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - 40)
.attr("x", 0 - (height / 2) + 3)
.attr("id", "yAxistext")
.attr("dy", ".5em")
.style("text-anchor", "middle")
.text(function (jsdata) {
return Object.keys(jsdata)[1];
});
var bars = innerChart.selectAll(".bar")
.data(jsdata) // Using the data join pattern
.enter().append("rect") //Selecting the innerChart container then append the width and height for new nodes
.style("fill", function (jsdata, i) {
return color(i);
})
.style("color", function () {
return '#FFFFFF';
})
.on("mousemove", function (jsdata) {
tooltip
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html((jsdata.name) + "<br>" + "£" + (jsdata.value));
})
.on("mouseout", function (jsdata) {
tooltip.style("display", "none");
})
.attr("class", "bar")
.attr("data-legend", function (jsdata) {
return jsdata.name
})
.attr("x", function (jsdata) {
return x(jsdata.name);
})
.attr("id", "sampledata")
.attr("y", function (jsdata) {
return y(jsdata.value);
})
.attr("height", function (jsdata) {
return height - y(jsdata.value);
})
.attr("width", x.rangeBand());
innerChart.selectAll(".text")
.data(jsdata)
.enter()
.append("text")
.attr("text-anchor", "middle")
.attr("class", "label")
.attr("x", (function (jsdata, i) {
return x(jsdata.name) + (x.rangeBand() / 2);
}))
.attr("y", function (jsdata) {
return y(jsdata.value) - 20;
})
.attr("dy", ".75em")
.text(function (jsdata) {
return jsdata.value;
})
//Converting the column from string to integer
function type(jsdata) {
jsdata.value = +jsdata.value;
return jsdata;
}
function togglePressed(identity) {
var id = identity.id;
if (id == "dataLabel") {
$(".label").toggle();
}
else if (id = "dataLegend") {
$("#dataLegend").toggle();
}
}
function colorize() {
var colorInput = document.getElementById("colorInput").value;
var newColors = JSON.parse(colorInput);
color = d3.scale.ordinal().range(newColors);
innerChart.selectAll(".bar")
.style('fill', function (jsdata, i) {
return color(i);
})
.attr("height", function (jsdata) {
return height - y(jsdata.value);
})
.attr("width", x.rangeBand())
}
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
}
function changeYAxisScale() {
var min = document.getElementById("min").value;
var max = document.getElementById("max").value;
y.domain([min, max]);
innerChart.select(".y.axis").transition().duration(300).call(yAxis);
innerChart.selectAll(".bar").data(jsdata)
.transition()
.duration(500)
.attr("y", function (jsdata) {
return (jsdata.value);
})
.attr("height", function (jsdata) {
return height - y(jsdata.value);
});
innerChart.selectAll(".label").data(jsdata)
.transition()
.duration(500)
.attr("y", function (jsdata) {
return y(jsdata.value) - 20;
})
.attr("dy", ".75em")
.attr("text-anchor", "middle")
.text(function (jsdata) {
return jsdata.value;
});
innerChart.select(".y.axis").transition().duration(300).call(yAxis);
innerChart.selectAll(".bar").data(jsObjectsArray)
.transition()
.duration(500)
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
innerChart.selectAll(".label").data(jsObjectsArray)
.transition()
.duration(500)
.attr("y", (function (d) {
return y(d.value) - 20;
}))
.attr("dy", ".75em")
.attr("text-anchor", "middle")
.text(function (d) {
return d.value;
});
}
function changeLegendPosition(position) {
var value = position.value;
if (value == "bottom") {
d3.select("#dataLegend").attr('transform', "translate(460,390)");
}
else if (value == "right") {
d3.select("#dataLegend").attr('transform', "translate(" + (margin.left + width) + ",35)")
}
else if (value == "left") {
d3.select("#dataLegend").attr('transform', "translate(15,25)")
}
else if (value == "top") {
d3.select("#dataLegend").attr('transform', "translate(460,25)")
}
}
function addjsObjectArray() {
var xname = document.getElementById("xvalue").value;
var yname = document.getElementById("yvalue").value;
if (xname && yname != null) {
var jsObjects = document.getElementById("jstextarea").value;
jsObjectsArray = eval(jsObjects);
jsObjectsArray = jsObjectsArray.map(function (d) { return { key: d[xname], value: d[yname] }; });
x.domain(jsObjectsArray.map(function (d) {
return d.key;
}));
y.domain([0, d3.max(jsObjectsArray, function (d) {
return d.value;
})]);
console.log(jsObjectsArray);
innerChart.select('.x.axis').transition().duration(300).call(xAxis);
innerChart.select(".y.axis").transition().duration(300).call(yAxis);
innerChart.data(jsObjectsArray);
innerChart.select("#xAxistext").text(function (d) {
return xname;
});
innerChart.select("#yAxistext").text(function () {
return yname;
});
innerChart.selectAll("#sampledata").remove();
innerChart.selectAll("#jsondata").remove();
innerChart.selectAll(".label").remove();
var bars = innerChart.selectAll(".bar").data(jsObjectsArray);
bars.enter().append("rect")
.attr("x", function (d) {
return x(d.key);
})
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
.attr("width", x.rangeBand())
.attr("id", "jsondata")
.attr("class", "bar")
.style("fill", function (d, i) {
return color(i);
})
.style("color", function () {
return '#FFFFFF';
})
.on("mousemove", function (d) {
tooltip
.style("left", d3.event.pageX - 50 + "px")
.style("top", d3.event.pageY - 70 + "px")
.style("display", "inline-block")
.html((d.key) + "<br>" + (d.value));
})
.on("mouseout", function (d) {
tooltip.style("display", "none");
})
.attr("data-legend", function (d) {
return d.key
});
var texts = innerChart.selectAll(".label")
.data(jsObjectsArray);
texts.enter()
.append("text")
.attr("class", "label");
texts.attr("x", (function (d) {
return x(d.key) + (x.rangeBand() / 2);
}))
.attr("y", (function (d) {
return y(d.value) - 20;
}))
.attr("dy", ".75em")
.attr("text-anchor", "middle")
.text(function (d) {
return d.value;
});
mainChart.select("#dataLegend").call(d3.legend);
}
else {
alert("Please enter your X and Y axes");
}
}
var legend = mainChart.append("g")
.attr("class", "legend")
.attr('transform', "translate(" + (margin.left + width) + ",35)")
.attr("data-legend-pos", "top")
.attr("id", "dataLegend")
.style("font-size", "15px")
.call(d3.legend);
</script>
</body>