send multiple requests in parallel - javascript

I have to make a bridge (script) between two databases (Mongo and Oracle).
I run three find queries on my MONGO database in three different collections.
Collection 1 = [{
name: 'Toto',
from: 'Momo',
note: 5,
cat: 'noCategori'
}]
Collection 2 = [{
city: 'london',
country: 'UK'
}]
...etc
I retrieve lists of documents from each collection I make a treatment on this list (Ex: average).
RowToSend = {
name: 'Toto',
note: 17, // average all document
city: 'london'
}
I establish a connection with Oracle and I persist this row.
I would like to run queries to mongo in parallel. at the end of the three requests and treatments. I compose my recording and I persist it on my database.
I have with async but it does not work. With await too. the function (Script) ends before the request is processed
function RequestOne(dateStart, dateEnd, RowToInsert) =
CollectionOne.find({
AQS_REF_TIME_EVENT_MSR: {
$gte: startInterv,
$lte: endInerv
},
})
.exec((err, arrAqsOneHourMoy) => {
if (err)
return err;
if (arrAqsOneHourMoy) {
AttributeOneAverge = 0;
AttributeTwoAverage = 0;
for (i = 0; i < arrAqsOneHourMoy.length; i++) {
AttributeOneAverge = (arrAqsOneHourMoy[i].AttributeOne + AttributeOneAverge);
AttributeTwoAverge = (arrAqsOneHourMoy[i].AttributeTwo + AttributeTwoAverge);
}
RowToInsert.AttributeOne = ((AttributeOneAverge) / (i + 1));
RowToInsert.AttributeOne = (AttributeTwoAverge) / (i + 1);
}
})
}
Function TWO .. same logic
Globale function :
function GenericFunction(time, sensorID, TEST_oracle_save) {
var d = new Date(2018, 00, 03, 11, 00, 00, 000);
var x = d.toISOString();
var d2 = new Date(2018, 00, 03, 11, 59, 59, 999);
var y = d2.toISOString();
RequestOne(x, y, TEST_oracle_save);
RequestTwo(x, y, TEST_oracle_save);
//Connexion to ORACLE DATABASE
//Connexion etablished
// Persist TEST_oracle_save on field Oracle
}

function RequestOne(dateStart, dateEnd, RowToInsert) =
CollectionOne.find({
AQS_REF_TIME_EVENT_MSR: {
$gte: startInterv,
$lte: endInerv
},
})
.exec((err, arrAqsOneHourMoy) => {
if (err)
return err;
if (arrAqsOneHourMoy) {
AttributeOneAverge = 0;
AttributeTwoAverage = 0;
for (i = 0; i < arrAqsOneHourMoy.length; i++) {
AttributeOneAverge = (arrAqsOneHourMoy[i].AttributeOne + AttributeOneAverge);
AttributeTwoAverge = (arrAqsOneHourMoy[i].AttributeTwo + AttributeTwoAverge);
}
RowToInsert.AttributeOne = ((AttributeOneAverge) / (i + 1));
RowToInsert.AttributeOne = (AttributeTwoAverge) / (i + 1);
}
})
}
Function TWO .. same logic
Globale function :
function GenericFunction(time, sensorID, TEST_oracle_save) {
var d = new Date(2018, 00, 03, 11, 00, 00, 000);
var x = d.toISOString();
var d2 = new Date(2018, 00, 03, 11, 59, 59, 999);
var y = d2.toISOString();
RequestOne(x, y, TEST_oracle_save);
RequestTwo(x, y, TEST_oracle_save);
//Connexion to ORACLE DATABASE
//Connexion etablished
// Persist TEST_oracle_save on field Oracle
}

Related

How To Create An Algorithm That Combines Arrays

