Hi I implemented the multiline graph with tooltip using the following posts help,Multiseries line chart with mouseover tooltip
But i am facing the following issue,
At all points the highest point is displayed(58) and since its a linear graph the values at straight lines are not displayed.
The code for this is as shown below:
var margin = { top : 20,
right : 100,
bottom : 100,
left : 60},
margin2 = { top : 430,
right : 10,
bottom : 20,
left : 40},
width = 600 ,
height = 500- margin.top - margin.bottom - 20,
height2 = 500 - margin2.top - margin2.bottom - 5;
var parseDate = d3.time.format("%Y%m%d%H").parse;
var xScale = d3.time.scale().range([ 0, width ]),
xScale2 = d3.time.scale().range([ 0, width ]);
var yScale = d3.scale.linear().range([ height, 0 ]);
var color = d3.scale.ordinal().range( [ "#48A36D", "#9788CD", "#E2AA59" ]);
var xAxis = d3.svg.axis().scale(xScale).orient( "bottom"),
xAxis2 = d3.svg.axis().scale(xScale2).orient("bottom");
var yAxis = d3.svg.axis().scale(yScale).orient("left");
var line = d3.svg.line().interpolate("linear").x( function ( d ) {
return xScale(d.date);
}).y(function ( d ) {
return yScale(d.rating);
})
var maxY;
var svg = d3.select("#chart").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom +100) .append("g").attr( "transform","translate(" + margin.left + ","+ margin.top + ")");
svg.append("rect").attr("width", width).attr("height", height).attr("x", 0).attr("y", 0).attr("id", "mouse-tracker").style("fill", "transparent");
var context = svg.append("g")
.attr("transform","translate(" + 0 + "," + 395 + ")")
.attr("class", "context");
svg.append("defs").append("clipPath").attr("id","clip").append("rect")
.attr("width", width)
.attr("height", height);
d3.json( "/a//aaaa/aaa",function ( data ) {
var time_changed = function ( timeFormat ) {
var split = 0;
switch ( timeFormat ) {
case 'M':
split = 12;
break;
case 'H':
split = 10;
break;
case 'D':
split = 8;
break;
case 'm':
split = 6;
break;
case 'Y':
split = 4;
break;
}
var temp = data.map(function ( d ) {dat = d.date.substring(0,10);
return {data = temp;}
time_changed('d');
data.forEach(function ( d ) { d.date = parseDate(d.date); });
var categories = color.domain().map( function ( name ) {
return {
name : name, values : data .map(function ( d ) { return { date : d.date, rating : +(d[name]), }; }), visible : (name === "A" ? true: false)
};});
xScale.domain(d3.extent(data, function ( d ) { return d.date; }));
maxY = findMaxY(categories);
yScale.domain([ 0, maxY]); xScale2.domain(xScale.domain());
var brush = d3.svg.brush().x(xScale2).on("brush", brushed);
context.append("g").attr("class", "x axis1").attr( "transform","translate(0,"+ height2 + ")").call(xAxis2);
var contextArea = d3.svg.area().interpolate("monotone").x( function ( d ) {
return xScale2(d.date); })
.y0(height2) .y1(0);
context.append("path") .attr( "d",contextArea(categories[0].values))
.attr("fill","darkgray");
context.append("g").attr( "class", "x brush") .call(brush).selectAll("rect").attr( "height", height2)
.attr("fill", "coral");
svg.append("g").attr("class", "x axis").attr( "transform",
"translate(0," + height + ")").attr( "fill", "white").call(
xAxis);
svg .append("g") .attr("class", "y axis") .call(yAxis)
.append("text").attr("transform",
"rotate(-90)") .attr("y", 6) .attr("x", -10) .attr("dy", ".71em")
.attr("fill", "white") .style("text-anchor", "end")
var issue = svg.selectAll(
".issue").data(
categories)
.enter().append("g").attr(
"class", "issue");
issue
.append("path")
.attr("class", "line")
.style(
"pointer-events",
"none")
.attr(
"id",
function ( d ) {
return "line-"
+ d.name
.replace(
" ",
"")
.replace(
"/",
""); // Give
// line id
// of
// line-(insert
// issue
// name,with
// any
// spaces
// replaced
// with no
// spaces) }) .attr( "d", function ( d ) { return d.visible ? line(d.values): null; })
.attr("clip-path","url(#clip)") .style( "stroke", function ( d ) { return color(d.name); });
var legendSpace = 450 / categories.length;
issue .append("rect") .attr("width", 10) .attr("height", 10)
.attr( "x",width + (margin.right / 3) - 15)
.attr( "y",function ( d, i ) { return (legendSpace)+ i * (legendSpace)- 8; }) .attr( "fill", function ( d ) { return d.visible ? color(d.name): "#F1F1F2"; })
.attr("class","legend-box") .on( "click", function ( d ) {d.visible = !d.visible;
maxY = findMaxY(categories);
yScale.domain([0,maxY ]);
svg.select(".y.axis").transition().call(yAxis);
issue.select("path")
.transition()
.attr("d",function (d ) { return d.visible ? line(d.values): null;})
issue.select("rect")
.transition() .attr("fill",function (d ) { return d.visible ? color(d.name): "#F1F1F2";
});
})
.on( "mouseover", function ( d ) {
d3
.select(
this)
.transition()
.attr(
"fill",
function (d ) {return color(d.name);});
d3
.select(
"#line-"
+ d.name
.replace(
" ",
"")
.replace(
"/",
""))
.transition()
.style(
"stroke-width",
2.5);
})
.on(
"mouseout",
function ( d ) {
d3
.select(
this)
.transition()
.attr(
"fill",
function (
d ) {
return d.visible ? color(d.name)
: "#F1F1F2";
});
d3
.select(
"#line-"
+ d.name
.replace(
" ",
"")
.replace(
"/",
""))
.transition()
.style(
"stroke-width",
1.5);
})
issue
.append("text")
.attr(
"x",
width
+ (margin.right / 3))
.attr(
"y",
function ( d, i ) {
return (legendSpace)
+ i
* (legendSpace);
}) // (return
// (11.25/2
// =) 5.625)
// + i *
// (5.625)
.text(function ( d ) {
return d.name;
});
// Hover line
var hoverLineGroup = svg
.append("g").attr(
"class",
"hover-line");
var hoverLine = hoverLineGroup
// Create line with
// basic attributes
.append("line")
.attr("id",
"hover-line")
.attr("x1", 10)
.attr("x2", height)
.attr("y1", 0)
.attr("y2", height + 10)
.style(
"pointer-events",
"none")
.style("opacity", 1e-6);
var hoverDate = hoverLineGroup .append('text')
.attr("class", "hover-text") .attr( "y",height
- (height - 40)) .attr("x", width - 150) .style("fill",
"#E6E7E8");
var columnNames = d3.keys(
data[0]) // grab the
// key values from your first
// data row these are the same
// as your column names
.slice(1); // remove the first
// column name (`date`);
var focus = issue.select("g") // create
// group elements to house
// tooltip text
.data(columnNames) // bind each
// column name date to each g
// element
.enter().append("g") // create
// one <g> for each columnName
.attr("class", "focus");
focus
.append("text")
.attr("class",
"tooltip")
.attr("fill", "white")
.attr("x", width + 20)
// position tooltips
.attr(
"y",
function ( d, i ) {
return (legendSpace)
+ i
* (legendSpace);
}); // (return
// (11.25/2 =) 5.625) + i *
// (5.625) position tooltips
function mousemove () {
var mouse_x = d3
.mouse(this)[0]; // Finding
// mouse x position on rect
var graph_x = xScale
.invert(mouse_x);
// var mouse_y =
// d3.mouse(this)[1]; //
// Finding mouse y position
// on rect
// var graph_y =
// yScale.invert(mouse_y);
// console.log(graph_x);
var format = d3.time
.format('%b %Y'); hoverDate
.text(format(graph_x)); d3
.select(
"#hover-line")
.attr("x1", mouse_x)
.attr("x2", mouse_x)
.style("opacity", 1);
var x0 = xScale.invert(d3 .mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1], d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0; focus.select("text").text(function (columnName ) { return (d[columnName]); }); };
function brushed () {
xScale .domain(brush .empty() ? xScale2.domain(): brush.extent());
svg.select(".x.axis").transition().call(xAxis);
maxY = findMaxY(categories);
yScale.domain([ 0, maxY ]);
svg.select(".y.axis").transition().call(yAxis);
issue.select("path").transition().attr("d",function (d ) {
return d.visible ? line(d.values): null; }); };
function findMaxY ( data ) {
var maxYValues = data .map(function ( d ) { if ( d.visible ) {
return d3.max(d.values,function (value ) {return value.rating;
}) } }); return d3.max(maxYValues);
}
var mouseG = svg.append("g")
.attr("class", "mouse-over-effects");
mouseG.append("path")
.attr("class", "mouse-line").style("stroke", "white") .style("stroke-width", "1px").style("opacity", "0");
var lines = document.getElementsByClassName('line');
var mousePerLine = mouseG.selectAll('.mouse-per-line') .data(categories)
.enter().append("g").attr("class", "mouse-per-line");
mousePerLine.append("circle").attr("r", 7) .style("stroke", function(d) {
return color(d.name);
})
.style("fill", function(d) {return color(d.name);})
.style("stroke-width", "1px") .style("opacity", "0");
mousePerLine.append("text").attr("transform", "translate(10,3)").style("font-size", "12px").style("font-family", "cursive")
.attr("fill", "white");
mouseG.append('svg:rect').attr('width', width).attr('height', height)
.attr('fill', 'none').attr('pointer-events', 'all')
.on('mouseout', function({ d3.select(".mouse-line").style("opacity","0");
d3.selectAll(".mouse-per-line circle") .style("opacity", "0");
d3.selectAll(".mouse-per-line text").style("opacity", "0");
}).on('mouseover', function() {
d3.select(".mouse-line")
.style("opacity", "1");
d3.selectAll(".mouse-per-line circle")
.style("opacity", "1");
d3.selectAll(".mouse-per-line text")
.style("opacity", "1");
})
.on('mousemove', function() { var mouse = d3.mouse(this);
d3.select(".mouse-line").attr("d", function() {
var d = "M" + mouse[0] + "," + height;
d += " " + mouse[0] + "," + 0;
return d; });
d3.selectAll(".mouse-per-line").attr("transform", function(d, i) {
var xDate = xScale.invert(mouse[0]),
bisect = d3.bisector(function(d) { return d.date; }).right;
idx = bisect(d.values, xDate);
var beginning = 0,
end = lines[i].getTotalLength(),target = null;
while (true){target = Math.floor((beginning + end) / 2);
pos = lines[i].getPointAtLength(target);
if ((target === end || target === beginning) && pos.x !== mouse[0]) {
break; }
if (pos.x > mouse[0]) end = target;
else if (pos.x < mouse[0]) beginning = target;
else break; }
d3.select(this).select('text')
.text(yScale.invert(pos.y).toFixed(2));
return "translate(" + mouse[0] + "," + pos.y +")"; });
}); }); });
Does anybody know where i am going wrong My json format is as follows: date:25012016 A:12 B:11 C:0.44, date:25012016 A:99 B:11 C:0.44,