add rss-flow basically
This commit is contained in:
parent
e90ccf59d9
commit
3da9c33d14
2 changed files with 202 additions and 3 deletions
16
src/main.rs
16
src/main.rs
|
@ -113,6 +113,9 @@ fn tw_stock_process_json(response_json : &Value) -> HashMap<&str, Vec<String>>{
|
||||||
#[get("/<stock_id>")]
|
#[get("/<stock_id>")]
|
||||||
fn get_tw_stock(stock_id: String) -> Template {
|
fn get_tw_stock(stock_id: String) -> Template {
|
||||||
|
|
||||||
|
let rss_content = get_rss_data(stock_id.as_str());
|
||||||
|
println!("{:}", rss_content);
|
||||||
|
|
||||||
let response_body = get_stock_data(stock_id.as_str(), Date::Day(1), Date::YearToDate);
|
let response_body = get_stock_data(stock_id.as_str(), Date::Day(1), Date::YearToDate);
|
||||||
let response_json: Value = serde_json::from_str(response_body.as_str()).unwrap();
|
let response_json: Value = serde_json::from_str(response_body.as_str()).unwrap();
|
||||||
|
|
||||||
|
@ -120,6 +123,9 @@ fn get_tw_stock(stock_id: String) -> Template {
|
||||||
let mut stock_total_data = tw_stock_process_json(&response_json);
|
let mut stock_total_data = tw_stock_process_json(&response_json);
|
||||||
stock_total_data.insert("stock_id", vec![stock_id]);
|
stock_total_data.insert("stock_id", vec![stock_id]);
|
||||||
|
|
||||||
|
stock_total_data.insert("news", vec![rss_content]);
|
||||||
|
|
||||||
|
|
||||||
let mut stock_total_data_by_date = transverse_stock_data_by_date(stock_total_data.clone());
|
let mut stock_total_data_by_date = transverse_stock_data_by_date(stock_total_data.clone());
|
||||||
//let mut stock_total_data_by_date_wrapper = HashMap::new();
|
//let mut stock_total_data_by_date_wrapper = HashMap::new();
|
||||||
|
|
||||||
|
@ -161,6 +167,16 @@ fn transverse_stock_data_by_date(orig_data : HashMap<&str, Vec<String>>) ->
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_rss_data(stock_id : &str) -> String{
|
||||||
|
let url = format!(
|
||||||
|
"https://tw.stock.yahoo.com/rss?s={:}",
|
||||||
|
stock_id
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return get_url_data(&url);
|
||||||
|
}
|
||||||
|
|
||||||
fn get_stock_data(stock_id: &str, interval: Date, range: Date) -> String {
|
fn get_stock_data(stock_id: &str, interval: Date, range: Date) -> String {
|
||||||
let intrval_str = interval.as_str();
|
let intrval_str = interval.as_str();
|
||||||
|
|
|
@ -15,13 +15,64 @@
|
||||||
padding: 1em 0.6em;
|
padding: 1em 0.6em;
|
||||||
border: 1px solid red;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<table id="stock-table">
|
<h2 id="stock_id">{{stock_id.0}}</h2>
|
||||||
|
(<a href="{{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">
|
<tr id="title-of-table">
|
||||||
<th>日期</th>
|
<th>日期</th>
|
||||||
<th>開盤</th>
|
<th>開盤</th>
|
||||||
|
@ -40,6 +91,138 @@
|
||||||
<td class="volume">{{lookup ../volume @index}}</td>
|
<td class="volume">{{lookup ../volume @index}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</table>
|
</table></div><div>
|
||||||
</body>
|
|
||||||
|
<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">
|
||||||
|
<div id="news_content">{{news.0}}</div></div>
|
||||||
|
</div></div>
|
||||||
|
|
||||||
|
<script src="http://d3js.org/d3.v4.min.js"></script>
|
||||||
|
<script src="http://techanjs.org/techan.min.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var margin = {top: 20, right: 20, bottom: 30, left: 50},
|
||||||
|
width = 960 - margin.left - margin.right,
|
||||||
|
height = 500 - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
var parseDate = d3.timeParse("%d-%b-%y");
|
||||||
|
|
||||||
|
var x = techan.scale.financetime()
|
||||||
|
.range([0, width]);
|
||||||
|
|
||||||
|
var y = d3.scaleLinear()
|
||||||
|
.range([height, 0]);
|
||||||
|
|
||||||
|
var candlestick = techan.plot.candlestick()
|
||||||
|
.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(`{{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: +d["volume"][i],
|
||||||
|
});};
|
||||||
|
|
||||||
|
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)); });
|
||||||
|
|
||||||
|
console.log("===" + JSON.stringify(data_by_date));
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "candlestick");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "x axis")
|
||||||
|
.attr("transform", "translate(0," + height + ")")
|
||||||
|
.append("text")
|
||||||
|
.text("日期")
|
||||||
|
.attr("transform", "translate(" + width + ", 0)");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
svg.append("g")
|
||||||
|
.attr("class", "y axis")
|
||||||
|
.append("text")
|
||||||
|
.attr("transform", "rotate(-90)")
|
||||||
|
.attr("y", 6)
|
||||||
|
.attr("dy", ".71em")
|
||||||
|
.style("text-anchor", "end")
|
||||||
|
.text("股價(NT$)");
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
|
||||||
|
svg.selectAll("g.candlestick").datum(data).call(candlestick);
|
||||||
|
svg.selectAll("g.x.axis").call(xAxis);
|
||||||
|
svg.selectAll("g.y.axis").call(yAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
Loading…
Reference in a new issue