d3.js water bar chart - javascript

I am trying to fix this watery bar chart so that it can handle dynamic data sets -- http://jsfiddle.net/NYEaX/1855/
Having an issue with the positioning of the labels and adjusting the width/height of the lines.
var lineHeights = 100;
//__ labels
var labels = labelsholder.selectAll("text")
.data(data);
labels.enter()
.append("text")
.attr("class", "barlabels")
.attr("x", 200)
.attr("y", function(d, i) {
return lineHeights - (20 * i);
})
.text(function(d) {
return d.label;
})
var lines = lineholder.selectAll("line")
.data(data);
//horizontal
lines.enter()
.append("line") // attach a line
.style("stroke-dasharray", ("3, 3"))
.style("stroke", "black") // colour the line
.attr("x1", function(d, i) {
return barWidth - 100/(i+1);
}) //x pos of the 1st end of the line
.attr("y1", function(d, i) {
return lineHeights - (20 * i);
}) //y pos of the 1st end of the line
.attr("x2", function(d, i) {
return barWidth;
}) //x pos of the 2nd end of the line
.attr("y2", function(d, i) {
return lineHeights - (20 * i);
}); //y pos of the 2nd end of the line
//verticals
lines.enter()
.append("line") // attach a line
.style("stroke-dasharray", ("3, 3"))
.style("stroke", "black") // colour the line
.attr("x1", function(d, i) {
return 30 * i;
}) //x pos of the 1st end of the line
.attr("y1", function(d, i) {
return lineHeights - (20 * i);
}) //y pos of the 1st end of the line
.attr("x2", function(d, i) {
return 30 * i;
}) //x pos of the 2nd end of the line
.attr("y2", function(d, i) {
return -15;
}); //y pos of the 2nd end of the line

