Reputation: 57
I know this question has been asking many times, but I still can't find any solution ! Here is my code : I'm programming an array of cryptocurrency's values but I'm stuck when I'm trying to create graphs.
ajaxGet("https://api.coinmarketcap.com/v1/ticker/?limit=300", function (reponse) {
// Transforme la réponse en tableau d'objets JavaScript
var monnaie = JSON.parse(reponse);
$("#tableBody").empty();
var tr;
function page1(event) {
var timestamp = Math.round(new Date().getTime() / 1000);
console.log(timestamp);
for (var i = 0; i < 50; i++) {
ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {
var monnaieGraph = JSON.parse(reponse2)['Data'];
var points = '';
var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))
for (var j=0; j<=28; j++){
var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;
points += (j*12) + ',' + echelle + '\n';
}
});
tr = $('<tr/>');
tr.append("<td>" + monnaie[i].rank + "</td>");
tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
if (Number(monnaie[i].percent_change_24h) > 0) {
tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
//tr.append("<i class=fa fa-caret-up>" + "</i>");
}
else {
tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
}
tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
$('#tableBody').append(tr);
}
}
Everything works ! I got an array with all the values I want.
And as I said, I'm trying to add a column of graphs for each currency ! I tried 3 different code but none of them are working ! Here are the 3 codes with an image of each result:
for (var i = 0; i < 50; i++) {
ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {
var monnaieGraph = JSON.parse(reponse2)['Data'];
var points = '';
var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))
for (var j=0; j<=28; j++){
var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;
points += (j*12) + ',' + echelle + '\n';
}
});
tr = $('<tr/>');
tr.append("<td>" + monnaie[i].rank + "</td>");
tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
if (Number(monnaie[i].percent_change_24h) > 0) {
tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
//tr.append("<i class=fa fa-caret-up>" + "</i>");
}
else {
tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
}
tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
$('#tableBody').append(tr);
}
Inside my "for" loop, I added the ajaxGet, in which I create a variable "points" which get the values from the API scaled for the graph.
This code doesn't work, I got the error: "points is not defined".
Here is my 2nd try :
for (var i = 0; i < 50; i++) {
tr = $('<tr/>');
tr.append("<td>" + monnaie[i].rank + "</td>");
tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
if (Number(monnaie[i].percent_change_24h) > 0) {
tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
//tr.append("<i class=fa fa-caret-up>" + "</i>");
}
else {
tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
}
ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {
var monnaieGraph = JSON.parse(reponse2)['Data'];
var points = '';
var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))
for (var j=0; j<=28; j++){
var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;
points += (j*12) + ',' + echelle + '\n';
}
tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
});
$('#tableBody').append(tr);
}
This time, I added the creation of the column inside the ajaxGet. The graphs are ok, but they only appear as a row, on the last row !
And here is my last try:
for (var i = 0; i < 50; i++) {
ajaxGet("https://min-api.cryptocompare.com/data/histohour?fsym=" + monnaie[i].symbol + "&tsym=USD&limit=28&aggregate=6&toTs=" + timestamp, function (reponse2) {
var monnaieGraph = JSON.parse(reponse2)['Data'];
var points = '';
var maximum = Math.max.apply(Math,monnaieGraph.map(function(o){return o.high;}))
var minimum = Math.min.apply(Math,monnaieGraph.map(function(o){return o.low;}))
for (var j=0; j<=28; j++){
var moyenne = ((monnaieGraph[j].high)+(monnaieGraph[j].low))/2;
echelle = ((-100/(maximum-minimum))*(moyenne-minimum))+100;
points += (j*12) + ',' + echelle + '\n';
}
tr = $('<tr/>');
tr.append("<td>" + monnaie[i].rank + "</td>");
tr.append("<td>" + "<img class=imageCrypto src=logos/" + monnaie[i].symbol + ".png" + " " + "style=width:37.5px; height:37.5px;" + ">" + "<div class=nomCurr><a href=http://www.google.com/" + monnaie[i].id +">" + monnaie[i].name + "</a>" + "<div>" + monnaie[i].symbol + "</div></div></td>");
tr.append("<td>" + formatter.format(monnaie[i].price_btc) + " BTC" + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].price_usd) + "</td>");
tr.append("<td>" + "$ " + formatter.format(monnaie[i].market_cap_usd) + "</td>");
tr.append("<td>" + formatter.format(monnaie[i].available_supply) + " " + monnaie[i].symbol + "</td>");
if (Number(monnaie[i].percent_change_24h) > 0) {
tr.append("<td class=pourcentPositif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-up'" + "</td>");
//tr.append("<i class=fa fa-caret-up>" + "</i>");
}
else {
tr.append("<td class=pourcentNegatif>" + Number(monnaie[i].percent_change_24h) + "%" + "<i class='fa fa-caret-down'" + "</td>");
}
tr.append('<td><svg viewBox="0 0 336 100" width=116 height=35><polyline fill=none stroke=#0074d9 stroke-width=6 points="' + points + '"/></svg></div>');
$('#tableBody').append(tr);
});
}
I added the declaration of the whole table, inside the ajaxGet ! I don't understand the result : This time, the graphs are what I want, but the rest of the array (every columns in every rows) have the value of the 51th coin (but the "graphs" column works), while my variable i is supposed to be 0
Hope my problem is clear, I'm sorry I can't post images... Thank you for your time !
Upvotes: 0
Views: 126
Reputation: 308
I think the first of the three code snippets should work, if you change the following things:
The scope of your points
variable is limited to the callback function you provide to the ajaxGet
function. Therefore when you try to use it when building your table, it can't be accessed. That is why you get the error points is not defined
. Declare the points
variable in scope of your for-loop to solve this.
When building your points you delimit your point pairs by \n
, I'm not sure if that works in your SVG code in this case. Maybe try to delimit by a blank space.
The problem with the SVG images not showing is because apparently you have to reload the actual HTML that you generated to get the SVG images rendered in the browser. See this related anwer. In your case you should reload the HTML of your table every time after a row is added. Using jQuery it would look something like this:
// Row creation logic...
$('#tableBody').append(tr);
$("#tableBody").html($("#tableBody").html());
function getTimestamp() {
return Math.round(new Date().getTime() / 1000);
}
function getAveragePrice(pricepoint) {
return (pricepoint.high + pricepoint.low) / 2;
}
function getPointMap(min, max) {
return function (price, index) {
var range = max - min;
var offset = price - min;
var value = 100 - (offset * 100 / range);
return `${index * 12},${value}`;
}
}
function getPoints(prices) {
var min = Math.min(...prices);
var max = Math.max(...prices);
var points = prices.map(getPointMap(min, max));
return points.join(" ");
}
function getSvg(points) {
var line = $('<polyline/>');
line.attr("fill", "none");
line.attr("stroke", "#0074d9");
line.attr("stroke-width", 6);
line.attr("points", points);
var svg = $('<svg/>');
svg.attr("viewBox", "0 0 336 100");
svg.attr("width", 116);
svg.attr("height", 35);
svg.append(line);
return svg;
}
function getCell(content) {
return $("<td/>").append(content);
}
function getRow(coin, points) {
// Set id to SortOrder provided by API so
// we can use it to add the rows to the
// table in the right order.
var tr = $('<tr/>');
tr.attr("id", coin.SortOrder);
tr.append(getCell(coin.SortOrder));
tr.append(getCell(coin.CoinName));
tr.append(getCell(`${coin.TotalCoinSupply}`));
tr.append(getCell(getSvg(points)));
return tr;
}
function addRow(row, table)
{
var current = table.children().first();
// While there is a next row
while(current.is("tr")) {
// Check if the rank of current row is
// larger than the rank of the row we
// want to add.
if(Number(current.attr("id")) > Number(row.attr("id"))) {
// If true, add the row before the
// current row and we are done.
current.before(row);
return;
}
// Else check the next row.
current = current.next();
}
// If the table does not contain rows yet or
// the end of the table is reached without
// finding larger ranks, just add the row at
// the end.
table.append(row);
}
function getHistoryCallback(table, coin) {
return function (history) {
var prices = history.Data.map(getAveragePrice);
var points = getPoints(prices);
var row = getRow(coin, points);
addRow(row, table);
table.html(table.html());
}
}
function sortCoins(a, b) {
return a.SortOrder - b.SortOrder;
}
function getCoinsCallback(table) {
return function (coinlist) {
var coins = Object.values(coinlist.Data).sort(sortCoins);
table.empty();
for (var i = 0; i < 10; i++) {
var coin = coins[i];
var url = "https://min-api.cryptocompare.com/data/histohour";
var data = {
fsym: coin.Symbol,
tsym: "USD",
limit: 28,
aggregate: 6,
toTs: getTimestamp()
};
var callback = getHistoryCallback(table, coin);
$.getJSON(url, data, callback);
}
}
}
function populateTable(table_id) {
var table = $(`#${table_id}`);
var url = "https://min-api.cryptocompare.com/data/all/coinlist";
var callback = getCoinsCallback(table);
$.getJSON(url, callback);
}
$(document).ready(function () {
populateTable("tableBody");
});
Upvotes: 1