418 lines
11 KiB
Handlebars
418 lines
11 KiB
Handlebars
<!DOCTYPE html>
|
||
<!--
|
||
以下內容屬於程式碼一部分
|
||
This code is under MIT License
|
||
(c) 2023 Tan, Kian-ting
|
||
|
||
==========8964路路线资讯==================================
|
||
起讫站:程式码→墙内
|
||
票价:Free(<五毛人民币)
|
||
時刻:机动发车,单向行驶
|
||
停靠站:程式码→民主化→六四天安门→自由门下载→毋忘六四→刘晓波→
|
||
台湾独立→民运→西藏独立→新疆独立→港独→九评共产党→法轮功→
|
||
Tiananmen Massacre→Free Tibet→ 占领中环→民主→真普选→
|
||
南方街头运动→新公民运动→东突厥斯坦→湖南共和国→上访→ 大纪元→胡耀邦
|
||
→赵紫阳→Tank Man→北京之春→达赖喇嘛→六四真相→无界下载→通商宽衣→
|
||
躺平就是正义→习包子→梁家河小学博士→清零宗→习炀帝→庆丰大帝→
|
||
独裁国贼→新疆集中营→光复香港时代革命→祈翠→南蒙古独立→香港独立→
|
||
Free Hong Kong→天安门屠杀→中国言论钳制→中共文字狱→
|
||
如何润到墙外→中国青年失业率真相→历史的伤口→白纸革命→四通桥事件→
|
||
墙内
|
||
-->
|
||
<head>
|
||
<title>台股通</title>
|
||
<style type="text/css">
|
||
#stock-table{
|
||
border-collapse: collapse;
|
||
|
||
}
|
||
#stock-table th {
|
||
border: 1px solid red;
|
||
}
|
||
#stock-table td {
|
||
text-align: right;
|
||
padding: 1em 0.6em;
|
||
border: 1px solid red;
|
||
}
|
||
|
||
#css-table {
|
||
display:table;
|
||
}
|
||
.css-tr {
|
||
display: table-row;
|
||
}
|
||
.css-td {
|
||
display: table-cell;
|
||
}
|
||
</style>
|
||
|
||
<style>
|
||
|
||
body {
|
||
font: 10px sans-serif;
|
||
}
|
||
|
||
text {
|
||
fill: #000;
|
||
font-size: 14px;
|
||
}
|
||
|
||
button {
|
||
position: absolute;
|
||
right: 20px;
|
||
top: 440px;
|
||
display: none;
|
||
}
|
||
|
||
path.candle {
|
||
stroke: #000000;
|
||
}
|
||
|
||
path.candle.body {
|
||
stroke-width: 0;
|
||
}
|
||
|
||
path.candle.up {
|
||
fill: #dc3526;
|
||
stroke: #dc3526;
|
||
}
|
||
|
||
path.candle.down {
|
||
fill: #007d30;
|
||
stroke: #007d30;
|
||
}
|
||
|
||
path.volume.up {
|
||
fill: #dc3526;
|
||
stroke: #dc3526;
|
||
}
|
||
path.volume.equal {
|
||
fill: #dc3526;
|
||
stroke: #dc3526;
|
||
}
|
||
|
||
path.volume.down {
|
||
fill: #007d30;
|
||
stroke: #007d30;
|
||
}
|
||
|
||
.indicator.ma-0{
|
||
stroke:blue;
|
||
}
|
||
|
||
.text.ma-0{
|
||
fill:blue;
|
||
}
|
||
|
||
.indicator.ma-1{
|
||
stroke:orange;
|
||
}
|
||
|
||
.text.ma-1{
|
||
fill:orange;
|
||
}
|
||
|
||
.indicator.ma-2{
|
||
stroke:green;
|
||
}
|
||
|
||
.text.ma-2{
|
||
fill:green;
|
||
}
|
||
|
||
|
||
</style>
|
||
|
||
</head>
|
||
|
||
<html>
|
||
<body>
|
||
<h2 id="stock_id">{{main.stock_id.0}}</h2>
|
||
(<a href="{{main.stock_id.0}}/json">JSON</a>)
|
||
<div id="css-table">
|
||
<div class="css-tr">
|
||
<div class="css-td"><table id="stock-table">
|
||
<tr id="title-of-table">
|
||
<th>日期</th>
|
||
<th>開盤</th>
|
||
<th>收盤</th>
|
||
<th>最高</th>
|
||
<th>最低</th>
|
||
<th>成交量</th>
|
||
</tr>
|
||
{{#with main}}
|
||
{{#each date}}
|
||
<tr id={{this}}>
|
||
<td class="date">{{this}}</td>
|
||
<td class="open">{{lookup ../open @index}}</td>
|
||
<td class="close">{{lookup ../close @index}}</td>
|
||
<td class="high">{{lookup ../high @index}}</td>
|
||
<td class="low">{{lookup ../low @index}}</td>
|
||
<td class="volume">{{lookup ../volume @index}}</td>
|
||
</tr>
|
||
{{/each}}{{/with}}
|
||
</table></div><div>
|
||
|
||
<h3 id="chart-title"></h3>
|
||
<div class="css-td">
|
||
<input type="radio" name="range" value="5d">5日<br>
|
||
<input type="radio" name="range" value="30d">30日<br>
|
||
<input type="radio" name="range" value="ytd" checked="checked">今年迄今<br>
|
||
<svg id="chart"></svg></div>
|
||
|
||
<div class="css-td"><h3 id="chart-title">Yahoo 股市新聞</h3>
|
||
<div id="news_content">{{#each news}}
|
||
<div><div class="news-title"><a href="{{this.link}}">{{this.title}}</a></div>
|
||
<div class="news-date">{{this.date}}</div>
|
||
<div class="news-summary">{{this.summary}}……</div>
|
||
|
||
{{/each}}</div></div>
|
||
</div></div>
|
||
|
||
<script src="https://d3js.org/d3.v4.min.js"></script>
|
||
<script src="https://techanjs.org/techan.min.js"></script>
|
||
<script>
|
||
|
||
var margin = {top: 20, right: 50, bottom: 30, left: 50},
|
||
width = 960 - margin.left - margin.right,
|
||
height = 800 - margin.top - margin.bottom;
|
||
|
||
var parseDate = d3.timeParse("%d-%b-%y");
|
||
|
||
var x = techan.scale.financetime()
|
||
.range([0, width]);
|
||
|
||
var y_height = height * 0.7;
|
||
var y = d3.scaleLinear()
|
||
.range([y_height, 0]);
|
||
|
||
var candlestick = techan.plot.candlestick()
|
||
.xScale(x)
|
||
.yScale(y);
|
||
|
||
|
||
var y_volume = d3.scaleLinear()
|
||
.range([y(0), y(0.3)]);
|
||
|
||
|
||
var volume = techan.plot.volume()
|
||
.accessor(candlestick.accessor()) // Set the accessor to a ohlc accessor so we get highlighted bars
|
||
.xScale(x)
|
||
.yScale(y_volume);
|
||
|
||
var volume_axis = d3.axisLeft(y_volume)
|
||
.ticks(5)
|
||
.tickFormat(d3.format(",.3s"));
|
||
|
||
var volume_accessor = volume.accessor();
|
||
|
||
var sma0 = techan.plot.sma()
|
||
.xScale(x)
|
||
.yScale(y);
|
||
var sma1 = techan.plot.sma()
|
||
.xScale(x)
|
||
.yScale(y);
|
||
|
||
var sma2 = techan.plot.sma()
|
||
.xScale(x)
|
||
.yScale(y);
|
||
|
||
|
||
var xAxis = d3.axisBottom()
|
||
.scale(x)
|
||
.tickFormat(d3.timeFormat('%y-%m-%d'));
|
||
|
||
var yAxis = d3.axisLeft()
|
||
.scale(y);
|
||
|
||
var svg = d3.select('#chart')
|
||
.attr("width", width + margin.left + margin.right)
|
||
.attr("height", height + margin.top + margin.bottom)
|
||
.append("g")
|
||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
||
|
||
|
||
var data_by_date = [];
|
||
|
||
|
||
|
||
d3.json(`{{main.stock_id.0}}/json`, function(d) {
|
||
console.log(d);
|
||
|
||
var data_by_date = [];
|
||
var parseDate = d3.timeParse("%Y-%m-%d");
|
||
|
||
|
||
for (var i=0;i<d["close"].length;i++){
|
||
data_by_date.push({
|
||
date: parseDate(d["date"][i]),
|
||
open: +d["open"][i],
|
||
high: +d["high"][i],
|
||
low: +d["low"][i],
|
||
close: +d["close"][i],
|
||
volume: parseInt(d["volume"][i].replace(/,/g, "")),
|
||
});};
|
||
|
||
console.log('dataGet', data_by_date);
|
||
|
||
var accessor = candlestick.accessor();
|
||
data_by_date = data_by_date.sort(function(a, b) { return d3.ascending(accessor.d(a), accessor.d(b)); });
|
||
|
||
svg.append("g")
|
||
.attr("class", "candlestick");
|
||
svg.append("g")
|
||
.attr("class", "volume")
|
||
.attr("transform", "translate(0," + height * 0.21 +")")
|
||
|
||
|
||
|
||
svg.append("g")
|
||
.attr("class", "x axis")
|
||
.attr("transform", "translate(0," + height * 0.7 + ")")
|
||
.append("text")
|
||
.text("日期")
|
||
.attr("transform", "translate(" + width + ", 20)");
|
||
|
||
svg.append("g")
|
||
.attr("class", "volume axis")
|
||
.attr("transform", "translate(0, " + height * 0.21 + ")")
|
||
.append("text")
|
||
.text("成交量")
|
||
.attr("transform", "rotate(-90) translate(-"+ height * 0.50 +", 10)")
|
||
.attr("y", 6)
|
||
.attr("dy", ".71em")
|
||
.style("text-anchor", "end")
|
||
|
||
|
||
svg.append("g")
|
||
.attr("class", "y axis")
|
||
.append("text")
|
||
.attr("y", 6)
|
||
.attr("dy", ".71em")
|
||
.style("text-anchor", "end")
|
||
.text("股價(NT$)")
|
||
.attr("transform", "translate(10, 0) rotate(-90)");
|
||
|
||
|
||
|
||
svg.append("g")
|
||
.attr("class", "indicator sma ma-0")
|
||
.attr("fill", "transparent");
|
||
|
||
svg.append("g")
|
||
.attr("class", "indicator sma ma-1")
|
||
.attr("fill", "transparent");
|
||
|
||
|
||
svg.append("g")
|
||
.attr("class", "indicator sma ma-2")
|
||
.attr("fill", "transparent");
|
||
|
||
|
||
|
||
|
||
// Data to display initially
|
||
d3.select("#chart-title").text("今年迄今");
|
||
draw(data_by_date);
|
||
// Only want this button to be active if the data has loaded
|
||
// d3.select("input").on("click", function() { draw(data_by_date); }).style("display", "inline");
|
||
|
||
d3.selectAll('input[name="range"]').on("change", function(){
|
||
if (this.value == "ytd"){
|
||
draw(data_by_date);
|
||
d3.select("#chart-title").text("今年迄今");
|
||
}
|
||
else if(this.value == "30d"){
|
||
draw(data_by_date.slice(data_by_date.length-30, data_by_date.length-1));
|
||
d3.select("#chart-title").text("30日");
|
||
}
|
||
else{
|
||
draw(data_by_date.slice(data_by_date.length-5, data_by_date.length-1));
|
||
d3.select("#chart-title").text("5日");
|
||
};
|
||
});
|
||
|
||
|
||
} );
|
||
|
||
|
||
|
||
function draw(data) {
|
||
x.domain(data.map(candlestick.accessor().d));
|
||
y.domain(techan.scale.plot.ohlc(data, candlestick.accessor()).domain());
|
||
y_volume.domain(techan.scale.plot.volume(data).domain());
|
||
|
||
svg.selectAll("g.candlestick").datum(data).call(candlestick);
|
||
|
||
svg.select("g.volume").datum(data).call(volume);
|
||
svg.select("g.volume.axis").call(volume_axis);
|
||
|
||
svg.selectAll("g.x.axis").call(xAxis);
|
||
svg.selectAll("g.y.axis").call(yAxis);
|
||
|
||
let sma0range = 5;
|
||
let sma1range = 20;
|
||
let sma2range = 60;
|
||
|
||
|
||
svg.select("g.sma.ma-0").datum(techan.indicator.sma().period(sma0range)(data)).call(sma0);
|
||
svg.select("g.sma.ma-1").datum(techan.indicator.sma().period(sma1range)(data)).call(sma1);
|
||
svg.select("g.sma.ma-2").datum(techan.indicator.sma().period(sma2range)(data)).call(sma2);
|
||
|
||
svg.select("g.sma.ma-0 g path").attr("id", "sma-0");
|
||
svg.select("g.sma.ma-1 g path").attr("id", "sma-1");
|
||
svg.select("g.sma.ma-2 g path").attr("id", "sma-2");
|
||
|
||
|
||
svg.append("text")
|
||
.attr("x", "1")
|
||
.attr("y", "1")
|
||
.append("textPath")
|
||
.attr("xlink:href", "#sma-0")
|
||
.attr("class", "ma-0 text")
|
||
.text("MA" + sma0range);
|
||
|
||
svg.append("text")
|
||
.attr("x", "1")
|
||
.attr("y", "1")
|
||
.append("textPath")
|
||
.attr("xlink:href", "#sma-1")
|
||
.attr("class", "ma-1 text")
|
||
.text("MA" + sma1range);
|
||
|
||
svg.append("text")
|
||
.attr("x", "1")
|
||
.attr("y", "1")
|
||
.append("textPath")
|
||
.attr("xlink:href", "#sma-2")
|
||
.attr("class", "ma-2 text")
|
||
.text("MA" + sma2range);
|
||
|
||
|
||
|
||
d3.selectAll("g.y .tick")
|
||
.append("line")
|
||
.attr("class", "gridline")
|
||
.attr("z-index", -100)
|
||
.attr("x1", 0)
|
||
.attr("y1", 0)
|
||
.attr("x2", width)
|
||
.attr("y2", 0)
|
||
.attr("stroke", "rgb(210, 210, 210)"); // line color
|
||
|
||
|
||
|
||
d3.selectAll("g.volume .tick")
|
||
.append("line")
|
||
.attr("class", "gridline")
|
||
.attr("z-index", -100)
|
||
.attr("x1", 0)
|
||
.attr("y1", 0)
|
||
.attr("x2", width)
|
||
.attr("y2", 0)
|
||
.attr("stroke", "rgb(210, 210, 210)"); // line color
|
||
|
||
}
|
||
|
||
</script>
|
||
</html>
|