我的目标是绘制一个有线和点的图形。
我能够使用缩放和画笔绘制线条和点,但问题是,当我放大或缩小时,点不会根据缩放移动。
我对D3图表比较新。下面是我用来绘制点的代码:
g.selectAll(".dot")
.data(dots)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) { return x(new Date(d.date)); })
.attr("cy", function(d) { return y(d.price); })
.on("mouseover", function(d){
return tooltip.style("visibility", "visible").html("Expected value is: "+d.expected_value + "<br/>" + "value : "+d.close +"<br/>" + "deviation is: "+d.deviation_expected)
})
.on("mousemove", function(){return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
我创建了jsfiddle
请帮忙。
答案 0 :(得分:1)
我将介绍在实现可视化之前必须了解的一些基本功能。根据小提琴,你有两套数据必须在X&amp; Y轴。(例如:数据,点)。虽然您需要了解域和范围的概念,但此数据集的域名是不同的。
d3.scaleLinear()&lt;&gt;
构造一个新的连续标度,单位域[0,1],单位范围[0,1],默认插值器和钳位禁用。线性刻度是连续定量数据的一个很好的默认选择,因为它们保留了比例差异。每个范围值y可以表示为域值x的函数:y = mx + b。
d3.scaleTime()&lt;&gt;
使用域[2000-01-01,2000-01-02]构建新的时间刻度,单位范围[0,1],默认插值器和禁用钳位。
** 下面的代码片段只是为了解释画笔实现而不考虑点的比例。通过阅读文档,尝试自己来映射逻辑 Brush Event Example
var data = [{
"date": "2017-04-22T11:45:00.000Z",
"total": 731.6047915220261,
"min": 1.8769680261611938,
"key_field": "1492861500000",
"max": 2.7165653705596924,
"price": 1.8769680261611938,
"total_count": 315,
"mean": 2.3225548937207177,
"count": 315
},
{
"date": "2017-04-01T05:30:00.000Z",
"total": 708.6527144908905,
"min": 1.779407262802124,
"key_field": "1491024600000",
"max": 2.6382412910461426,
"price": 1.779407262802124,
"total_count": 315,
"mean": 2.249691157113938,
"count": 315
},
{
"date": "2017-03-31T02:45:00.000Z",
"total": 700.1026722192764,
"min": 1.8156663179397583,
"key_field": "1490928300000",
"max": 2.587003469467163,
"price": 1.8156663179397583,
"total_count": 315,
"mean": 2.2225481657754806,
"count": 315
},
{
"date": "2017-03-31T02:30:00.000Z",
"total": 699.6637561321259,
"min": 1.8294581174850464,
"key_field": "1490927400000",
"max": 2.57082200050354,
"price": 1.8294581174850464,
"total_count": 315,
"mean": 2.221154781371828,
"count": 315
},
{
"date": "2017-03-31T02:15:00.000Z",
"total": 702.4780179262161,
"min": 1.8524492979049683,
"key_field": "1490926500000",
"max": 2.628413677215576,
"price": 1.8524492979049683,
"total_count": 315,
"mean": 2.2300889457975117,
"count": 315
},
{
"date": "2017-03-31T02:00:00.000Z",
"total": 705.038315653801,
"min": 1.8353750705718994,
"key_field": "1490925600000",
"max": 2.604921340942383,
"price": 1.8353750705718994,
"total_count": 315,
"mean": 2.2382168750914317,
"count": 315
},
{
"date": "2017-03-31T01:45:00.000Z",
"total": 701.7422981262207,
"min": 1.8062856197357178,
"key_field": "1490924700000",
"max": 2.5804450511932373,
"price": 1.8062856197357178,
"total_count": 315,
"mean": 2.2277533273848276,
"count": 315
},
{
"date": "2017-03-31T01:30:00.000Z",
"total": 706.3951338529587,
"min": 1.8176854848861694,
"key_field": "1490923800000",
"max": 2.584993600845337,
"price": 1.8176854848861694,
"total_count": 315,
"mean": 2.242524234453837,
"count": 315
},
{
"date": "2017-03-31T01:15:00.000Z",
"total": 704.2638461589813,
"min": 1.7730687856674194,
"key_field": "1490922900000",
"max": 2.6350574493408203,
"price": 1.7730687856674194,
"total_count": 315,
"mean": 2.235758241774544,
"count": 315
},
{
"date": "2017-03-31T01:00:00.000Z",
"total": 703.4522807598114,
"min": 1.8147484064102173,
"key_field": "1490922000000",
"max": 2.5720791816711426,
"price": 1.8147484064102173,
"total_count": 315,
"mean": 2.233181843681941,
"count": 315
},
{
"date": "2017-03-31T00:45:00.000Z",
"total": 706.2918384075165,
"min": 1.7760894298553467,
"key_field": "1490921100000",
"max": 2.596073627471924,
"price": 1.7760894298553467,
"total_count": 315,
"mean": 2.2421963124048143,
"count": 315
},
{
"date": "2017-03-31T00:30:00.000Z",
"total": 707.0961575508118,
"min": 1.7756011486053467,
"key_field": "1490920200000",
"max": 2.6146974563598633,
"price": 1.7756011486053467,
"total_count": 315,
"mean": 2.2447497065105138,
"count": 315
},
{
"date": "2017-03-31T00:15:00.000Z",
"total": 706.1140650510788,
"min": 1.7976468801498413,
"key_field": "1490919300000",
"max": 2.6084225177764893,
"price": 1.7976468801498413,
"total_count": 315,
"mean": 2.2416319525431074,
"count": 315
},
{
"date": "2017-03-31T00:00:00.000Z",
"total": 707.5575115680695,
"min": 1.8497636318206787,
"key_field": "1490918400000",
"max": 2.5975091457366943,
"price": 1.8497636318206787,
"total_count": 315,
"mean": 2.2462143224383158,
"count": 315
},
{
"date": "2017-03-30T23:45:00.000Z",
"total": 707.9171552658081,
"min": 1.8517450094223022,
"key_field": "1490917500000",
"max": 2.5352094173431396,
"price": 1.8517450094223022,
"total_count": 315,
"mean": 2.247356048462883,
"count": 315
},
{
"date": "2017-03-30T23:30:00.000Z",
"total": 707.09266269207,
"min": 1.8389506340026855,
"key_field": "1490916600000",
"max": 2.593708038330078,
"price": 1.8389506340026855,
"total_count": 315,
"mean": 2.244738611720857,
"count": 315
},
{
"date": "2017-03-30T23:15:00.000Z",
"total": 708.3666490316391,
"min": 1.861556053161621,
"key_field": "1490915700000",
"max": 2.6234216690063477,
"price": 1.861556053161621,
"total_count": 315,
"mean": 2.2487830127988544,
"count": 315
}
]
var dots =
[
{
"date": "2017-04-22T11:45:00.000Z",
"total": 731.6047915220261,
"min": 1.8769680261611938,
"key_field": "1492861500000",
"max": 2.7165653705596924,
"price": 1.8769680261611938,
"total_count": 315,
"mean": 2.3225548937207177,
"count": 315
},
{
"date": "2017-03-31T01:45:00.000Z",
"total": 701.7422981262207,
"min": 1.8062856197357178,
"key_field": "1490924700000",
"max": 2.5804450511932373,
"price": 1.7062856197357178,
"total_count": 315,
"mean": 2.2277533273848276,
"count": 315
},
{
"date": "2017-03-31T01:30:00.000Z",
"total": 706.3951338529587,
"min": 1.8176854848861694,
"key_field": "1490923800000",
"max": 2.584993600845337,
"price": 1.8176854848861694,
"total_count": 315,
"mean": 2.242524234453837,
"count": 315
},
{
"date": "2017-03-28T18:00:00.000Z",
"total": 728.67049741745,
"min": 1.2837289810180664,
"key_field": "1490724000000",
"max": 2.706052541732788,
"price": 1.3837289810180664,
"total_count": 315,
"mean": 2.3132396743411108,
"count": 315
},
{
"date": "2017-03-26T20:00:00.000Z",
"total": 721.6712145805359,
"min": 1.8257900476455688,
"key_field": "1490558400000",
"max": 2.762291669845581,
"price": 1.4257900476455688,
"total_count": 315,
"mean": 2.291019728827098,
"count": 315
},
{
"date": "2017-03-28T17:45:00.000Z",
"total": 726.2018908262253,
"min": 1.8992395401000977,
"key_field": "1490723100000",
"max": 2.7374281883239746,
"price": 1.8992395401000977,
"total_count": 315,
"mean": 2.305402828019763,
"count": 315
},
{
"date": "2017-03-28T17:30:00.000Z",
"total": 730.83118724823,
"min": 1.8232735395431519,
"key_field": "1490722200000",
"max": 2.696560859680176,
"price": 1.3232735395431519,
"total_count": 315,
"mean": 2.320099007137238,
"count": 315
},
{
"date": "2017-03-28T17:15:00.000Z",
"total": 728.1204907894135,
"min": 1.8851990699768066,
"key_field": "1490721300000",
"max": 2.654668092727661,
"price": 1.8851990699768066,
"total_count": 315,
"mean": 2.3114936215536934,
"count": 315
},
{
"date": "2017-03-27T02:45:00.000Z",
"total": 702.2468013763428,
"min": 1.7651863098144531,
"key_field": "1490582700000",
"max": 2.6390604972839355,
"price": 1.373651863098144531,
"total_count": 315,
"mean": 2.229354925004263,
"count": 315
},
{
"date": "2017-03-27T02:30:00.000Z",
"total": 700.9137979745865,
"min": 1.8334004878997803,
"key_field": "1490581800000",
"max": 2.620957136154175,
"price": 1.8334004878997803,
"total_count": 315,
"mean": 2.2251231681732904,
"count": 315
},
{
"date": "2017-03-27T02:15:00.000Z",
"total": 700.9274371862411,
"min": 1.8098258972167969,
"key_field": "1490580900000",
"max": 2.6065454483032227,
"price": 1.8098258972167969,
"total_count": 315,
"mean": 2.2251664672579086,
"count": 315
},
{
"date": "2017-03-27T02:00:00.000Z",
"total": 703.2963272333145,
"min": 1.7948274354934692,
"key_field": "1490580000000",
"max": 2.549198865890503,
"price": 1.7968274354934692,
"total_count": 315,
"mean": 2.2326867531216332,
"count": 315
},
{
"date": "2017-03-27T01:45:00.000Z",
"total": 700.4703311920166,
"min": 1.8429771661758423,
"key_field": "1490579100000",
"max": 2.518679141998291,
"price": 1.348429771661758423,
"total_count": 315,
"mean": 2.223715337117513,
"count": 315
},
{
"date": "2017-03-27T01:30:00.000Z",
"total": 701.4555011987686,
"min": 1.7773451805114746,
"key_field": "1490578200000",
"max": 2.635554790496826,
"price": 1.27773451805114746,
"total_count": 315,
"mean": 2.2268428609484716,
"count": 315
},
{
"date": "2017-03-26T20:00:00.000Z",
"total": 721.6712145805359,
"min": 1.8257900476455688,
"key_field": "1490558400000",
"max": 2.762291669845581,
"price": 1.48257900476455688,
"total_count": 315,
"mean": 2.291019728827098,
"count": 315
},
{
"date": "2017-03-26T19:45:00.000Z",
"total": 724.9882735013962,
"min": 1.80784010887146,
"key_field": "1490557500000",
"max": 2.6430490016937256,
"price": 0.40784010887146,
"total_count": 315,
"mean": 2.301550074607607,
"count": 315
},
]
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 110, left: 40},
margin2 = {top: 430, right: 20, bottom: 30, left: 40},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
height2 = +svg.attr("height") - margin2.top - margin2.bottom;
var parseDate = d3.timeParse("%m/%d/%Y %H:%M");
var g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scaleTime().range([0, width]),
x2 = d3.scaleTime().range([0, width]),
y = d3.scaleLinear().range([height, 0]),
y2 = d3.scaleLinear().range([height2, 0]),
dotXScale = d3.scaleTime().range([0, width]),
dotYScale = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom(x),
xAxis2 = d3.axisBottom(x2),
yAxis = d3.axisLeft(y);
var brush = d3.brushX()
.extent([[0, 0], [width, height2]])
.on("brush end", brushed);
var zoom = d3.zoom()
.scaleExtent([1, Infinity])
.translateExtent([[0, 0], [width, height]])
.extent([[0, 0], [width, height]])
.on("zoom", zoomed);
var line = d3.line()
.x(function (d) { return x(new Date(d.date)); })
.y(function (d) { return y(d.price); });
var line2 = d3.line()
.x(function (d) { return x2(new Date(d.date)); })
.y(function (d) { return y2(d.price); });
var clip = svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("x", 0)
.attr("y", 0);
var Line_chart = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("clip-path", "url(#clip)");
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
x.domain(d3.extent(data, function(d) { return new Date(d.date); }));
dotXScale.domain(d3.extent(dots, function(d) { return new Date(d.date); }));
y.domain([0, d3.max(data, function (d) { return d.price; })]);
dotYScale.domain([0, d3.max(dots, function (d) { return d.price; })]);
x2.domain(x.domain());
y2.domain(y.domain());
focus.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "axis axis--y")
.call(yAxis);
Line_chart.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
context.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line2);
context.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, x.range());
svg.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
var tooltip = d3.select("body")
.append("div")
.style("position", "absolute")
.style("z-index", "10")
.style("visibility", "hidden")
.text("a simple tooltip");
g.selectAll(".dot")
.data(dots)
.enter()
.append("circle")
.attr("class", "dot")
.attr("r", 3.5)
.attr("cx", function(d) {
//console.log('---',x(new Date(d.date)))
return dotXScale(new Date(d.date));
})
.attr("cy", function(d) {
//console.log(y(d.price));
return dotYScale(d.price);
})
.on("mouseover", function(d){
console.log(d);
return tooltip.style("visibility", "visible").html("Expected value is: "+d.expected_value + "<br/>" + "value : "+d.close +"<br/>" + "deviation is: "+d.deviation_expected)
})
.on("mousemove", function(){return tooltip.style("top", (event.pageY-10)+"px").style("left",(event.pageX+10)+"px");})
.on("mouseout", function(){return tooltip.style("visibility", "hidden");});
function brushed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom
var s = d3.event.selection || x2.range();
x.domain(s.map(x2.invert, x2));
dotXScale.domain(s.map(x2.invert), x2);
Line_chart.select(".line").attr("d", line);
focus.select(".axis--x").call(xAxis);
svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
.scale(width / (s[1] - s[0]))
.translate(-s[0], 0));
g.selectAll(".dot").transition(1000)
.attr("cx", function (d) {
return dotXScale(new Date(d.date)) })
.attr("cy", function (d) {
//console.log(y(d.price));
return dotYScale(d.price) });
}
function zoomed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
var t = d3.event.transform;
x.domain(t.rescaleX(x2).domain());
Line_chart.select(".line").attr("d", line);
focus.select(".axis--x").call(xAxis);
context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
}
function type(d) {
d.date = new Date(d.date);
d.price = +d.price;
return d;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.heading {
padding-top: 30px;
}
.buttonWidth {
height: 34px;
width: 50px;
}
.actiontable {
width: 36rem;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.zoom {
cursor: move;
fill: none;
pointer-events: all;
}
.area {
fill: none;
stroke: #a2dced;
stroke-width: 2;
clip-path: url(#clip);
}
.zoom {
cursor: move;
fill: none;
pointer-events: all;
}
rect.selection
{
fill:green;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>