Datatable : How to jump to the first empty cell - javascript

I'm using datatable to display predictions about future events. Among my columns I have "Day" "Hour" "Prediction" "Reality".
Prediction is always filled, but reality is only filled when the event happens.
I want to jump to the page corresponding to the current time. So I used jumpToData() on the date. With that, I have quick access to the last events of the current day but I still need to turn 4 or 5 pages if it's 9AM for example.
I think the easiest way to solve the problem is to jump to the first empty cell in the "Reality" column.
Have you any elements to do that ?
Thanks in advance for any help,
Thomas

Is that what you were trying to achieve?:
//Make up random chronological data to fill DataTable
var srcData = [...Array(300)].map((value, index) => {
let obj = {};
let today = new Date()
let randomDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()-10, index);
obj.date = randomDate.toLocaleDateString();
obj.hour = index%24;
obj.prediction = Math.floor(Math.random()*1000);
obj.reality = randomDate < Date.now() ? obj.prediction+(3-Math.floor(Math.random()*6)) : '';
return obj;
});
//Define DataTables object
var dataTable = $('#forecasts').DataTable({
sDom: 'tp',
orderFixed: [[0, 'asc'],[1, 'asc']],
ordering: false,
data: srcData,
columns: [
{title: 'date', data: 'date'},
{title: 'hour', data: 'hour'},
{title: 'prediction', data: 'prediction'},
{title: 'reality', data: 'reality'},
]
});
$('#jumptoblank').on('click', () => {
//Search for empty cell
var emptyRowIndex = dataTable.rows().data().toArray().findIndex(row => row.reality == '');
//Go to the page, where necessary row is located
dataTable.page(Math.floor(emptyRowIndex/dataTable.page.info().length)).draw(false)
});
.dataTables_wrapper {width: 600px}
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script type="application/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="application/javascript" src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
</head>
<body>
<button id="jumptoblank">Jump to blank reality</button>
<table id="forecasts"></table>
</body>
</html>

Related

How to display column headers in Y axis for a Datatable using HighCharts?

I am using Datatables and HighCharts. Please see my code below. I am not sure how to display this bar chart where Years are displayed in Y axis. I have added an image below to show how it looks like.
I am new to HighCharts, so I am not sure of all the functions. Thanks.
How can I get graph to show like this? I want years in Y axis. Thanks.
http://live.datatables.net/febayaxa/1/edit
$(document).ready(function() {
var table = $("#example1").DataTable();
var salary = getSalaries(table);
// Declare axis for the column graph
var axis = {
id: "salary",
min: 0,
title: {
text: "Number"
}
};
// Declare inital series with the values from the getSalaries function
var series = {
name: "Overall",
data: Object.values(salary)
};
var myChart = Highcharts.chart("container", {
chart: {
type: "column"
},
title: {
text: "Test Data"
},
xAxis: {
categories: Object.keys(salary)
},
yAxis: axis,
series: [series]
});
// On draw, get updated salaries and refresh axis and series
table.on("draw", function() {
salary = getSalaries(table);
myChart.axes[0].categories = Object.keys(salary);
myChart.series[0].setData(Object.values(salary));
});
});
function getSalaries(table) {
var salaryCounts = {};
var salary = {};
// Get the row indexes for the rows displayed under the current search
var indexes = table
.rows({ search: "applied" })
.indexes()
.toArray();
// For each row, extract the office and add the salary to the array
for (var i = 0; i < indexes.length; i++) {
var office = table.cell(indexes[i], 0).data();
if (salaryCounts[office] === undefined) {
salaryCounts[office] = [+table.cell(indexes[i], 1).data().replace(/[^0-9.]/g, "")];
}
else {
salaryCounts[office].push(+table.cell(indexes[i], 1).data().replace(/[^0-9.]/g, ""));
}
}
// Extract the office names that are present in the table
var keys = Object.keys(salaryCounts);
// For each office work out the average salary
for (var i = 0; i < keys.length; i++) {
var length = salaryCounts[keys[i]].length;
var total = salaryCounts[keys[i]].reduce((a, b) => a + b, 0);
salary[keys[i]] = total / length;
}
return salary;
};
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<meta charset=utf-8 />
</head>
<body>
<div id="container" style=" width: 100%; height: 400px;"></div>
<div class="container">
<table id="example1" class="display nowrap" width="100%"><thead>
<tr><th>Year</th><th>2012</th><th>2013</th><th>2014</th><th>2015</th><th>2016</th><th>2017</th><th>2018</th><th>2019</th><th>2020</th><th>2021</th></tr></thead>
<tr ><td> Data</td><td>3,823</td><td>3,823</td><td>3,954</td><td>3,959</td><td>3,955</td><td>3,956</td><td>3,843</td><td>3,699</td><td>3,472</td><td>3,551</td></tr></tbody>
</tbody></table>
I am going to assume you mean the x-axis (the horizontal axis) when you say that you want to use the years (from the table headings) from your DataTable for each bar's label in the chart.
You can access these table headings using the DataTables API and some jQuery.
Use this to get an array of table heading elements:
api.columns().header()
And then use $(element).html() to get the label (the year) from each heading.
There is a lot of code in your example in the question which does not appear to be relevant to the chart you want to create, so in the following example, I removed all of that. If it is needed, you can put it back.
$(document).ready(function() {
var tableData = [];
var tableCategories = []
var table = $("#example1").DataTable({
initComplete: function(settings, json) {
let api = new $.fn.dataTable.Api(settings);
// get the seris data as an array of numbers from the table row data:
api.rows().data().toArray()[0].forEach(function(element, index) {
if (index > 0) {
tableData.push(parseFloat(element.replace(/,/g, '')));
}
});
// get the x-axis caregories from the table headings:
api.columns().header().toArray().forEach(function(element, index) {
if (index > 0) {
tableCategories.push($(element).html());
}
});
  
}
});
var myChart = Highcharts.chart("container", {
chart: {
type: "column"
},
title: {
text: "Test Data"
},
xAxis: {
categories: tableCategories
},
series: [{
data: tableData
}]
});
});
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<link href="https://nightly.datatables.net/css/jquery.dataTables.css" rel="stylesheet" type="text/css" />
<script src="https://nightly.datatables.net/js/jquery.dataTables.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<meta charset=utf-8 />
</head>
<body>
<div id="container" style=" width: 100%; height: 400px;"></div>
<div class="container">
<table id="example1" class="display nowrap" width="100%">
<thead>
<tr>
<th>Year</th>
<th>2012</th>
<th>2013</th>
<th>2014</th>
<th>2015</th>
<th>2016</th>
<th>2017</th>
<th>2018</th>
<th>2019</th>
<th>2020</th>
<th>2021</th>
</tr>
</thead>
<tr>
<td> Data</td>
<td>3,823</td>
<td>3,823</td>
<td>3,954</td>
<td>3,959</td>
<td>3,955</td>
<td>3,956</td>
<td>3,843</td>
<td>3,699</td>
<td>3,472</td>
<td>3,551</td>
</tr>
</tbody>
</tbody>
</table>
The output looks like this:
If you do actually want the years labels to be displayed on the y-axis (with horizontal bars, instead of vertical bars) then you can change the chart type by changing this part of the chart...
chart: { type: "column" },
to this:
chart: { type: "bar" },

groupByRowLabel doesn't work on Google Timeline

Currently, My timeline Chart looks like this
but I want to put all bars which is the same country on one row
and I already set
timeline:{groupByRowLabel:true}
in options but it doesn't work
My data from google sheet looks like this
My full code below
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
<script>
google.charts.load('current', {
packages: ["timeline"]
});
google.charts.setOnLoadCallback(drawRegionsMap);
var data1;
function handleQueryResponseTR1(response1) {
if (response1.isError()) {
alert('Error in query: ' + response1.getMessage() + ' ' + response1.getDetailedMessage());
return;
}
data1 = response1.getDataTable();
var view1 = new google.visualization.DataView(data1);
view1.setColumns([{
type: 'string',
id: 'Country',
calc: function(dt, row) {
return dt.getFormattedValue(row, 0)
}
}, 1, 3, 4]);
var chart1 = new google.visualization.Timeline(document.getElementById('colormap1'));
var options1 = {
width: 800,
height: 1600,
timeline: {
groupByRowLabel: true
}
}
chart1.draw(view1, options1);
}
function drawRegionsMap() {
var query1 = new google.visualization.Query("https://docs.google.com/spreadsheets/d/1sOyYwL51uWTd7Pv4Sp_bKdxWmH-g6QA2SDHhw93_2s8/edit?usp=sharing");
query1.send(handleQueryResponseTR1);
}
</script>
<div id='colormap1'> </div>
What you have done is absolutely correct. there is nothing to be added in your code.
timeline:{groupByRowLabel:true}
this will give your labels in same row.
But the problem here is the dataset that ur giving.
All the labels for country(in ur case) will come in same row if and only if date of labels are not overlapping.
say for example, in ur case.
Albania WEEE 7/20/2000 6/6/2017
Albania Batteries 7/20/2015 6/5/2017
See the above dates (end time of WEEE and start time of Batteries) are overlapiing.
if the dates are like
Albania WEEE 7/20/2000 6/6/2016
Albania Batteries 6/6/2016 6/5/2017
check this dates. with this data set ur labels will come in the same row.

Present JSON data in HTML table using JS

I have managed to present JSON data in an HTML table as shown below :
$("#example-table").tabulator({
height:"300px",
fitColumns:true,
tooltips:true,
columns:[
{title:"Month", field:"Month", sorter:"string"},
{title:"Numbers", field:"numbers", width:400, sorter:"string"},
],
});
var sampleData= [
{Month:"January", numbers:"124010"},
]
$("#example-table").tabulator("setData", sampleData);
$(window).resize(function(){
$("#example-table").tabulator("redraw");
});
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js" integrity="sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.rawgit.com/olifolkerd/tabulator/master/tabulator.css">
<script type="text/javascript" src="https://cdn.rawgit.com/olifolkerd/tabulator/master/tabulator.js"></script>
</head>
<body>
<div id="example-table"></div>
</body>
</html>
Now, I am getting the JSON data in a slightly different format. The first format was :
{Month:"January", numbers:"124010"},
{Month:"February", numbers:"545010"}
and now it is :
{"headers":["Month","numbers"],"rows":[["January",124010],["February",545010]]}
So, in a new snippet I tried to parse the data from the JSON data without success :
$("#example-table").tabulator({
height:"300px",
fitColumns:true,
tooltips:true,
columns:[
{title:"Month", field:"Month", sorter:"string"},
{title:"Numbers", field:"numbers", width:200, sorter:"string"},
],
});
var data= {"headers":["Month","numbers"],"rows":[["January",124010],["February",545010]]}
var finaldata = [];
for (var i = 0; i < data.rows.length; i++) {
finaldata.push(data.rows[i][1])
}
$("#example-table").tabulator("setData", finaldata);
$(window).resize(function(){
$("#example-table").tabulator("redraw");
});
<html>
<head>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js" integrity="sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.rawgit.com/olifolkerd/tabulator/master/tabulator.css">
<script type="text/javascript" src="https://cdn.rawgit.com/olifolkerd/tabulator/master/tabulator.js"></script>
</head>
<body>
<div id="example-table"></div>
</body>
</html>
Case 1 :
I might have to make a small change to make the parsing successful but I am pretty stuck here.
Case 2 :
A second though I had was to convert the JSON format to the one used in the first snippet. So, from a multidimensional JSON, I will have a flat one.
Convert this
{"headers":["Month","numbers"],"rows":[["January",124010],["February",545010]]}
to
{Month:"January", numbers:"124010"},
{Month:"February", numbers:"545010"}
Am I missing something? And if it is not possible to change the current script, is it worthy trying to convert the JSON format?
I'm assuming that the headers are fixed. If they are, it's just a simple case of looping through all of the rows and pushing them as a new object.
var unformatted = {
"headers": [
"Month",
"numbers"
],
"rows": [
[
"January",
124010
],
[
"February",
545010
]
]
};
var formatted = [];
for (var i = 0; i < unformatted.rows.length; i++) {
var row = unformatted.rows[i];
formatted.push({
Month: row[0],
numbers: row[1]
});
}
console.log(formatted);
As requested in the comments, if the headers are dynamic and may change in the future, you can use the below code.
var unformatted = {
"headers": [
"Month",
"numbers",
"another_column"
],
"rows": [
[
"January",
124010,
"Hello"
],
[
"February",
545010,
"World!"
]
]
};
var formatted = [];
for (var i = 0; i < unformatted.rows.length; i++) {
var row = unformatted.rows[i],
newObject = {};
for (var j = 0; j < unformatted.headers.length; j++) {
newObject[unformatted.headers[j]] = row[j];
}
formatted.push(newObject);
}
console.log(formatted);

Graph display issue using flot

I'm totally new in flot. At first I want to display three chart(d1, d2, d3) data in the same page and after that when I click on new chart button first chart(d1) will hide and new chart(d4) will insert and three chart(d2,d3,d4) will show and continuing the process. But the problem is that graph is not displaying. If I use random data under a function then it is showing the graph like this but when I tried with different variables, the graph is not showing.
How can I fix this problem?
Here is my code:
<html>
<head>
<title>Graph</title>
<style>
div.placeholder {
width: 400px;
height: 200px;
}
</style>
<script type="text/javascript" src="jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="jquery.flot.js"></script>
<script type="text/javascript">
function getdata(){
var d1 = [[0,1],[1,4],[2,4],[3,8],[4,2],[5,11],[6,19]];
var d2 = [[7,1],[8,5],[9,4],[10,13],[11,2],[12,11],[13,19]];
var d3 = [[14,10],[15,4],[16,14],[17,8],[18,2],[19,1],[20,19]];
var d4 = [[21,4],[22,11],[23,18],[24,12],[25,1],[26,19],[27,8]];
var d5 = [[28,5],[29,14],[30,13],[31,2],[32,11],[33,9]];
}
$(document).ready(function () {
getdata();
var dataset1 = [{
label: "Day1",
data: d1,
points: { symbol: "triangle" }
}];
var dataset2 = [{
label: "Day2",
data: d2,
points: { symbol: "cross" }
}];
var dataset3 = [{
label: "Day3",
data: d3,
points: { symbol: "square" }
}];
var dataset4 = [{
label: "Day4",
data: d4,
points: { symbol: "diamond" }
}];
var dataset5 = [{
label: "Day5",
data: d5,
points: { symbol: "circle", color: "black" }
}];
for(var i = 1, j = 0; i < dataset.length, j < $('div.placeholder').length; i++, j++){
$.plot("div.placeholder:eq("+j+")"),[dataset("+i+")];
}
function update() {
$('div.placeholder:visible:first').hide();
$('div.placeholder:last').after($('<div>').addClass('placeholder'));
$.plot("div.placeholder:last", [getdata()]); 
  }
$('#btn').on('click', update);
});
</script>
</head>
<body>
DAY 1<div class="placeholder"></div>
DAY 2<div class="placeholder"></div>
DAY 3<div class="placeholder"></div>
<input id="btn" type="button" value=" New Chart " />
</body>
</html>
There are multiple of issues with your code, most of which are not specific to Flot:
The d1... arrays are local to the getdata() function and not defined outside of it where you try to use them
You use dataset in your for loop like an array, but there is not such variable defined
Your call of the plot() method makes no sense, you can't access variables like this: $.plot("div.placeholder:eq(" + j + ")"), [dataset("+i+")];
The call to plot() in the update() function tries to use the raw data, not you labeled data (but fails because of point 1 above).
Here is a fiddle with most of the issues fixed. It still does not handle the titles above the charts when updating and gives errors after updating more then two times (when your data is used up).

Dojo Calendar Matrix VIew

I am new in dojo and in js, my question is how can add event to dojo calendar with on clicked method and add exist events by json format to Matrix calendar.
It is part of code but it can't add event and not show Matrix Calendar
but if close this line //store: new Observable(new Memory({data: someData})),
Matrix calendar displayed.
<!DOCTYPE html>
<html >
<head>
<link rel="stylesheet" href="claro.css">
<link rel="stylesheet" href="Calendar.css" />
<script>dojoConfig = {parseOnLoad: true}</script>
<script src='unicorn/js/dojo/dojo.js'></script>
<script>
require(["dojo/parser", "dojo/ready", "dojox/calendar/Calendar"],
function(parser, ready, Calendar){
ready(function(){
require(["dojo/store/Observable", "dojo/store/Memory"], function(Observable, Memory){
var someData = [
{
id: 0,
summary: "Event 1",
startTime: "2015-01-01T10:00",
endTime: "2015-01-01T12:00"
}
];
calendar = new Calendar({
date: new Date(2015, 1, 1),
decodeDate: function(s){
return stamp.fromISOString(s);
},
encodeDate: function(d){
return stamp.toISOString(d);
},
store: new Observable(new Memory({data: someData})),
dateInterval: "day",
style: "position:relative;width:500px;height:500px"
}, "someId");
});
}
)}
);
</script>
</head>
<body class="claro">
<style type="text/css">
.dojoxCalendar{ font-size: 12px; font-family:Myriad,Helvetica,Tahoma,Arial,clean,sans-serif; }
</style>
<div id="someId" >
</div>
</body>
</html>
Thanks
you mean create an event like in the code example by CRTL+clic?
// Enable creation of event interactively by ctrl clicking grid.
var createItem = function(view, d, e){
var cal1 = ActiviteCB.get("checked");
var cal2 = TacheCB.get("checked");
// create item by maintaining control key
if(!e.ctrlKey || e.shiftKey || e.altKey || (!cal1 && !cal2)){
return null;
}
// create a new event
var start, end;
var colView = calendar.columnView;
var cal = calendar.dateModule;
if(view == colView){
start = calendar.floorDate(d, "minute", colView.timeSlotDuration);
end = cal.add(start, "minute", colView.timeSlotDuration);
}else{
start = calendar.floorToDay(d);
end = cal.add(start, "day", 1);
}
var item = {
unid: '',
summary: "New event " ,
startTime: start,
endTime: end,
calendar: cal1 ? "Activite": "Tache",
allDay: view.viewKind == "matrix",
idclient: '',
TypeAction:''
};
return item;
};
calendar.set("createItemFunc", createItem);
Not sure it's want your asked...

Categories

Resources