I have a very basic time series data set of SOI values at monthly intervals from 1950 to 1995.
date soi
1-Dec-94 2.993
1-Nov-94 1.293
1-Oct-94 -1.006
1-Sep-94 -0.80696
1-Aug-94 -1.406
1-Jul-94 -0.20696
1-Jun-94 -2.006
1-May-94 -0.90696
1-Apr-94 -1.806
1-Mar-94 -2.006
1-Feb-94 -1.306
1-Jan-94 -1.306
1-Dec-93 -1.706
1-Nov-93 -1.506
1-Oct-93 0.29374
1-Sep-93 -0.60696
1-Aug-93 1.2937
That is what it looks like.
I want to create a simple Dimple based line graphic. Here is my code:
<div id="chartContainer">
<script type="text/javascript" src="d3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v2.1.2.min.js"></script>
// This loads in dimple and d3 libraries
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer", 1000, 600);
d3.csv("SOI_data.csv", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 800, 550);
var x = myChart.addTimeAxis("x", "date", "%d-%b-%y", "%b-%y");
x.addOrderRule("date");
x.timeInterval = 4;
myChart.addMeasureAxis("y", "soi");
var s = myChart.addSeries(null, dimple.plot.line);
myChart.draw();
});
</script>
</div>
And it executes but with a very odd output. It displays the data from Jan-69 to Dec-94 then has a large gap (with a connecting line between) to Jan-50 and then continues on correctly until Dec-68. All the day is displayed it is just displayed in two halves (with a connecting line). I don't know how to display an image or I would but simply put: The data is being graphed in two chunks out of order for no particular reason. I will include any other information if need be, this is my first stackover flow post, so thanks for any help!
Under the hood dimple is using d3.time.format to parse times. It has to make a choice: is "1-Dec-50", 2050 or 1950? It chooses 2050:
> format = d3.time.format("%d-%b-%y")
> format.parse("1-Dec-50")
Thu Dec 01 2050 00:00:00 GMT-0500 (Eastern Standard Time)
Easiest fix is to modify your source data to include century.
Related
I'm trying to create a spline chart using this CSV:
slave_id,date,time,rtc_temp,temp1,temp2,temp3
1,2017/12/26,16:42:59,21,11.50,13.13,5.88
2,2017/12/26,16:43:29,21,14.13,20.63,99.99
1,2017/12/26,16:44:00,21,11.50,13.13,5.88
2,2017/12/26,16:44:30,21,14.13,20.63,99.99
1,2017/12/26,16:45:01,21,11.50,13.13,5.88
2,2017/12/26,16:45:31,21,14.13,20.63,99.99
1,2017/12/26,16:46:02,21,11.50,13.13,5.88
2,2017/12/26,16:46:32,21,14.13,20.63,99.99
As you can see here [IMAGE], the graph is showing the date and time, but the x Axis is not accepting the date / time.
Ive tried using date.UTC, but that did not work either. Can someone point me in the right direction?
https://jsfiddle.net/asvoy6b9/ [not working due to CSV missing]
Full code [Hastebin]
I see that date variable in your code is a string:
// all data lines start with a double quote
line = line.split(',');
date = line[1] + " " + line[2];
(...)
RTC.push([
date,
parseInt(line[3], 10)
]);
If you choose to construct the point's options as an array of two values and the first value is a string then it's treated as its name property (not x).
Explanation: https://www.highcharts.com/docs/chart-concepts/series
In that case Highcharts assigns subsequent integers as x values for all points (that's why there're values like 00:00:00.000 (1 Jan 1970), 00:00:00.001 etc.).
You need to parse your date to timestamp. You can use Date.UTC() (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) or some other function for this.
I've managed to get it working with Date.UTC using the following code:
var yyyymmdd = line[2].split("-"); //Split the date: 2017 12 16
var hhmmss = line[3].split(":"); //Split the time: 16 11 14
var date = Date.UTC(yyyymmdd[0], yyyymmdd[1] - 1, yyyymmdd[2], hhmmss[0], hhmmss[1], hhmmss[2]); //Stitch 'em together using Date.UTC
I want to display a text string, or a bit of code each day of the week for two weeks, then it will repeat. So through the days it will display Monday 1, Tuesday 1...Friday 1, Monday 2, Tuesday 2...Friday 2. Then it will revert back to Monday 1. If there is a way without using I-frame (have to spell like this so it will let me post the question) from another site then please say. I have tested out with I-frame but it never seems to work. So maybe a counter which when reaching 14 will revert to 1 again. Thank you in advance!
You should be able to achieve it with pure JavaScript using the following:
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
var today = new Date(this.getFullYear(),this.getMonth(),this.getDate());
var dayOfYear = ((today - onejan +1)/86400000);
return Math.ceil(dayOfYear/7)
};
var sentences = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelvth", "thirsteenth", "fourteenth"];
var date = new Date();
var day = (date.getDay()+6)%7+1;
day = day * ((date.getWeek()%2)+1);
document.getElementById("container").innerHTML = sentences[day-1];
Fiddle: https://jsfiddle.net/04wha99e/1/
Using simple JavaScript, you create an array of sentences you wish to have, and basically get the current day of the week (JavaScript Date.getDay() returns Sunday as 0, hence the workaround) and based on the week number being odd or even you multiply it by 1 on 2 getting a range of 1-14 and then return the sentence from the array (starting index 0, hence the minus 1)
The above script assumes, you have a div with the id container, where the inner html gets replaced:
<div id="container">
This is where the sentence goes
</div>
I am using the d3 Timeline plugin (https://github.com/jiahuang/d3-timeline) and I finally got it to where the viz can read my data. However, I now need to make it so that all entries for a particular student show on the same line. The viz is currently displaying each entry separately.
CSV data looks like this:
Start,End,Student,Event Type,tooltip
2015-May-27 20:08:15,2015-May-27 20:08:21,Student 338,Pretest,Student 338 spent 00:00:06 on Biological Chemistry test. Student scored 100%.
2015-May-27 20:08:21,2015-May-27 20:08:30,Student 338,Learning Path,Student 338 spent 00:00:09 on Biological Buffers Website.
2015-May-27 20:08:30,2015-May-27 20:08:34,Student 338,Learning Path,Student 338 spent 00:00:04 on Organic Molecules Textbook.
2015-May-27 20:08:34,2015-May-27 20:08:36,Student 338,Learning Path,Student 338 spent 00:00:03 on Nucleic Acid Structure and Function Textbook 2.
The viz file looks like this:
<script type="text/javascript">
window.onload = function() {
var width = 800;
var height = 700;
var parseDate = d3.time.format("%Y-%b-%d %H:%M:%S").parse; //With parseDate, I define what my time data looks like for d3
d3.csv("https://dl.dropboxusercontent.com/u/42615722/LeaP/biology-course2.csv", function(d){
return {
label : d.Student,
eventType: d["Event Type"],
times:[{"starting_time" : parseDate(d.Start),
"ending_time" : parseDate(d.End)}], //the timeline plugin is looking for a times array of objects with these keys so they must be defined.
info: d.tooltip
};
}, function(data) {
console.log(data);
function timelineRect() {
var colorScale = d3.scale.ordinal().range(['#ed5565','#ffce54','#48cfad','#5d9cec','#ec87c0','#ac92ec','#4fc1e9','#fc6e51','#a0d468','#656d78'])
.domain(['Pretest','Learning Path','Supplemental Info','Questions','Test Me','Remedial Page','Search Query','Recommended Reading','Search Results','Practice Questions']);
var chart = d3.timeline()
.colors( colorScale )
.colorProperty('event_type')
.rotateTicks(45)
.stack(); //necessary to unstack all of the labels
var svg = d3.select("#timeline1").append("svg").attr("width", width)
.datum(data).call(chart);
}
timelineRect();
});
}
</script>
</head>
<body>
<div>
<div id="timeline1"></div>
</div>
</body>
None of the examples define domain for this and, unfortunately, all of the example data is given in arrays, instead of from a CSV. How can I define the data so that each entry with the same student label will appear on the same timeline row?
Problem 1
You are not grouping your csv data this can be done like this:
What I mean is
//this will do the grouping
var k = d3.nest()
.key(function(d) {
return d.label;
}).entries(data);
var b = [];
//this will make it in the format expected by d3 time line
k.forEach(function(d) {
var ob = {};
ob.label = d.key;
ob.times = [];
b.push(ob);
d.values.forEach(function(v) {
ob.times.push(v.times);//collecting all the times
});
ob.times = [].concat.apply([], ob.times);
});
Problem 2
You have to define the tick format
.tickFormat({
format: d3.time.format("%d-%m"),
tickTime: d3.time.day,
tickInterval: 20,
tickSize: 6
})
Refer this for d3 time format
Your data set is very close on seconds and so the rectangle are coming very small..:( i tried my level best to span it up.. best of luck with it :)
Working code here
Hope this helps!
I've made this simple line chart in d3, but as well as showing the tooltip data for mouseover, I would also like to display the data for where the blue dotted line of the tooltip intersects with the data path in the first instance.
For intsance at the link below, if the mouse hovers at 2012, data for 2005 would show at the first intersection between the tooltip line and the data path.
http://bl.ocks.org/anonymous/49f04076adbec7e2c2f9
Any ideas? Thanks
In the linked example, you would want to search for months with CPI intervals that contain the CPI value that is currently displayed. So, create a list of such intervals, with references to the month that contains them, then find matching intervals on hover.
Something like this, for example (untested):
// after loading data
var cpi_intervals = [];
data.forEach(function(d, i) {
if (i > 0) {
cpi_intervals.push({
cpis: d3.extent([data[i-1].cpi, d.cpi]),
date: d.date
});
}
});
...
// function to find months containing specified cpi
function monthsContainingCPI(cpi) {
return cpi_intervals.filter(function(d) {
return cpi >= d.cpis[0] && cpi < d.cpis[1];
}).map(function(d) {return d.date;})
}
If needed, you can improve the performance of the monthsContainingCPI function by using a more complex data structure, like an interval tree, to store and access the CPI intervals.
There is an element that get updates using DWR comet command in server side
Like this
Util.setValue("newnumber", number);
So in Client Side I can get it like in simple command like
<div id = newnumber></div>
Now I want to add the data in HighCharts' live chart. My question is there any event command that says that the "newnumber" value is updated so that I can add the new data in highchart series?
Ok, I figured it out.
The only way to get value in dwr
var xx = dwr.util.getValue(newnumber);
And I used periodic function to get latest value add in series of Highcharts
setInterval(function() {
var yy = parseInt(xx);
var x = (new Date()).getTime(), // current time
y = yy;
series.addPoint([x, y], true, true);
}, 1000);