score:2

Accepted answer

The circles are in the correct position.

You intuitively answered your question when you asked "Should I change the shape of my lines?". Yes, you should. The problem is that the "basis" interpolation doesn't intercept the data points. For instance, have a look at this figure (from v5 API, but the principle is the same):

enter image description here

You can see that the line doesn't cross all the points.

The solution* is changing the interpolation. For instance:

.interpolate("monotone")

Here is the snippet with that change:

//set the screen dimensions
var margin = {top: 20, right: 200, bottom: 150, left: 50},
	margin2 = { top: 430, right: 10, bottom: 20, left: 40 },
	width = 1600 - margin.left - margin.right,
	height = 600 - margin.top - margin.bottom,
	height2 = 500 - margin2.top - margin2.bottom;

// Time Parser with the format exemple of the datalog
var parseTime = d3.time.format("%m/%d/%Y %H:%M:%S %p").parse;
var bisectDate = d3.bisector(function(d) { return d.log_time; }).left;

var xScale = d3.time.scale()
	.range([0, width]),

	xScale2 = d3.time.scale()
	.range([0, width]); // Duplicate xScale for brushing reference

var yScale = d3.scale.linear()
	.range([height, 0]);

// 40 Custom DDV colors 
var color = d3.scale.ordinal().range(["#48A36D",  "#56AE7C",  "#64B98C", "#72C39B", "#80CEAA", "#80CCB3", "#7FC9BD", "#7FC7C6", "#7EC4CF", "#7FBBCF", "#7FB1CF", "#80A8CE", "#809ECE", "#8897CE", "#8F90CD", "#9788CD", "#9E81CC", "#AA81C5", "#B681BE", "#C280B7", "#CE80B0", "#D3779F", "#D76D8F", "#DC647E", "#E05A6D", "#E16167", "#E26962", "#E2705C", "#E37756", "#E38457", "#E39158", "#E29D58", "#E2AA59", "#E0B15B", "#DFB95C", "#DDC05E", "#DBC75F", "#E3CF6D", "#EAD67C", "#F2DE8A"]);  


var xAxis = d3.svg.axis()
	.scale(xScale)
	.orient("bottom"),

	xAxis2 = d3.svg.axis() // xAxis for brush slider
	.scale(xScale2)
	.orient("bottom");    

var yAxis = d3.svg.axis()
	.scale(yScale)
	.orient("left");  

var line = d3.svg.line()
	.interpolate("monotone")
	.x(function(d) { return xScale(d.log_time); })
	.y(function(d) { return yScale(d.temperature); })
	.defined(function(d) { return d.temperature; });  // Hiding line value defaults of 0 for missing data

var maxY; // Defined later to update yAxis

var svg = d3.select("body").append("svg")
	.attr("width", width + margin.left + margin.right)
	.attr("height", height + margin.top + margin.bottom) //height + margin.top + margin.bottom
  .append("g")
	.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// Create invisible rect for mouse tracking
svg.append("rect")
	.attr("width", width)
	.attr("height", height)                                    
	.attr("x", 0) 
	.attr("y", 0)
	.attr("id", "mouse-tracker")
	.style("fill", "white"); 

var data = {"Header":{"add_data":"N/A","add_data_2":"N/A","add_data_3":"N/A","device_type":"PCU12_r7p1_ELFR","diags":"PCU12_r7p1_72h.s19"
,"entered_qty":"84","file_path":"C:\\Winapps\\MBI\\logs\\PCU12\\248649_7_PCU12_M2_ELFR72H_DriverMonitor.log","found_qty":"84","infos_system":"System ZFR11-CC3-11 MBI Burn In Wizard 6.8.10 - ","lot_ID":"248649_7_PCU12_M2_ELFR72H"
,"start_log_date":"4/13/2018 08:31:28 AM","system_version":"6.8.10"},"Session_test":[{"datas_lines":[{"bib":"No data","bin2_tests":{},"datas_line":[],"driver":"No data","error_code":"No data","log_time":"No data","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{"5":[]},"slot":"No data","start_time":"No data"},{"bib":"No data","bin2_tests":{},"datas_line":[],"driver":"No data","error_code":"No data","log_time":"No data","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{"7":[]},"slot":"No data","start_time":"No data"},{"bib":"01074601150135","bin2_tests":{},"datas_line":["169","170","169","169","169","168","168","170","170","170","171","169","170","167","169","169","169","169","168","168","168","168","168","168","169","167","167","166"],"driver":"00000000000000","error_code":"120","log_time":"4/13/2018 8:37:45 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"3","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150140","bin2_tests":{},"datas_line":["169","169","169","170","168","168","167","169","169","169","170","170","169","167","168","168","169","170","168","170","167","169","169","170","170","170","169","167"],"driver":"00000000000000","error_code":"120","log_time":"4/13/2018 8:37:47 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"5","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150129","bin2_tests":{},"datas_line":["169","169","167","167","167","167","165","170","170","169","169","167","167","165","168","168","170","168","168","167","165","167","169","169","168","167","166","165"],"driver":"00000000000000","error_code":"120","log_time":"4/13/2018 8:37:50 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"7","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150135","bin2_tests":{},"datas_line":["170","171","171","172","171","169","169","171","171","172","173","171","171","168","171","171","171","171","170","169","168","168","169","169","170","168","168","167"],"driver":"00000000000000","error_code":"122","log_time":"4/13/2018 8:40:06 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"3","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150135","bin2_tests":{},"datas_line":["173","174","174","175","174","172","172","173","174","174","176","173","175","171","173","174","173","174","173","172","171","171","172","172","173","171","171","169"],
"driver":"00000000000000","error_code":"123","log_time":"4/13/2018 8:40:06 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"3","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150135","bin2_tests":{},"datas_line":["172","174","173","174","173","172","171","173","173","174","175","173","174","170","172","173","173","173","172","172","171","170","171","171","172","170","170","169"],"driver":"00000000000000","error_code":"124","log_time":"4/13/2018 8:40:06 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"3","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150135","bin2_tests":{},"datas_line":["170","172","171","172","171","170","169","171","171","171","173","171","172","168","170","171","170","171","170","169","168","168","169","169","170","168","169","167"],"driver":"00000000000000","error_code":"125","log_time":"4/13/2018 8:40:07 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"3","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150140","bin2_tests":{},"datas_line":["170","171","171","172","170","170","168","171","171","171","173","173","171","169","168","170","171","172","170","171","168","169","170","171","172","171","170","168"],"driver":"00000000000000","error_code":"122","log_time":"4/13/2018 8:40:08 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"5","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150140","bin2_tests":{},"datas_line":["173","174","174","175","173","173","171","174","173","174","175","175","174","172","171","172","173","175","173","174","171","172","173","174","174","174","173","171"],"driver":"00000000000000","error_code":"123","log_time":"4/13/2018 8:40:09 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"5","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150140","bin2_tests":{},"datas_line":["173","173","173","174","173","173","170","173","173","173","175","175","174","171","171","171","173","175","172","174","170","171","172","174","173","174","172","170"],
"driver":"00000000000000","error_code":"124","log_time":"4/13/2018 8:40:09 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"5","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150140","bin2_tests":{},"datas_line":["170","171","171","172","171","171","168","171","170","170","173","173","171","169","169","169","171","172","170","172","168","169","170","172","172","172","170","168"],"driver":"00000000000000","error_code":"125","log_time":"4/13/2018 8:40:09 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],
"nrds":{},"slot":"5","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150129","bin2_tests":{},"datas_line":["172","171","170","171","171","170","168","172","172","172","172","171","170","167","169","170","173","171","170","170","167","168","170","171","170","169","168","167"],"driver":"00000000000000","error_code":"122","log_time":"4/13/2018 8:40:11 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"7","start_time":"4/13/2018 8:32:57 AM"},{"bib":"01074601150129","bin2_tests":{},"datas_line":["174","174","173","174","174","172","170","175","174","174","174","173","173","170","172","173","175","174","173","173","170","171","173","173","173","172","171","169"],"driver":"00000000000000","error_code":"123","log_time":"4/13/2018 8:42:11 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"7","start_time":"4/13/2018 8:34:57 AM"},{"bib":"01074601150129","bin2_tests":{},"datas_line":["174","173","173","173","173","172","169","174","174","174","174","173","172","169","172","173","175","173","173","172","170","170","172","172","173","171","170","169"],"driver":"00000000000000","error_code":"124","log_time":"4/13/2018 8:42:12 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"7","start_time":"4/13/2018 8:34:57 AM"},{"bib":"01074601150129","bin2_tests":{},"datas_line":["172","171","170","171","171","170","167","172","172","172","172","171","171","167","170","171","173","171","171","170","168","168","170","171","171","169","169","167"],"driver":"00000000000000","error_code":"125","log_time":"4/13/2018 8:42:12 AM","lotID":"248649_7_PCU12_M2_ELFR72H","lot_removed":[],"nrds":{},"slot":"7","start_time":"4/13/2018 8:34:57 AM"}],"session_number":0}]};
 
var data = data["Session_test"][0]["datas_lines"];
  
// To be able to map data, we extract data and place them into a new array of objects  
let data_converted = [];
	
data.forEach(obj => {
	if (obj.log_time !== "No data") {
		let iterator = 0;
		let final = {};
		obj.datas_line.forEach(d => {
		final[iterator.toString()] = d;
		iterator++;
		});
		final.log_time = parseTime(obj.log_time);
		data_converted.push(final);
	}
});
		
var dateKey = d3.keys(data_converted[0]);

color.domain(dateKey.filter(function(key) { // Set the domain of the color ordinal scale to be all the JSON id except "log_time", matching a color to an issue
	return key !== "log_time"; 
}));

var i = dateKey.indexOf("log_time")
	if(i != -1) {
		dateKey.splice(i, 1);
	}

var products = color.domain().map(function(d) { 
	return {
		id:d,
		values: data_converted.map( function(e) {
			return {
				log_time: e.log_time,
				temperature: e[d]
			};
		}),
		visible: true
	}
});

xScale.domain(d3.extent(data_converted, function(d) { return d.log_time; })); // extent = highest and lowest points
yScale.domain([
	d3.min(products, function(c) { return d3.min(c.values, function(d) { return d.temperature; }); }),
	d3.max(products, function(c) { return d3.max(c.values, function(d) { return d.temperature; }); })
]);
xScale2.domain(xScale.domain()); // Setting a duplicate xdomain for brushing reference later

// draw line graph
svg.append("g")
	.attr("class", "x axis")
	.attr("transform", "translate(0," + height + ")")
	.call(xAxis);
	
// text label for the x axis
svg.append("text")             
  .attr("transform",
		"translate(" + (width/2) + " ," + 
					   (height + margin.top + 20) + ")")
  .style("text-anchor", "middle")
  .text("Time");
  
svg.append("g")
	.attr("class", "y axis")
	.call(yAxis)
	.append("text")  // text label for the y axis
	  .attr("transform", "rotate(-90)")
	  .attr("y", 0 - margin.left)
	  .attr("x", 0 - (height / 2))
	  .attr("dy", "1em")
	  .style("text-anchor", "middle")
	  .text("Temperature (°C)");

var points = svg.selectAll(".points")
	.data(products) // Select nested data and append to new svg group elements
  .enter().append("g")
	.attr("class", "points");   

points.append("path")
	.attr("class", "line")
	.style("pointer-events", "none") // Stop line interferring with cursor
	.attr("id", function(d) {
		return "line-" + d.id; // Give line id of line
	})
	.attr("d", function(d) { 
		return d.visible ? line(d.values) : null; // If array key "visible" = true then draw line, if not then don't 
	})
	.attr("clip-path", "url(#clip)")//use clip path to make irrelevant part invisible
	.style("stroke", function(d) { return color(d.id); });
	

points.selectAll("circle")
.data(function(d){return d.values})
.enter()
.append("circle")
.attr("r", 3)
.attr("cx", function(d) { return xScale(d.log_time); })
.attr("cy", function(d) { return yScale(d.temperature); })

.style("fill", function(d,i,j) { return color(products[j].id); });
body {
  font: 12px sans-serif;
}

.axis path,
.axis line, 
.axis1 path,
.axis1 line {
  fill: none;
  stroke: #E6E7E8;
  shape-rendering: crispEdges;
}

.x.axis path, .x.axis1 path {
  display: none;
}

.line {
  fill: none;
  stroke: steelblue;
  stroke-width: 1.5px;
}

.legend-box {
  cursor: pointer;  
}

#mouse-tracker {
  stroke: #E6E7E8;
  stroke-width: 1px;
}

.dot {
     fill: white;
     stroke: steelblue;
     stroke-width: 1.5px;
}

.hover-line { 
  stroke: #E6E7E8;
  fill: none;
  stroke-width: 1px;
  left: 10px;
  shape-rendering: crispEdges;
  opacity: 1e-6;
}

.hover-text {
  stroke: none;
  font-size: 30px;
  font-weight: bold;
  fill: #000000;
}

.tooltip {
  font-weight: normal;
}

.brush .extent {
  stroke: #FFF;
  shape-rendering: crispEdges;
}

p {
	font-size: 18px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.min.js"></script>


* I'm not saying that you should use that interpolation, the result is awful. I'm just answering your question regarding the circles' positions.


Related Query