如何在D3图中添加点?

时间:2018-01-08 05:35:50

标签: javascript d3.js

我的目标是绘制一个有线和点的图形。

我能够使用缩放和画笔绘制线条和点,但问题是,当我放大或缩小时,点不会根据缩放移动。

我对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

请帮忙。

1 个答案:

答案 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>