I have this code that draws a d3js multichart object, the value time:Years values are given in this format Year=2011...
with this time format the code works fine but once I wanted to change the data time in this format Year=(Y-M-D H:M:S)
var data = [{"Year":"2011-10-01 20:46:04","Happy":"63.4","Sad":"42.7","Angry":"12.2","Surprised":"44.2"},
{"Year":"2012-10-01 17:02:04","Happy":"75.4","Sad":"32.7","Angry":"78.2","Surprised":"82.2"},
{"Year":"2013-10-01 19:55:44","Happy":"73.4","Sad":"20.7","Angry":"92.2","Surprised":"75.4"}];
I parsed the data Year:
var parseDate=d3.time.format("%Y-%m-%d %H:%M:%S").parse; //line 13
d.Year=parseDate(d.Year); //and then line 53
But it is not working, how can I read data Year in this format:(Y-M-D H:M:S)
The problem in your example is that you're converting all properties of the objects to numbers. This works if the date is just the year, but not if it is a string that needs to be parsed. In your case, you don't need to do this conversion anyway because you can give the numbers as numbers rather than strings directly. That is, you don't need
for(var prop in d) {
if(d.hasOwnProperty(prop)) {
d[prop] = parseFloat(d[prop]);
}
}
Working jsfiddle with the conversion code removed here.
Related
If I had an array of dates, is there a way I could match up another date by rounding up until one is matched?
For example, say I have an array of dates:
"2022-09-15"
"2022-10-10"
"2022-12-01"
And I have a date pulled from the application: "2022-09-29", I want the date to update itself by rounding up until the next upcoming date ("2022-10-10") is selected.
I am unsure how I would round up like I could in mathematics situations.
Assuming your dates are in order, you can iterate through your array starting at the beginning until you find the first date that is bigger than you date provided by the application. In JavaScript, your can do a direct comparison like this:
"2022-09-15" > "2022-10-10" // false
"2022-09-15" < "2022-10-10" // true
Note that this works because of the ordering of the year, month, and day that you have presented. If you wanted to do comparisons where you had day, month, year, you would want to create a Date JavaScript object and do the comparisons that way. You can read more about those here: Compare two dates with JavaScript
But for your use case, a simple loop could look like this:
for(let i = 0; i < array.length; i++) {
if(applicationDate < array[i])
return array[i]
}
You don't necessarily need to "round" the dates up. Incrementing the date and comparing it to every entry in the array until you find a match would take a relatively large amount of time and resources. I prefer a kind of "knock-out" approach to problems like this. Simply rule out everything it can't be until you're left with a single option. In this case, since you specifically need a date that comes after the input date, we can first rule out anything before the input date. We can then take this new list of dates (that we now know are all after the input date) and get the "smallest" one. This will effectively give you the date that is closest to the input date but still after it.
In your question you presented the dates as a list of strings. This isn't a huge deal because this can still be fairly easily accomplished, but the strings must be in a format that JavaScript recognizes as a date, otherwise all comparisons will result in false. Here is a list of the valid date formats.
I personally like to avoid depending on the order of arrays just because it can be hard to maintain and if/when it breaks, it's generally very hard to find that the issue is that the array is out of order (speaking from experience here). For this reason, the code examples provided here will be completely unreliant on the order of the array.
First, let's discuss a solution using Date objects. This is fairly straight forward. The only thing is that you would need to make sure the date being input is in a valid format as discussed previously. Keep in mind the input needs to be converted to a Date object (if it isn't already) because comparisons between date strings and Date objects always return false. To get only dates after the current date, we can use Array.prototype.filter(), and to get the "smallest" date afterwards we can use Math.min.apply() as explained in this Stack Overflow answer.
var dates = [
new Date("2022-09-15"),
new Date("2022-10-10"),
new Date("2022-12-01")
];
var inputDate = new Date("2022-09-29");
var datesAfter = dates.filter(x => x > inputDate);
var closestDate = new Date(Math.min.apply(null,datesAfter));
console.log(closestDate);
Now for date strings. The idea is largely the same as Date objects. The only difference really is that we can't use Math.min.apply() on date strings. We can however use Array.prototype.reduce() in order to compare all the dates, it's just a bit more involved.
var dates = [
"2022-09-15",
"2022-10-10",
"2022-12-01"
];
var inputDate = "2022-09-29";
var datesAfter = dates.filter(x => x > inputDate);
var closestDate = dates.reduce((a, b) => a > b ? a : b);
console.log(closestDate);
I am encountering a problem with my chart created with HighCharts (StockChart), and more precisely with the dates which do not apply for certain data series and are set by default in 1970.
I get the data from ajax request and I create my data series with the Highchart format as below:
data.forEach(element => {
var d = new Date(Date.parse(element[0]));
console.log("d : " + d);
timestampData.push([d, element[1]]);
});
console.log(timestampData);
timestampData = timestampData.sort((a, b) => a[0] - b[0]);
chart.series[0].setData(timestampData, true);
And here is the result for both cases the date format is exactly the same and yet the date applies for one series but not for the other
Here the date works
Here the date is to 1970 but when can see the date result in console is to 2019
This is strange because nothing is done differently for the two series and the conversion to Date format is good for the two series
About the logged dates, it's hard to debug without knowing the value of element iterator, but Date.parse() can have ambiguous results, depending on the format of its argument.
In general, my advice is to use js millisecond timestamps instead of Date objects like so:
data.forEach(element => {
var d = new Date(Date.parse(element[0]));
timestampData.push([d.valueOf(), element[1]]);
});
It's more universal and highcharts responds fine to it.
This is my data format:
"21/03/2019 19:18"
The problem i am facing is, when ever if i am dealing with date or time there is an issue with the month ( it has 03 instead of 3 ). I am using library called date-fns. And also i have tried with the help of javascript date objects without using library, but no luck still the month should not have zero in-front of it.
So, how to remove the "0" in-front of "3", and one more problem is how to do this conditionally , because when its Dec, i will be getting data as "21/12/2019 19:18". So, in this case , i should not remove "1" as its located in same position of "0" in previous scenario.
In other words, i want to remove "0" by checking if there is "1" presented in that position or index, if presented then remove else remove "0"
How to achieve this.
I tried the below code:
const d = new Date(2019,03,21)
But, its says legacy error. So when i removed "0" infront of "3" it works fine. Please help
I assume you get the data back as a string and you just want to remove leading zeros from the 2nd number only?
we can use .split to break up the string into parts, and then we can use parseInt to convert some string parts into numbers. that will turn the string "03" into the number 3
function removeleadingZerosFromDateString(str) {
//Break up the date string on the slashes and whitespace, so we have an array of all the parts
var parts = str.split(/\/|\s/);
console.log(parts);
//Assign each array item to a variable so we can see what is what
var day = parseInt(parts[0], 10);
var month = parseInt(parts[1], 10);
var year = parts[2];
var time = parts[3];
var meridian = parts[4];
return day+'/'+month+'/'+year+' '+time+' '+meridian;
}
var result = removeleadingZerosFromDateString("21/03/2019 19:18 PM");
console.log(result);
You said you were using date-fns, so I'll give an answer in that regard.
The current 1.x version doesn't support parsing strings in a custom format, but they are adding that to 2.x, and you can use the alpha release to try it today.
The syntax is:
var date = parse(dateString, formatString, baseDate, [options]);
See the documentation for the parse function in version 2.0.0-alpha.27.
In your case, it would be like this:
var date = parse("21/03/2019 19:18", "MM/dd/yyyy HH:mm", new Date());
Lastly, if you want to use a library for this but don't want to experiment with an alpha, you can either wait for Date-fns 2.0 to become final, or you can try Luxon or Moment - both of which already have this functionality (though Moment uses a slightly different token format "MM/DD/YYYY HH:mm").
I am parsing 2 different date strings
var d1 = '2014-02-01T00:00:00.000+0530'
var d2 = '2014-02-23T00:00:00.000+0530'
when i parse them using moment
alert(moment(d1, 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"').toDate());
alert(moment(d2, 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"').toDate());
both of them print Sat Feb 1 2014 xxxxx
what is wrong with it??
here is the link to the fiddle i created
jsfiddle
I think your moment formatting string is causing you the problem. If I remove this, the dates do not print as the same.
http://jsfiddle.net/K5ub8/7/
EDIT: The specific issue is you are using dd for day, instead of DD. http://momentjs.com/docs/#/parsing/string-format/
Here is your fiddle fixed:
http://jsfiddle.net/K5ub8/9/
However, I am not 100% sure about the fractional seconds, I believe it is SSS instead of fffffff but I would test this if you need to cater for fractional seconds.
I should mention that if you are converting it back into a JavaScript date object anyway with toDate(), then you don't really need the moment formatting parameter as the date will be formatted in JSON Date format.
I would question why you would want to generate a moment formatted date, and then convert it back to JavaScript, a normal practice might be to receive a date in JavaScript format, then create a moment object which you can use to perform calculations and display in a nice user friendly way.
Simple answer: your format was off a bit.
http://jsfiddle.net/K5ub8/8/
After tweaking the format to be 'YYYY-MM-DDTHH:mm:ss.SSSZZ' rather than 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"' it worked just fine. When you're trying to debug issues like this, it's always good to keep the format in a separate variable so you can use the same format that you're trying to parse out to display what you're getting. Had you done that, you would have noticed that 'YYYY-MM-dd"T"HH:mm:ss.fffffff"Z"' was messed up due to it printing out 2014-01-Fr"T"11:32:03.fffffff"-08:00". Which obviously isn't quite right.
how can i remove the time from the date when shown on the highchart.the data (dates) are received from a twitter get request and saved into an array.
for (var i in array) {
dateArray.push(array[i].date);
}
highchart(dateArray);
an example of date shown on the graph: Sat,04 Aug 2012 19:35:02 +0000
The way I see it you have two options:
Only pass in the day value of the time for your categories. Involves processing on the backend.
Pull your data as-is and convert to Javascript time format, make your xAxis datetime type, set up your tickInterval to be one day, and run your chart.
Without know what your data looks like, what you are plotting on the yAxis, or what your expected outcome is it is really hard to say.
I recommend to go with option #2 because this is time based data.
EDIT: Based on your comments
You can first convert the string to a date object, and then format the date object to your liking using SimpleDateFormat.
SimpleDateFormat format = new SimpleDateFormat("EEE, MMM d yyyy");
String formattedDate = format.format(new Date(array[i].date));
dateArray.push(formattedDate);
You can find various date formats # http://blog.stevenlevithan.com/archives/date-time-format