Skip to content

Instantly share code, notes, and snippets.

@hendrix0623
Last active May 30, 2016 07:01
Show Gist options
  • Save hendrix0623/adc42ef893d45087fde25e7e1467c5d5 to your computer and use it in GitHub Desktop.
Save hendrix0623/adc42ef893d45087fde25e7e1467c5d5 to your computer and use it in GitHub Desktop.
Five-star hotels annual income in Taipei
hotel y0000 y2008 y2009 y2010 y2011 y2012 y2013 y2014 y2015 lon lat add
台北寒舍喜來登大飯店 0 2284739672 2116462177 2392306175 2559432961 2704907749 2813719414 2868330396 2723573005 121.52205400000003 25.0449723 台北市中正區忠孝東路一段12號
台北君悅酒店 0 2686187539 2258704906 2478414432 2446115843 2058505486 1917871225 2502528914 2649780550 121.56259279999995 25.0356905 台北市信義區松壽路2號
晶華酒店 0 2469997148 2501191897 2749108910 2885932223 3045064298 3153359626 3330169655 3297877523 121.52423999999996 25.0541874 台北市中山區中山北路二段39巷3號
西華大飯店 0 889136584 795485760 890625245 870533116 921801542 956268431 975487956 1004454392 121.54568459999996 25.0580736 台北市松山區民生東路三段111號
遠東國際大飯店 0 1717314916 1480692732 1740848689 1712157902 1696460224 1597077254 1426337763 1511309596 121.54900299999997 25.0268885 台北市大安區敦化南路二段201號
台北威斯汀六福皇宮 0 1211457358 1045101996 1272318204 1262801729 1200895020 1292908897 1262353327 1447396354 121.54132860000004 25.0523025 台北市中山區南京東路三段133號
台北寒舍艾美酒店 0 0 0 117587001 1201134020 1909784079 2115670871 1403243740 1379643183 121.56815000000006 25.038533 台北市信義區松仁路38號
台北君品大酒店 0 0 0 283757879 1122791557 1257160199 1376642913 2188524990 2156537727 121.5168741 25.0494693 台北市大同區承德路一段3號
台北W飯店 0 0 0 0 643906434 838849419 993208287 1086375186 1095885507 121.56586560000005 25.0406673 台北市信義區忠孝東路五段10號
寒舍艾麗酒店 0 0 0 0 0 0 41345480 637465480 812983744 121.56748570000002 25.0389721 台北市信義區松高路18號
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.axis path,
.axis line {
fill: none;
stroke: grey;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
tick {
font-family: Agency FB Solid;
font: 10px;
fill: Steel
}
.tpecityarea {
stroke: black;
fill: #ddc;
stroke: white;
stroke-width: 1px;
text-shadow:2px 2px 3px #c0cfbc;
}
div.tooltip {
position: absolute;
text-align: center;
width: 160px;
padding: 2px;
font-family: "Agency FB" Solid;
font: 16px "Agency FB" Solid;
background: white;
border: 1px;
border-radius: 5px;
pointer-events: none;
font: 12px Agency FB Solid;
}
div.years_buttons div {
background-color: #ddc;
font-family: Microsoft JhengHei;
padding: 3px;
text-align: center;
width: 90px;
margin: 1px;
float: left;
font-size: .8em;
}
form {
position: absolute;
right: 10px;
top: 0px;
}
.title.text {
font-family: Agency FB Solid;
font: 16px Agency FB Solid;
fill: black;
}
text {
font-family: Agency FB Solid;
font: 9px;
fill: #074e67;
text-shadow:2px 2px 3px #c0cfbc;
}
text.area-label
{
font-family: Agency FB Solid;
font: 10px;
fill: black;
text-shadow:2px 2px 3px #69675b;
}
text.bar-label
{
font-family: Calibri;
font: 22px;
fill: white;
text-shadow:2px 2px 3px #69675b;
}
header {
background-color:#83B8DC;
color:white;
text-align:left;
padding:5px;
font-size: 20px;
}
.header img {
float: left;
width: 100px;
height: 50px;
background: #83B8DC;
}
section {
width:1000px;
float:left;
padding:10px;
}
footer {
background-color:#83B8DC;
color:white;
clear:both;
text-align:center;
padding:5px;
}
</style>
<body>
<head>
<title>Hotels Revenue</title>
<link rel="stylesheet" href="style.css">
</head>
<section>
<div class="radio">
<input id="check2008" type="radio" name="income_years" value="2008"><label for="check2008">2008</label>
<input id="check2009" type="radio" name="income_years" value="2009"><label for="check2009">2009</label>
<input id="check2010" type="radio" name="income_years" value="2010"><label for="check2010">2010</label>
<input id="check2011" type="radio" name="income_years" value="2011"><label for="check2011">2011</label>
<input id="check2012" type="radio" name="income_years" value="2012"><label for="check2012">2012</label>
<input id="check2013" type="radio" name="income_years" value="2013"><label for="check2013">2013</label>
<input id="check2014" type="radio" name="income_years" value="2014"><label for="check2014">2014</label>
<input id="check2015" type="radio" name="income_years" value="2015"><label for="check2015">2015</label>
</div >
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-geo-projection/0.2.16/d3.geo.projection.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.20/topojson.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.7/d3-tip.js"></script>
<script>
var margin = {top: 40, right: 10, bottom: 40, left: 10},
width = 1140 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var color_table =
{"遠東國際大飯店" : "rgb(31 , 119, 180)",
"台北君品大酒店" : "rgb(174, 199, 232)",
"台北君悅酒店" : "rgb(255, 127, 14 )",
"台北威斯汀六福皇宮" : "rgb(255, 187, 120)",
"台北寒舍喜來登大飯店" : "rgb(44 , 160, 44 )",
"台北寒舍艾美酒店" : "rgb(152, 223, 138)",
"寒舍艾麗酒店" : "rgb(214, 39 , 40 )",
"晶華酒店" : "rgb(255, 152, 150)",
"西華大飯店" : "rgb(148, 103, 189)",
"台北W飯店" : "rgb(197, 176, 213)"}
/*地圖tooltip*/
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
/*projection類型*/
var projection_tpe_area = d3.geo.mercator().center([121.620,25.04]).scale(210000);
/*宣告畫地理圖的方法,並把投影方式帶入*/
var path = d3.geo.path().projection(projection_tpe_area);
/*千位數符號轉換*/
var commaFormat = d3.format(',');
/*畫布*/
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var x = d3.scale.ordinal()
.rangeRoundBands([1100, 500], .2);
var y = d3.scale.linear()
.range([350, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.ticks(20)
.orient("right")
;
//劃格線用Y
var axisYGrid = d3.svg.axis()
.scale(y)
.orient("right")
.ticks(10)
.tickFormat("")
.tickSize(500,0);
//劃格線Y
svg.append('g')
.call(axisYGrid)
.attr("transform", "translate(" + 390 + " ,100)")
.style("stroke", "rgba(0,0,0,.1)")
.style("fill","none");
/*準備畫區界的資料*/
d3.json("tpe_area.json", function(error, topology) {
if (error) throw error;
/*topojson解析資料*/
var features_area= topojson.feature(topology, topology.objects["tpe_area_test"]).features;
/*畫台北市區界*/
var tpe_area=svg.selectAll("path-area")
.data(features_area)
.enter().append("path")
.attr("d", path)
.attr("class", "tpecityarea");
/*區界文字標籤*/
svg.selectAll("path-area").data(features_area).enter()
.append("text")
.attr("class", "area-label")
.attr("transform", function(d) { return "translate(" +path.centroid(d)+ ")"; })
.attr("dy", ".35em")
.attr("text-anchor","middle")
.attr("font-size","9pt")
.text(function(d){
return d.properties.PTNAME.substring(3, 8);;
});
/*準備畫旅館總營收資料*/
d3.csv("hotel_income.csv", function(error, data) {
if (error) throw error;
/*bar chart的X、Y坐標軸設定*/
x.domain(data.map(function(d) { return d.hotel; }));
y.domain([0, d3.max(data, function(d) { return +d["y2014"]/1000000; })]);
/*以hotel為key,整理csv資料成object型態*/
var hotel_dataset = d3.nest().key(function(d){return d.hotel;}).map(data)
/*畫X軸、並設定偏移至svg右下*/
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(-120," + 380 + ")")
.style("font-size", "8px")
.call(xAxis)
.selectAll("text")
.attr("transform", "rotate(15)" )
;
/*畫Y軸、並設定偏移至svg右下*/
svg.append("g")
.attr("class", "y axis")
.style("font-size", "6px")
.attr("transform", "translate(" + 970 + " ,20)")
.call(yAxis)
.append("text")
.attr("y", 6)
.attr("dy", "2.71em")
.style("text-anchor", "end")
.text("百萬元");
/*畫bar chart,綁group與餵資料*/
var draw_bar = svg.append("g").attr("class", "bar").selectAll("bar").data(data);
var draw_bar_label = svg.append("g").attr("class", "bar.label").selectAll("text").data(data);
/*畫bar chart */
draw_bar
.enter()
.append("rect")
.attr("class", ".bar")
.attr("transform", "translate(" + -120 + " ,15)")
.attr("x", function(d) { return x(d.hotel); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(+d["y2008"]/1000000); })
.attr("height", function(d) { return 350- y(+d["y2008"]/1000000); })
//若為"遠東國際大飯店",標成紅色
//.attr("fill", function(d,i) { return d.hotel=="遠東國際大飯店" ? "red":"steelblue" } )
.attr("fill", function(d,i) { return color_table[d.hotel] } )
.attr('fill-opacity', 1);
/*畫bar的數字標籤*/
draw_bar_label
.enter()
.append("text")
.attr("class", "bar-label")
.attr("transform", "translate(" + -110+ " ,25)")
.transition()
.delay(500)
.duration(1000)
//設置標籤文字捕間動畫
.tween("number", function(d) {
var i = d3.interpolateRound(0, +d["y2008"]/1000000);
return function(t) {
i(t)==0 ? this.textContent = "" :this.textContent =commaFormat(i(t));
};
})
.attr("y", function(d) { return y(+d["y2008"]/1000000); })
.attr("x", function(d){ return x(d.hotel); } )
.attr("dx", -5)
.attr("dy", ".36em")
.attr("text-anchor", "right");
var draw_circle=svg.append('g')
.selectAll('circle')
.data(data)
.enter()
.append("circle")
.attr("transform", function(d) {
return "translate(" + projection_tpe_area([
d.lon,
d.lat
]) + ")";
}).attr("r","2").attr("fill", "yellow");
/*畫circle,綁group與餵資料(標示地點)*/
var draw_circle_ctrl=svg.append('g')
.selectAll('circle')
.data(data)
.enter()
.append("circle")
.attr("transform", function(d) {
return "translate(" + projection_tpe_area([
d.lon,
d.lat
]) + ")";
}).attr("r","2").attr("fill", function(d,i) { return color_table[d.hotel] } );
/*初始化資料,不畫營收圓圈大小*/
var draw_0000 =
draw_circle
.attr("r", function(d,i) {
return d.y2008== 0 ? '2.5' : d.y2008/50000000;
} )
//.attr("fill", function(d,i) {return d.properties.landmarkad=="6300003" ? 'red' : "steelblue" })
.attr("stroke",function(d,i){ return d.hotel=="遠東國際大飯店" ? "red":" white"})
.attr("stroke-width",function(d,i){ return d.hotel=="遠東國際大飯店" ? "2":" 1"})
.attr("fill", function(d,i) { return color_table[d.hotel] } )
.attr('fill-opacity', .75);
draw_circle
.on('mouseover', function(d, i) {
//tip顯示
d3.select(this)
.transition()
.style("stroke-width",3);
div.transition()
.duration(300)
.style("opacity", 0.9);
div.html( d.hotel+"<br>" + commaFormat(Math.round(d.y2008/1000000))+" 百萬元" )
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 50) + "px");
d3.select(this).style('fill-opacity', .3); //控制bar的顏色透明度
})
.on('mouseout', function(d, i) {
//tip隱藏
d3.select(this)
.transition()
.style("stroke-width", 1);
div.transition()
.duration(300)
.style("opacity", 0);
d3.select(this).style('fill-opacity', function(d){ return 0.5}); //控制bar的顏色透明度
});
//偵測radio的變化,並呼叫change()
d3.selectAll("input").on("change", change);
///////////////////////////
//用draw_graphic畫各年度//
//////////////////////////
function draw_graphic(para_year) {
svg.selectAll("rect")
.data(data)
.transition()
.duration(1000)
.attr("transform", "translate(" + -120 + " ,15)")
.attr("x", function(d) { return x(d.hotel); })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(+d[para_year]/1000000); })
.attr("height", function(d) { return 350 - y(+d[para_year]/1000000); })
.attr("fill", function(d,i) { return color_table[d.hotel] } )
.attr('fill-opacity', 1);
draw_bar_label
.transition()
.duration(1000)
.tween("number", function(d) {
var i = d3.interpolateRound(0, +d[para_year]/1000000);
return function(t) {
i(t)==0 ? this.textContent = "" :this.textContent =commaFormat(i(t));
};
})
//.text(function(d) {
// return +d["y2008"]==0?"":commaFormat(+d["y2008"]);
// })
.attr("y", function(d) { return y(+d[para_year]/1000000); })
.attr("x", function(d){ return x(d.hotel); } )
.attr("dx", -5)
.attr("dy", ".36em")
.attr("text-anchor", "right")
.attr("transform", "translate(" + -110+ " ,25)")
;
draw_circle
.transition()
.duration(1000)
.attr("r", function(d,i) {
return +d[para_year]== 0 ? '2' : +d[para_year]/50000000;
} )
//.attr("fill", function(d,i) {return d.properties.landmarkad=="6300003" ? 'red' : "steelblue" })
.attr("stroke",function(d,i){ return d.hotel=="遠東國際大飯店" ? "red":" white"})
.attr("stroke-width",function(d,i){ return d.hotel=="遠東國際大飯店" ? "2":" 1"})
.attr("fill", function(d,i) { return color_table[d.hotel] } )
.attr('fill-opacity', .75);
draw_circle
.on('mouseover', function(d, i) {
//tip顯示
d3.select(this)
.transition()
.style("stroke-width", 3);
div.transition()
.duration(300)
.style("opacity", 0.9);
div.html( d.hotel+"<br>" + commaFormat(Math.round(+d[para_year]/1000000))+" 百萬元" )
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 50) + "px");
d3.select(this).style('fill-opacity', .3); //控制bar的顏色透明度
})
.on('mouseout', function(d, i) {
//tip隱藏
d3.select(this)
.transition()
.style("stroke-width", 1);
div.transition()
.duration(300)
.style("opacity", 0);
d3.select(this).style('fill-opacity', function(d){ return 0.5}); //控制bar的顏色透明度
});
}
function change() {
years = this.value;
if (years == "2008") {draw_graphic("y2008");}
if (years == "2009") {draw_graphic("y2009");}
if (years == "2010") {draw_graphic("y2010");}
if (years == "2011") {draw_graphic("y2011");}
if (years == "2012") {draw_graphic("y2012");}
if (years == "2013") {draw_graphic("y2013");}
if (years == "2014") {draw_graphic("y2014");}
if (years == "2015") {draw_graphic("y2015");}
}
});
});
</script>
</section>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment