I am using DateRangePicker for dates. I was trying to disable if the date selected was < 3 days by setting min date to current date + 3 days as below.
$(document).ready(function() {
const today = new Date();
// Add 3 days to the current date to get the minimum selectable date
const minDate = new Date();
minDate.setDate(today.getDate() + 3);
$('input[name="check_in"]').daterangepicker({
opens: 'right',
autoUpdateInput: false,
locale: {
cancelLabel: 'Clear'
},
autoApply: true,
minDate: minDate,
isInvalidDate: function(startDate, endDate) {
// Calculate the duration of the selected date range in days
const duration = Math.abs(endDate - startDate) / (1000 * 60 * 60 * 24);
// Return true if the duration is less than 3 days
return (duration < 3);
},
}, function(start, end, label) {
$('input[name="check_in"]').val(start.format('YYYY-MM-DD'));
$('input[name="check_out"]').val(end.format('YYYY-MM-DD'));
});
$('input[name="check_out"]').click(function() {
$('input[name="check_in"]').trigger('click');
});
});
this my code but not working
i want to display like this
enter image description here
Related
I have 2 input boxes, beginDate and endDate, that when clicked, allows the user to select a range of dates with flatpickr.
I would like both textboxes to display the same date ranges where beginDate is populated with the minDate
and endDate is populated with maxDate. Ideally, I would like to have both boxes refer to the same instance of flatpickr, with
the selected date range persisted for both. Currently I have:
let resultMax;
$("#BeginDate").flatpickr({
mode: 'range',
dateFormat: "Y-m-d",
onOpen: function (selectedDates, dateStr, instance) {
instance.set('minDate', new Date(new Date().getTime()));
},
onClose: function (selectedDates, dateStr, instance) {
resultMin = new Date(new Date(selectedDates[0]).getTime());
resultMax = new Date(new Date(selectedDates[1]).getTime());
instance.set('selectedDates', resultMax);
}
});
$("#EndDate").flatpickr({
minDate: resultMin,
maxDate: resultMax,
mode: "range",
onOpen: function (selectedDates, dateStr, instance) {
const ONE_MINUTE_AGO = new Date(new Date().getTime());
instance.set('minDate', resultMin);
instance.set('maxDate', resultMax);
instance.set('selectedDates', resultMax);
instance.jumpToDate(resultMax);
},
onClose: function (selectedDates, dateStr, instance) {
instance.set('minDate', resultMin);
instance.set('maxDate', resultMax);
instance.set('selectedDates', resultMax);
instance.jumpToDate(resultMax);
}
});
This doesn't quite work. When BeginDate is selected first and the date range is set, those date are picked up with EndDate, although the dates are displayed
in bold instead of a shaded range.
I am trying to display a stacked bar chart with dates as xAxis. it display the number of sport session by type of sport.
The idea is to have for a specific time range the number of sessions displayed. For example for the last 4 weeks, the number of sessions per day will be displayed, and for the last 12 weeks, it will display the number of sessions per week.
These values are being calculated and displayed fine. The issue is that they are displayed as a 1px wide bar, instead of a "wide" automatically calculated bar width.
If someone have an idea how this fix this kind of issue... please help!
Data are structured as follows. I only show concerned data
const sessions_summary = [
{
activity_name: 'regular_biking',
date_time: '2020-03-18T15:57:47.853Z',
// ...
},
{
activity_name: 'swimming',
date_time: '2020-03-18T15:57:47.853Z'
},
{
activity_name: 'running',
date_time: '2020-03-19T15:57:47.853Z'
},
// ...
];
Crossfilter:
const ndx = crossfilter(sessions_summary);
const Dimension = ndx.dimension(function(d) {
return d3.timeDay(new Date(d.date_time));
});
Scaletime:
const today = new Date(new Date().toDateString());
const minDate = d3.timeDay(
new Date(
new Date().setDate(
today.getDate() - parseFloat(timeranges[timerange_name]) // 7 or 30 or 90 or 180 or 360 : number of days, depends on the interval selected in Select Entry
)
)
);
let maxDate = d3.timeDay(today);
maxDate = d3.timeDay.offset(maxDate, 1);
const scaletime = d3.scaleTime().domain([minDate, maxDate]);
Chart.x(scaletime);
const interval = intervals[timerange_name]; // d3.timeDay or d3.timeWeek or d3.timeMonth, depending on the choice made in Select Entry
Chart.xUnits(interval);
Group:
const types = [...new Set(sessions_summary.map(session => session.type))];
Group = Dimension.group(function(k) {
return interval(k);
}).reduce(
function(p, v) {
if (v.type in p.types) {
p.types[v.type]++;
} else {
p.types[v.type] = 1;
}
return p;
},
function(p, v) {
p.types[v.type]--;
if (p.types[v.type] === 0) {
delete p.types[v.type];
}
return p;
},
function() {
return {
types: {}
};
}
);
Chart.group(Group, types[0], sel_stack(types[0])).render();
for (let i = 1; i < types.length; i++) {
Chart.stack(Group, types[i], sel_stack(types[i]));
}
Bar Chart:
const Chart = dc.barChart('#sessions_chart');
Chart.width(968)
.height(240)
.elasticY(true)
.margins({
left: 40,
top: 10,
right: 20,
bottom: 40
})
.gap(5)
.centerBar(true)
.round(d3.timeDay.round)
.alwaysUseRounding(true)
.xUnits(d3.timeDays)
.brushOn(false)
.renderHorizontalGridLines(true)
.renderVerticalGridLines(false)
.dimension(Dimension)
.title(d => {
return (
'Date: ' +
new Date(d.key).toDateString() +
'\n' +
'Sessions: ' +
Object.keys(d.value.types)
);
});
Chart.legend(
dc
.legend()
.x(40)
.y(465)
.gap(10)
.horizontal(true)
.autoItemWidth(true)
);
Chart.render();
Complete code can be found on JSFiddle
Thanks in advance
[SOLVED]
The issue was the double xUnits, and the wrong use of d3.TimeDay instead of d3.TimeDays.
I've been trying to create a dc.js rowchart showing stats per day, my dimension and group are
var dayNameFormat = d3.time.format("%A");
var weekDayFormat = d3.time.format('%w'); //weekday as a decimal number [0(Sunday),6].
var dayOfWeek = ndx.dimension(function(d) {
return weekDayFormat(d.date) + '.' + dayNameFormat(d.date);
});
var dayOfWeekGroup = dayOfWeek.group().reduce(
function(p, d) {
++p.count;
p.totalPoints += +d.points_per_date;
p.averagePoints = (p.totalPoints / p.count);
if (d.student_name in p.studentNames) {
p.studentNames[d.student_name] += 1
} else {
p.studentNames[d.student_name] = 1;
p.studentCount++;
}
return p;
},
function(p, d) {
--p.count;
p.totalPoints -= +d.points_per_date;
p.averagePoints = (p.totalPoints / p.count);
if (p.studentNames[d.student_name] === 0) {
delete p.studentNames[d.student_name];
p.studentCount--;
}
return p;
},
function() {
return {
count: 0,
totalPoints: 0,
averagePoints: 0,
studentNames: {},
studentCount: 0
};
});
and chart
dayOfWeekChart
.width(250)
.height(180)
.margins({
top: 20,
left: 20,
right: 10,
bottom: 20
})
.dimension(dayOfWeek)
.group(dayOfWeekGroup)
.valueAccessor(function(d) {
return d.value.totalPoints
})
.renderLabel(true)
.label(function(d) {
return d.key.split('.')[1] + '(' + d.value.totalPoints + ' points)';
})
.renderTitle(true)
.title(function(d) {
return d.key.split('.')[1];
})
.elasticX(true);
I expected the results to match those of my database query
The total values are correct, but the days have been offset by a day (Sunday has Monday's total)
My fiddle https://jsfiddle.net/santoshsewlal/txrLw9Lc/
I've been doing my head in trying to get this right, any help will be great.
Thanks
It appears to be a UTC date/time problem. Dealing with data from multiple time zones is always confusing!
All of your timestamps are very near to the next day - they are all timestamped at 22:00. So it depends on the timezone which day they should be interpreted as. I guess you might be in the eastern hemisphere, which adds a couple of hours to these timestamps when you read them in your spreadsheet?
You're chopping off the time with substr:
d.date = dateFormat.parse(d.activity_date.substr(0, 10));
I'd suggest trying to parse the whole time instead:
var dateFormat = d3.time.format('%Y-%m-%dT%H:%M:%S.%LZ');
data.forEach(function(d, i) {
d.index = i;
d.date = dateFormat.parse(d.activity_date);
However, I'm no expert in timezones so I can't promise anything. Just pointing out where the problem likely lies.
I am using google API to create charts. I am able to create OHLC(Candlestick) charts. But I want to add an overlay of Moving Average to it. Can anyone please guide me as to how I can do it?
Thanks in advance.
Here's an example of how to add a moving average line to a CandlestickChart:
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Low');
data.addColumn('number', 'Open');
data.addColumn('number', 'Close');
data.addColumn('number', 'High');
var low, open, close = 45, high;
for (var i = 0; i < 30; i++) {
open = close;
close += ~~(Math.random() * 10) * Math.pow(-1, ~~(Math.random() * 2));
high = Math.max(open, close) + ~~(Math.random() * 10);
low = Math.min(open, close) - ~~(Math.random() * 10);
data.addRow([new Date(2014, 0, i + 1), low, open, close, high]);
}
// use a DataView to calculate an x-day moving average
var days = 5;
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, 2, 3, 4, {
type: 'number',
label: days + '-day Moving Average',
calc: function (dt, row) {
// calculate average of closing value for last x days,
// if we are x or more days into the data set
if (row >= days - 1) {
var total = 0;
for (var i = 0; i < days; i++) {
total += dt.getValue(row - i, 3);
}
var avg = total / days;
return {v: avg, f: avg.toFixed(2)};
}
else {
// return null for < x days
return null;
}
}
}]);
var chart = new google.visualization.ComboChart(document.querySelector('#chart_div'));
chart.draw(view, {
height: 400,
width: 600,
chartArea: {
left: '7%',
width: '70%'
},
series: {
0: {
type: 'candlesticks'
},
1: {
type: 'line'
}
}
});
}
google.load("visualization", "1", {packages:["corechart"], callback: drawChart});
see it working here: http://jsfiddle.net/asgallant/74u6ox8b/
I am using Cal-HeatMap:
cal.init({
data: "data/datas.json",
domain: "day", // Group data by days
subDomain: "hour", // Split each day by hours
range: 10, // Number of days to display
browsing: true,
cellSize: 15,
highlight: ["now"],
previousSelector: "#previousSelector-a-previous",
nextSelector: "#previousSelector-a-next",
subDomainTextFormat: function (date, value) {
return value;
},
onClick: function (date, count) {
alert("Oh gosh, " + count + " things occured on " + date.toISOString());
}
});
How can I update using JSON, I did this:
cal.update("data/datas.js");
cal.options.data = "data/datas.json";
cal.next();
I hit an error at:
var c=new Date(a.getFullYear(),a.getMonth(),a.getDate(),a.getHours())
Error:
Unable to get property for getFullYear()....