I'm plotting data as a line chart and for some reason there are random horizontal lines going across one part of the graph:
I'm plotting my data like this:
const timeConv = d3.timeParse("%Y-%m-%dT%H:%M:%S.%f");
const width = 960;
const height = 500;
const margin = 5;
const padding = 5;
const adj = 30;
/* adding svg */
const svg = d3.select("#chart").append("svg")
.attr("preserveAspectRatio", "none")
.attr("viewBox", "-"
+ adj + " -"
+ adj + " "
+ (width + adj * 3) + " "
+ (height + adj * 3))
.attr("height", "100%")
.style("padding", padding)
.style("margin", margin)
/* sanitizing data */
const dataset = d3.json("formattedStats.json")
dataset.then(function(data) {
/* scaling */
const xScale = d3.scaleTime().range([0, width]);
const yScale = d3.scaleLinear().rangeRound([height, 0]);
xScale.domain(d3.extent(data, d => timeConv(d.dateCreated)));
yScale.domain([
0,
d3.max(data, d => d.balance)
]);
const yaxis = d3.axisLeft()
.ticks(20)
.scale(yScale);
const xaxis = d3.axisBottom()
.ticks(d3.timeDay.filter(d => d3.timeDay.count(0, d) % 3 === 0))
.tickFormat(d3.timeFormat('%b %d'))
.scale(xScale);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 0)")
.call(yaxis);
const line = d3.line()
.x((d) => xScale(timeConv(d.dateCreated)))
.y((d) => yScale(d.balance));
svg.append("path")
.attr("d", line(data))
.attr("stroke", "black")
});
And my data looks like this:
[
{
"balance":1433,
"dateCreated":"2020-07-23T19:03:38.627"
},
{
"balance":1426,
"dateCreated":"2020-07-23T19:01:50.766"
},
{
"balance":1449,
"dateCreated":"2020-07-23T06:58:56.856"
},
{
"balance":1465,
"dateCreated":"2020-07-23T06:45:02.957"
},
{
"balance":1476,
"dateCreated":"2020-07-23T06:38:27.707"
},
{
"balance":1483,
"dateCreated":"2020-07-23T06:09:21.723"
},
{
"balance":1489,
"dateCreated":"2020-07-23T06:07:10.662"
},
{
"balance":1506,
"dateCreated":"2020-07-23T06:07:01.501"
},
{
"balance":1515,
"dateCreated":"2020-07-23T04:06:49.871"
},
{
"balance":1531,
"dateCreated":"2020-07-23T03:47:41.251"
},
{
"balance":1542,
"dateCreated":"2020-07-23T03:04:08.571"
},
{
"balance":1558,
"dateCreated":"2020-07-23T02:27:07.284"
},
{
"balance":1575,
"dateCreated":"2020-07-23T02:21:03.609"
},
{
"balance":1591,
"dateCreated":"2020-07-23T02:14:47.54"
},
{
"balance":1596,
"dateCreated":"2020-07-23T02:13:51.064"
},
{
"balance":1612,
"dateCreated":"2020-07-23T02:13:35.578"
},
{
"balance":1620,
"dateCreated":"2020-07-23T01:49:01.64"
},
{
"balance":1606,
"dateCreated":"2020-07-23T01:05:31.986"
},
{
"balance":1639,
"dateCreated":"2020-07-23T00:13:31.93"
},
{
"balance":1656,
"dateCreated":"2020-07-23T00:05:29.045"
},
{
"balance":1672,
"dateCreated":"2020-07-22T23:53:33.355"
},
{
"balance":1679,
"dateCreated":"2020-07-22T23:45:19.324"
},
{
"balance":1702,
"dateCreated":"2020-07-22T08:06:04.961"
},
{
"balance":1709,
"dateCreated":"2020-07-22T07:41:31.159"
},
{
"balance":949,
"dateCreated":"2020-07-22T06:11:06.519"
},
{
"balance":915,
"dateCreated":"2020-07-22T04:11:45.495"
},
{
"balance":932,
"dateCreated":"2020-07-22T03:31:21.528"
},
{
"balance":981,
"dateCreated":"2020-07-22T02:09:29.896"
},
{
"balance":965,
"dateCreated":"2020-07-22T02:08:44.348"
},
{
"balance":859,
"dateCreated":"2020-07-21T23:16:21.725"
},
{
"balance":837,
"dateCreated":"2020-07-21T22:11:51.734"
},
{
"balance":853,
"dateCreated":"2020-07-21T21:51:33.269"
},
{
"balance":869,
"dateCreated":"2020-07-21T21:25:00.833"
},
{
"balance":862,
"dateCreated":"2020-07-21T21:17:35.604"
},
{
"balance":839,
"dateCreated":"2020-07-21T20:30:21.715"
},
{
"balance":856,
"dateCreated":"2020-07-21T07:51:15.532"
},
{
"balance":899,
"dateCreated":"2020-07-21T07:10:07.262"
},
{
"balance":915,
"dateCreated":"2020-07-21T05:37:19.123"
},
{
"balance":910,
"dateCreated":"2020-07-21T05:33:59.065"
},
{
"balance":883,
"dateCreated":"2020-07-21T05:24:11.467"
},
{
"balance":871,
"dateCreated":"2020-07-21T03:21:38.474"
},
{
"balance":888,
"dateCreated":"2020-07-21T03:10:32.186"
},
{
"balance":891,
"dateCreated":"2020-07-21T03:05:09.042"
},
{
"balance":861,
"dateCreated":"2020-07-21T02:05:56.146"
},
{
"balance":878,
"dateCreated":"2020-07-21T01:43:27.761"
},
{
"balance":901,
"dateCreated":"2020-07-21T01:34:25.554"
},
{
"balance":907,
"dateCreated":"2020-07-20T23:18:39.558"
},
{
"balance":924,
"dateCreated":"2020-07-20T22:59:25.504"
},
{
"balance":940,
"dateCreated":"2020-07-20T21:01:51.96"
},
{
"balance":879,
"dateCreated":"2020-07-20T20:48:54.406"
},
{
"balance":857,
"dateCreated":"2020-07-20T19:56:13.648"
},
{
"balance":890,
"dateCreated":"2020-07-20T19:50:26.716"
},
{
"balance":906,
"dateCreated":"2020-07-20T19:00:18.921"
},
{
"balance":882,
"dateCreated":"2020-07-20T07:46:33.574"
},
{
"balance":896,
"dateCreated":"2020-07-20T07:07:40.55"
},
{
"balance":879,
"dateCreated":"2020-07-20T07:04:25.858"
},
{
"balance":906,
"dateCreated":"2020-07-20T06:52:07.748"
},
{
"balance":922,
"dateCreated":"2020-07-20T06:42:51.575"
},
{
"balance":927,
"dateCreated":"2020-07-20T06:42:31.973"
},
{
"balance":934.26,
"dateCreated":"2020-07-20T06:16:09.036"
},
{
"balance":902,
"dateCreated":"2020-07-20T05:31:56.692"
},
{
"balance":923,
"dateCreated":"2020-07-20T05:31:47.108"
},
{
"balance":894,
"dateCreated":"2020-07-20T05:22:20.871"
},
{
"balance":867,
"dateCreated":"2020-07-20T04:00:32.576"
},
{
"balance":883,
"dateCreated":"2020-07-20T04:00:26.06"
},
{
"balance":900,
"dateCreated":"2020-07-20T02:14:11.529"
},
{
"balance":916,
"dateCreated":"2020-07-20T01:38:55.908"
},
{
"balance":933,
"dateCreated":"2020-07-20T01:23:53.772"
},
{
"balance":949,
"dateCreated":"2020-07-20T01:23:45.458"
},
{
"balance":956,
"dateCreated":"2020-07-19T23:33:45.224"
},
{
"balance":962,
"dateCreated":"2020-07-19T23:08:56.22"
},
{
"balance":979,
"dateCreated":"2020-07-19T23:08:38.623"
},
{
"balance":880,
"dateCreated":"2020-07-19T23:06:48.195"
},
{
"balance":894,
"dateCreated":"2020-07-19T22:12:00.778"
},
{
"balance":877,
"dateCreated":"2020-07-19T21:57:13.62"
},
{
"balance":910,
"dateCreated":"2020-07-19T21:33:02.45"
},
{
"balance":925,
"dateCreated":"2020-07-19T21:25:22.116"
},
{
"balance":949,
"dateCreated":"2020-07-19T21:20:51.796"
},
{
"balance":965,
"dateCreated":"2020-07-19T20:59:27.897"
},
{
"balance":982,
"dateCreated":"2020-07-19T07:47:45.451"
},
{
"balance":822,
"dateCreated":"2020-07-19T07:44:31.419"
},
{
"balance":879,
"dateCreated":"2020-07-19T07:34:22.508"
},
{
"balance":797,
"dateCreated":"2020-07-19T06:46:47.993"
},
{
"balance":814,
"dateCreated":"2020-07-19T06:46:07.785"
},
{
"balance":820,
"dateCreated":"2020-07-19T06:36:24.427"
},
{
"balance":827,
"dateCreated":"2020-07-19T06:20:59.223"
},
{
"balance":861,
"dateCreated":"2020-07-19T06:19:46.962"
},
{
"balance":823,
"dateCreated":"2020-07-19T06:08:21.955"
},
{
"balance":840,
"dateCreated":"2020-07-19T06:07:30.056"
},
{
"balance":851,
"dateCreated":"2020-07-19T06:05:20.705"
},
{
"balance":849,
"dateCreated":"2020-07-19T05:39:32.269"
},
{
"balance":866.29,
"dateCreated":"2020-07-19T05:26:06.534"
},
{
"balance":825,
"dateCreated":"2020-07-19T05:13:44.842"
},
{
"balance":836,
"dateCreated":"2020-07-19T05:11:43.612"
},
{
"balance":852,
"dateCreated":"2020-07-19T05:04:52.876"
},
{
"balance":858,
"dateCreated":"2020-07-19T05:04:27.291"
},
{
"balance":874.54,
"dateCreated":"2020-07-19T05:04:12.409"
},
{
"balance":843,
"dateCreated":"2020-07-19T04:57:22.911"
},
{
"balance":859,
"dateCreated":"2020-07-19T04:52:21.601"
},
{
"balance":875.24,
"dateCreated":"2020-07-19T04:50:29"
},
{
"balance":847,
"dateCreated":"2020-07-19T04:45:57.354"
},
{
"balance":880,
"dateCreated":"2020-07-19T04:28:35.598"
},
{
"balance":897,
"dateCreated":"2020-07-19T04:17:26.469"
},
{
"balance":913,
"dateCreated":"2020-07-18T07:16:47.016"
},
{
"balance":947,
"dateCreated":"2020-07-18T06:37:00.094"
},
{
"balance":930,
"dateCreated":"2020-07-18T06:31:42.495"
},
{
"balance":952,
"dateCreated":"2020-07-17T09:08:22.177"
},
{
"balance":939.94,
"dateCreated":"2020-07-17T08:49:21.978"
},
{
"balance":918,
"dateCreated":"2020-07-17T08:34:31.417"
},
{
"balance":929,
"dateCreated":"2020-07-17T08:34:01.094"
},
{
"balance":935,
"dateCreated":"2020-07-16T07:08:20.004"
},
{
"balance":951,
"dateCreated":"2020-07-16T07:07:46.132"
},
{
"balance":968,
"dateCreated":"2020-07-14T04:39:32.887"
},
{
"balance":984,
"dateCreated":"2020-07-14T04:39:15.779"
},
{
"balance":1000,
"dateCreated":"2020-07-14T02:03:00.87"
},
{
"balance":1017,
"dateCreated":"2020-07-14T01:31:32.207"
},
{
"balance":1033,
"dateCreated":"2020-07-14T01:31:19.978"
},
{
"balance":1040,
"dateCreated":"2020-07-13T23:23:29.921"
},
{
"balance":1095.59,
"dateCreated":"2020-07-13T23:18:21.912"
},
{
"balance":1072,
"dateCreated":"2020-07-13T22:37:24.883"
},
{
"balance":1088,
"dateCreated":"2020-07-13T21:00:57.88"
},
{
"balance":1091,
"dateCreated":"2020-07-13T20:10:58.344"
},
{
"balance":1093.04,
"dateCreated":"2020-07-13T20:10:39.9"
},
{
"balance":1055,
"dateCreated":"2020-07-13T19:20:51.553"
},
{
"balance":1071,
"dateCreated":"2020-07-13T19:09:34.993"
},
{
"balance":1071,
"dateCreated":"2020-07-13T19:09:12.291"
},
{
"balance":1088.47,
"dateCreated":"2020-07-13T08:34:06.731"
},
{
"balance":1020.97,
"dateCreated":"2020-07-13T08:24:09.093"
},
{
"balance":999,
"dateCreated":"2020-07-13T08:12:13.226"
},
{
"balance":1015,
"dateCreated":"2020-07-13T07:49:26.818"
},
{
"balance":1032,
"dateCreated":"2020-07-13T07:40:00.178"
},
{
"balance":1114,
"dateCreated":"2020-07-12T23:23:32.335"
},
{
"balance":1154,
"dateCreated":"2020-07-12T21:01:59.128"
},
{
"balance":1169.97,
"dateCreated":"2020-07-12T14:39:57.463"
},
{
"balance":1156,
"dateCreated":"2020-07-12T14:01:02.792"
},
{
"balance":1172,
"dateCreated":"2020-07-12T13:55:36.566"
},
{
"balance":1177,
"dateCreated":"2020-07-12T13:55:19.394"
},
{
"balance":1156,
"dateCreated":"2020-07-12T08:24:33.968"
},
{
"balance":1121,
"dateCreated":"2020-07-12T08:08:41.735"
},
{
"balance":1089,
"dateCreated":"2020-07-12T06:48:28.84"
},
{
"balance":1106,
"dateCreated":"2020-07-12T05:40:55.865"
},
{
"balance":1036,
"dateCreated":"2020-07-11T22:45:14.995"
},
{
"balance":1012,
"dateCreated":"2020-07-11T21:52:56.498"
},
{
"balance":1028,
"dateCreated":"2020-07-11T21:36:53.419"
},
{
"balance":1043,
"dateCreated":"2020-07-11T09:20:19.116"
},
{
"balance":1037,
"dateCreated":"2020-07-11T08:27:01.816"
},
{
"balance":1043,
"dateCreated":"2020-07-11T08:26:45.696"
},
{
"balance":1066,
"dateCreated":"2020-07-11T08:26:30.808"
},
{
"balance":1070,
"dateCreated":"2020-07-11T08:08:32.191"
},
{
"balance":1081.18,
"dateCreated":"2020-07-11T08:04:44.88"
},
{
"balance":1049,
"dateCreated":"2020-07-11T06:59:57.157"
},
{
"balance":1066,
"dateCreated":"2020-07-11T06:29:55.306"
},
{
"balance":1082,
"dateCreated":"2020-07-11T06:29:37.378"
},
{
"balance":1089,
"dateCreated":"2020-07-10T07:20:38.373"
},
{
"balance":1120,
"dateCreated":"2020-07-10T07:04:02.663"
},
{
"balance":1131,
"dateCreated":"2020-07-10T07:02:00.364"
},
{
"balance":1148,
"dateCreated":"2020-07-10T05:50:07.739"
},
{
"balance":1164,
"dateCreated":"2020-07-10T05:24:33.478"
},
{
"balance":1108,
"dateCreated":"2020-07-10T05:23:31.012"
},
{
"balance":1083,
"dateCreated":"2020-07-10T04:10:02.153"
},
{
"balance":1099,
"dateCreated":"2020-07-10T04:09:37.055"
},
{
"balance":1114,
"dateCreated":"2020-07-10T02:40:05.837"
},
{
"balance":1095,
"dateCreated":"2020-07-10T02:13:02.745"
},
{
"balance":1106.16,
"dateCreated":"2020-07-10T02:10:33.916668"
},
{
"balance":1108,
"dateCreated":"2020-07-10T01:43:12.406"
},
{
"balance":1092,
"dateCreated":"2020-07-10T01:39:59.102"
},
{
"balance":1113,
"dateCreated":"2020-07-10T01:35:38.467"
},
{
"balance":1087,
"dateCreated":"2020-07-10T01:14:38.311"
},
{
"balance":1103,
"dateCreated":"2020-07-10T00:50:09.294"
},
{
"balance":1153,
"dateCreated":"2020-07-10T00:35:48.635"
},
{
"balance":1136,
"dateCreated":"2020-07-10T00:13:15.698"
},
{
"balance":1169,
"dateCreated":"2020-07-09T23:42:45.742"
},
{
"balance":1180,
"dateCreated":"2020-07-09T23:41:51.207"
},
{
"balance":1186,
"dateCreated":"2020-07-09T20:29:33.056"
},
{
"balance":1219,
"dateCreated":"2020-07-09T19:34:09.69"
},
{
"balance":1235,
"dateCreated":"2020-07-09T19:18:24.581"
},
{
"balance":1236,
"dateCreated":"2020-07-09T19:11:14.349"
},
{
"balance":1252,
"dateCreated":"2020-07-09T17:13:40.924"
},
{
"balance":1268,
"dateCreated":"2020-07-09T06:47:22.183"
},
{
"balance":1284,
"dateCreated":"2020-07-08T17:42:38.056"
},
{
"balance":1301,
"dateCreated":"2020-07-08T17:42:28.833"
},
{
"balance":1306.58,
"dateCreated":"2020-07-08T08:49:25.341"
},
{
"balance":1285.58,
"dateCreated":"2020-07-08T08:32:08.722"
},
{
"balance":1275,
"dateCreated":"2020-07-08T08:29:17.285"
},
{
"balance":1282,
"dateCreated":"2020-07-08T08:29:09.891"
},
{
"balance":1285,
"dateCreated":"2020-07-08T08:22:57.768"
},
{
"balance":1290,
"dateCreated":"2020-07-08T08:20:55.432"
},
{
"balance":1294,
"dateCreated":"2020-07-08T07:06:29.286"
},
{
"balance":1300,
"dateCreated":"2020-07-08T06:47:13.151"
},
{
"balance":1291,
"dateCreated":"2020-07-08T06:44:23.775"
},
{
"balance":1270,
"dateCreated":"2020-07-08T05:46:22.013"
},
{
"balance":1287,
"dateCreated":"2020-07-08T05:45:47.899"
},
{
"balance":1149,
"dateCreated":"2020-07-07T11:19:38.463"
},
{
"balance":1129.93,
"dateCreated":"2020-07-07T08:29:41.744"
},
{
"balance":1107,
"dateCreated":"2020-07-07T07:48:21.005"
},
{
"balance":1116,
"dateCreated":"2020-07-07T07:48:04.45"
},
{
"balance":1134,
"dateCreated":"2020-07-07T06:07:27.17"
},
{
"balance":1101,
"dateCreated":"2020-07-06T18:13:04.993"
},
{
"balance":1075,
"dateCreated":"2020-07-06T16:50:49.551"
},
{
"balance":1098,
"dateCreated":"2020-07-06T16:41:05.869"
},
{
"balance":1105,
"dateCreated":"2020-07-06T04:53:57.638"
},
{
"balance":1121,
"dateCreated":"2020-07-06T04:53:47.715"
},
{
"balance":1128,
"dateCreated":"2020-07-06T03:52:28.386"
},
{
"balance":1194,
"dateCreated":"2020-07-06T03:33:55.42"
},
{
"balance":1177,
"dateCreated":"2020-07-06T03:19:55.119"
},
{
"balance":1210,
"dateCreated":"2020-07-06T02:53:50.235"
},
{
"balance":1227,
"dateCreated":"2020-07-06T02:40:53.788"
},
{
"balance":1243,
"dateCreated":"2020-07-06T02:40:39.762"
},
{
"balance":1252,
"dateCreated":"2020-07-06T02:19:43.451"
},
{
"balance":1269,
"dateCreated":"2020-07-05T21:41:31.196"
},
{
"balance":1275,
"dateCreated":"2020-07-05T21:34:16.157"
},
{
"balance":1219,
"dateCreated":"2020-07-05T19:53:26.309"
},
{
"balance":1192,
"dateCreated":"2020-07-05T19:04:36.269"
},
{
"balance":1198,
"dateCreated":"2020-07-05T19:04:10.751"
},
{
"balance":1249,
"dateCreated":"2020-07-04T05:38:08.098"
},
{
"balance":1228,
"dateCreated":"2020-07-04T05:23:06.225"
},
{
"balance":1271,
"dateCreated":"2020-07-04T03:26:17.131"
},
{
"balance":1304,
"dateCreated":"2020-07-04T03:12:01.939"
},
{
"balance":1327,
"dateCreated":"2020-07-04T03:09:45.315"
},
{
"balance":1334,
"dateCreated":"2020-07-04T02:45:19.182"
},
{
"balance":1343,
"dateCreated":"2020-07-03T20:49:14.146"
},
{
"balance":1353.8,
"dateCreated":"2020-07-03T08:00:24.059"
},
{
"balance":1290,
"dateCreated":"2020-07-03T07:39:10.192"
},
{
"balance":1322,
"dateCreated":"2020-07-03T07:28:01.269"
},
{
"balance":1322.65,
"dateCreated":"2020-07-02T08:16:47.869"
},
{
"balance":1287,
"dateCreated":"2020-07-02T06:46:09.676"
},
{
"balance":1304,
"dateCreated":"2020-07-02T06:40:26.221"
},
{
"balance":1310,
"dateCreated":"2020-07-02T06:30:15.057"
},
{
"balance":1328,
"dateCreated":"2020-07-01T06:40:06.844"
},
{
"balance":1345,
"dateCreated":"2020-07-01T06:23:22.739"
},
{
"balance":1348,
"dateCreated":"2020-06-30T08:09:53.259"
},
{
"balance":1318,
"dateCreated":"2020-06-30T06:43:08.339"
},
{
"balance":1334,
"dateCreated":"2020-06-30T06:42:51.645"
}
]
Does anyone know why this might be happening? Thanks!
This sort of error (where the graph/chart line/rect/path/circle is largely correct but with one or two errant points) can generally be traced to one of two issues:
Errors in data
Errors in parsing the data
In your case, the data is fine but your parsing of it does not account for an edge case, when your time does not have milliseconds, compare:
const timeConv = d3.timeParse("%Y-%m-%dT%H:%M:%S.%f");
console.log(timeConv("2020-07-19T04:50:29"));
console.log(timeConv("2020-07-19T04:52:21.601"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
In your case, for one data point, d3.timeParse returns a null value in your case for one data point, causing a badly scaled x value for the path.
Two solutions come to mind, fix the data so this point is formatted as expected, or create a second time parser to account for this edge case:
.x((d) => xScale(timeConv(d.dateCreated) || timeConvEdgeCase(d.dateCreated)))
This seems hackier than ensuring consistently formatted data, but depending on your data source, this might need to be done inline or in loading the data in the browser anyways.
const data=[{"balance":1433,"dateCreated":"2020-07-23T19:03:38.627"},{"balance":1426,"dateCreated":"2020-07-23T19:01:50.766"},{"balance":1449,"dateCreated":"2020-07-23T06:58:56.856"},{"balance":1465,"dateCreated":"2020-07-23T06:45:02.957"},{"balance":1476,"dateCreated":"2020-07-23T06:38:27.707"},{"balance":1483,"dateCreated":"2020-07-23T06:09:21.723"},{"balance":1489,"dateCreated":"2020-07-23T06:07:10.662"},{"balance":1506,"dateCreated":"2020-07-23T06:07:01.501"},{"balance":1515,"dateCreated":"2020-07-23T04:06:49.871"},{"balance":1531,"dateCreated":"2020-07-23T03:47:41.251"},{"balance":1542,"dateCreated":"2020-07-23T03:04:08.571"},{"balance":1558,"dateCreated":"2020-07-23T02:27:07.284"},{"balance":1575,"dateCreated":"2020-07-23T02:21:03.609"},{"balance":1591,"dateCreated":"2020-07-23T02:14:47.54"},{"balance":1596,"dateCreated":"2020-07-23T02:13:51.064"},{"balance":1612,"dateCreated":"2020-07-23T02:13:35.578"},{"balance":1620,"dateCreated":"2020-07-23T01:49:01.64"},{"balance":1606,"dateCreated":"2020-07-23T01:05:31.986"},{"balance":1639,"dateCreated":"2020-07-23T00:13:31.93"},{"balance":1656,"dateCreated":"2020-07-23T00:05:29.045"},{"balance":1672,"dateCreated":"2020-07-22T23:53:33.355"},{"balance":1679,"dateCreated":"2020-07-22T23:45:19.324"},{"balance":1702,"dateCreated":"2020-07-22T08:06:04.961"},{"balance":1709,"dateCreated":"2020-07-22T07:41:31.159"},{"balance":949,"dateCreated":"2020-07-22T06:11:06.519"},{"balance":915,"dateCreated":"2020-07-22T04:11:45.495"},{"balance":932,"dateCreated":"2020-07-22T03:31:21.528"},{"balance":981,"dateCreated":"2020-07-22T02:09:29.896"},{"balance":965,"dateCreated":"2020-07-22T02:08:44.348"},{"balance":859,"dateCreated":"2020-07-21T23:16:21.725"},{"balance":837,"dateCreated":"2020-07-21T22:11:51.734"},{"balance":853,"dateCreated":"2020-07-21T21:51:33.269"},{"balance":869,"dateCreated":"2020-07-21T21:25:00.833"},{"balance":862,"dateCreated":"2020-07-21T21:17:35.604"},{"balance":839,"dateCreated":"2020-07-21T20:30:21.715"},{"balance":856,"dateCreated":"2020-07-21T07:51:15.532"},{"balance":899,"dateCreated":"2020-07-21T07:10:07.262"},{"balance":915,"dateCreated":"2020-07-21T05:37:19.123"},{"balance":910,"dateCreated":"2020-07-21T05:33:59.065"},{"balance":883,"dateCreated":"2020-07-21T05:24:11.467"},{"balance":871,"dateCreated":"2020-07-21T03:21:38.474"},{"balance":888,"dateCreated":"2020-07-21T03:10:32.186"},{"balance":891,"dateCreated":"2020-07-21T03:05:09.042"},{"balance":861,"dateCreated":"2020-07-21T02:05:56.146"},{"balance":878,"dateCreated":"2020-07-21T01:43:27.761"},{"balance":901,"dateCreated":"2020-07-21T01:34:25.554"},{"balance":907,"dateCreated":"2020-07-20T23:18:39.558"},{"balance":924,"dateCreated":"2020-07-20T22:59:25.504"},{"balance":940,"dateCreated":"2020-07-20T21:01:51.96"},{"balance":879,"dateCreated":"2020-07-20T20:48:54.406"},{"balance":857,"dateCreated":"2020-07-20T19:56:13.648"},{"balance":890,"dateCreated":"2020-07-20T19:50:26.716"},{"balance":906,"dateCreated":"2020-07-20T19:00:18.921"},{"balance":882,"dateCreated":"2020-07-20T07:46:33.574"},{"balance":896,"dateCreated":"2020-07-20T07:07:40.55"},{"balance":879,"dateCreated":"2020-07-20T07:04:25.858"},{"balance":906,"dateCreated":"2020-07-20T06:52:07.748"},{"balance":922,"dateCreated":"2020-07-20T06:42:51.575"},{"balance":927,"dateCreated":"2020-07-20T06:42:31.973"},{"balance":934.26,"dateCreated":"2020-07-20T06:16:09.036"},{"balance":902,"dateCreated":"2020-07-20T05:31:56.692"},{"balance":923,"dateCreated":"2020-07-20T05:31:47.108"},{"balance":894,"dateCreated":"2020-07-20T05:22:20.871"},{"balance":867,"dateCreated":"2020-07-20T04:00:32.576"},{"balance":883,"dateCreated":"2020-07-20T04:00:26.06"},{"balance":900,"dateCreated":"2020-07-20T02:14:11.529"},{"balance":916,"dateCreated":"2020-07-20T01:38:55.908"},{"balance":933,"dateCreated":"2020-07-20T01:23:53.772"},{"balance":949,"dateCreated":"2020-07-20T01:23:45.458"},{"balance":956,"dateCreated":"2020-07-19T23:33:45.224"},{"balance":962,"dateCreated":"2020-07-19T23:08:56.22"},{"balance":979,"dateCreated":"2020-07-19T23:08:38.623"},{"balance":880,"dateCreated":"2020-07-19T23:06:48.195"},{"balance":894,"dateCreated":"2020-07-19T22:12:00.778"},{"balance":877,"dateCreated":"2020-07-19T21:57:13.62"},{"balance":910,"dateCreated":"2020-07-19T21:33:02.45"},{"balance":925,"dateCreated":"2020-07-19T21:25:22.116"},{"balance":949,"dateCreated":"2020-07-19T21:20:51.796"},{"balance":965,"dateCreated":"2020-07-19T20:59:27.897"},{"balance":982,"dateCreated":"2020-07-19T07:47:45.451"},{"balance":822,"dateCreated":"2020-07-19T07:44:31.419"},{"balance":879,"dateCreated":"2020-07-19T07:34:22.508"},{"balance":797,"dateCreated":"2020-07-19T06:46:47.993"},{"balance":814,"dateCreated":"2020-07-19T06:46:07.785"},{"balance":820,"dateCreated":"2020-07-19T06:36:24.427"},{"balance":827,"dateCreated":"2020-07-19T06:20:59.223"},{"balance":861,"dateCreated":"2020-07-19T06:19:46.962"},{"balance":823,"dateCreated":"2020-07-19T06:08:21.955"},{"balance":840,"dateCreated":"2020-07-19T06:07:30.056"},{"balance":851,"dateCreated":"2020-07-19T06:05:20.705"},{"balance":849,"dateCreated":"2020-07-19T05:39:32.269"},{"balance":866.29,"dateCreated":"2020-07-19T05:26:06.534"},{"balance":825,"dateCreated":"2020-07-19T05:13:44.842"},{"balance":836,"dateCreated":"2020-07-19T05:11:43.612"},{"balance":852,"dateCreated":"2020-07-19T05:04:52.876"},{"balance":858,"dateCreated":"2020-07-19T05:04:27.291"},{"balance":874.54,"dateCreated":"2020-07-19T05:04:12.409"},{"balance":843,"dateCreated":"2020-07-19T04:57:22.911"},{"balance":859,"dateCreated":"2020-07-19T04:52:21.601"},{"balance":875.24,"dateCreated":"2020-07-19T04:50:29"},{"balance":847,"dateCreated":"2020-07-19T04:45:57.354"},{"balance":880,"dateCreated":"2020-07-19T04:28:35.598"},{"balance":897,"dateCreated":"2020-07-19T04:17:26.469"},{"balance":913,"dateCreated":"2020-07-18T07:16:47.016"},{"balance":947,"dateCreated":"2020-07-18T06:37:00.094"},{"balance":930,"dateCreated":"2020-07-18T06:31:42.495"},{"balance":952,"dateCreated":"2020-07-17T09:08:22.177"},{"balance":939.94,"dateCreated":"2020-07-17T08:49:21.978"},{"balance":918,"dateCreated":"2020-07-17T08:34:31.417"},{"balance":929,"dateCreated":"2020-07-17T08:34:01.094"},{"balance":935,"dateCreated":"2020-07-16T07:08:20.004"},{"balance":951,"dateCreated":"2020-07-16T07:07:46.132"},{"balance":968,"dateCreated":"2020-07-14T04:39:32.887"},{"balance":984,"dateCreated":"2020-07-14T04:39:15.779"},{"balance":1000,"dateCreated":"2020-07-14T02:03:00.87"},{"balance":1017,"dateCreated":"2020-07-14T01:31:32.207"},{"balance":1033,"dateCreated":"2020-07-14T01:31:19.978"},{"balance":1040,"dateCreated":"2020-07-13T23:23:29.921"},{"balance":1095.59,"dateCreated":"2020-07-13T23:18:21.912"},{"balance":1072,"dateCreated":"2020-07-13T22:37:24.883"},{"balance":1088,"dateCreated":"2020-07-13T21:00:57.88"},{"balance":1091,"dateCreated":"2020-07-13T20:10:58.344"},{"balance":1093.04,"dateCreated":"2020-07-13T20:10:39.9"},{"balance":1055,"dateCreated":"2020-07-13T19:20:51.553"},{"balance":1071,"dateCreated":"2020-07-13T19:09:34.993"},{"balance":1071,"dateCreated":"2020-07-13T19:09:12.291"},{"balance":1088.47,"dateCreated":"2020-07-13T08:34:06.731"},{"balance":1020.97,"dateCreated":"2020-07-13T08:24:09.093"},{"balance":999,"dateCreated":"2020-07-13T08:12:13.226"},{"balance":1015,"dateCreated":"2020-07-13T07:49:26.818"},{"balance":1032,"dateCreated":"2020-07-13T07:40:00.178"},{"balance":1114,"dateCreated":"2020-07-12T23:23:32.335"},{"balance":1154,"dateCreated":"2020-07-12T21:01:59.128"},{"balance":1169.97,"dateCreated":"2020-07-12T14:39:57.463"},{"balance":1156,"dateCreated":"2020-07-12T14:01:02.792"},{"balance":1172,"dateCreated":"2020-07-12T13:55:36.566"},{"balance":1177,"dateCreated":"2020-07-12T13:55:19.394"},{"balance":1156,"dateCreated":"2020-07-12T08:24:33.968"},{"balance":1121,"dateCreated":"2020-07-12T08:08:41.735"},{"balance":1089,"dateCreated":"2020-07-12T06:48:28.84"},{"balance":1106,"dateCreated":"2020-07-12T05:40:55.865"},{"balance":1036,"dateCreated":"2020-07-11T22:45:14.995"},{"balance":1012,"dateCreated":"2020-07-11T21:52:56.498"},{"balance":1028,"dateCreated":"2020-07-11T21:36:53.419"},{"balance":1043,"dateCreated":"2020-07-11T09:20:19.116"},{"balance":1037,"dateCreated":"2020-07-11T08:27:01.816"},{"balance":1043,"dateCreated":"2020-07-11T08:26:45.696"},{"balance":1066,"dateCreated":"2020-07-11T08:26:30.808"},{"balance":1070,"dateCreated":"2020-07-11T08:08:32.191"},{"balance":1081.18,"dateCreated":"2020-07-11T08:04:44.88"},{"balance":1049,"dateCreated":"2020-07-11T06:59:57.157"},{"balance":1066,"dateCreated":"2020-07-11T06:29:55.306"},{"balance":1082,"dateCreated":"2020-07-11T06:29:37.378"},{"balance":1089,"dateCreated":"2020-07-10T07:20:38.373"},{"balance":1120,"dateCreated":"2020-07-10T07:04:02.663"},{"balance":1131,"dateCreated":"2020-07-10T07:02:00.364"},{"balance":1148,"dateCreated":"2020-07-10T05:50:07.739"},{"balance":1164,"dateCreated":"2020-07-10T05:24:33.478"},{"balance":1108,"dateCreated":"2020-07-10T05:23:31.012"},{"balance":1083,"dateCreated":"2020-07-10T04:10:02.153"},{"balance":1099,"dateCreated":"2020-07-10T04:09:37.055"},{"balance":1114,"dateCreated":"2020-07-10T02:40:05.837"},{"balance":1095,"dateCreated":"2020-07-10T02:13:02.745"},{"balance":1106.16,"dateCreated":"2020-07-10T02:10:33.916668"},{"balance":1108,"dateCreated":"2020-07-10T01:43:12.406"},{"balance":1092,"dateCreated":"2020-07-10T01:39:59.102"},{"balance":1113,"dateCreated":"2020-07-10T01:35:38.467"},{"balance":1087,"dateCreated":"2020-07-10T01:14:38.311"},{"balance":1103,"dateCreated":"2020-07-10T00:50:09.294"},{"balance":1153,"dateCreated":"2020-07-10T00:35:48.635"},{"balance":1136,"dateCreated":"2020-07-10T00:13:15.698"},{"balance":1169,"dateCreated":"2020-07-09T23:42:45.742"},{"balance":1180,"dateCreated":"2020-07-09T23:41:51.207"},{"balance":1186,"dateCreated":"2020-07-09T20:29:33.056"},{"balance":1219,"dateCreated":"2020-07-09T19:34:09.69"},{"balance":1235,"dateCreated":"2020-07-09T19:18:24.581"},{"balance":1236,"dateCreated":"2020-07-09T19:11:14.349"},{"balance":1252,"dateCreated":"2020-07-09T17:13:40.924"},{"balance":1268,"dateCreated":"2020-07-09T06:47:22.183"},{"balance":1284,"dateCreated":"2020-07-08T17:42:38.056"},{"balance":1301,"dateCreated":"2020-07-08T17:42:28.833"},{"balance":1306.58,"dateCreated":"2020-07-08T08:49:25.341"},{"balance":1285.58,"dateCreated":"2020-07-08T08:32:08.722"},{"balance":1275,"dateCreated":"2020-07-08T08:29:17.285"},{"balance":1282,"dateCreated":"2020-07-08T08:29:09.891"},{"balance":1285,"dateCreated":"2020-07-08T08:22:57.768"},{"balance":1290,"dateCreated":"2020-07-08T08:20:55.432"},{"balance":1294,"dateCreated":"2020-07-08T07:06:29.286"},{"balance":1300,"dateCreated":"2020-07-08T06:47:13.151"},{"balance":1291,"dateCreated":"2020-07-08T06:44:23.775"},{"balance":1270,"dateCreated":"2020-07-08T05:46:22.013"},{"balance":1287,"dateCreated":"2020-07-08T05:45:47.899"},{"balance":1149,"dateCreated":"2020-07-07T11:19:38.463"},{"balance":1129.93,"dateCreated":"2020-07-07T08:29:41.744"},{"balance":1107,"dateCreated":"2020-07-07T07:48:21.005"},{"balance":1116,"dateCreated":"2020-07-07T07:48:04.45"},{"balance":1134,"dateCreated":"2020-07-07T06:07:27.17"},{"balance":1101,"dateCreated":"2020-07-06T18:13:04.993"},{"balance":1075,"dateCreated":"2020-07-06T16:50:49.551"},{"balance":1098,"dateCreated":"2020-07-06T16:41:05.869"},{"balance":1105,"dateCreated":"2020-07-06T04:53:57.638"},{"balance":1121,"dateCreated":"2020-07-06T04:53:47.715"},{"balance":1128,"dateCreated":"2020-07-06T03:52:28.386"},{"balance":1194,"dateCreated":"2020-07-06T03:33:55.42"},{"balance":1177,"dateCreated":"2020-07-06T03:19:55.119"},{"balance":1210,"dateCreated":"2020-07-06T02:53:50.235"},{"balance":1227,"dateCreated":"2020-07-06T02:40:53.788"},{"balance":1243,"dateCreated":"2020-07-06T02:40:39.762"},{"balance":1252,"dateCreated":"2020-07-06T02:19:43.451"},{"balance":1269,"dateCreated":"2020-07-05T21:41:31.196"},{"balance":1275,"dateCreated":"2020-07-05T21:34:16.157"},{"balance":1219,"dateCreated":"2020-07-05T19:53:26.309"},{"balance":1192,"dateCreated":"2020-07-05T19:04:36.269"},{"balance":1198,"dateCreated":"2020-07-05T19:04:10.751"},{"balance":1249,"dateCreated":"2020-07-04T05:38:08.098"},{"balance":1228,"dateCreated":"2020-07-04T05:23:06.225"},{"balance":1271,"dateCreated":"2020-07-04T03:26:17.131"},{"balance":1304,"dateCreated":"2020-07-04T03:12:01.939"},{"balance":1327,"dateCreated":"2020-07-04T03:09:45.315"},{"balance":1334,"dateCreated":"2020-07-04T02:45:19.182"},{"balance":1343,"dateCreated":"2020-07-03T20:49:14.146"},{"balance":1353.8,"dateCreated":"2020-07-03T08:00:24.059"},{"balance":1290,"dateCreated":"2020-07-03T07:39:10.192"},{"balance":1322,"dateCreated":"2020-07-03T07:28:01.269"},{"balance":1322.65,"dateCreated":"2020-07-02T08:16:47.869"},{"balance":1287,"dateCreated":"2020-07-02T06:46:09.676"},{"balance":1304,"dateCreated":"2020-07-02T06:40:26.221"},{"balance":1310,"dateCreated":"2020-07-02T06:30:15.057"},{"balance":1328,"dateCreated":"2020-07-01T06:40:06.844"},{"balance":1345,"dateCreated":"2020-07-01T06:23:22.739"},{"balance":1348,"dateCreated":"2020-06-30T08:09:53.259"},{"balance":1318,"dateCreated":"2020-06-30T06:43:08.339"},{"balance":1334,"dateCreated":"2020-06-30T06:42:51.645"}]
const timeConv = d3.timeParse("%Y-%m-%dT%H:%M:%S.%f");
const timeConvEdge = d3.timeParse("%Y-%m-%dT%H:%M:%S");
const width = 960;
const height = 500;
const margin = 5;
const padding = 5;
const adj = 30;
/* adding svg */
const svg = d3.select("#chart").append("svg")
.attr("preserveAspectRatio", "none")
.attr("viewBox", "-"
+ adj + " -"
+ adj + " "
+ (width + adj * 3) + " "
+ (height + adj * 3))
.attr("height", "100%")
.style("padding", padding)
.style("margin", margin)
/* scaling */
const xScale = d3.scaleTime().range([0, width]);
const yScale = d3.scaleLinear().rangeRound([height, 0]);
xScale.domain(d3.extent(data, d => timeConv(d.dateCreated) || timeConvEdge(d.dateCreated)));
yScale.domain([
0,
d3.max(data, d => d.balance)
]);
const yaxis = d3.axisLeft()
.ticks(20)
.scale(yScale);
const xaxis = d3.axisBottom()
.ticks(d3.timeDay.filter(d => d3.timeDay.count(0, d) % 3 === 0))
.tickFormat(d3.timeFormat('%b %d'))
.scale(xScale);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xaxis);
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0, 0)")
.call(yaxis);
const line = d3.line()
.x((d) => xScale(timeConv(d.dateCreated) || timeConvEdge(d.dateCreated)))
.y((d) => yScale(d.balance));
svg.append("path")
.attr("d", line(data))
.attr("stroke", "black")
path {
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="chart">
I am trying to display data in a line graph within a 24 hr period.
I have created a d3 v4 line graph, and have successfully:
Applied an x Axis only zoom, and redraw of all elements
Used clippath to keep my data from showing left/below of my axis lines
My issue is now trying to apply translateExtent to my d3.zoom. It seems to keep me from panning left/right before zooming, but when I zoom, it seems to cut off or add on a half hour or so to the end and beginning of my data set.
I think all I need to do is maybe add some code to my d3.zoom declaration, and maybe also add something into my zoom function.
I have tried adding .translateExtent([[0,0],[w,h]]) to my d3.zoom code and so many other variations that included subtracting/adding my margins, etc.
It looks like adding the w"2*margin like below takes away the jumping on initial click. (which confuses me because I would assume the first coordinate group should affect the left panning of my graph) but once I zoom in, it keeps me from panning left beyond the beginning of the day (yay) but allows me to pan a little past the end of the day (boo).
var zoomCall = d3.zoom()
.scaleExtent([1, 24]) // no zooming out (1x), only zoom to 1hr (24x)
.translateExtent([[0,0],[w+2*margin,h]])
.on("zoom", zoom);
I am also thinking in my zoom function of multiplying my width extent by d3.event.transform.k which should be the zoom level i believe, but it is not giving me what I want either:
function zoom() {
zoomCall.translateExtent([[0,0],[w+margin*2*d3.event.transform.k, h]]);
There also sometimes is a translation of my data left or right 20px just when clicking on the graph once after the translateExtent code is added.
window.onload = function() {
// parse the date / time functions
var formatTime = d3.timeFormat("%H:%M"),
formatMinutes = function(d) {
return formatTime(new Date(2012, 0, 1, 0, d));
};
// Get and Prepare Data for gap_array and range_array
var count_data = [
{
"date_time":"\/Date(1494864780000)\/",
"count":14
},
{
"date_time":"\/Date(1494864780000)\/",
"count":11
},
{
"date_time":"\/Date(1494864780000)\/",
"count":25
},
{
"date_time":"\/Date(1494864840000)\/",
"count":31
},
{
"date_time":"\/Date(1494864840000)\/",
"count":53
},
{
"date_time":"\/Date(1494864840000)\/",
"count":56
},
{
"date_time":"\/Date(1494864900000)\/",
"count":57
},
{
"date_time":"\/Date(1494864960000)\/",
"count":68
},
{
"date_time":"\/Date(1494865020000)\/",
"count":69
},
{
"date_time":"\/Date(1494865020000)\/",
"count":70
},
{
"date_time":"\/Date(1494865140000)\/",
"count":65
},
{
"date_time":"\/Date(1494865200000)\/",
"count":68
},
{
"date_time":"\/Date(1494865320000)\/",
"count":68
},
{
"date_time":"\/Date(1494865380000)\/",
"count":68
},
{
"date_time":"\/Date(1494865500000)\/",
"count":70
},
{
"date_time":"\/Date(1494865560000)\/",
"count":67
},
{
"date_time":"\/Date(1494865680000)\/",
"count":61
},
{
"date_time":"\/Date(1494865740000)\/",
"count":61
},
{
"date_time":"\/Date(1494865860000)\/",
"count":67
},
{
"date_time":"\/Date(1494865920000)\/",
"count":67
},
{
"date_time":"\/Date(1494866040000)\/",
"count":67
},
{
"date_time":"\/Date(1494866100000)\/",
"count":67
},
{
"date_time":"\/Date(1494866220000)\/",
"count":68
},
{
"date_time":"\/Date(1494866280000)\/",
"count":66
},
{
"date_time":"\/Date(1494866400000)\/",
"count":67
},
{
"date_time":"\/Date(1494866460000)\/",
"count":67
},
{
"date_time":"\/Date(1494866580000)\/",
"count":68
},
{
"date_time":"\/Date(1494866640000)\/",
"count":66
},
{
"date_time":"\/Date(1494866760000)\/",
"count":67
},
{
"date_time":"\/Date(1494866820000)\/",
"count":67
},
{
"date_time":"\/Date(1494866940000)\/",
"count":67
},
{
"date_time":"\/Date(1494867000000)\/",
"count":67
},
{
"date_time":"\/Date(1494867120000)\/",
"count":53
},
{
"date_time":"\/Date(1494867180000)\/",
"count":66
},
{
"date_time":"\/Date(1494867300000)\/",
"count":72
},
{
"date_time":"\/Date(1494867360000)\/",
"count":67
},
{
"date_time":"\/Date(1494867480000)\/",
"count":69
},
{
"date_time":"\/Date(1494867540000)\/",
"count":70
},
{
"date_time":"\/Date(1494867660000)\/",
"count":61
},
{
"date_time":"\/Date(1494867720000)\/",
"count":28
},
{
"date_time":"\/Date(1494867720000)\/",
"count":10
},
{
"date_time":"\/Date(1494867840000)\/",
"count":60
},
{
"date_time":"\/Date(1494867900000)\/",
"count":60
},
{
"date_time":"\/Date(1494868020000)\/",
"count":50
},
{
"date_time":"\/Date(1494868020000)\/",
"count":42
},
{
"date_time":"\/Date(1494868140000)\/",
"count":63
},
{
"date_time":"\/Date(1494868200000)\/",
"count":63
},
{
"date_time":"\/Date(1494868320000)\/",
"count":63
},
{
"date_time":"\/Date(1494868380000)\/",
"count":61
},
{
"date_time":"\/Date(1494868500000)\/",
"count":63
},
{
"date_time":"\/Date(1494868560000)\/",
"count":44
},
{
"date_time":"\/Date(1494868560000)\/",
"count":14
},
{
"date_time":"\/Date(1494868680000)\/",
"count":35
},
{
"date_time":"\/Date(1494868740000)\/",
"count":73
},
{
"date_time":"\/Date(1494868860000)\/",
"count":63
},
{
"date_time":"\/Date(1494868920000)\/",
"count":63
},
{
"date_time":"\/Date(1494869040000)\/",
"count":58
},
{
"date_time":"\/Date(1494869100000)\/",
"count":63
},
{
"date_time":"\/Date(1494869220000)\/",
"count":63
},
{
"date_time":"\/Date(1494869280000)\/",
"count":62
},
{
"date_time":"\/Date(1494869400000)\/",
"count":62
},
{
"date_time":"\/Date(1494869460000)\/",
"count":63
},
{
"date_time":"\/Date(1494869580000)\/",
"count":63
},
{
"date_time":"\/Date(1494869640000)\/",
"count":55
},
{
"date_time":"\/Date(1494869700000)\/",
"count":63
},
{
"date_time":"\/Date(1494869820000)\/",
"count":63
},
{
"date_time":"\/Date(1494869880000)\/",
"count":58
},
{
"date_time":"\/Date(1494869880000)\/",
"count":58
},
{
"date_time":"\/Date(1494869880000)\/",
"count":58
},
{
"date_time":"\/Date(1494870000000)\/",
"count":35
},
{
"date_time":"\/Date(1494870060000)\/",
"count":43
},
{
"date_time":"\/Date(1494870120000)\/",
"count":53
},
{
"date_time":"\/Date(1494870180000)\/",
"count":0
},
{
"date_time":"\/Date(1494870180000)\/",
"count":6
},
{
"date_time":"\/Date(1494870180000)\/",
"count":8
},
{
"date_time":"\/Date(1494870240000)\/",
"count":0
},
{
"date_time":"\/Date(1494870240000)\/",
"count":4
},
{
"date_time":"\/Date(1494870240000)\/",
"count":0
},
{
"date_time":"\/Date(1494870240000)\/",
"count":6
},
{
"date_time":"\/Date(1494870300000)\/",
"count":0
},
{
"date_time":"\/Date(1494870300000)\/",
"count":6
},
{
"date_time":"\/Date(1494870300000)\/",
"count":15
},
{
"date_time":"\/Date(1494870300000)\/",
"count":14
},
{
"date_time":"\/Date(1494870300000)\/",
"count":22
},
{
"date_time":"\/Date(1494870360000)\/",
"count":27
},
{
"date_time":"\/Date(1494870420000)\/",
"count":63
},
{
"date_time":"\/Date(1494870540000)\/",
"count":63
},
{
"date_time":"\/Date(1494870600000)\/",
"count":67
},
{
"date_time":"\/Date(1494870720000)\/",
"count":63
},
{
"date_time":"\/Date(1494870780000)\/",
"count":63
},
{
"date_time":"\/Date(1494870900000)\/",
"count":54
},
{
"date_time":"\/Date(1494870900000)\/",
"count":0
},
{
"date_time":"\/Date(1494870900000)\/",
"count":6
},
{
"date_time":"\/Date(1494870960000)\/",
"count":15
},
{
"date_time":"\/Date(1494871020000)\/",
"count":13
},
{
"date_time":"\/Date(1494871020000)\/",
"count":0
},
{
"date_time":"\/Date(1494871080000)\/",
"count":0
},
{
"date_time":"\/Date(1494871200000)\/",
"count":0
},
{
"date_time":"\/Date(1494871260000)\/",
"count":0
},
{
"date_time":"\/Date(1494871380000)\/",
"count":0
},
{
"date_time":"\/Date(1494871440000)\/",
"count":0
},
{
"date_time":"\/Date(1494871560000)\/",
"count":0
},
{
"date_time":"\/Date(1494871620000)\/",
"count":0
},
{
"date_time":"\/Date(1494888600000)\/",
"count":6
},
{
"date_time":"\/Date(1494888600000)\/",
"count":6
},
{
"date_time":"\/Date(1494888720000)\/",
"count":0
},
{
"date_time":"\/Date(1494888780000)\/",
"count":0
},
{
"date_time":"\/Date(1494888900000)\/",
"count":0
},
{
"date_time":"\/Date(1494888960000)\/",
"count":0
},
{
"date_time":"\/Date(1494889080000)\/",
"count":0
},
{
"date_time":"\/Date(1494889140000)\/",
"count":0
},
{
"date_time":"\/Date(1494889260000)\/",
"count":0
},
{
"date_time":"\/Date(1494889320000)\/",
"count":0
},
{
"date_time":"\/Date(1494889380000)\/",
"count":4
},
{
"date_time":"\/Date(1494889380000)\/",
"count":4
},
{
"date_time":"\/Date(1494889380000)\/",
"count":0
},
{
"date_time":"\/Date(1494889380000)\/",
"count":5
},
{
"date_time":"\/Date(1494889380000)\/",
"count":0
},
{
"date_time":"\/Date(1494889500000)\/",
"count":0
},
{
"date_time":"\/Date(1494889560000)\/",
"count":0
},
{
"date_time":"\/Date(1494889680000)\/",
"count":0
},
{
"date_time":"\/Date(1494889740000)\/",
"count":4
},
{
"date_time":"\/Date(1494889740000)\/",
"count":0
},
{
"date_time":"\/Date(1494889860000)\/",
"count":0
},
{
"date_time":"\/Date(1494889920000)\/",
"count":0
},
{
"date_time":"\/Date(1494889920000)\/",
"count":4
},
{
"date_time":"\/Date(1494889980000)\/",
"count":0
},
{
"date_time":"\/Date(1494889980000)\/",
"count":0
},
{
"date_time":"\/Date(1494890220000)\/",
"count":5
},
{
"date_time":"\/Date(1494890220000)\/",
"count":5
},
{
"date_time":"\/Date(1494890280000)\/",
"count":6
},
{
"date_time":"\/Date(1494890340000)\/",
"count":0
},
{
"date_time":"\/Date(1494890400000)\/",
"count":0
},
{
"date_time":"\/Date(1494890520000)\/",
"count":0
},
{
"date_time":"\/Date(1494890580000)\/",
"count":0
},
{
"date_time":"\/Date(1494890700000)\/",
"count":0
},
{
"date_time":"\/Date(1494890760000)\/",
"count":0
},
{
"date_time":"\/Date(1494890880000)\/",
"count":0
},
];
count_data.forEach(function(d) {
d.date_time = new Date(parseInt(d.date_time.replace(/\/Date\((-?\d+)\)\//gi, "$1")));
//d.date_time = formatTime(d.date_time);
});
var maxY = d3.max(count_data, function(d) {
return d.count;
});
var minY = 0;
var minX = new Date(count_data[0].date_time).setHours(0, 0, 0, 0);
var maxX = new Date(count_data[0].date_time).setHours(23, 59, 59, 999);
var gap_array = [];
var range_array = [];
var range_start = moment(new Date(firstDateTime)),
range_end,
range_start_position = 0,
range_end_position,
in_range = true;
var gap_start,
gap_end,
gap_start_position,
gap_end_position,
in_gap = false,
gap_min = 2;
var firstDateTime = count_data[0].date_time;
var lastDateTime = count_data[count_data.length - 1].date_time;
var date_previous = moment(new Date(firstDateTime));
for (i = 0; i < count_data.length; i++) {
var current = moment(new Date(count_data[i].date_time));
if (current.diff(date_previous, "m") > gap_min && !in_gap) {
range_end = date_previous;
range_end_position = i - 1;
in_range = !in_range;
range_array.push({
start: range_start.toDate(),
end: range_end.toDate(),
start_position: range_start_position,
end_position: range_end_position
});
gap_start = date_previous;
gap_start_position = i;
in_gap = !in_gap;
} else if (current.diff(date_previous, "m") <= gap_min && in_gap) {
range_start_position = i;
range_start = current;
in_range = !in_range;
gap_end_position = i;
gap_end = current;
in_gap = !in_gap;
gap_array.push({
start: gap_start.toDate(),
end: gap_end.toDate(),
start_position: gap_start_position,
end_position: gap_end_position
});
} else if (i == count_data.length - 1) {
if (in_gap) {
gap_end_position = i;
gap_end = current;
in_gap = !in_gap;
gap_array.push({
start: gap_start.toDate(),
end: gap_end.toDate(),
start_position: gap_start_position,
end_position: gap_end_position
});
} else {
range_end = current;
range_end_position = i;
in_range = !in_range;
range_array.push({
start: range_start.toDate(),
end: range_end.toDate(),
start_position: range_start_position,
end_position: range_end_position
});
}
}
date_previous = current;
}
gap_array.push({
start: minX,
end: firstDateTime,
start_position: null,
end_position: 0
}); // push initial gap
gap_array.push({
start: lastDateTime,
end: maxX,
start_position: count_data.length - 1,
end_position: null
}); // push final gap
var count_data_array = [];
for (i = 0; i < range_array.length; i++) {
count_data_array.push(count_data.slice(range_array[i].start_position, range_array[i].end_position + (range_array[i].end_position < count_data.length - 1 ? 1 : 0)));
}
//
var margin = 40;
var w = document.getElementById("d3-chart").offsetWidth - margin - margin,
h = 250 - margin - margin;
var x = d3.scaleTime().range([0, w]).domain([minX, maxX]);
var y = d3.scaleLinear().range([h, 0]).domain([minY, maxY]);
var zoomCall = d3.zoom()
.scaleExtent([1, 24]) // no zooming out (1x), only zoom to 1hr (24x)
.on("zoom", zoom);
var container = d3.select("#d3-chart");
var svg = container.append("svg")
.attr("width", w + margin + margin)
.attr("height", h + margin + margin);
var g = svg.append("g")
.attr("transform",
"translate(" + margin + "," + margin + ")")
.call(zoomCall);
g.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", w)
.attr("height", h);
var xAxis = d3.axisBottom(x).ticks(20); //.tickFormat(formatMinutes);
var yAxis = d3.axisLeft(y);
function zoom() {
// re-scale y axis during zoom;
xAxisCall.transition()
.duration(50)
.call(xAxis.scale(d3.event.transform.rescaleX(x)));
// re-draw circles using new y-axis scale;
var new_xScale = d3.event.transform.rescaleX(x);
var new_valueline = d3.line()
.x(function(d) {
return new_xScale(d.date_time);
})
.y(function(d) {
return y(d.count);
});
gaps.attr("x", d => new_xScale(d.start)).attr("width", d => new_xScale(d.end) - new_xScale(d.start)).attr("clip-path", "url(#clip)");
for (i = 0; i < paths.length; i++) {
paths[i]
.attr("d", new_valueline).attr("clip-path", "url(#clip)");
}
}
var gaps = g.selectAll('.gap')
.data(gap_array)
.enter().append('rect')
.attr("class", "gap")
.attr("x", d => x(d.start))
.attr("y", 0)
.attr("width", d => x(d.end) - x(d.start))
.attr("height", h)
.attr("fill", "#efefef");
var xAxisCall = g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
var yAxisCall = g.append("g")
.attr("class", "axis")
.call(yAxis);
// define the line
var valueline = d3.line()
.x(function(d) {
return x(d.date_time);
})
.y(function(d) {
return y(d.count);
});
var paths = [];
// Add the valueline path.
for (i = 0; i < count_data_array.length; i++) {
paths.push(
g.append("path")
.data([count_data_array[i]])
.attr("class", "line")
.attr("d", valueline)
);
}
g.append("rect")
.attr("class", "overlay")
.attr("width", w)
.attr("height", h)
};
#d3-chart {
position: relative;
}
.axis {
font: 14px sans-serif;
}
.line {
fill: none;
stroke: #3988ff;
stroke-width: 2px;
}
.overlay {
fill: none;
pointer-events: all;;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.js"></script>
<h3>D3 Test</h3>
<div id="d3-chart"></div>
Not sure logically why, but the margin offset needs to be divided by the zoom factor.
function zoom() {
var zoomFactor = (d3.event != null ? d3.event.transform.k : 1);
zoomCall.translateExtent([[0,0],[w+((2*margin)/zoomFactor), h]]);