This is what I've tried and it seems like I'm on the right path but I've been trying to tweak this algorithm for a while and I can't figure out what I'm doing wrong. Here is my code so far:
const getThem = async () => {
const format2 = 'YYYY/MM/DD';
const obj = {};
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].tests.length; j++) {
for (let z = 0; z < channel.length; z++) {
if (data[i].tests[j] === channel[z].id) {
const dateTime = moment(channel[z].start).format(format2);
const dateTime2 = moment(channel[z].end).format(format2);
const dateList = getDateArray(new Date(dateTime), new Date(dateTime2));
if (Date.parse(dateTime) > Date.parse('2019-11-15') || Date.parse(dateTime) < Date.parse('2019-11-04')) {
break;
}
if (!channel[z].end) {
// eslint-disable-next-line operator-assignment
obj[dateTime] += (1 / data.length);
} else {
for (let k = 0; k < dateList.length; k++) {
if (!obj.hasOwnProperty(dateList[k])) {
obj[dateList[k]] = 1 / data.length;
} else {
obj[dateList[k]] += (1 / data.length);
}
}
}
}
}
}
}
setDates(Array.sort(Object.keys(obj)));
setValues(Object.values(obj));
};
Check my answer. The approach is simple. First we loop through all the testsResponse data and get the minimum and maximum dates then we iterate through each day from min to max date. For each current day we check the test ids in testsResponse data and then we filter the channels data from the tests array in channelsResponse data and then finally we take the % by the filtered channels data and total channels response data and push it in the results array. The only catch here is that it will push all the dates between minimum test.start and maximum test.end dates both inclusive. If you want to exclude the dates for which testIds is empty then just before the results.push() check if testIds.length is not 0. Here is the getThem():
// given channelsResponse & testsResponse
const getThem = () => {
// get min and max dates
let max='';
let min=new Date().toISOString();
testsResponse.forEach(test => {
min=test.start && min.localeCompare(test.start)>0?test.start:min;
max=test.end && max.localeCompare(test.end)<0?test.end:max;
});
min=new Date(min.substr(0,10)+'T00:00:00.000Z');
max=new Date(max.substr(0,10)+'T00:00:00.000Z');
let results = [];
// loop from min date to max date
for(var i=min; i<=max; i.setDate(i.getDate()+1)) {
let p=0;
let d=i.toISOString().substr(0,10);
// get test ids within the current date
const testIds = testsResponse.filter(t => d.localeCompare((t.start+'').substr(0,10))>=0 && d.localeCompare((t.end+'').substr(0,10))<=0).map(t => t.id);
// get channels where above test ids were found
const channels = channelsResponse.filter(c => c.tests.some(t => testIds.includes(t)));
// calculate %
p=Math.round(channels.length*100.0/channelsResponse.length);
// push data for current date to results
results.push({date: i.toISOString(), utilizationPercentage: p})
}
return results;
};
console.log(getThem());
// [{"date":"2019-11-04T00:00:00.000Z","utilizationPercentage":14},{"date":"2019-11-05T00:00:00.000Z","utilizationPercentage":86},{"date":"2019-11-06T00:00:00.000Z","utilizationPercentage":71},{"date":"2019-11-07T00:00:00.000Z","utilizationPercentage":43},{"date":"2019-11-08T00:00:00.000Z","utilizationPercentage":57},{"date":"2019-11-09T00:00:00.000Z","utilizationPercentage":29},{"date":"2019-11-10T00:00:00.000Z","utilizationPercentage":29},{"date":"2019-11-11T00:00:00.000Z","utilizationPercentage":57},{"date":"2019-11-12T00:00:00.000Z","utilizationPercentage":57},{"date":"2019-11-13T00:00:00.000Z","utilizationPercentage":57},{"date":"2019-11-14T00:00:00.000Z","utilizationPercentage":43},{"date":"2019-11-15T00:00:00.000Z","utilizationPercentage":43}]
Check the demo code here: https://ideone.com/L2rbVe
To avoid iteration over your inputs several times, getting a bad time complexity, I would suggest using Maps and Sets, so you can find related information efficiently.
I kept your function getDateArray. As you didn't provide its source, I reproduced it. But you may want to use your own:
const channelsResponse = [{id: 372,name: 'Channel 01',lab: 'Fullerton',tests: [3, 4, 7, 8],},{id: 373,name: 'Channel 02',lab: 'Fullerton',tests: [1, 2, 5, 6],},{id: 374,name: 'Beta Channel',lab: 'Fullerton',tests: [],},{id: 472,name: 'Channel 01',lab: 'Queens',tests: [9, 11, 12, 13],},{id: 473,name: 'Channel 02',lab: 'Queens',tests: [15, 17, 19],},{id: 474,name: 'Channel 03',lab: 'Queens',tests: [21, 22, 24, 25],},{id: 475,name: 'Channel 04',lab: 'Queens',tests: [26, 27, 28, 29, 30],},];
const testsResponse = [{id: 1,start: '2019-11-05T11:05:00Z',end: '2019-11-05T13:05:00Z',},{id: 2,start: '2019-11-06T11:05:00Z',end: '2019-11-06T13:05:00Z',},{id: 3,start: '2019-11-04T11:05:00Z',end: '2019-11-04T13:09:00Z',},{id: 4,start: '2019-11-04T17:00:00Z',end: '2019-11-05T09:32:00Z',},{id: 5,start: '2019-11-11T11:05:00Z',end: '2019-11-12T13:05:00Z',},{id: 6,start: '2019-11-12T14:05:00Z',end: '2019-11-15T13:05:00Z',},{id: 7,start: '2019-11-07T11:05:00Z',end: '2019-11-08T13:05:00Z',},{id: 8,start: '2019-11-08T15:05:00Z',end: '2019-11-08T15:35:00Z',},{id: 9,start: '2019-11-05T09:05:00Z',end: '2019-11-08T12:05:00Z',},{id: 11,start: '2019-11-08T12:35:00Z',end: '2019-11-08T13:35:00Z',},{id: 12,start: '2019-11-08T17:00:00Z',end: '2019-11-11T10:00:00Z',},{id: 13,start: '2019-11-11T12:00:00Z',end: null,},{id: 15},{id: 17,start: '2019-11-05T17:00:00Z',end: '2019-11-06T10:00:00Z',},{id: 19,start: '2019-11-06T12:00:00Z',end: '2019-11-06T13:22:00Z',},{id: 21,start: '2019-11-05T09:05:00Z',end: '2019-11-06T12:05:00Z',},{id: 22,start: '2019-11-08T12:35:00Z',end: '2019-11-08T13:35:00Z',},{id: 24,start: '2019-11-11T17:00:00Z',end: '2019-11-15T10:00:00Z',},{id: 25,start: '2019-11-15T12:00:00Z',},{id: 26,start: '2019-11-05T09:05:00Z',end: '2019-11-06T12:05:00Z',},{id: 27,start: '2019-11-07T12:35:00Z',end: '2019-11-07T13:35:00Z',},{id: 28,start: '2019-11-08T17:00:00Z',end: '2019-11-11T10:00:00Z',},{id: 29,start: '2019-11-12T12:00:00Z',end: '2019-11-12T14:00:00Z',},{id: 30,start: '2019-11-13T12:00:00Z',end: '2019-11-13T14:00:00Z',},];
function getDateArray(start, end) {
if (!start || !end) return [];
let date = new Date(start.slice(0,11) + "00:00:00Z");
let last = Date.parse(end.slice(0,11) + "00:00:00Z");
let dates = [date.toJSON()];
while (+date != last) {
date.setDate(date.getDate()+1);
dates.push(date.toJSON());
}
return dates; // array of date-strings
}
// Create two maps for faster retrieval
let mapTestToDates = new Map(testsResponse.map(( { id, start, end }) => [id, getDateArray(start, end)]));
let allDates = [...new Set([...mapTestToDates.values()].flat())].sort();
let mapDateToChannels = new Map(allDates.map(date => [date, new Set]));
// Main data collection loop
for (let channel of channelsResponse) {
for (let test of channel.tests) {
for (let date of mapTestToDates.get(test)) {
mapDateToChannels.get(date).add(channel);
}
}
}
// Finally calculate the percentages
let result = Array.from(mapDateToChannels.entries(), ([date, channels]) =>
({ date, utilizationPercentage: Math.round(channels.size * 100 / channelsResponse.length) })
);
console.log(result);

