JS-echart-histpgram-X axis - javascript

blue is the standard, the red is current mine
compared with these two diagrams, I do not no how to design the x-axis in the blue diagram, which is a range to describe the data.
Now, I using an array to store all value displayed, and on the y-axis, another array stores the times of each number displays. But I do not know make the X-axis to be a range.
<script>
var sheetName = null;
var sheets = null;
var ageArray = new Array();
var ageTimes = new Array();
function readExcel(file_obj){
var reader = new FileReader();
var file = file_obj.files[0];
reader.readAsBinaryString(file);
reader.onload = function (e) {
var data = e.target.result;
var wb = XLSX.read(data, {type: 'binary'});
sheetName = wb.SheetNames[0] // 获取文档中第一个sheet页签的名字
sheets = wb.Sheets[sheetName] // 获sheet名页签下的数据
var json = XLSX.utils.sheet_to_json(sheets)
// console.log(sheets); // 返回sheet对象到控制台
// console.log(json.length);
// console.log(json);
for (let i = 0; i < json.length; i++) {
ageArray.push(json[i]['Age ']);
}
// console.log(ageArray);
function unique (arr) {
return Array.from(new Set(arr))
}
ageArray = unique(ageArray);
ageArray.sort(function (a,b){
if (a>b) {
return 1
} else if (a<b){
return -1
} else return 0
});
// console.log(ageArray);
// count times
let LevelList = json.map(item => {
return item['Age '];
})
let contlist = LevelList.reduce(function(prev,next){
prev[next] = (prev[next]+1) || 1;
return prev
},{});
console.log(contlist);
for (let j = 0; j < ageArray.length; j++) {
var index = ageArray[j];
// console.log(contlist[index]);//
ageTimes.push(contlist[index]);
// console.log(ageTimes);
}
var myChart = echarts.init(document.querySelector('.box'));
var option = {
title: {
text: 'ECharts'
},
tooltip: {},
legend: {
data: ['sale']
},
xAxis: {
data: ageArray,
},
yAxis: {
},
series: [
{
name: 'sale',
type: 'bar',
data: ageTimes
}
]
};
myChart.setOption(option);
};
}
</script>
<style>
.box {
width: 1000px;
height: 400px;
background-color: pink;
}
</style>
<body>
<input type="file" onchange="readExcel(this)" />
<div class="box"></div>
</body>

Related

How to change csv to json array using javascript

I want to add an external CSV file into a JOSN Array in my JS Code.
I tried lots of codes, with no luck like this:
var map = {};
var rows = csv.split(/\n/g);
var keys = rows.shift().split(",");
rows.forEach(raw_row => {
var row = {};
var row_key;
var columns = raw_row.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);
columns.forEach((column, index) => {
var key = keys[index];
if (!key) return;
if (key === 'Name') {
row_key = column;
return;
}
if (key === "Coordinates") {
column = column.replace(/""/g, '"');
column = column.substring(1, column.length - 1);
column = column.replace(/([a-zA-Z_]+):/g, `"$1":`);
try {
column = JSON.parse(`{${column}}`);
} catch (e) {}
}
row[key] = column;
});
map[row_key] = row;
});
console.log(map);
but I believe my expectation is something else, so I dont get what I want.
could some one pleae help me to change this csv(file):
contry;fromNr;toNr;Type;cust_1;cust_2
US;0;100;wood;max;nuk
DE;100;500;metal;max;pal
into JSON Array:
[{
"country": "US",
"fromNr": 0,
"toNr": 100,
"Type": "wood",
"cust_1": "max",
"cust_2": "nuk"
}, {
"country": "DE",
"fromNr": 100,
"toNr": 500,
"Type": "metal",
"cust_1": "max"
}]
You can use the below function csvIntoJson to convert.
const csv = 'contry;fromNr;toNr;Type;cust_1;cust_2\nUS;0;100;wood;max;nuk\nDE;100;500;metal;max;pal';
const csvIntoJson = (csv, separator) => {
let [headers, ...rows] = csv.split('\n');
headers = headers.split(separator);
rows = rows.map(row => row.split(separator));
return rows.reduce((jsonArray, row) => {
const item = row.reduce((item, value, index) => {
return {...item, [headers[index]]: value};
}, {});
return jsonArray.concat(item);
}, []);
};
const jsonArray = csvIntoJson(csv, ';');
My suggestion use a library, But you still want to understand how it can be done then here is the simple code.
I have used ',' delimiter, You can change it to ';' or anything else as per your usecase.
steps:
Read csv as text
split text by new line to get rows
split row by delimiter like ',' or ';'
Do your stuff
code:
function Upload(input){
console.log("uploading");
let file = input.files[0];
let reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
map_object = [];
console.log(reader.result);
var textByLine = (reader.result).split("\n")
console.log(textByLine);
// read header
header = (textByLine[0]).split(',');
// read data
for(var i = 1 ; i< textByLine.length -1; i++){
temp_row = {}
row_data = textByLine[i].split(',');
for (var j = 0 ; j< header.length; j++){
temp_row[header[j]] = row_data[j]
}
console.log(temp_row);
map_object.push(temp_row);
}
console.log(map_object);
document.write(JSON.stringify(map_object));
};
reader.onerror = function() {
console.log(reader.error);
};
}
<input type="file" id="fileUpload" accept='.csv' onchange="Upload(this)"/>
var data = "contry;fromNr;toNr;Type;cust_1;cust_2\nUS;0;100;wood;max;nuk\nDE;100;500;metal;max;pal";
function CSVtoJSON(csv) {
var lines = csv.split("\n");
var result = [];
var headers = lines[0].split(";");
for (var i = 1; i < lines.length; i++) {
var obj = {};
var currentline = lines[i].split(";");
for (var j = 0; j < headers.length; j++) {
obj[headers[j]] = currentline[j];
}
result.push(obj);
}
return result;
}
console.log(CSVtoJSON(data));

