I am working on a project and want to dynamically create highchart by assigning series arrays to the highchart. I use some dummy data to generate the array, however, in the example I provided below, the two columns are excatly the same which is not expected.
examples
$(function () {
var field_result = new Object();
var series = [];
var result_array = [];
var fields = [32, 22]
for (var i=0; i<fields.length; i++)
{
field_result.name = fields[i];
for (var m=0; m<4; m ++) {
result_array[m] = Math.random()*10;
}
field_result.data = result_array;
series.push(field_result);
}
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Column chart with negative values'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
credits: {
enabled: false
},
series: series
});
});
Thank you very much.
You intent to create two distinct series-objects with separate data-arrays and put these in the series-array. But you are initializing these objects outside the loop for each individual series, so you end up overwriting the first data object with the second data.
You just have to move the initialization inside the loop:
$(function () {
var series = [];
var fields = [32, 22];
for (var i=0; i<fields.length; i++)
{
var field_result = new Object(); // <---- moved here
var result_array = []; // <---- moved here
field_result.name = fields[i];
for (var m=0; m<4; m ++){
result_array[m] = Math.random()*10;
}
field_result.data = result_array;
series.push(field_result);
}
[...]
Then in each loop iteration a new object and array will be created and filled with random data.
http://jsfiddle.net/doc_snyder/jgoyynzd/2/
Related
I am trying to add the values of multiple arrays (one starts out empty, but all the ones I am adding to it are the same length, though it be great if we could come up with something that adds them even if they are all different lengths) - not the sum of all values in each array, instead, sum of the values in the same index. For example:
array1 = [1, 2, 3]
array2 = [2, 3, 4]
desiredArray = [3, 5, 7]
The number of the arrays I will be adding is arbitrary, as they are created based on the users selection. (Based on the length of the array created from the selection). I want to sum the arrays by index to create a new array, and from the new array, I will create a decline curve. When I attempt to add them using "indexSum" I get an array below back full of NaaNs...though they are the correct legth:
requestedOil
requestedGas
requestedWater
These are the temporary arrays created by the length of the var "values" - these are the ones I am trying to add by respective index to eventually get the ones mentioned above:
Oil[well]
Gas[well]
Water[well]
THIS IS THE FUNCTON I CURRENTLY HAVE TO ADD ARRAYS AND CALLED WHEN USER MAKES SELECTION FROM multiple-site-selection
function updateCurves(){
var dropdownMenu = document.getElementById("multiple-site-selection").selectedOptions;
var values = Array.from(dropdownMenu).map(({ value }) => value);
console.log(values);
d3.json('./static/wellNames.json').then((data) => { //read in the wellNames.json file, which contains the array "names" with all the well names
wellOptions = data.names;
forSelection = wellOptions.map((x) => ({id:x}))
console.log(forSelection);
d3.json("./static/all_production.json").then((data) =>{
var requestedOil = [];
var requestedGas = [];
var requestedWater = [];
var site_date = [];
var Oil = [];
var Gas = [];
var Water = [];
values.forEach((well) => {
forSelection.forEach((pair) => {
if(well == Object.values(pair)){
Oil[well] = new Array();
Gas[well] = new Array();
Water[well] = new Array();
new Promise ((resolve) => data.forEach((site) => {
if(values.length == 1 && well == site[0]){
requestedOil.push(site[2]);
requestedGas.push(site[3]);
requestedWater.push(site[4]);
site_date.push(site[8])}
else if(values.length > 1 && well == site[0]){
indexSum = (a1, a2) => a1.map((v, i) => i + a2[v]);
Oil[well].push(site[2])
requestedOil = indexSum(Oil[well], requestedOil);
Gas[well].push(site[3])
requestedGas = indexSum(Gas[well], requestedGas);
Water[well].push(site[4])
requestedWater = indexSum(Water[well], requestedWater);
site_date.push(site[8])}
else{}
resolve()}))//PROMISE CLOSED
} //IF CLOSED
})//forSelection (dic containing names of well selected) closed
console.log(Oil[well]);
}); //values.forEach closed
THIS CODE CURRENTLY WORKS AS I AM NOT ADDING ANY ARRAYS AND IT IS CALLED AS SOON AS THE WEBPAGE LOADS
//FUNCTION TO CREATE DROP DOWN VALUES
function createDropdownOptions() {
var selector = d3.select("#multiple-site-selection"); //select dropdown <select> in well.html with id:"siteSelection"
d3.json('./static/wellNames.json').then((data) => { //read in the wellNames.json file, which contains the array "names" with all the well names
var wellOptions = data.names;
wellOptions.forEach((well) => {
selector
.append('option')
.text(well)
.property('Value', well);
})
})
};
createDropdownOptions(); //CALL FUNCTION TO CREATE DROPDOWN MENU VALUES
// //FUNCTION TO CREATE HOME/SUMMARY CURVES
function curvesHome() {
d3.json("./static/all_production.json").then((data) =>{ //THIS WORKS!!!
var site_oil = [];
var site_gas = [];
var site_water = [];
summarySiteDate = [];
new Promise ((resolve) => data.forEach(site => {if (site[0]==="Summary") {
site_oil.push(site[2]);
site_gas.push(site[3]);
site_water.push(site[4]);
summarySiteDate.push(site[8]);
} resolve()}));
//CALL FUNCTION TO CREATE DROPDOWN MENU VALUES
var mostRecentEntry = summarySiteDate[0]; //MOST RECENT DATE WITHOUT HOUR AS VARIABLE
var addingHours = "T00:00"; //HOURS TO ADD TO MOST RECENT DATE - NEEDED TO NORMALIZE FROM ORIGINAL 19 HOUR FORMAT
var nextYear = mostRecentEntry.concat(addingHours); //DATE AND HOUR AS SINGLE VARIABLE TO MAKE INTO DATE
var mostRecentDate = new Date(nextYear); //MAKE VARIABLE INTO DATE
var nextYearsDate = new Date(mostRecentDate.setFullYear(mostRecentDate.getFullYear() + 1)); //GET YEAR FROM MOST RECENT DATE AND ADD A YEAR
var nextYear= nextYearsDate.getFullYear() //GET NEXT YEARS DATE
var nextMonth= nextYearsDate.getMonth() + 1 // GET NEXTS YEARS MONTH, ADD ONE BECAUSE MONTHS ARE INDEXED AT 0
var nextDate= nextYearsDate.getDate() //GET NEXT YEARS DATE
nextYearGraph = `${nextYear}-${nextMonth}-${nextDate}`; // CREATE FULL DATE FOR NEXT YEAR IN RIGHT FORMAT FOR AXIS
console.log(`${nextYearGraph} is a year from the most recent production date. This is from curvesHome()`);
var dataOil = [{
x: summarySiteDate,
y: site_oil,
type: "line",
line:
{color: "green"}
}];
var layoutOil = {
title: "Oil BBL",
yaxis: {
type: 'log',
autorange: true
},
xaxis: {
autorange: false,
range: [summarySiteDate[summarySiteDate.length-1], nextYearGraph]
}
};
Plotly.newPlot("oilDeclineCurve", dataOil, layoutOil);
// gas decline curve data
var dataGas = [{
x: summarySiteDate,
y: site_gas,
type: "line",
line: {color: "red"}
}];
var layoutGas = {
title: "Gas BBL",
yaxis: {
type: 'log',
autorange: true
},
xaxis: {
autorange: false,
range: [summarySiteDate[summarySiteDate.length-1], nextYearGraph]
}
};
Plotly.newPlot("gasDeclineCurve", dataGas, layoutGas);
// water decline curve data
var dataWater = [{
x: summarySiteDate,
y: site_water,
type: "line" }
];
var layoutWater = {
title: "Water BBL",
yaxis: {
type: 'log',
autorange: true
},
xaxis: {
autorange: false,
range: [summarySiteDate[summarySiteDate.length-1], nextYearGraph]
}
};
Plotly.newPlot("waterDeclineCurve", dataWater, layoutWater);
})};
I have both HTML sand JS in my code, so it is probably best if you have the whole thing to better understand what I am doing and trying to do. Here are my links:
My repo:
My GitPage
Thank you in advanced!
Here is a function that bases length off of first array length and doesn't care about the number of input arrays
function stackSum(arr) {
return arr[0].map((a, i) => {
let r = 0;
arr.forEach(b, j) => r+=arr[j][i]);
return r;
})
}
console.log(stackSum([
[1,1,1],
[1,2,2],
[2,2,3],
[3,7,7]
]).join(','));
console.log(stackSum([
[1,2,3],
[2,3,4]
]).join(','));
Since the arrays are of equal lengths, you can simply use Array#map.
const
indexSum = (a1, a2) => a1.map((v, i) => v + a2[i]),
desiredArray = indexSum([1, 2, 3], [4, 5, 6])
console.log(desiredArray)
I need help to improve the number of points displayed on the chart line.
With the current code, for 100000 points, only 20 drawn in the graph line.
var elements = new Array(100000);
for (i = 0; i < elements.length; i++) {
elements[i] = i;
}
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: {
text: 'ECharts entry example'
},
tooltip: {},
legend: {
data:['Sales']
},
xAxis: {
data: elements
},
yAxis: {},
series: [{
name: 'Sales',
type: 'line',
data: elements
}]
};
myChart.setOption(option);
You have to modify the xAxis for this. You should take a look at the axisTicks, and play around with the interval option. It either supports auto, a number or a function.
Alternatively, you can also manually show/hide the datapoints, by telling the data elements to display them, but maybe this only works when there's an axis tick available.
For displaying every datapoint, set showAllSymbol to true in the series data.
series: [{
name: 'Sales',
type: 'line',
showAllSymbol: true,
data: elements
}]
However, 20.000 datapoints may be a lot, so you can also create an interval by setting showSymbol within the data elements
for(i = 0; i < elements.length; i++){
elements[i] = {
value: i,
symbol: (i % 100 === 0) ? 'circle' : 'none'
}
}
This will set showSymbol to true for every 100th iteration. You may have to combine this with showAllSymbol: true in the series data to work properly.
Note: % is the modulus operator
I am requesting a webservice, which responds with a CSV file like this (with more monthly data available for the last years). Important for me are the first and last piece of information in the line (aka date and value):
2010/01/01,51.67074582499006,13.789093928493081,-0.0010074468085106377
2010/02/01,51.67074582499006,13.789093928493081,0.0024117021276595747
2010/03/01,51.67074582499006,13.789093928493081,0.026550000000000004
2010/04/01,51.67074582499006,13.789093928493081,0.08252659574468087
2010/05/01,51.67074582499006,13.789093928493081,0.12837446808510639
2010/06/01,51.67074582499006,13.789093928493081,0.140618085106383
2010/07/01,51.67074582499006,13.789093928493081,0.0668787234042553
2010/08/01,51.67074582499006,13.789093928493081,0.10335744680851064
2010/09/01,51.67074582499006,13.789093928493081,0.08095000000000001
2010/10/01,51.67074582499006,13.789093928493081,0.0400159574468085
2010/11/01,51.67074582499006,13.789093928493081,0.004214893617021277
2010/12/01,51.67074582499006,13.789093928493081,-0.0018680851063829788
2011/01/01,51.67074582499006,13.789093928493081,0.0011914893617021279
2011/02/01,51.67074582499006,13.789093928493081,0.003752127659574468
2011/03/01,51.67074582499006,13.789093928493081,0.027225531914893623
With this information, I would like to build a Highcharts graphic, which displays a separate line for each individual year. It should look like this:
My current version adds all data up to a long line - which is nice, but doesn't make the values comparable between the years:
function processData(allText)
{
var allTextLines = allText.split(/\r\n|\n/);
var lines = []; var n = 0; var data = []; var dateValue = [];
for (var i=1; i<allText.length; i++)
{
if (allTextLines[i])
{
if ((allTextLines[i].substring(0,2) == "19") || (allTextLines[i].substring(0,2) == "20"))
{
dateValue = allTextLines[i].split(",");
// everything will be concatenated into one single line
if(Number.isFinite(parseFloat(dateValue[3])))
{
data[n] = [new Date(dateValue[0]).getTime(), parseFloat(dateValue[3])];
}
n++;
}
}
}
return data;
}
Now, what I need is a result which looks like this:
series:
[{
name: "2010",
data: [-0.001007447,0.002411702,0.02655,0.082526596,0.128374468,0.140618085,0.066878723,0.103357447,0.08095,0.040015957,0.004214894,-0.001868085]
},{
name: "2011",
data: [0.001191489,0.003752128,0.027225532,0.090589362,0.129121277,0.141264894,0.119343617,0.113290426,0.093575532,0.044221277,0.015881915,0.004068085]
}
],
...
But I have no idea how my Javascript code must look like, to generate such an outcome. Can anyone give me a hint?
You can extract your data like this :
function extract(csv) {
var rows = csv.split(/\r\n|\n/);
var data;
var series = [];
var serie = {name: -1, data: []};
for (var i = 0; i < rows.length; i++) {
data = rows[i].split(',');
if (serie.name === -1) {
serie.name = data[0].substr(0,4);
}
else if (serie.name !== data[0].substr(0,4)) {
series.push(serie);
serie = {name: data[0].substr(0,4), data: []};
}
serie.data.push(parseFloat(data[3]));
}
series.push(serie);
return series;
}
jsFiddle : https://jsfiddle.net/mk7x7bbe/
My custom X-axis values are not displayed in flot js.
Code for drawing the line chart as below :
var length = 0;
var length1 = 0;
var dataXY = [];
var data = [];
var dataX = [];
length = allVenues.length;
for (var i = 0; i < length; i++) {
length1 = allVenues[i].length;
for (var j = 0; j < length1; j++) {
dataX.push([j, returnDate(allVenues[i][j].date)]);
dataXY.push([returnTimestamp(allVenues[i][j].date), allVenues[i][j].price, "<b>X</b> : " + returnDate(allVenues[i][j].date) + " | " + " <b>Y</b>: " + allVenues[i][j].price]);
}
}
var result = {'label': 'Demo Graph', 'data': dataXY};
data = [result];
var options = {
lines: {
show: true
},
points: {
show: true
},
xaxis: {
ticks: dataX
},
grid: {
hoverable: true,
clickable: true
},
tooltip: {
show: true,
content: "%s | X: %x | Y: %y"
}
};
function returnTimestamp(val) {
var dateTime = new Date(val);
return moment(dateTime).unix();
}
function returnDate(val) {
var dateTime = new Date(val);
return moment(dateTime).format("YYYY-MM-DD hh:mm:ss A");
}
$.plot("#placeholder", data, options);
dataXY array values are:
{"label":"Demo Graph","data":[[1455776629,12],[1455801889,30],[1455962948,45]]}
dataX array values are:
[[0, "2016-02-18 11:53:49 AM"], [1, "2016-02-18 06:54:49 PM"], [2, "2016-02-20 03:39:08 PM"]]
Now i want to set this "dataX" array as X axis values (ticks) on the chart.
This values display below in each point of line graph with X-Axis.
Here dataX and dataXY from allVenues Json Array.
My graph is woking fine except the X-Axis data. You can see in the image below.
Your dataX array for the ticks must have the same x values (timestamps) as your real data array:
[[1455776629, "2016-02-18 11:53:49 AM"], [1455801889, "2016-02-18 06:54:49 PM"], [1455962948, "2016-02-20 03:39:08 PM"]]
PS: I would also suggest to put a linebreak (<br>) between date and time in the labels.
I am working in representing data in Highcharts. I have got a task like representing sales of every company for every year, where x axis has categories from jan to dec and y axis has data in which each year's data should be shown in different series, for example, if year is 2010, then jan to dec of 2010's data should be displayed as one series and remaining years.
For that I have googled all over the StackOverflow but I have not succeeded yet.
Here is my code:
$.post('./reportdata/salesbyyear.php', { reportid: value }, function(data) {
//incoming data from php echo statement
var year_data = data;
//replacing all special characters with space, except :
year_data = year_data.replace(/[()""/>{}<]/g, '');
//replacing : with ,
year_data = year_data.replace(/:/g, ',');
//splitting the input data into array
var total_data = new Array();
total_data = year_data.split(',');
//creted two new arrays and stroing alternate elements of previous array into two different arrays
var month_data = new Array();
var year_name = new Array();
var y = 0;
for (i = 0; i < total_data.length; i++) {
month_data[y] = total_data[i];
year_name[y] = total_data[i + 1];
i++;
y++;
}
series = [];
series = generatedata(month_data);
function generatedata(data_array) {
// finding total number of arrays by divding the elements by 12
//so that if I get 44 elements, the total arrays will be 4 , i.e each array
// has sequential 12 elements that represents 1 year (12 months)data
var total = Math.ceil(data_array.length / 12);
var values = [];
var l = 0;
for (i = 0; i < total; i++) {
values[i] = [];
for (j = 0; j < 12; j++) {
values[i][j] = parseFloat(data_array[l]);
l++;
//adding data to series and using this series in highcharts code
series.push({
data: values[i]
});
}
}
}
$('#container').highcharts({
chart: {
type: 'line',
backgroundColor: 'rgba(255, 255, 255, 0.1)',
lineColor: 'orange'
},
title: {
text: 'Customer Details',
style: {
fontFamily: 'monospace',
color: 'orange'
}
},
xAxis: {
categories:['January','February','March','April','May','June','July','August','September','October','November','December'],
lineColor: 'orange',
labels: {
style: {
fontFamily: 'monospace',
color: 'orange'
},
},
},
series: [{
data: series
}]
});
});