How to Insert dates if the dates are not there in the array

I have an array with object (date and value), problem is few date objects are missing from that array. I want to full fill that array with every date based on Start Date and End date, also we should consider inner dates, so if a date not exists after one day then that day object should be added after that with the value of null.
I have created a stackblitz for that : https://stackblitz.com/edit/js-pfbcxz
In that code I have added different date objects as well as same date object with different time. I wrote some code but that is not fullfilling my requirement. Only few objects are inserting.
The other solution uses moment.js, but what I will be writing for my solution uses pure, Vanilla JavaScript. Basically, we will be using the while loop to loop through the array, and then we check if there are any difference between the current index's date and the date of the previous index. If there is a difference, we will be adding the dates in between, with a null value on y.
const json_data = [{
x: "2018-06-21T20:30:00Z",
y: 6.39
},
{
x: "2018-07-21T10:30:00Z",
y: 6.39
},
{
x: "2018-07-21T09:30:00Z",
y: 6.39
},
{
x: "2018-08-21T21:30:00Z",
y: 5.93
},
{
x: "2018-09-21T21:30:00Z",
y: 5.93
}
];
const getDates = (startDate, stopDate) => {
const dateArray = [];
let counterDate = startDate;
const stopCounter = new Date(stopDate.setDate(stopDate.getDate() -1));
while (counterDate < stopCounter) {
dateArray.push(counterDate);
counterDate = new Date(counterDate.setDate(counterDate.getDate() + 1));
}
return dateArray;
}
//console.log(getDates(new Date(json_data[0].x),new Date(json_data[1].x)))
let k = 1;
const result = [];
while (k < json_data.length) {
const inBetween = getDates(new Date(json_data[k - 1].x),new Date(json_data[k].x)).map(date => ({
x: date.toISOString(),
y: null
}));
//console.log(inBetween)
if (inBetween.length > 0) {
result.push(json_data[k-1], ...inBetween)
}
if (k === json_data.length - 1) {
result.push(json_data[k]);
}
k++;
}
console.log(result)
Try converting the list of objects to a simple object
and then search the key (date) in the object.
If not found create the key with null
var json_data = [
{x: "2018-06-21T20:30:00.000Z", y: 6.39},
{x: "2018-07-21T10:30:00.000Z", y: 6.39},
{x: "2018-07-21T09:30:00.000Z", y: 6.39},
{x: "2018-08-21T21:30:00.000Z", y: 5.93},
{x: "2018-09-21T21:30:00.000Z", y: 5.93}
];
var obj = json_data.reduce((acc, data) => {
acc[data.x] = data.y;
return acc;
}, {});
var firstDate = new Date(json_data[0].x);
var secondDate = new Date(json_data[json_data.length-1].x);
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var diffDays = Math.round(Math.abs((firstDate.getTime() -
secondDate.getTime())/(oneDay)));
let k=0;
while(k < diffDays) {
let nextDay = new Date(new Date(firstDate).getTime() + (k * oneDay));
if(obj[nextDay] === undefined) {
obj[nextDay.toISOString()] = null
}
k++
}
var res = Object.entries(obj).map(item => ({
x: item[0],
y: item[1],
}));
console.log(res);
You can use moment.js library to do any kind of date operation.
Add days to date
Check a date is same or before another date
Here is the solution using moment.js
var json_data = [
{ x: "2018-06-21T20:30:00Z", y: 6.39 },
{ x: "2018-07-21T10:30:00Z", y: 6.39 },
{ x: "2018-07-21T09:30:00Z", y: 6.39 },
{ x: "2018-08-21T21:30:00Z", y: 5.93 },
{ x: "2018-09-21T21:30:00Z", y: 5.93 }
];
var obj = json_data.reduce((acc, data) => {
acc[data.x] = data.y;
return acc;
}, {});
var start = moment("2018-06-21T20:30:00Z");
var end = moment("2018-09-21T21:30:00Z");
while (start.isSameOrBefore(end)) {
if (obj[start] === undefined) {
obj[start] = null;
}
start = start.add(1, "days");
}
var res = Object.entries(obj).map(item => ({
x: item[0],
y: item[1],
}));
console.log(JSON.stringify(res))