Get value of 2nd Column of table and then graph it Javascript

I'm trying to create a graph from values I get from the https://financialmodelingprep.com/ API. Basically what I did so far is that I create a table with all the values like this:
function myFunction() {
var symbol =
document.getElementById("Ticker").value;
//var symbol = "TSLA";
// https://financialmodelingprep.com/developer/docs
getRequest(
'https://financialmodelingprep.com/api/v3/financials/income-statement/' + symbol + '?period=quarter',
drawOutput
);
function drawOutput(responseText) {
let resp = JSON.parse(responseText).financials;
let financials = resp;
let $table = document.createElement("table");
$table.className += " table2";
var elements = document.querySelectorAll('.stock-name')[0];
let $head = document.createElement("thead");
let $body = document.createElement("tbody");
let $lineHader = document.createElement("tr");
/* let $elefirst = document.createElement("th");
$elefirst.textContent = 'Fiscal';
$lineHader.appendChild($elefirst); */
for (let i = 0; i < financials.length; i++) {
let financial = financials[i];
let $line = document.createElement("tr");
for (var key in financial) {
if (i === 0 && financial.hasOwnProperty(key)) {
let $ele = document.createElement("th");
$ele.textContent = key;
$lineHader.appendChild($ele);
}
}
$head.appendChild($lineHader);
$table.appendChild($head);
var z = 0;
for (var key2 in financial) {
if (financial.hasOwnProperty(key2)) {
/* if (z === 0) {
let title = Object.keys(resp)[i];
let $eleTile = document.createElement("td");
$eleTile.textContent = title;
$line.appendChild($eleTile);
} */
let $eletd = document.createElement("td");
if (z === 0) {
$eletd.textContent = financial[key2];
} else {
$eletd.textContent = financial[key2];
}
$line.appendChild($eletd);
}
z++;
}
$body.appendChild($line)
$table.appendChild($body);
}
document.body.appendChild($table);
}
function getRequest(url, success) {
var req = false;
try {
req = new XMLHttpRequest();
} catch (e) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return false;
}
}
}
if (!req) return false;
if (typeof success != 'function') success = function() {};
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status === 200) {
success(req.responseText)
}
}
}
req.open("GET", url, true);
req.send(null);
return req;
}
}
</script>
<div class="stock-name"></div>
Which will look something like This
What I'm trying to do is to get the 2nd Column so the Revenue and graph those values with this:
<canvas id="myChart" width="400" height="200"></canvas>
<script>
var ctx = document.getElementById('myChart');
var myLineChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [2, 1, 3, 5, 2, 3],
backgroundColor: 'rgba(255, 99, 132, 0.2)',
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 1,
fill: false,
showLine: true,
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
And basically plug in the Revenue to the data values which are currently 2, 1, 3, 5, 2, 3 . I would appreciate any help possible.
I can help you fetch the second row but not graphing it.
For this to work, your table needs to be in the html, and you need to add an id to the table like so:
$table.id = "chartTable";
Put this after the let $table = createElement() or whatever.
Then:
let secondRow = document.querySelectorAll('#' + $table.id + ' tr')[1].;
Edit:
For columns:
let rows = document.querySelectorAll('#' + $table.id + ' tr'), i, col = [];
for (i = 0; i < rows.length; i++) {
let row = rows[i][1];
col.push(row.innerText);
}
Then the col array would contain all the values.
Explanation (for the columns bit):
To access the second column, you need to access the second value of each row.
Second Edit:
let tds = document.querySelectorAll('#' + $table.id + ' tr td'), i, col = [];
let l = 20; // l is the number of elements in a **row**
for (i = 1; i < tds.length; i += l) {
col.push(tds[i].innerHTML);
}