Here's the working JSFiddle: http://jsfiddle.net/NYEaX/1860/
Where you were appending the horizontal lines, you were using barWidth - 100/(i+1); to determine the x-axis. This would have worked if barWidth was actually the width of each bar, (but it had been set to 150 instead?)
.attr("x1", function(d, i) {
return (i * 30);
Each bar has a width of 20 and a margin of 5 on each side. So to calculate the offset, just multipy the bar number, i by with total width of the bar, 30.

Related

Alternating or preventing overlapping paths in D3

I am creating an arc diagram where I'd like to, hopefully, find a way to prevent the overlap of arcs. There's an example of the working bl.ock here.
The darker lines in this case are overlapping lines where multiple nodes share the same edge. I'd like to prevent that, perhaps by doing two passes: the first would alternate the arc to go above the nodes rather than below, giving a sort of helix appearance; the second would draw a slightly larger arc if an arc already exists above/below to help differentiate the links.
var width = 1000,
height = 500,
margin = 20,
pad = margin / 2,
radius = 6,
yfixed = pad + radius;
var color = d3.scale.category10();
// Main
//-----------------------------------------------------
function arcDiagram(graph) {
var radius = d3.scale.sqrt()
.domain([0, 20])
.range([0, 15]);
var svg = d3.select("#chart").append("svg")
.attr("id", "arc")
.attr("width", width)
.attr("height", height);
// create plot within svg
var plot = svg.append("g")
.attr("id", "plot")
.attr("transform", "translate(" + pad + ", " + pad + ")");
// fix graph links to map to objects
graph.links.forEach(function(d,i) {
d.source = isNaN(d.source) ? d.source : graph.nodes[d.source];
d.target = isNaN(d.target) ? d.target : graph.nodes[d.target];
});
linearLayout(graph.nodes);
drawLinks(graph.links);
drawNodes(graph.nodes);
}
// layout nodes linearly
function linearLayout(nodes) {
nodes.sort(function(a,b) {
return a.uniq - b.uniq;
})
var xscale = d3.scale.linear()
.domain([0, nodes.length - 1])
.range([radius, width - margin - radius]);
nodes.forEach(function(d, i) {
d.x = xscale(i);
d.y = yfixed;
});
}
function drawNodes(nodes) {
var gnodes = d3.select("#plot").selectAll("g.node")
.data(nodes)
.enter().append('g');
var nodes = gnodes.append("circle")
.attr("class", "node")
.attr("id", function(d, i) { return d.name; })
.attr("cx", function(d, i) { return d.x; })
.attr("cy", function(d, i) { return d.y; })
.attr("r", 5)
.style("stroke", function(d, i) { return color(d.gender); });
nodes.append("text")
.attr("dx", function(d) { return 20; })
.attr("cy", ".35em")
.text(function(d) { return d.name; })
}
function drawLinks(links) {
var radians = d3.scale.linear()
.range([Math.PI / 2, 3 * Math.PI / 2]);
var arc = d3.svg.line.radial()
.interpolate("basis")
.tension(0)
.angle(function(d) { return radians(d); });
d3.select("#plot").selectAll(".link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("transform", function(d,i) {
var xshift = d.source.x + (d.target.x - d.source.x) / 2;
var yshift = yfixed;
return "translate(" + xshift + ", " + yshift + ")";
})
.attr("d", function(d,i) {
var xdist = Math.abs(d.source.x - d.target.x);
arc.radius(xdist / 2);
var points = d3.range(0, Math.ceil(xdist / 3));
radians.domain([0, points.length - 1]);
return arc(points);
});
}
Any pointers on how I might start approaching the problem?
Here is a bl.ock for reference. It shows your original paths in gray, and the proposed paths in red.
First store the counts for how many times a given path occurs:
graph.links.forEach(function(d,i) {
var pathCount = 0;
for (var j = 0; j < i; j++) {
var otherPath = graph.links[j];
if (otherPath.source === d.source && otherPath.target === d.target) {
pathCount++;
}
}
d.pathCount = pathCount;
});
Then once you have that data, I would use an ellipse instead of a radial line since it appears the radial line can only draw a curve for a circle:
d3.select("#plot").selectAll(".ellipse-link")
.data(links)
.enter().append("ellipse")
.attr("fill", "transparent")
.attr("stroke", "gray")
.attr("stroke-width", 1)
.attr("cx", function(d) {
return (d.target.x - d.source.x) / 2 + radius;
})
.attr("cy", pad)
.attr("rx", function(d) {
return Math.abs(d.target.x - d.source.x) / 2;
})
.attr("ry", function(d) {
return 150 + d.pathCount * 20;
})
.attr("transform", function(d,i) {
var xshift = d.source.x - radius;
var yshift = yfixed;
return "translate(" + xshift + ", " + yshift + ")";
});
Note that changing the value for ry above will change the heights of different curves.
Finally you'll have to use a clippath to restrict the area of each ellipse that's actually shown, so that they only display below the nodes. (This is not done in the bl.ock)

How to update a bar chart with accompanying text in d3?

I'm creating a bar chart as part of a bigger data visualization in d3. I want to be able to change the data in one part of the visualization and all the charts will be updated. A simplified version of the chart is as follows.
var dataset = [1, 3, 5, 3, 3];
...
var svg = d3.select("body #container").append("svg")
.attr("width", width)
.attr("height", height);
var g = svg.append("g");
...
I create other charts like a map, circle etc with this svg element. The bar chart is implemented like this.
function bars(dataset) {
var barChart = g.selectAll("rect.bar")
.data(dataset)
.enter();
barChart.append("rect")
.attr("class", "bar")
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
barChart.append("text")
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}
Now this renders the bar chart fine but there is a function
...
.on("click", function() {
...
var newdata = [5, 2, 6, 2, 4]; // new values
g.selectAll("rect.bar").remove(); // This removes the bars
g.selectAll("text").remove(); // Problem here: All texts are removed
bars(newdata);
}
I have tried to transition the bar chart with new values with the .remove() function. This works for the bar rectangles because there are no othe bar charts but when I tried to remove the value labels like shown above all the other text elements were also removed. Is there a way to only update the text associated with the bars?
Have you tried applying a class to the text and only selecting those ones for removal?
e.g.
barChart.append("text")
.attr('class','label')
.text(function(d) { return d; })
then
g.selectAll(".label").remove();
Incidentally, if not all of the elements are being deleted between updates, then instead of removing all of the elements, have you considered using enter() and exit() to bind the new data to the existing elements and only remove the elements that are changing?
EDIT Like this:
function bars(dataset) {
var bar = g.selectAll(".bar").data(dataset);
bar.exit().remove();
bar.enter().append("rect").attr("class", "bar");
bar
.attr("x", function(d, i) { return i * 30 + 100; })
.attr("y", function(d) { return (height - 130) - d * 4;})
.attr("width", 25)
.attr("height", function(d) { return d * 4; });
var label = g.selectAll(".label").data(dataset);
label.exit().remove();
label.enter().append("text").attr("class", "label");
label
.text(function(d) { return d; })
.attr("x", function(d, i) { return i * 30 + 103; })
.attr("y", function(d) { return (height - 130) - d/10 - 5;})
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.attr("fill", "darkgray");
}

How to add an arrow to the marker in buller chart using d3

Fiddle Example
I'd like to know how to add an arrowhead marker to the symbol marker in bullet chart to make it clear what it means, sort of like this:
I've tried adding this block of code to the bullet function,but it is nowhere to be seen:
marker.enter().append("line")
.attr("class", "marker")
.attr("marker-start","url(#avg)")
.attr("x1", x0)
.attr("x2", x0)
.attr("y1", height / 6)
.attr("y2", height * 5 / 6)
g.append("svg:defs")
.append("svg:marker")
.attr("id", "avg")
.attr("viewBox", "0 5 10 10")
.attr("refX", 340)
.attr("refY", 1)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
Can anyone show me how to add an arrow marker?
Here's the code:
(function() {
// Chart design based on the recommendations of Stephen Few. Implementation
// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
// http://projects.instantcognition.com/protovis/bulletchart/
d3.bullet = function() {
var orient = "left", // TODO top & bottom
reverse = false,
duration = 0,
ranges = bulletRanges,
markers = bulletMarkers,
measures = bulletMeasures,
width = 380,
height =100,
tickFormat = null;
// For each small multiple…
function bullet(g) {
g.each(function(d, i) {
var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
markerz = markers.call(this, d, i).slice().sort(d3.descending),
measurez = measures.call(this, d, i).slice().sort(d3.descending),
g = d3.select(this);
// Compute the new x-scale.
var x1 = d3.scale.linear()
.domain([0, Math.max(rangez[0], markerz[0], measurez[0])])
.range(reverse ? [width, 0] : [0, width]);
// Retrieve the old x-scale, if this is an update.
var x0 = this.__chart__ || d3.scale.linear()
.domain([0, Infinity])
.range(x1.range());
// Stash the new scale.
this.__chart__ = x1;
// Derive width-scales from the x-scales.
var w0 = bulletWidth(x0),
w1 = bulletWidth(x1);
// Update the range rects.
var range = g.selectAll("rect.range")
.data(rangez).enter()
var range2 = range.append("rect")
.attr("class", function(d, i) { return "range s" + i; })
.attr("width", w0)
.attr("height", height)
.attr("x", reverse ? x0 : 0)
.transition()
.duration(duration)
.attr("width", w1)
.attr("x", reverse ? x1 : 0)
.transition()
.duration(duration)
.attr("x", reverse ? x1 : 0)
.attr("width", w1)
.attr("height", height);
range.append("text").text(function(d,k){
console.log(k)
})
.attr("x",w1)
.attr("y",height * 2)
.attr("class","3232")
// Update the measure rects.
var measure = g.selectAll("rect.measure")
.data(measurez).enter()
measure.append("rect")
.attr("class", function(d, i) { return "measure s" + i; })
.attr("width", w0)
.attr("height", height / 3)
.attr("x", reverse ? x0 : 0)
.attr("y", height / 3)
.attr("marker-end","url(#b_1)")
.transition()
.duration(duration)
.attr("width", w1)
.attr("x", reverse ? x1 : 0)
.transition()
.duration(duration)
.attr("width", w1)
.attr("height", height / 3)
.attr("x", reverse ? x1 : 0)
.attr("y", height / 3);
// Update the marker lines.
var marker = g.selectAll("line.marker")
.data(markerz);
marker.enter().append("line")
.attr("class", "marker")
.attr("marker-start","url(#avg)")
.attr("x1", x0)
.attr("x2", x0)
.attr("y1", height / 6)
.attr("y2", height * 5 / 6)
.transition()
.duration(duration)
.attr("x1", x1)
.attr("x2", x1);
marker.transition()
.duration(duration)
.attr("x1", x1)
.attr("x2", x1)
.attr("y1", height / 6)
.attr("y2", height * 5 / 6);
// Compute the tick format.
var format = tickFormat || x1.tickFormat(8);
// Update the tick groups.
var tick = g.selectAll("g.tick")
.data(x1.ticks(8), function(d) {
return this.textContent || format(d);
});
// Initialize the ticks with the old scale, x0.
var tickEnter = tick.enter().append("g")
.attr("class", "tick")
.attr("transform", bulletTranslate(x0))
.style("opacity", 1e-6);
tickEnter.append("line")
.attr("y1", height)
.attr("y2", height * 7 / 6);
tickEnter.append("text")
.attr("text-anchor", "middle")
.attr("dy", "1em")
.attr("y", height * 7 / 6)
.text(format);
// Transition the entering ticks to the new scale, x1.
tickEnter.transition()
.duration(duration)
.attr("transform", bulletTranslate(x1))
.style("opacity", 1);
// Transition the updating ticks to the new scale, x1.
var tickUpdate = tick.transition()
.duration(duration)
.attr("transform", bulletTranslate(x1))
.style("opacity", 1);
tickUpdate.select("line")
.attr("y1", height)
.attr("y2", height * 7 / 6);
tickUpdate.select("text")
.attr("y", height * 7 / 6);
// Transition the exiting ticks to the new scale, x1.
tick.exit().transition()
.duration(duration)
.attr("transform", bulletTranslate(x1))
.style("opacity", 1e-6)
.remove();
g.append("svg:defs")
.append("svg:marker")
.attr("id", "avg")
.attr("viewBox", "0 5 10 10")
.attr("refX", 340)
.attr("refY", 1)
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M0,-5L10,0L0,5");
});
d3.timer.flush();
}
// left, right, top, bottom
bullet.orient = function(x) {
if (!arguments.length) return orient;
orient = x;
reverse = orient == "right" || orient == "bottom";
return bullet;
};
// ranges (bad, satisfactory, good)
bullet.ranges = function(x) {
if (!arguments.length) return ranges;
ranges = x;
return bullet;
};
// markers (previous, goal)
bullet.markers = function(x) {
if (!arguments.length) return markers;
markers = x;
return bullet;
};
// measures (actual, forecast)
bullet.measures = function(x) {
if (!arguments.length) return measures;
measures = x;
return bullet;
};
bullet.width = function(x) {
if (!arguments.length) return width;
width = x;
return bullet;
};
bullet.height = function(x) {
if (!arguments.length) return height;
height = x;
return bullet;
};
bullet.tickFormat = function(x) {
if (!arguments.length) return tickFormat;
tickFormat = x;
return bullet;
};
bullet.duration = function(x) {
if (!arguments.length) return duration;
duration = x;
return bullet;
};
return bullet;
};

How to make plotting possible on x-axis lines only? (d3.js)

I've just started with trying out the d3 library.
I am trying to create an interactive line chart where people can plot their own points. You can find it over here: http://jsfiddle.net/6FjJ2/
My question is: how can I make sure that plotting can only be done on the x-axis' lines? If you check out my example, you will see it kind of works, but with a lot of cheating. Check out the ok variable... What would be the correct way of achieving this? I have no idea how I can achieve this with a ... so I'm getting a lot of seperate 's.
var data = [2, 3, 4, 3, 4, 5],
w = 1000,
h = 300,
monthsData = [],
months = 18;
for(i = 0; i < months; i++) {
monthsData.push(i);
}
var max = d3.max(monthsData),
x = d3.scale.linear().domain([0, monthsData.length]).range([0, w]),
y = d3.scale.linear().domain([0, max]).range([h, 0]),
pointpos = [];
lvl = [0, 10],
lvly = d3.scale.linear().domain([0, d3.max(lvl)]).range([h, 0]);
svg = d3.select(".chart")
.attr("width", w)
.attr("height", h);
svg.selectAll('path.line')
// Return "data" array which will form the path coordinates
.data([data])
// Add path
.enter().append("svg:path")
.attr("d", d3.svg.line()
.x(function(d, i) { return x(i); })
.y(y));
// Y-axis ticks
ticks = svg.selectAll(".ticky")
// Change number of ticks for more gridlines!
.data(lvly.ticks(10))
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(0, " + (lvly(d)) + ")"; })
.attr("class", "ticky");
ticks.append("svg:line")
.attr("y1", 0)
.attr("y2", 0)
.attr("x1", 0)
.attr("x2", w);
ticks.append("svg:text")
.text( function(d) { return d; })
.attr("text-anchor","end")
.attr("dy", 2)
.attr("dx", -4);
// X-axis ticks
ticks = svg.selectAll(".tickx")
.data(x.ticks(monthsData.length))
.enter().append("svg:g")
.attr("transform", function(d, i) { return "translate(" + (x(i)) + ", 0)"; })
.attr("class", "tickx");
ticks.append("svg:line")
.attr("y1", h)
.attr("y2", 0)
.attr("x1", 0)
.attr("x2", 0);
ticks.append("svg:text")
.text( function(d, i) { return i; })
.attr("y", h)
.attr("dy", 15)
.attr("dx", -2);
// var d = $(".tickx:first line").css({"stroke-width" : "2", opacity : "1"});
var line;
var ok = -55;
svg.on("mousedown", mouseDown)
.on("mouseup", mouseUp);
function mouseDown() {
var m = d3.mouse(this);
line = svg.append("line")
.data(monthsData)
/* .attr("x1", m[0]) */
.attr("x1", function(d, i) { pointpos.push(m[0]); ok += 55; return ok;})
.attr("y1", m[1])
.attr("x2", function(d, i) { return ok + 56; })
/* .attr("x2", function(d, i) {return 300; }) */
.attr("y2", m[1]);
svg.on("mousemove", mouseMove);
var m = d3.mouse(this);
var point = svg.append("circle")
.attr("cx", function(d, i) { return ok; })
.attr("cy", function(d, i) { return m[1]; })
.attr("r", 8);
lvl.push(100);
}
function mouseMove() {
var m = d3.mouse(this);
line.attr("y2", m[1]);
/* .attr("y1", m[0]); */
}
function mouseUp() {
// Change null to mousemove for a graph kinda draw mode
svg.on("mousemove", mouseMove);
}
Excuse my bad code!
Thanks in advance.
It looks like you need:
histogram layout for binning your points.
ordinal scales for restricting their x-axis positions according to the bin
As a sidenote, you can use d3.svg.axis to draw the axis for you.

dealing with dates on d3.js axis

How do I make my line x-axis based on date in d3.js?
I am attempting to teach myself how to use d3.js. I've been looking at the examples that come with it and have been attempting to recreate the line graph using json delivered data. I'm able to feed the data into the line graph, but the x-axis is supposed to be a date instead of a number. The date format that I'm using is MM/DD/YY, but the graph plots everything at 0. My json data is coming across fine, but I'm having trouble figuring out how to plot the x coordinates. This was taken straight from the line.js that comes in the d3.js examples folder when downloaded. The date portion doesn't do the trick. I'm hoping someone can point me to an example or be able to explain how I can make it work.
d3.json('jsonChartData.action',
function (data) {
console.log(data);
var w = 450,
h = 275,
p = 30,
x = d3.scale.linear().domain([0, 100]).range([0, w]),
y = d3.scale.linear().domain([0, 100]).range([h, 0]);
var vis = d3.select("body")
.data([data])
.append("svg:svg")
.attr("width", w + p * 2)
.attr("height", h + p * 2)
.append("svg:g")
.attr("transform", "translate(" + p + "," + p + ")");
var rules = vis.selectAll("g.rule")
.data(x.ticks(5))
.enter().append("svg:g")
.attr("class", "rule");
rules.append("svg:line")
.attr("x1", x)
.attr("x2", x)
.attr("y1", 0)
.attr("y2", h - 1);
rules.append("svg:line")
.attr("class", function(d) { return d ? null : "axis"; })
.attr("y1", y)
.attr("y2", y)
.attr("x1", 0)
.attr("x2", w + 1);
rules.append("svg:text")
.attr("x", x)
.attr("y", h + 3)
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(x.tickFormat(10));
rules.append("svg:text")
.attr("y", y)
.attr("x", -3)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(y.tickFormat(10));
vis.append("svg:path")
.attr("class", "line")
.attr("d", d3.svg.line()
.x(function(d) { return x(d3.time.days(new Date(d.jsonDate))); })
.y(function(d) { return y(d.jsonHitCount); }));
vis.selectAll("circle.line")
.data(data)
.enter().append("svg:circle")
.attr("class", "line")
.attr("cx", function(d) { return x(d3.time.days(new Date(d.jsonDate))); })
.attr("cy", function(d) { return y(d.jsonHitCount); })
.attr("r", 3.5);
});
JSON as printed out by my action:
[{"jsonDate":"09\/22\/11","jsonHitCount":2,"seriesKey":"Website Usage"},`{"jsonDate":"09\/26\/11","jsonHitCount":9,"seriesKey":"Website Usage"},{"jsonDate":"09\/27\/11","jsonHitCount":9,"seriesKey":"Website Usage"},{"jsonDate":"09\/29\/11","jsonHitCount":26,"seriesKey":"Website Usage"},{"jsonDate":"09\/30\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/03\/11","jsonHitCount":3,"seriesKey":"Website Usage"},{"jsonDate":"10\/06\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/11\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/12\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/13\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"10\/14\/11","jsonHitCount":5,"seriesKey":"Website Usage"},{"jsonDate":"10\/17\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/18\/11","jsonHitCount":6,"seriesKey":"Website Usage"},{"jsonDate":"10\/19\/11","jsonHitCount":8,"seriesKey":"Website Usage"},{"jsonDate":"10\/20\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"10\/21\/11","jsonHitCount":4,"seriesKey":"Website Usage"},{"jsonDate":"10\/24\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"10\/25\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"10\/27\/11","jsonHitCount":3,"seriesKey":"Website Usage"},{"jsonDate":"11\/01\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"11\/02\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"11\/03\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"11\/04\/11","jsonHitCount":37,"seriesKey":"Website Usage"},{"jsonDate":"11\/08\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"11\/10\/11","jsonHitCount":39,"seriesKey":"Website Usage"},{"jsonDate":"11\/11\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"11\/14\/11","jsonHitCount":15,"seriesKey":"Website Usage"},{"jsonDate":"11\/15\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"11\/16\/11","jsonHitCount":5,"seriesKey":"Website Usage"},{"jsonDate":"11\/17\/11","jsonHitCount":4,"seriesKey":"Website Usage"},{"jsonDate":"11\/21\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"11\/22\/11","jsonHitCount":3,"seriesKey":"Website Usage"},{"jsonDate":"11\/23\/11","jsonHitCount":11,"seriesKey":"Website Usage"},{"jsonDate":"11\/24\/11","jsonHitCount":2,"seriesKey":"Website Usage"},{"jsonDate":"11\/25\/11","jsonHitCount":1,"seriesKey":"Website Usage"},{"jsonDate":"11\/28\/11","jsonHitCount":10,"seriesKey":"Website Usage"},{"jsonDate":"11\/29\/11","jsonHitCount":3,"seriesKey":"Website Usage"}]`
You're trying to use d3.scale.linear() for dates, and that won't work. You need to use d3.time.scale() instead (docs):
// helper function
function getDate(d) {
return new Date(d.jsonDate);
}
// get max and min dates - this assumes data is sorted
var minDate = getDate(data[0]),
maxDate = getDate(data[data.length-1]);
var x = d3.time.scale().domain([minDate, maxDate]).range([0, w]);
Then you don't need to deal with the time interval functions, you can just pass x a date:
.attr("d", d3.svg.line()
.x(function(d) { return x(getDate(d)) })
.y(function(d) { return y(d.jsonHitCount) })
);
Working fiddle here: http://jsfiddle.net/nrabinowitz/JTrnC/

Categories

Resources