Dynamically created object not populated as expected

I am trying to extract data from one object, restructure and create a new one.
Simplified example for the source object
var res = [{
DateTime: '00:00',
Number: 1,
WeekDay: 1
},
{
DateTime: '00:00',
Number: 4,
WeekDay: 1
},
{
DateTime: '00:00',
Number: 1,
WeekDay: 2
},
{
DateTime: '00:30',
Number: 1,
WeekDay: 2
}]
From here I want to create a new object where "number" is summed by
1. WeekDay
2. Half hour interval
var intervals = ['00:00', '00:30']
var weekdays = [1, 2]
var target = []
var intervalObj = [];
for (i = 0; i < intervals.length; i++) {
intervalObj.push({
interval: intervals[i],
number: 0
})
}
for (i = 0; i < weekdays.length; i++) {
var day = i + 1;
target.push({
day: day,
data: intervalObj,
})
}
And then populate the new object like this:
for(var row in res) {
var dt = res[row].DateTime;
var wd = res[row].WeekDay;
var wdidx = weekdays.indexOf(wd)
var dtidx = intervals.indexOf(dt)
var num = res[row].Number;
target[wdidx].data[dtidx].number += num;
}
This does not work when creating the target object like above. The summed results gets repeated for the same interval over all week days.
However, when object is statically:
var target = [{
day: 1,
data: [{
interval: '00:00',
number: 0
},
{
interval: '00:30',
number: 0
}]
},
{
day: 2,
data: [{
interval: '00:00',
number: 0
},
{
interval: '00:30',
number: 0
}]
}]
It works as expected. I cannot figure out why.
Here is a fiddle example:
https://jsfiddle.net/oceansmoving/wkfL9e3o/
You are using the same array reference intervalObj for data in each instance of loop. Need to create new array for each instance
Change
var intervalObj = [];
for (i = 0; i < weekdays.length; i++) {
var day = i + 1;
target.push({
day: day,
data: intervalObj,
})
}
To
//var intervalObj = [];
for (i = 0; i < weekdays.length; i++) {
var day = i + 1;
target.push({
day: day,
data: [],
})
}

