Skip to content

Instantly share code, notes, and snippets.

@kurotanshi
Created February 16, 2017 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kurotanshi/949bc9cc6e53a2518bdedb438be0de79 to your computer and use it in GitHub Desktop.
Save kurotanshi/949bc9cc6e53a2518bdedb438be0de79 to your computer and use it in GitHub Desktop.
d3 長條圖範例
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.axis path,
.axis line {
fill: none;
stroke: #555;
}
.axis text {
fill: #555;
}
.line {
fill: none;
stroke: #ef0d0c;
stroke-width: 1.5px;
}
#content {
display: block;
width: 100%;
height: 100%;
min-width: 300px;
max-width: 1060px;
max-height: 500px;
overflow: hidden;
}
#button-container {
width: 600px;
margin: 30px auto;
padding:30px;
}
/* .active {
color: white;
background-color: black;
border-color: grey;
}*/
button {
cursor: pointer;
font-size: 16px;
display: inline;
padding: 10px;
margin: 0 20px;
color: black;
background-color: white;
border-style: solid;
border-width: 2px;
border-color: black;
}
</style>
</head>
<body>
<div id="button-container">
<button id="price">平均租金</button>
<button id="unit_price">平均每坪租金</button>
<button id="unit">平均租屋坪數</button>
<button id="reset">清除</button>
</div>
<div id="content">
<svg class="svg"></svg>
</div>
<script type="text/javascript">
var data = [
{
"region": "大安",
"unit": 46.40977922,
"price": 91086.0211,
"unit_price": 2570.210781
},
{
"region": "松山",
"unit": 32.4142328,
"price": 63651.00159,
"unit_price": 2173.609712
},
{
"region": "萬華",
"unit": 29.51372024,
"price": 69658.03571,
"unit_price": 2125.218562
},
{
"region": "士林",
"unit": 34.4416108,
"price": 73852.80682,
"unit_price": 1970.313951
},
{
"region": "信義",
"unit": 26.92638889,
"price": 48446.94739,
"unit_price": 1893.854422
},
{
"region": "中正",
"unit": 43.1695172,
"price": 85949.14021,
"unit_price": 1813.571443
},
{
"region": "南港",
"unit": 31.25626667,
"price": 50813.33333,
"unit_price": 1694.577185
},
{
"region": "中山",
"unit": 39.56244844,
"price": 63101.91847,
"unit_price": 1655.043669
},
{
"region": "文山",
"unit": 33.11200327,
"price": 47315.73129,
"unit_price": 1501.26019
},
{
"region": "大同",
"unit": 36.26450183,
"price": 48655.03391,
"unit_price": 1489.35871
},
{
"region": "內湖",
"unit": 42.60729097,
"price": 55846.34104,
"unit_price": 1427.583885
},
{
"region": "北投",
"unit": 37.96167857,
"price": 44534.22619,
"unit_price": 1293.030994
}
];
var svg = d3.select('.svg');
// 設定畫布尺寸 & 邊距
var margin = 80,
width = 960 - margin * 0.7,
height = 500 - margin * 2;
svg.attr({
"width": width + margin,
"height": height + margin * 2,
"transform": "translate(" + margin + "," + margin + ")"
});
// x 軸比例尺
var xScale_price = d3.scale.linear()
.domain([0, data.length])
.range([0, width]);
// y 軸比例尺 給繪製矩形用
var yScale_price = d3.scale.linear()
.domain([0, 100000])
.range([0, height]);
// y 軸比例尺 2 繪製座標軸用
var yScale2_price = d3.scale.linear()
.domain([0, 100000])
.range([height, 0]);
// x 軸
var xAxis = d3.svg.axis()
.scale(xScale_price)
.orient("bottom")
.ticks( data.length )
.tickFormat(function(i){
return (data[i]) ? data[i].region : ''; // 這裡控制坐標軸的單位
});
// y 軸
var yAxis = d3.svg.axis()
.scale(yScale2_price)
.orient("left");
// 繪製 x 軸
svg.append("g")
.attr({
"class": "x axis",
"transform": "translate(" + margin + "," + (height + margin) + ")",
'fill': '#ffffff'
})
.call(xAxis);
// 繪製 y 軸
svg.append("g")
.attr({
"class": "y axis",
"transform": "translate(" + margin + ", " + margin + ")",
'fill': '#ffffff'
})
.call(yAxis);
// 處理軸線位移
svg.select('.x.axis').selectAll('.tick text').attr("dx", width * 0.05);
svg.select('.x.axis').selectAll('.tick line').attr('transform', 'translate(' + width * 0.05 + ', 0)');
d3.selectAll('#button-container > button').on('click', function(){
// price, unit_price, unit
var chartType = d3.select(this).attr('id');
var xScale, yScale, yScale2, xAxis, yAxis;
var c10 = d3.scale.category10();
// 依照圖表的類別,重新定義 x, y 比例尺
if( chartType === 'price' ){
// x 軸比例尺
xScale = d3.scale.linear().domain([0, data.length]).range([0, width]);
// y 軸比例尺 給繪製矩形用
yScale = d3.scale.linear().domain([0, 100000]).range([0, height]);
// y 軸比例尺 2 繪製座標軸用
yScale2 = d3.scale.linear().domain([0, 100000]).range([height, 0]);
}
else if( chartType === 'unit_price' ){
// x 軸比例尺
xScale = d3.scale.linear().domain([0, data.length]).range([0, width]);
// y 軸比例尺 給繪製矩形用
yScale = d3.scale.linear().domain([0, 3000]).range([0, height]);
// y 軸比例尺 2 繪製座標軸用
yScale2 = d3.scale.linear().domain([0, 3000]).range([height, 0]);
}
else if( chartType === 'unit' ){
// x 軸比例尺
xScale = d3.scale.linear().domain([0, data.length]).range([0, width]);
// y 軸比例尺 給繪製矩形用
yScale = d3.scale.linear().domain([0, 60]).range([0, height]);
// y 軸比例尺 2 繪製座標軸用
yScale2 = d3.scale.linear().domain([0, 60]).range([height, 0]);
}
// 座標軸重繪
// x 軸
xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks( data.length )
.tickFormat(function(i){
return (data[i]) ? data[i].region : ''; // 這裡控制坐標軸的單位
});
// y 軸
yAxis = d3.svg.axis().scale(yScale2).orient("left");
// 更新軸線
svg.selectAll('.x.axis').transition().duration(1000).call(xAxis);
svg.selectAll('.y.axis').transition().duration(1000).call(yAxis);
// 資料排序, 透過 d3.descending 或 d3.ascending 來決定排序方式
data.sort(function(a, b){
// 降冪
// return d3.descending(a[chartType], b[chartType]);
// 升冪
return d3.ascending(a[chartType], b[chartType]);
});
// 產生長條圖
svg.selectAll('.bar')
.data(data)
.enter()
.append('rect')
.classed('bar', true);
svg.selectAll('.bar')
.transition()
.duration(700)
.attr({
'x': function(d, i) {
return xScale(i) + margin
},
'y': function(d, i) {
return height - yScale(d[chartType])+ margin;
},
'width': '5%',
'height': function(d, i) {
return yScale(d[chartType]);
},
'fill': function(d, i){
return c10(i);
},
"transform": "translate(" + width * (0.02) + ", " + 0 + ")",
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment