1
D3.jsをツールチップとともに使用して複数行のチャートを作成しました。このグラフではすべてが正常に機能していますが、グラフのすべてのグラフのツールチップにスタイリングを追加したいが、そうすることはできません。マルチラインD3.jsラインチャートのツールチップのスタイル
var margin = {
top: 20,
right: 30,
bottom: 30,
left: 40
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var z = d3.scale.category20c();
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ");
var data = [{
data: [
["2016-01-20T05:31:17.000Z", 95.9, {}],
["2016-01-20T05:31:47.000Z", 95.9, {}],
["2016-01-20T05:32:17.000Z", 95.4, {}],
["2016-01-20T05:32:47.000Z", 96.1, {}],
["2016-01-20T05:33:17.000Z", 95.7, {}],
["2016-01-20T05:33:47.000Z", 95.9, {}],
["2016-01-20T05:34:17.000Z", 95.5, {}],
["2016-01-20T05:34:47.000Z", 95.9, {}],
["2016-01-20T05:35:17.000Z", 95.8, {}],
["2016-01-20T05:35:47.000Z", 95.9, {}],
["2016-01-20T05:36:17.000Z", 95.7, {}],
["2016-01-20T05:36:47.000Z", 95.7, {}],
["2016-01-20T05:37:17.000Z", 95.9, {}],
["2016-01-20T05:37:47.000Z", 95.5, {}],
["2016-01-20T05:38:17.000Z", 95.4, {}],
["2016-01-20T05:38:47.000Z", 95.8, {}],
["2016-01-20T05:39:17.000Z", 96.0, {}],
["2016-01-20T05:39:47.000Z", 96.1, {}],
["2016-01-20T05:40:17.000Z", 95.8, {}],
["2016-01-20T05:40:47.000Z", 96.0, {}],
["2016-01-20T05:41:17.000Z", 95.9, {}],
["2016-01-20T05:41:47.000Z", 94.9, {}],
["2016-01-20T05:42:17.000Z", 95.8, {}],
["2016-01-20T05:42:47.000Z", 95.9, {}],
["2016-01-20T05:43:17.000Z", 95.8, {}],
["2016-01-20T05:43:47.000Z", 96.0, {}],
["2016-01-20T05:44:17.000Z", 95.7, {}],
["2016-01-20T05:44:47.000Z", 96.0, {}],
["2016-01-20T05:45:17.000Z", 95.9, {}],
["2016-01-20T05:45:47.000Z", 96.0, {}],
["2016-01-20T05:46:17.000Z", 95.8, {}],
["2016-01-20T05:46:47.000Z", 96.0, {}],
["2016-01-20T05:47:17.000Z", 95.7, {}],
["2016-01-20T05:47:47.000Z", 96.2, {}],
["2016-01-20T05:48:17.000Z", 95.8, {}],
["2016-01-20T05:48:47.000Z", 95.9, {}],
["2016-01-20T05:49:17.000Z", 95.7, {}],
["2016-01-20T05:49:47.000Z", 95.9, {}],
["2016-01-20T05:50:18.000Z", 95.7, {}],
["2016-01-20T05:50:48.000Z", 95.8, {}],
["2016-01-20T05:51:18.000Z", 95.7, {}],
["2016-01-20T05:51:48.000Z", 95.9, {}],
["2016-01-20T05:52:18.000Z", 95.5, {}],
["2016-01-20T05:52:48.000Z", 95.9, {}],
["2016-01-20T05:53:18.000Z", 95.8, {}],
["2016-01-20T05:53:48.000Z", 95.9, {}],
["2016-01-20T05:54:18.000Z", 95.7, {}],
["2016-01-20T05:54:48.000Z", 95.9, {}],
["2016-01-20T05:55:18.000Z", 95.8, {}],
["2016-01-20T05:55:48.000Z", 95.8, {}],
["2016-01-20T05:56:18.000Z", 95.6, {}],
["2016-01-20T05:56:48.000Z", 95.7, {}],
["2016-01-20T05:57:18.000Z", 95.7, {}],
["2016-01-20T05:57:48.000Z", 95.8, {}],
["2016-01-20T05:58:18.000Z", 95.7, {}],
["2016-01-20T05:58:48.000Z", 95.7, {}],
["2016-01-20T05:59:18.000Z", 95.6, {}],
["2016-01-20T05:59:48.000Z", 95.8, {}],
["2016-01-20T06:00:18.000Z", 95.7, {}],
["2016-01-20T06:00:48.000Z", 95.7, {}],
["2016-01-20T06:01:18.000Z", 95.6, {}],
["2016-01-20T06:01:48.000Z", 95.7, {}],
["2016-01-20T06:02:18.000Z", 95.8, {}],
["2016-01-20T06:02:48.000Z", 95.8, {}],
["2016-01-20T06:03:18.000Z", 95.8, {}],
["2016-01-20T06:03:48.000Z", 95.8, {}],
["2016-01-20T06:04:18.000Z", 95.8, {}],
["2016-01-20T06:04:48.000Z", 95.8, {}],
["2016-01-20T06:05:18.000Z", 95.7, {}],
["2016-01-20T06:05:48.000Z", 95.7, {}]
],
label: "a"
}, {
data: [
["2016-01-20T05:31:17.000Z", 90.9, {}],
["2016-01-20T05:31:47.000Z", 91.9, {}],
["2016-01-20T05:32:17.000Z", 92.4, {}],
["2016-01-20T05:32:47.000Z", 90.1, {}],
["2016-01-20T05:33:17.000Z", 89.7, {}],
["2016-01-20T05:33:47.000Z", 91.9, {}],
["2016-01-20T05:34:17.000Z", 85.5, {}],
["2016-01-20T05:34:47.000Z", 93.9, {}],
["2016-01-20T05:35:17.000Z", 94.8, {}],
["2016-01-20T05:35:47.000Z", 93.9, {}],
["2016-01-20T05:36:17.000Z", 92.7, {}],
["2016-01-20T05:36:47.000Z", 95.7, {}],
["2016-01-20T05:37:17.000Z", 92.9, {}],
["2016-01-20T05:37:47.000Z", 93.5, {}],
["2016-01-20T05:38:17.000Z", 93.4, {}],
["2016-01-20T05:38:47.000Z", 93.8, {}],
["2016-01-20T05:39:17.000Z", 93.0, {}],
["2016-01-20T05:39:47.000Z", 93.1, {}],
["2016-01-20T05:40:17.000Z", 93.8, {}],
["2016-01-20T05:40:47.000Z", 93.0, {}],
["2016-01-20T05:41:17.000Z", 93.9, {}],
["2016-01-20T05:41:47.000Z", 93.9, {}],
["2016-01-20T05:42:17.000Z", 92.8, {}],
["2016-01-20T05:42:47.000Z", 92.9, {}],
["2016-01-20T05:43:17.000Z", 93.8, {}],
["2016-01-20T05:43:47.000Z", 93.0, {}],
["2016-01-20T05:44:17.000Z", 93.7, {}],
["2016-01-20T05:44:47.000Z", 93.0, {}],
["2016-01-20T05:45:17.000Z", 93.9, {}],
["2016-01-20T05:45:47.000Z", 93.0, {}],
["2016-01-20T05:46:17.000Z", 93.8, {}],
["2016-01-20T05:46:47.000Z", 96.0, {}],
["2016-01-20T05:47:17.000Z", 92.7, {}],
["2016-01-20T05:47:47.000Z", 92.2, {}],
["2016-01-20T05:48:17.000Z", 92.8, {}],
["2016-01-20T05:48:47.000Z", 92.9, {}],
["2016-01-20T05:49:17.000Z", 92.7, {}],
["2016-01-20T05:49:47.000Z", 92.9, {}],
["2016-01-20T05:50:18.000Z", 93.7, {}],
["2016-01-20T05:50:48.000Z", 93.8, {}],
["2016-01-20T05:51:18.000Z", 92.7, {}],
["2016-01-20T05:51:48.000Z", 92.9, {}],
["2016-01-20T05:52:18.000Z", 92.5, {}],
["2016-01-20T05:52:48.000Z", 94.9, {}],
["2016-01-20T05:53:18.000Z", 94.8, {}],
["2016-01-20T05:53:48.000Z", 94.9, {}],
["2016-01-20T05:54:18.000Z", 94.7, {}],
["2016-01-20T05:54:48.000Z", 94.9, {}],
["2016-01-20T05:55:18.000Z", 94.8, {}],
["2016-01-20T05:55:48.000Z", 93.8, {}],
["2016-01-20T05:56:18.000Z", 94.6, {}],
["2016-01-20T05:56:48.000Z", 94.7, {}],
["2016-01-20T05:57:18.000Z", 93.7, {}],
["2016-01-20T05:57:48.000Z", 93.8, {}],
["2016-01-20T05:58:18.000Z", 93.7, {}],
["2016-01-20T05:58:48.000Z", 93.7, {}],
["2016-01-20T05:59:18.000Z", 93.6, {}],
["2016-01-20T05:59:48.000Z", 93.8, {}],
["2016-01-20T06:00:18.000Z", 93.7, {}],
["2016-01-20T06:00:48.000Z", 93.7, {}],
["2016-01-20T06:01:18.000Z", 93.6, {}],
["2016-01-20T06:01:48.000Z", 94.7, {}],
["2016-01-20T06:02:18.000Z", 94.8, {}],
["2016-01-20T06:02:48.000Z", 94.8, {}],
["2016-01-20T06:03:18.000Z", 94.8, {}],
["2016-01-20T06:03:48.000Z", 94.8, {}],
["2016-01-20T06:04:18.000Z", 94.8, {}],
["2016-01-20T06:04:48.000Z", 94.8, {}],
["2016-01-20T06:05:18.000Z", 94.7, {}],
["2016-01-20T06:05:48.000Z", 94.7, {}]
],
label: "b"
}]
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d) {
return x(parseDate.parse(d[0]));
})
.y(function(d) {
return y(d[1]);
});
var ary = [];
data.forEach(function(d) {
ary.push(d.data);
});
x.domain(d3.extent(d3.merge(ary), function(d) {
return parseDate.parse(d[0]);
}));
y.domain([
d3.min(data, function(c) {
return d3.min(c.data, function(v) {
return v[1];
});
}),
d3.max(data, function(c) {
return d3.max(c.data, function(v) {
return v[1];
});
})
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
var series = svg.selectAll(".series")
.data(data)
.enter().append("g")
.attr("class", "series");
series.append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.data);
})
.style("stroke", function(d, i) {
return z(i);
});
series.append("text")
.datum(function(d) {
return {
label: d.label,
data: d.data[d.data.length - 1]
};
})
.attr("transform", function(d) {
return "translate(" + x(parseDate.parse(d.data[0])) + "," + y(d.data[1]) + ")";
})
.attr("x", 3)
.attr("dy", ".35em");
var mouseG = svg.append("g")
.attr("class", "mouse-over-effects");
mouseG.append("path") // this is the black vertical line to follow mouse
.attr("class", "mouse-line")
.style("stroke", "black")
.style("stroke-width", "1px")
.style("opacity", "0");
var lines = document.getElementsByClassName('line');
var mousePerLine = mouseG.selectAll('.mouse-per-line')
.data(data)
.enter()
.append("g")
.attr("class", "mouse-per-line");
mousePerLine.append("circle")
.attr("r", 7)
.style("stroke", function(d, i) {
return z(i);
})
.style("fill", "none")
.style("stroke-width", "1px")
.style("opacity", "0");
mousePerLine.append("text")
.attr("transform", "translate(10,3)");
mouseG.append('svg:rect') // append a rect to catch mouse movements on canvas
.attr('width', width) // can't catch mouse events on a g element
.attr('height', height)
.attr('fill', 'none')
.attr('pointer-events', 'all')
.on('mouseout', function() { // on mouse out hide line, circles and text
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() { // on mouse in show line, circles and text
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() { // mouse moving over canvas
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) {
console.log(width/mouse[0])
var xDate = x.invert(mouse[0]),
bisect = d3.bisector(function(d) {
return d[0];
}).right;
var idx = bisect(d.data, xDate);
var beginning = 0,
end = lines[i].getTotalLength(),
target = null;
while (true) {
target = Math.floor((beginning + end)/2);
var 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; //position found
}
d3.select(this).select('text')
.text(y.invert(pos.y).toFixed(2));
return "translate(" + mouse[0] + "," + pos.y + ")";
});
});
text.inner-circle {
font-weight: 400;
font-size: 12px;
text-transform: uppercase;
}
text.inner-text {
font-weight: 400;
font-size: 36px;
font-family: 'Metric Regular', 'Metric';
text-align: center;
font-style: normal;
text-transform: uppercase;
}
path {
stroke: steelblue;
stroke-width: 2;
fill: none;
}
.axis path,
.axis line {
fill: none;
stroke: grey;
stroke-width: 2;
shape-rendering: crispEdges;
}
.grid .tick {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Iは、xとyの値の両方を有する各チャートラインの上部に小さな白いボックスを追加します。私を助けてください。
解決していただきありがとうございますが、もう1つ手助けできますか?私は、マウスが動いたときにラインを削除したいと思います。また、グラフが交差したり、近くに近づいたりするようなツールチップを配置したい場合は、ツールチップの長方形が交差して自動的に配置を変更するべきではありません。それは可能ですか? – nikunj2512
@ nikunj2512ツールチップが交差するようになると、それは難しいコールです.. :( – Cyril