insert date object to json

I have this json which i need to work with amCharts line chart,
var chartData = [{
date: "2009/10/2",
value: 5,
name: 5
}, {
date: "2009/10/3",
value: 15,
name: 5
}, {
date: "2009/10/4",
value: 13,
name: 10
}, {
date: "2009/10/5",
value: 17,
name: 30
}, {
date: "2009/10/6",
value: 15,
name: 5
}, {
date: "2009/10/7",
value: 19,
name: 5
}];
in order to be compatible with amCharts i need to assign date value as a Date object so i did through the following function,
function parseDate(){
for( var i = 0; i < chartData.length; ++i ) {
var dateArray = chartData[i]["date"].split("/");
chartData[i]["date"] = new Date(Number(dateArray[0]), Number(dateArray[1])-1, Number(dateArray[2]));
window.alert(chartData[i]["date"]);//for debugging purposes
}
return chartData;
}
But still i get an empty graph with no lines.. :( but if i hard code the json as follows,
var chartData = [{
date: new Date(2009, 10, 2),
value: 5,
name: 5
}, {
date: new Date(2009, 10, 3),
value: 15,
name: 5
}, {
date: new Date(2009, 10, 4),
value: 13,
name: 10
}, {
date: new Date(2009, 10, 5),
value: 17,
name: 30
}, {
date: new Date(2009, 10, 6),
value: 15,
name: 5
}, {
date: new Date(2009, 10, 7),
value: 19,
name: 5
}];
The chart is displayed ,Please help me on this one.
Thank you very much :)
EDIT: CODE TO GENERATE GRAPH (FYI)
AmCharts.ready(function () {
parseDate();
// SERIAL CHART
chart = new AmCharts.AmSerialChart();
chart.pathToImages = "../amcharts/images/";
chart.zoomOutButton = {
backgroundColor: '#000000',
backgroundAlpha: 0.15
};
chart.dataProvider = chartData;
chart.categoryField = "date";
// listen for "dataUpdated" event (fired when chart is inited) and call zoomChart method when it happens
chart.addListener("dataUpdated", zoomChart);
// AXES
// category
var categoryAxis = chart.categoryAxis;
categoryAxis.parseDates = true; // as our data is date-based, we set parseDates to true
categoryAxis.minPeriod = "DD"; // our data is daily, so we set minPeriod to DD
categoryAxis.dashLength = 2;
categoryAxis.gridAlpha = 0.15;
categoryAxis.axisColor = "#DADADA";
var i = 0;
for (var key in chartData[0]) {
if (key != 'date') {
var valueAxis = new AmCharts.ValueAxis();
valueAxis.offset = i * 40;
valueAxis.dashLength = 4;
valueAxis.axisColor = "#FF6600";
valueAxis.axisAlpha = 0;
chart.addValueAxis(valueAxis);
// GRAPH
var graph = new AmCharts.AmGraph();
graph.valueAxis = valueAxis; // we have to indicate which value axis should be used
graph.type = "line";
graph.title = "infection # " + i;
graph.valueField = key;
graph.customBullet = "images/star.gif"; // bullet for all data points
graph.bulletSize = 14; // bullet image should be a rectangle (width = height)
graph.customBulletField = "customBullet"; // this will make the graph to display custom bullet (red star)
chart.addGraph(graph);
}
i = i + 1;
}
// CURSOR
var chartCursor = new AmCharts.ChartCursor();
chartCursor.cursorPosition = "mouse";
chart.addChartCursor(chartCursor);
// SCROLLBAR
var chartScrollbar = new AmCharts.ChartScrollbar();
chart.addChartScrollbar(chartScrollbar);
// LEGEND
var legend = new AmCharts.AmLegend();
legend.marginLeft = 110;
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
Try this:
function parseDate() {
for( var i = 0; i < chartData.length; ++i )
chartData[i]["date"] = new Date(chartData[i]["date"]);
return chartData;
}

Javascript 'object expected' when working with Google Visualization API

Hey everyone, so I am working on creating a small class to help me work with the Google visualization API. You can see how it works here...
http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html
Here is google's implementation.
google.load('visualization', '1', {'packages':['annotatedtimeline']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Sold Pencils');
data.addColumn('string', 'title1');
data.addColumn('string', 'text1');
data.addColumn('number', 'Sold Pens');
data.addColumn('string', 'title2');
data.addColumn('string', 'text2');
data.addRows([
[new Date(2008, 1 ,1), 30000, undefined, undefined, 40645, undefined, undefined],
[new Date(2008, 1 ,2), 14045, undefined, undefined, 20374, undefined, undefined],
[new Date(2008, 1 ,3), 55022, undefined, undefined, 50766, undefined, undefined],
[new Date(2008, 1 ,4), 75284, undefined, undefined, 14334, 'Out of Stock','Ran out of stock on pens at 4pm'],
[new Date(2008, 1 ,5), 41476, 'Bought Pens','Bought 200k pens', 66467, undefined, undefined],
[new Date(2008, 1 ,6), 33322, undefined, undefined, 39463, undefined, undefined]
]);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(data, {displayAnnotations: true});
Here is the class I made that I am having issues with.
The class makes adding data to the graph a little easier and better for what I am trying to do. Basically, instead of making columns with a bunch of undefined values, the class does it for you, and you don't have to keep track of the location/value of each column.
function GraphManager(dataTable)
{
this.graphData = new Array();
this.dataTable = dataTable;
this.titleFinder = new Object(); // used to keep track of the indices
this.dataTable.addColumn('date', 'Date');
this.addSet = function(title)
{
var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
var place = this.dataTable.getNumberOfColumns();
this.titleFinder[title] = place; //the title of the column and its location
this.dataTable.addColumn('number', title);
this.dataTable.addColumn('string', 'title' + setCount);
this.dataTable.addColumn('string', 'text' + setCount);
}
this.addPoint = function(title, date, number)
{
//this function finds the location of the category
//and inserts a column with data at the location
var place = titleFinder[title]; //get the location
var column = new Array(dataTable.getNumberOfColumns());
column[0] = date;
column[place] = number;
for (var i = 0;i<place; i++)
{
column[i] = undefined;
}
for (var i = place + 1; i<dataTable.getNumberOfColumns(); i++)
{
column[i] = undefined;
}
var next = this.graphData.length;
this.graphData[next] = column;
data.addRows(graphData);
}
}
And then this code can be used to do the same thing with a fewer amount of code.
function printGraph()
{
var data = new google.visualization.DataTable();
var gm = new GraphManager(data);
var title = "testcategory";
gm.addSet(title);
gm.addPoint(title, new Date[2010, 5, 10], 100);
gm.addPoint(title, new Date[2010, 6, 10], 200);
var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(gm.dataTable, {displayAnnotations: true});
}
With this HTML body
<input type="button" onclick="printGraph()" value="Draw Graph">
<div id='chart_div' style='width: 800px; height: 350px;'></div>
The issue: I am getting an "Object expected" error on the line gm.addSet(title). Basically, I am not able to use the class GraphManager. What am I doing wrong here?
Isn't supposed to be "dataTable" instead of "tableData"?
for (var i = place + 1; i<tableData.count; i++)
{
column[i] = undefined;
}
I don't know, as per:
http://code.google.com/apis/visualization/documentation/reference.html#DataTable
count is not an attribute, but I see you referring to it many places in your code:
var column = new Array(dataTable.count)
There is dataTable.getNumberOfColumns() however
Ok, I figured out the problem. Basically I had left out a bunch of "this" statements, and when I created a new date I used a bracket instead of a parentheses. I also realized that when I added a new set of data, I needed to go through the old data to add the empty columns. Here is the finished code if anyone is interested... It's pretty useful if you are adding data at different dates or if you don't know how many data sets you will have.
function GraphManager(adataTable)
{
this.graphData = new Array();
this.dataTable = adataTable;
this.titleFinder = new Object(); // used to keep track of the indices
this.dataTable.addColumn('date', 'Date');
this.addSet = function(title)
{
var setCount = (this.dataTable.getNumberOfColumns() -1) / 3; //used for the column name
var pointsCount = this.graphData.length;
var place = this.dataTable.getNumberOfColumns();
this.titleFinder[title] = place; //the title of the column and its location
this.dataTable.addColumn('number', title);
this.dataTable.addColumn('string', 'title' + setCount);
this.dataTable.addColumn('string', 'text' + setCount);
var newCount = this.dataTable.getNumberOfColumns();
for (var i = 0; i<pointsCount; i++)
{
for (var j=place; j<newCount; j++)
{
this.graphData[i][j] = undefined;
}
}
}
this.addPoint = function(title, date, number)
{
//this function finds the location of the category
//and inserts a column with data at the location
var place = this.titleFinder[title]; //get the location
var column = new Array(this.dataTable.getNumberOfColumns());
column[0] = date;
column[place] = number;
for (var i = 1;i<place; i++)
{
column[i] = undefined;
}
for (var i = place + 1; i<this.dataTable.getNumberOfColumns(); i++)
{
column[i] = undefined;
}
var next = this.graphData.length;
this.graphData[next] = column;
this.dataTable.addRows(this.graphData);
}
}
And its as easy to use as this:
var data = new google.visualization.DataTable();
var gm = new GraphManager(data);
var title = "testcategory";
var title2 = "cat";
gm.addSet(title);
gm.addPoint(title, new Date(2010, 5, 10), 100);
gm.addPoint(title, new Date(2010, 6, 10), 200);
gm.addPoint(title, new Date(2010, 2, 10), 300);
gm.addSet(title2);
gm.addPoint(title2, new Date(2010, 6, 10), 100);
gm.addPoint(title2, new Date(2010, 2, 10), 500);
var chart = newgoogle.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));
chart.draw(gm.dataTable, {displayAnnotations: true});

Categories