【发布时间】:2017-01-29 22:38:50
【问题描述】:
我正在制作一个图表,其中整个 svg 对象和刻度值都应该在给定的高度范围内。我想知道为什么我的旋转刻度值没有完全显示。高度是 100px,我希望我的图表和刻度值在 100 以内。我试过了
.attr("transform", "scale(1,1.4)")
功能但没用。这是到目前为止的代码!
数据是这个,渲染图表的代码在下面。
{
"Height" : 100,
"Width" : 250,
"margins" : {
"top": 10,
"left": 20,
"right": 10,
"bottom": 20
},
"data":[
{
"fruit" : "apple",
"initialsale" : 40,
"totalsale": 600
},
{
"fruit" : "orange",
"initialsale" : 40,
"totalsale": 60
},
{
"fruit" : "mango",
"initialsale" : 1420,
"totalsale": 6000
}
]
}
function stackChart(){
data = {
"Height" : 100,
"Width" : 250,
"margins" : {
"top": 10,
"left": 20,
"right": 10,
"bottom": 20
},
"data":[
{
"fruit" : "apple",
"initialsale" : 40,
"totalsale": 600
},
{
"fruit" : "orange",
"initialsale" : 40,
"totalsale": 60
},
{
"fruit" : "mango",
"initialsale" : 1420,
"totalsale": 6000
}
]
};
var margin = data.margins;
var top = margin.top,
bottom = margin.bottom,
left = margin.left,
right = margin.right,
Width = data.Width,
Height = data.Height,
data = data.data;
var width = Width -left -right,
height = Height -top - bottom;
var svg = d3.select("#stackChart")
.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 + ")");
// Divider functionality
var div = 0;
if(Width>50&&Width<=100){
div = 1.2
}
else if(Width>100&&Width<=200)
{
div = 1.5
}
else if(Width>200&&Width<=300){
div = 2.0
}
else if(Width>300&&Width<=400){
div = 2.2
}
else if(Width>400&&Width<=500){
div = 2.4
}
else if(Width>500&&Width<=600){
div = 2.6
}
else if(Width>600&&Width<=800){
div = 2.8
}
else if(Width>800){
div = 3.0
}
var par = Width/div;
// var scale_parameter = Width/par;
var dataset = [];
var arr1 = [];
var arr2 = [];
data.forEach(function(d) {
var currentObj = {}
currentObj["os"] = d.os;
currentObj["value"] = d.total;
currentObj["percent"] = (d.initial/d.total)*100;
arr1.push(currentObj);
currentObj = {}
currentObj["os"] = d.os;
currentObj["value"] = d.total;
currentObj["percent"] = ((d.total - d.initial)/d.total)*100;
arr2.push(currentObj);
}
);
dataset = [{
data: arr1,
name: 'initial'
},{
data: arr2,
name: 'remaining'
}];
var series = dataset.map(function (d) {
return d.name;
}),
dataset = dataset.map(function (d) {
return d.data.map(function (o, i) {
// Structure it so that your numeric
// axis (the stacked amount) is y
return {
y: o.percent,
x: o.os,
v: o.value
};
});
}),
stack = d3.layout.stack(); //.layout in v3
stack(dataset);
var h1= Width * 0.7;
// Set x, y and colors
var x = d3.scale.ordinal()
.domain(dataset[0].map(function(d) { return d.x; }))
.rangeRoundBands([0, width], 0.15);
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) { return d3.max(d, function(d) { return d.y0+d.y; }); })])
.range([height, 0]);
var colors = ["#14a900", "#cccccc"];
// Define and draw axes
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5)
.tickSize(1)
.tickFormat( function(d) { return d } )
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
// Create groups for each series, rects for each segment
var groups = svg.selectAll("g.cost")
.data(dataset)
.enter().append("g")
.attr("class", "cost")
.style("fill", function(d, i) { return colors[i]; });
// Height Calculation of the stack bars
// y0 will be the base, y is the stacked up bar on y0
var crucial = 0;
var cr = 0;
var heightsof = [];
var rects = groups.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
// .attr("transform","scale(1,1.4)")
.attr("x", function(d) { return x(d.x); })
.attr("y", function(d) {
crucial = y(d.y0 + d.y);
return crucial;
})
.attr("height", function(d) {
return height - y(d.y);
})
.attr("width", x.rangeBand())
// Getting the length of the total bar
// For tilt angle
var calh=0;
for(i=0;i<data.length+1;i++){
var j = data.length;
if(i==j){
calh = heightsof[j]+heightsof[0];
}
}
console.log(calh);
var rect_width = Math.round($("rect").outerWidth());
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
// .attr("transform","scale(1,)")
var bool = [],
counter = 0,
y = [],
x = 0,
z = 0; // max value of y[]
svg.append("g")
.attr("class", "x axis")
.attr("transform", function(){
return "translate(0,"+(h1)+")";
})
.call(xAxis)
.selectAll("text")
.style("fill","black")
.each(function(d,i) {
var thisWidth = this.getComputedTextLength();
var x = Math.round(thisWidth);
y.push(x);
if(rect_width>x){
bool.push(true);
}
else{
bool.push(false);
counter++;
}
z = Math.max.apply(Math, y);
})
.style("text-anchor",function(d,i){
if(rect_width<=20){
return "end";
}
else {
return "middle";
}
})
.attr("transform", function(d,i) { // Rotation Code
if(rect_width<=20) {
x = -90;
return "translate(-13,8) rotate("+x+")"; // Minimum width rotation
}
else if (rect_width>z) {
return "rotate(0)";
}
else if(rect_width>20&&rect_width<z) {
var tilt = data.length;
var angle = Math.cos(z/rect_width)
console.log(angle);
if(angle>0&&bool[i]==false){
return "translate(-10,"+((y[i]/3)+12)+") rotate(-45)";// -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment
}
if(angle>0&&bool[i]==true){
return "translate(-10,"+((y[i]/3)+8)+") rotate(-45)"//"+ -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment
}
else{
return "translate(-10,"+((y[i]/3)+12)+") rotate("+ -(90+angle*10) +")"; // Rotating based on the maximum angle for proper alignment
}
}
});
}
<div id="stackChart">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script>
stackChart();
</script>
【问题讨论】:
-
嗨,我尽可能多地编辑帖子。 @AndreiGheorghiu
-
@AndreiGheorghiu 这是图表的小提琴jsfiddle.net/okdfhhvp/2
-
@GerardoFurtado 请取消删除您的答案。它比我的好。 Sai,如果你不能把你的图例放在 100px 的高度,只需使用这个 CSS:
transform:scale(factor)就可以了,其中 factor 应该小于1以便缩小。如果您只想缩放高度,请使用scaleY而不是scale。此外,Gerardo 关于没有两个不同的 svg 而是将所有内容都放在同一个svg中的评论是有道理的,除非您希望图例具有响应性。 -
@GerardoFurtado 嗨,我已将 y 轴和堆栈条按比例缩小到 1 以下,但我正面临失真问题。我猜唯一的解决方法是增加data.height。如果我错了,请纠正我。
标签: javascript html css d3.js