[英]How to consume this json
I'm trying to consume this API https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min&apikey=demo
using d3js candlestick chart, I managed to run an example using this index.html file, IDK why it can't be ran on the Snippet that stackoverflow offers nor codepen nor whatever, but it runs in a local enviorment and even on production. I'm trying to consume this API
https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min&apikey=demo
using d3js candlestick chart, I managed to run an example using this index.html file, IDK why it不能在stackoverflow提供的代码段上运行,也不能在codepen上运行,但它可以在本地环境甚至生产环境中运行。
Here's the file.这是文件。
<script src="https://d3js.org/d3.v5.js"></script>
<script src="https://d3js.org/d3-color.v1.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v1.min.js"></script>
<script src="https://d3js.org/d3-ease.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script src="https://d3js.org/d3-timer.v1.min.js"></script>
<script src="https://d3js.org/d3-transition.v1.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<style>
.label {
fill: #fff;
font-family: sans-serif;
font-size: 10px;
line-height : 1;
vertical-align: middle;
}
text {
fill : #777;
}
rect {
shape-rendering: crispEdges;
stroke-width : 1px;
}
line {
shape-rendering: crispEdges;
stroke-width: 1px;
}
line.focusLine {
stroke: #777;
stroke-linecap: butt;
}
.domain {
stroke: #777;
stroke-width : 1px;
}
</style>
<script>
(function() {
var jQuery;
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src",
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
jQuery = window.jQuery;
main();
}
function scriptLoadHandler() {
jQuery = window.jQuery.noConflict(true);
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
// We can use jQuery 1.4.2 here
// Widgets starts here
var json;
// Get data from API
const getJSON = async url => {
try {
const response = await fetch(url);
if(!response.ok) // check if response worked (no 404 errors etc...)
throw new Error(response.statusText);
const data = await response.json(); // get JSON from the response
return data; // returns a promise, which resolves to this data value
} catch(error) {
return error;
}
}
console.log("Fetching data...");
getJSON("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=IBM&interval=5min&apikey=demo").then(data => {
console.log(data);
var json = data;
}).catch(error => {
console.error(error);
});
console.log(json);
// Chart starts here
var totalWidth = window.innerWidth;
var totalHeight = window.innerHeight;
var margin = { top : 10, left : 50, bottom : 30 , right : 50 }
var width = totalWidth - margin.left - margin.right;
var height = totalHeight - margin.top - margin.bottom;
window.addEventListener( "resize", function(e) {
totalWidth = window.innerWidth;
totalHeight = window.innerHeight;
width = totalWidth - margin.left - margin.right;
height = totalHeight - margin.top - margin.bottom;
redrawChart()
});
// DATA STUFF
var formatDecimal = d3.format(',.2f');
var parseDate = d3.timeParse("%Y%m%d"); // 20150630
var outputFormat = d3.timeFormat("%d %b %Y") // 30 June 2015
var dataLoaded = null;
var dataModelJSON = function( d ) {
return {
date : parseDate(+d.date),
open : +d.open,
high : +d.high,
low : +d.low,
close : +d.close,
volume: +d.volume,
openInt : +d.openInt
}
};
var data = json.map( dataModelJSON );
function setData( data ) {
dataLoaded = data;
}
function redrawChart() {
if( dataLoaded ) {
d3.select("#candle-chart").remove();
prepareForBuild(dataLoaded);
buildChart(dataLoaded);
}
}
var xScale, xLabels, xAxis, yIsLinear, yDomain, yRange, yScale, yAxis;
function prepareForBuild( data ) {
xScale = d3.scaleBand()
.domain( data.map( function(d) { return d.date ; } ) )
.range( [ 0 , width ] )
.paddingInner(0.2)
.paddingOuter(0)
.align(0.5)
xLabels = xScale.domain().filter( function(d, i) {
if( i === data.length-1) return d;
var next;
if( data[i+1] ) {
next = data[i+1].date;
} else {
return false;
}
var monthA = d.getMonth();
var monthB = next.getMonth();
return (monthB > monthA ? d : ((monthB === 0 && monthA===11) ? d : false));
});
xAxis = d3.axisBottom( xScale )
.tickFormat( outputFormat )
.tickValues( xLabels );
yIsLinear = true;
yDomain = [d3.min(data, d => d.low), d3.max(data, d => d.high) ];
yRange = [ height, 0 ];
yScale = d3.scaleLinear().domain( yDomain ).range( yRange ).nice(5);
yAxis = d3.axisLeft( yScale )
.ticks(5)
.tickSizeInner(-width)
.tickFormat( formatDecimal );
}
function buildChart( data ) {
var svg = d3.select('body').append('svg')
.attr( "id", "candle-chart")
.attr( "width", totalWidth )
.attr( "height", totalHeight );
var mainGroup = svg.append("g")
.attr("id", "mainGroup")
.attr("transform", "translate( " + margin.left + ", " + margin.top + ")");
var xAxisGroup = mainGroup.append("g")
.attr("id", "xAxis")
.attr( "class" , "axis" )
.attr( "transform", "translate( "+0+","+ height + ")" )
.call( customXAxis );
function customXAxis(g) {
g.call( xAxis );
g.select(".domain").attrs({
})
g.selectAll(".tick line")
.attr("y1", -height)
.attr("y2", 0)
.attr("stroke", "#777")
.attr("stroke-dasharray", "3,2");
}
var yAxisGroup = mainGroup.append("g")
.attr("id", "yAxis")
.attr( "class" , "axis" )
.call( customYAxis );
function customYAxis( g ) {
g.call( yAxis );
g.selectAll(".tick line")
.attr("x1", 0)
.attr("x2", width )
.attr("stroke", "#777")
.attr("stroke-dasharray", "3,2");
g.selectAll(".tick:first-of-type line").remove()
g.selectAll(".tick text")
.attr("x", -9);
}
var eventGroup = mainGroup.append("g")
.attr('id' , 'event-overlay');
var crosshair = eventGroup.append("g")
.attr("id", "crosshair");
var eventRect = eventGroup.append('rect');
var canvasGroup = eventGroup.append("g")
.attr("id", "circleGroup");
// http://stackoverflow.com/questions/118241/calculate-text-width-with-javascript
function getTextWidth(text, font) {
var textWidth = 0;
var context = document.createElement("canvas").getContext("2d");
context.font = font;
textWidth = context.measureText(text).width;
return textWidth;
}
var crosshairSettings = {
xLabelTextOffset : height+12,
yLabelTextOffset : -9,
ylabelWidth : getTextWidth( formatDecimal(yDomain[1]), "10px sans-serif" )+2,
xlabelWidth : getTextWidth( "30 September 2000", "10px sans-serif"),
labelHeight: 14,
labelColor : "#aaa",
labelStrokeColor : "none",
labelStrokeWidth : "0.5px"
}
crosshair.append("line")
.attrs({
"id" : "focusLineX",
"class": "focusLine",
});
crosshair.append("line")
.attrs({
"id" : "focusLineY",
"class": "focusLine",
});
crosshair.append("rect") // x label bg
.attrs({
"id" : "focusLineXLabelBackground",
"class": "focusLineLabelBackground",
"fill" : crosshairSettings.labelColor,
"stroke" : crosshairSettings.labelStrokeColor,
"stroke-width" : crosshairSettings.labelStrokeWidth,
"width" : crosshairSettings.xlabelWidth,
"height" : crosshairSettings.labelHeight,
});
crosshair.append("text")
.attrs({
"id" : "focusLineXLabel",
"class" : "label",
"text-anchor" : "middle",
"alignment-baseline": "central"
});
var ylabel = crosshair.append("g").attr("id", "yLabelGroup");
ylabel.append("rect")
.attrs({
"id" : "focusLineYLabelBackground",
"class": "focusLineLabelBackground",
"fill" : crosshairSettings.labelColor,
"stroke" : crosshairSettings.labelStrokeColor,
"stroke-width" : crosshairSettings.labelStrokeWidth,
"width" : crosshairSettings.ylabelWidth,
"height" : crosshairSettings.labelHeight,
});
ylabel.append("text")
.attrs({
"id" : "focusLineYLabel",
"class" : "label",
"text-anchor" : "end",
"alignment-baseline": "central"
});
setCrosshair( width, 0);
var candleSettings = {
stroke : "black",
up : "#aaa",
down : "#d30000",
hover : "#ffffff",
lineMode : false
};
canvasGroup.selectAll("line")
.data( data )
.enter()
.append('line')
.attr( "x1", function( d, i) { return xScale( d.date ) + xScale.bandwidth()*0.5 } )
.attr( "y1", function( d ) { return yScale( d['high'] ) } )
.attr( "x2", function( d, i) { return xScale( d.date ) + xScale.bandwidth()*0.5 } )
.attr( "y2", function( d ) { return yScale( d['low'] ) } )
.style("stroke", candleSettings.stroke)
.style("stroke-width", "1px")
.style( "opacity", 1 )
if(xScale.bandwidth() > 1 ) {
candleSettings.lineMode = false;
canvasGroup.selectAll("rect")
.data( data )
.enter()
.append('rect')
.attrs({
x: function(d, i) {
return xScale( d.date );
},
y: function(d, i) {
return yScale( Math.max(d.close, d.open) )
},
width: xScale.bandwidth(),
height: function(d, i) {
var max = yScale(Math.min(d.close, d.open));
var min = yScale(Math.max(d.close, d.open));
var diff = max - min ;
return diff || 0.1;
},
})
.styles({
"fill" : function( d ) {
return d.close > d.open ? candleSettings.up : candleSettings.down;
},
"stroke" : candleSettings.stroke
})
} else {
candleSettings.lineMode = true
}
var els = candleSettings.lineMode ? canvasGroup.selectAll('line') : canvasGroup.selectAll('rect');
els.on("mouseover", function ( d, i ) {
d3.select( this )
.attrs( {
"cursor" : "pointer",
})
.styles({
"stroke": candleSettings.hover,
});
crosshair.style('display', null );
setCrosshair(
xScale( d.date )+xScale.bandwidth()*0.5,
yScale(d.close));
})
.on("mouseout", function (d, i) {
d3.select( this ).attrs({
})
.styles({
"fill" : function( d ) {
return d.close > d.open ? candleSettings.up : candleSettings.down;
},
"stroke" : candleSettings.stroke,
"stroke-width" : "1px",
});
})
eventRect.attrs(
{
'width' : width,
'height' : height
})
.styles({
'opacity' : 0.0,
'display' : null
})
.on('mouseover', function() {
crosshair.style('display', null);
})
.on('mouseout', function() {
crosshair.style('display', 'none');
})
.on('mousemove', function handleMouseMove() {
var mouse = d3.mouse( this );
var x = mouse[0];
var y = mouse[1];
setCrosshair(x,y);
} );
function setCrosshair( x, y ) {
d3.select('#focusLineX')
.attr( 'x1', x )
.attr( 'y1', 0 )
.attr( 'x2', x )
.attr( 'y2', height + 6 );
d3.select('#focusLineY')
.attr( 'x1', -6 )
.attr( 'y1', y )
.attr( 'x2', width )
.attr( 'y2', y );
d3.select("#focusLineXLabel")
.attr( "x", x )
.attr( "y", height+12)
.text( outputFormat(xScale.domain()[Math.floor(x / xScale.step())]) );
d3.select("#focusLineXLabelBackground")
.attr( "transform", "translate( " + (x - crosshairSettings.xlabelWidth * 0.5) + " , " + (height+6) + " )" )
.text( outputFormat(xScale.domain()[Math.floor(x / xScale.step())]) );
d3.select("#focusLineYLabel")
.attr( "transform" , "translate( "+ -9 +", " + y + ")")
.text( formatDecimal( yScale.invert(y) ));
d3.select("#focusLineYLabelBackground")
.attr( "transform" , "translate( "+ (-crosshairSettings.ylabelWidth-6) + ", " + (y-6) + ")")
}
}
(function(data) {
setData(data);
prepareForBuild(data);
buildChart(data);
})(data);
});
}
})(); // We call our anonymous function immediately
</script>
If you copy and paste it in a file.html and run it on a local browser it will ran sorry for the inconvenience.如果您将其复制并粘贴到一个文件中。html 并在本地浏览器上运行它会为您带来的不便而道歉。
What I'm trying to achieve is to consume that API example in this candlestick chart我想要实现的是在此烛台图中使用 API 示例
There's something I need to tweak in here to consume that URL我需要在这里调整一些东西来消耗 URL
var json =[{"close":69.06,"date":"20161020","high":70.1,"low":68.51,"open":68.87,"openInt":0,"volume":736533},{"close":70.58,"date":"20161023","high":70.74,"low":69.67,"open":69.9,"openInt":0,"volume":396860},{"close":71.17,"date":"20161024","high":72.99,"low":71.17,"open":72.6,"openInt":0,"volume":663227}]
and here to actually format that data because the example I have has nothing to do with what I have并在这里实际格式化该数据,因为我所拥有的示例与我所拥有的无关
// DATA STUFF
var formatDecimal = d3.format(',.2f');
var parseDate = d3.timeParse("%Y%m%d"); // 20150630
var outputFormat = d3.timeFormat("%d %b %Y") // 30 June 2015
var dataLoaded = null;
var dataModelJSON = function( d ) {
return {
date : parseDate(+d.date),
open : +d.open,
high : +d.high,
low : +d.low,
close : +d.close,
volume: +d.volume,
openInt : +d.openInt
}
};
var data = json.map( dataModelJSON );
I managed to add an example of how to fetch the data from the API using pure javascript, now I have that JSON on 'var json;'我设法添加了一个示例,说明如何使用纯 javascript 从 API 获取数据,现在我在 'FC46466DEEC7F6ECDF8Z but I'm getting another error at
Uncaught TypeError: Cannot read property 'map' of undefined
I'm tryinig to retrieve data only from this property ["Time Series (1min)"]
from that JSON但我在
Uncaught TypeError: Cannot read property 'map' of undefined
我正在尝试仅从该 JSON 的此属性["Time Series (1min)"]
检索数据
Your code is not working... but checking the code, I saw that you are doing json.map(....)
but you can't do that, because json
is an object, not an array.您的代码不起作用...但是检查代码,我看到您正在执行
json.map(....)
但您不能这样做,因为json
是 object,而不是数组。 To convert your json
object into the array that you want, is needed to loop over the object keys in this way:要将
json
object 转换为所需的数组,需要以这种方式循环 object 键:
const timeSeries = json['Time Series (5min)'];
var data = [];
Object.keys(timeSeries).forEach(key => {
const d = timeSeries[key];
d.date = new Date(key);
data.push( d );
});
So, use this loop instead of the json.map
that you have.因此,请使用此循环而不是您拥有的
json.map
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.