【发布时间】:2018-09-13 16:26:16
【问题描述】:
我已经逐步创建了一个 D3 图表。我进行了一些更改以使 SVG 具有响应性。我现在的目标是使条形图更具响应性,以便在屏幕尺寸较小(宽度)时更易于阅读。我在页面底部和下方粘贴了 sn-p,我将重点放在我认为解决方案被隐藏的部分。
var data = [
{"area": "one ", "value": 18000},
{"area": "Two ", "value": 17000},
{"area": "three ", "value": 80000},
{"area": "four ", "value": 55000},
{"area": "five ", "value": 100000},
{"area": "six", "value": 50000},
{"area": "seven", "value": 50000}
];
var margin = {top: 10, right: 10, bottom: 70, left: 30};
var width = 1900 - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
//A fully-responsive chart area
var svg = d3.select("#chart-div")
.append("svg")
.attr("width","100%")
.attr("height","500px")
.attr("viewBox","0 0 "+
(width+margin.left+margin.right)+
" "+
(height+margin.top+margin.bottom) )
.append("g")
.attr("transform","translate("+
margin.left+","+margin.top+")");
var tooltip = d3.select("body").append("div").attr("class", "toolTip");
var x = d3.scaleLinear().range([0, width]);
var y = d3.scaleBand().range([height, 0]);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
data.sort(function(a, b) { return a.value - b.value; });
x.domain([0, d3.max(data, function(d) { return d.value; })]);
y.domain(data.map(function(d) { return d.area; })).padding(0.1);
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(5).tickFormat(function(d) { return parseInt(d / 1000); }).tickSizeInner([-height]));
g.append("g")
.attr("class", "y axis")
.call(d3.axisLeft(y));
g.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", 0)
.attr("height", y.bandwidth())
.attr("y", function(d) { return y(d.area); })
.attr("width", function(d) { return x(d.value); })
.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.area) + "<br>" + "£" + (d.value));
})
.on("mouseout", function(d){ tooltip.style("display", "none");});
@import url('https://fonts.googleapis.com/css?family=Roboto');
body {
margin: 15px;
background-color: #F1F3F3;
font-family: 'Roboto'!important;
}
.bar {
fill: #6F257F;
}
.axis path,
.axis line {
fill: none;
stroke: #D4D8DA;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.x path {
display: none;
}
.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;
}
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%; /* aspect ratio */
vertical-align: top;
overflow: hidden;
}
.svg-content-responsive {
display: inline-block;
position: absolute;
top: 10px;
left: 0;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="chart-div" style="width:100%;height:100%;"></div>
我用以下代码更改了部分代码:
var parentwidth = $("#chart-div").parent().width();
var margin = {top: 10, right: 10, bottom: 70, left: 30};
var width = parentwidth - margin.left - margin.right;
var height = 400 - margin.top - margin.bottom;
我实际上是使用 jQuery 获得 parentwidth 的地方。
我实际上在考虑是否:
a) 在这种情况下可以避免使用 jQuery。
b) 理想情况下,让条形图以不同的方式缩放,以便用户轻松阅读所有内容(小文本大小是个问题):
我正在测试下面的函数,但我可能会遇到与某些 chrome 插件相关的错误,以避免跨域错误。如果以下是最佳解决方案,我可以更新问题:
function resize() {
var width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;
// Update the range of the scale with new width/height
xScale.range([0, width]);
yScale.rangeRoundBands([height, 0], 0.1);
// Update the axis and text with the new scale
svg.select(".x.axis")
.call(xAxis)
.attr("transform", "translate(0," + height + ")")
.select(".label")
.attr("transform", "translate(" + width / 2 + "," + margin.bottom / 1.5 + ")");
svg.select(".y.axis")
.call(yAxis);
// Update the tick marks
xAxis.ticks(Math.max(width/75, 2), " $");
// Force D3 to recalculate and update the line
svg.selectAll(".bar")
.attr("width", function(d) { return xScale(d["total"]); })
.attr("y", function(d) { return yScale(d["Name"]); })
.attr("height", yScale.rangeBand());
};
【问题讨论】:
标签: javascript jquery html css d3.js