How to draw graph with logarithmic scale by getting input from AJAX call in canvasjs

window.onload = function() {
var dataPoints = [];
// fetching the json data from api via AJAX call.
var X = [];
var Y = [];
var data = [];
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', ' https://api.myjson.com/bins/cixax', true);
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
}
xobj.send(null);
}
loadJSON(function(response) {
var response;
var field = JSON.parse(response);
var values = [];
//Iterating and storing leads & visits in a variable.
var $this = field;
for (var key in $this) {
if ($this.hasOwnProperty(key)) {
var data = $this[key].dates;
for (var val in data) {
values.push({
"X": data[val].visits,
"Y": data[val].leads
});
}
}
}
dataPoints = ({
"values": values
});
});
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Log Scale on Axis Y - Workaround using Linear Axis"
},
axisY: {
//valueFormatString: "0.## E0",
title: "In log scale",
labelFormatter: function(e) {
var lable = Math.pow(10, e.value);
if (lable >= 1000)
lable = CanvasJS.formatNumber(lable / 1000) + "k";
else
lable = CanvasJS.formatNumber(lable);
return lable;
},
interval: 1,
includeZero: false
},
toolTip: {
contentFormatter: function(e) {
var content = "Data Values";
for (var i = 0; i < e.entries.length; i++) {
content += "</br>" + e.entries[i].dataPoint.x + " : ";
content += CanvasJS.formatNumber(Math.round(Math.pow(10, e.entries[i].dataPoint.y)));
}
return content;
}
},
data: [{
type: "line",
dataPoints: []
}]
}); convertToLog(chart.options.data); chart.render();
function convertToLog(data) {
var dataPoints;
for (var j = 0; j < data.length; j++) {
dataPoints = data[j].dataPoints;
for (var i = 0; i < dataPoints.length; i++) {
dataPoints[i].y = Math.log10(dataPoints[i].y);
}
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 360px; width: 100%;"></div>
Here I am trying to draw the graph using canvasjs. I am getting the input from the external API using an AJAX call. And storing the variables X and Y in the array. Providing that as an input to that canvasjs library for drawing the graph. But I am not able to draw the graph. The above snippet is the one I have done.
The Chart wasn't getting rendered because the render method gets called before the data actually is loaded.
"x" & "y" should be in small instead of capital. The graph looks scrambled because the X Values in your JSON are not sorted.
Since the library now supports Logarithmic Scale on Y-Axis, you can use that instead of the work around.Here's a documentation link.
window.onload = function() {
//var dataPoints = [];
// fetching the json data from api via AJAX call.
var X = [];
var Y = [];
var data = [];
function loadJSON(callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', 'https://api.myjson.com/bins/cixax', true);
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
callback(xobj.responseText);
}
}
xobj.send(null);
}
loadJSON(function(response) {
var response;
var field = JSON.parse(response);
var values = [];
//Iterating and storing leads & visits in a variable.
var $this = field;
for (var key in $this) {
if ($this.hasOwnProperty(key)) {
var data = $this[key].dates;
for (var val in data) {
values.push({
"x": data[val].visits, // Should be "x" & "y"
"y": data[val].leads
});
}
}
}
//dataPoints = ({
// "values": values
//});
// Update the dataPoints & render the chart
// x values need to be in sorted order
chart.options.data[0].dataPoints = values;
chart.render();
});
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Log Scale on Axis Y - Workaround using Linear Axis"
},
axisY: {
//valueFormatString: "0.## E0",
title: "In log scale",
labelFormatter: function(e) {
var lable = Math.pow(10, e.value);
if (lable >= 1000)
lable = CanvasJS.formatNumber(lable / 1000) + "k";
else
lable = CanvasJS.formatNumber(lable);
return lable;
},
interval: 1,
includeZero: false
},
toolTip: {
contentFormatter: function(e) {
var content = "Data Values";
for (var i = 0; i < e.entries.length; i++) {
content += "</br>" + e.entries[i].dataPoint.x + " : ";
content += CanvasJS.formatNumber(Math.round(Math.pow(10, e.entries[i].dataPoint.y)));
}
return content;
}
},
data: [{
type: "line",
dataPoints: []
}]
}); //convertToLog(chart.options.data); chart.render();
function convertToLog(data) {
var dataPoints;
for (var j = 0; j < data.length; j++) {
dataPoints = data[j].dataPoints;
for (var i = 0; i < dataPoints.length; i++) {
dataPoints[i].y = Math.log10(dataPoints[i].y);
}
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 360px; width: 100%;"></div>

Uncaught TypeError: Cannot read property 'append' of null

I recreated the ploytly.js dropdown graph here:
https://plot.ly/javascript/dropdowns/#bind-dropdown-events-to-plotlyjs-charts
I copy and pasted the code in my app and it worked perfectly.
Now I just want to duplicate the graph and put it below the original. Here is the html:
<div class="showcase__section" id="bubble">
<div class="spacer --small"></div>
<div id="bubbleplots">
<div class="bubbleplot" data-num="0">
<div class="plot" id="plotdiv"></div>
<div class="control-row">
Country: <select class="countrydata">
</select>
</div>
</div>
</div>
</div>
<div class="showcase__section" id="bubble">
<div class="spacer --small"></div>
<div id="bubbleplots">
<div class="bubbleplot" data-num="0">
<div class="plot1" id="plotdiv1"></div>
<div class="control-row">
Country: <select class="countrydata1">
</select>
</div>
</div>
</div>
I changed 3 of the divs so the javascript can tell them apart.
Below is the javascript. Again, I changed the names of the some the variables of the second graph. Otherwise, the javascript of the first and second graph is identical.
The first graph shows up perfectly in my app, but there's an issue with the second graph. The second graph shows up, and the data is correct on the graph and the popup menu shows up but with no country names. I console.log('currentOption1') of the second graph three separate times.
The first two times the console returns as expected, but the third time it shows 'Uncaught TypeError: Cannot read property 'append' of null'. So the problem lies with
selector.appendChild(currentOption1);
Again,
selector.appendChild(currentOption);
works perfectly with the first graph.
So currentOption1 is null. Why, and how do I fix it?
Here is a link to the two graphs
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var allCountryNames = unpack(rows, 'country'),
allYear = unpack(rows, 'year'),
allGdp = unpack(rows, 'gdpPercap'),
listofCountries = [],
currentCountry,
currentGdp = [],
currentYear = [];
for (var i = 0; i < allCountryNames.length; i++ ){
if (listofCountries.indexOf(allCountryNames[i]) === -1 ){
listofCountries.push(allCountryNames[i]);
}
}
function getCountryData(chosenCountry) {
currentGdp = [];
currentYear = [];
for (var i = 0 ; i < allCountryNames.length ; i++){
if ( allCountryNames[i] === chosenCountry ) {
currentGdp.push(allGdp[i]);
currentYear.push(allYear[i]);
}
}
};
// Default Country Data
setBubblePlot('Afghanistan');
function setBubblePlot(chosenCountry) {
getCountryData(chosenCountry);
var trace1 = {
x: currentYear,
y: currentGdp,
mode: 'lines+markers',
marker: {
size: 12,
opacity: 0.5
}
};
var data = [trace1];
var layout = {
title: 'GDP per cap according to Country<br>'+ chosenCountry + ' GDP'
};
Plotly.newPlot('plotdiv', data, layout);
};
var innerContainer = document.querySelector('[data-num="0"'),
plotEl = innerContainer.querySelector('.plot'),
countrySelector = innerContainer.querySelector('.countrydata');
function assignOptions(textArray, selector) {
for (var i = 0; i < textArray.length; i++) {
var currentOption = document.createElement('option');
currentOption.text = textArray[i];
selector.appendChild(currentOption);
}
}
assignOptions(listofCountries, countrySelector);
function updateCountry(){
setBubblePlot(countrySelector.value);
}
countrySelector.addEventListener('change', updateCountry, false);
});
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv', function(err, rows){
function unpack(rows, key) {
return rows.map(function(row) { return row[key]; });
}
var allCountryNames = unpack(rows, 'country'),
allYear = unpack(rows, 'year'),
allGdp = unpack(rows, 'gdpPercap'),
listofCountries = [],
currentCountry,
currentGdp = [],
currentYear = [];
for (var i = 0; i < allCountryNames.length; i++ ){
if (listofCountries.indexOf(allCountryNames[i]) === -1 ){
listofCountries.push(allCountryNames[i]);
}
}
function getCountryData(chosenCountry) {
currentGdp = [];
currentYear = [];
for (var i = 0 ; i < allCountryNames.length ; i++){
if ( allCountryNames[i] === chosenCountry ) {
currentGdp.push(allGdp[i]);
currentYear.push(allYear[i]);
}
}
};
// Default Country Data
setBubblePlot('Brazil');
function setBubblePlot(chosenCountry) {
getCountryData(chosenCountry);
var trace1 = {
x: currentYear,
y: currentGdp,
mode: 'lines+markers',
marker: {
size: 12,
opacity: 0.5
}
};
var data = [trace1];
var layout = {
title: 'GDP per cap according to Country<br>'+ chosenCountry + ' GDP'
};
Plotly.newPlot('plotdiv1', data, layout);
};
var innerContainer = document.querySelector('[data-num="0"'),
plotEl = innerContainer.querySelector('.plot1'),
countrySelector = innerContainer.querySelector('.countrydata1');
function assignOptions(textArray, selector) {
for (var i = 0; i < textArray.length; i++) {
var currentOption1 = document.createElement('option');
console.log('currentOption1')
currentOption1.text = textArray[i];
console.log('currentOption1')
selector.appendChild(currentOption1);
console.log('currentOption1')
}
}
assignOptions(listofCountries, countrySelector);
function updateCountry(){
setBubblePlot(countrySelector.value);
}
countrySelector.addEventListener('change', updateCountry, false);
});
var innerContainer = document.querySelector('[data-num="0"')
calls the first dropdown box so I changed it to
var innerContainer = document.getElementById('bubble1')
and it retrieved the correct data from the second set of identical data after I created the 'bubble1' id in the html to differentiate the two.

I want to multiply chart data according as array length

I used this ,to multiply doughnut chart according as array(arr) has,but it can't change to object,(data has string type).So chart doesn't appear here..,how fix it
var arr=['HTML','CSS','JS'],i,data;
data ='[';
for(i=0;i<arr.length;i++){
if(i==arr.length-1){
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]}';
}
else{
data+='{value:"300",color:"#fff",highlight:"#aaa",label:arr[i]},';
}
}
data += ']';
var dat = data;
window.onload = function () {
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat,{
responsive: true,
});
};
//want like this
dat =[{value:"300",color:"#fff",highlight:"#aaa",label:"HTML"},
{value:"200",color:"#fff",highlight:"#aaa",label:"CSS"}];
You are creating your array as a String.
You need to create an array of objects [{},{},{}].
The method used to INSERT a new object in an array is PUSH().
Check the fiddle. Now it´s working OK (move the mouse on the screen to see the chart is there (you will only see it when mouse is over it):
window.onload = function() {
var arr = ['HTML', 'CSS', 'JS'],
i, data;
data = [];
for (i = 0; i < arr.length; i++) {
if (i == arr.length - 1) {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
} else {
data.push({
value: "300",
color: "#fff",
highlight: "#aaa",
label: arr[i]
});
}
}
var dat = data;
var ctx = document.getElementById("chart-area").getContext("2d");
window.myBar = new Chart(ctx).Doughnut(dat, {
responsive: true,
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/nnnick/Chart.js/master/Chart.js"></script>
<canvas id="chart-area"></canvas>

Categories