【问题标题】:Updating data point position on a line chart更新折线图上的数据点位置
【发布时间】:2017-08-07 12:10:02
【问题描述】:

我目前正在使用 nvd3 创建一个简单的折线图。数据由两个系列组成,正在以下函数中创建:

function buildData(xval) {
  var inputtedData = 2; 
  var bindedData = []; 
  var series2 = []; 

  for (var i = 0; i < 15; i++) {
    bindedData.push({y: inputtedData, x: i}); 
  }

  series2.push({y: inputtedData, x: xval}); 

  return [
  {
    values: bindedData, 
    color: '#4386f4'
  },
  {
    values: series2,
    color: '#000000'
  }
  ];
}

bindedData 形成一条直线,series2 由一个点组成,它将位于整条线上的某个位置。该参数用于为数据系列 2 点输入新的 x 位置。

最初,图形数据构建正确,图形显示完美。更进一步,我添加了一个 html 按钮,它有一个链接到一个函数的 onClick 事件,该函数旨在更新数据源并解析一个新的 xval(在本例中,我将值硬编码为 3 ):

function updateTheChart(){
  console.log('updating....'); 
  var data = buildData(3.4);  
  d3.select('#chart3').datum(data).transition().duration(500).call(chart); 
  nv.utils.windowResize(chart.update);
}

想要的结果显然是当函数被触发时数据点在视觉上移动到它的新 x 位置,但是,目前情况并非如此,我有点不确定为什么。

我不会在这个问题中发布我的所有代码,而是制作了一个最小的示例,希望符合站点指南。 fiddle.

我希望我已经在这篇文章中清楚地表达了我的意图,但如果我遗漏了相关信息,请务必告诉我。

提前非常感谢,

【问题讨论】:

    标签: javascript d3.js nvd3.js


    【解决方案1】:

    您正在使用nvd3 绘制图表和线条。然而,重点是您使用传统的d3 添加。 nvd3 对此一无所知,并且触发重画不会做任何事情。如果你想更新点,你只需要d3

    buildGraph();
    
    function buildData(xval) {
      var inputtedData = 2;
      var bindedData = [];
      var series2 = [];
    
      for (var i = 0; i < 15; i++) {
        bindedData.push({
          y: inputtedData,
          x: i
        });
      }
    
      series2.push({
        y: inputtedData,
        x: xval
      });
    
      return [{
        values: bindedData,
        color: '#4386f4'
      }, {
        values: series2,
        color: '#000000'
      }];
    }
    
    function buildGraph() {
      ckdDeathOutputGraph(buildData(5.5), '#chart3', 'test');
    }
    
    var chart;
    var chartData;
    var points;
    
    function ckdDeathOutputGraph(processedData, location, axisLabel) {
    
      nv.addGraph(function() {
        chart = nv.models.lineChart()
          .forceX([2.5, 7.5])
          .forceY([0, 3.5])
          .options({
            duration: 300,
            userInteractiveGuideline: true
          });
    
        chart.xAxis
          .axisLabel('')
          .tickFormat(d3.format(',.f'))
          .staggerLabels(true);
    
        chart.yAxis
          .axisLabel(axisLabel)
          .tickFormat(function(d) {
            if (d == null) {
              return 'N/A';
            }
            return d3.format(',.1f')(d);
          });
    
        data = processedData;
    
        chartData = d3.select('body').select(location).append('svg').datum(data);
        chartData.transition().duration(500).call(chart);
    
        points = d3.select('#chart3 .nv-groups')
          .selectAll("circle.myPoint")
          .data(data[0].values.filter(function(d) {
            return d.y;
          }))
          .enter().append("circle").attr("class", "myPoint")
    
        .attr("cx", function(d) {
          return chart.xAxis.scale()(data[1].values[0].x);
        })
    
        .attr("cy", function(d) {
            return chart.yAxis.scale()(data[1].values[0].y);
          })
          .attr("r", 5)
    
        nv.utils.windowResize(chart.update);
    
        return chart
      });
    }
    
    updateTheChart = function() {
      console.log('updating....');
      var data = buildData(3.4);
      
      points
      	.attr("cx", function(d) {
          return chart.xAxis.scale()(data[1].values[0].x);
        })
        .attr("cy", function(d) {
          return chart.yAxis.scale()(data[1].values[0].y);
        })
        .attr("r", 5);  
      
      //d3.select('#chart3').datum(data).transition().duration(500).call(chart);
      //nv.utils.windowResize(chart.update);
    }
    /* nvd3 version 1.8.1 (https://github.com/novus/nvd3) 2015-06-15 */
    
    .nvd3 .nv-axis {
      pointer-events: none;
      opacity: 1;
    }
    
    .nvd3 .nv-axis path {
      fill: none;
      stroke: #000;
      stroke-opacity: .75;
      shape-rendering: crispEdges;
    }
    
    .nvd3 .nv-axis path.domain {
      stroke-opacity: .75;
    }
    
    .nvd3 .nv-axis.nv-x path.domain {
      stroke-opacity: 0;
    }
    
    .nvd3 .nv-axis line {
      fill: none;
      stroke: #e5e5e5;
      shape-rendering: crispEdges;
    }
    
    .nvd3 .nv-axis .zero line,
    
    /*this selector may not be necessary*/
    
    .nvd3 .nv-axis line.zero {
      stroke-opacity: .75;
    }
    
    .nvd3 .nv-axis .nv-axisMaxMin text {
      font-weight: bold;
    }
    
    .nvd3 .x .nv-axis .nv-axisMaxMin text,
    .nvd3 .x2 .nv-axis .nv-axisMaxMin text,
    .nvd3 .x3 .nv-axis .nv-axisMaxMin text {
      text-anchor: middle
    }
    
    .nvd3 .nv-axis.nv-disabled {
      opacity: 0;
    }
    
    .nvd3 .nv-bars rect {
      fill-opacity: .75;
      transition: fill-opacity 250ms linear;
      -moz-transition: fill-opacity 250ms linear;
      -webkit-transition: fill-opacity 250ms linear;
    }
    
    .nvd3 .nv-bars rect.hover {
      fill-opacity: 1;
    }
    
    .nvd3 .nv-bars .hover rect {
      fill: lightblue;
    }
    
    .nvd3 .nv-bars text {
      fill: rgba(0, 0, 0, 0);
    }
    
    .nvd3 .nv-bars .hover text {
      fill: rgba(0, 0, 0, 1);
    }
    
    .nvd3 .nv-multibar .nv-groups rect,
    .nvd3 .nv-multibarHorizontal .nv-groups rect,
    .nvd3 .nv-discretebar .nv-groups rect {
      stroke-opacity: 0;
      transition: fill-opacity 250ms linear;
      -moz-transition: fill-opacity 250ms linear;
      -webkit-transition: fill-opacity 250ms linear;
    }
    
    .nvd3 .nv-multibar .nv-groups rect:hover,
    .nvd3 .nv-multibarHorizontal .nv-groups rect:hover,
    .nvd3 .nv-candlestickBar .nv-ticks rect:hover,
    .nvd3 .nv-discretebar .nv-groups rect:hover {
      fill-opacity: 1;
    }
    
    .nvd3 .nv-discretebar .nv-groups text,
    .nvd3 .nv-multibarHorizontal .nv-groups text {
      font-weight: bold;
      fill: rgba(0, 0, 0, 1);
      stroke: rgba(0, 0, 0, 0);
    }
    
    
    /* boxplot CSS */
    
    .nvd3 .nv-boxplot circle {
      fill-opacity: 0.5;
    }
    
    .nvd3 .nv-boxplot circle:hover {
      fill-opacity: 1;
    }
    
    .nvd3 .nv-boxplot rect:hover {
      fill-opacity: 1;
    }
    
    .nvd3 line.nv-boxplot-median {
      stroke: black;
    }
    
    .nv-boxplot-tick:hover {
      stroke-width: 2.5px;
    }
    
    
    /* bullet */
    
    .nvd3.nv-bullet {
      font: 10px sans-serif;
    }
    
    .nvd3.nv-bullet .nv-measure {
      fill-opacity: .8;
    }
    
    .nvd3.nv-bullet .nv-measure:hover {
      fill-opacity: 1;
    }
    
    .nvd3.nv-bullet .nv-marker {
      stroke: #000;
      stroke-width: 2px;
    }
    
    .nvd3.nv-bullet .nv-markerTriangle {
      stroke: #000;
      fill: #fff;
      stroke-width: 1.5px;
    }
    
    .nvd3.nv-bullet .nv-tick line {
      stroke: #666;
      stroke-width: .5px;
    }
    
    .nvd3.nv-bullet .nv-range.nv-s0 {
      fill: #eee;
    }
    
    .nvd3.nv-bullet .nv-range.nv-s1 {
      fill: #ddd;
    }
    
    .nvd3.nv-bullet .nv-range.nv-s2 {
      fill: #ccc;
    }
    
    .nvd3.nv-bullet .nv-title {
      font-size: 14px;
      font-weight: bold;
    }
    
    .nvd3.nv-bullet .nv-subtitle {
      fill: #999;
    }
    
    .nvd3.nv-bullet .nv-range {
      fill: #bababa;
      fill-opacity: .4;
    }
    
    .nvd3.nv-bullet .nv-range:hover {
      fill-opacity: .7;
    }
    
    .nvd3.nv-candlestickBar .nv-ticks .nv-tick {
      stroke-width: 1px;
    }
    
    .nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover {
      stroke-width: 2px;
    }
    
    .nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect {
      stroke: #2ca02c;
      fill: #2ca02c;
    }
    
    .nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect {
      stroke: #d62728;
      fill: #d62728;
    }
    
    .with-transitions .nv-candlestickBar .nv-ticks .nv-tick {
      transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
      -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
      -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
    }
    
    .nvd3.nv-candlestickBar .nv-ticks line {
      stroke: #333;
    }
    
    .nvd3 .nv-legend .nv-disabled rect {
      /*fill-opacity: 0;*/
    }
    
    .nvd3 .nv-check-box .nv-box {
      fill-opacity: 0;
      stroke-width: 2;
    }
    
    .nvd3 .nv-check-box .nv-check {
      fill-opacity: 0;
      stroke-width: 4;
    }
    
    .nvd3 .nv-series.nv-disabled .nv-check-box .nv-check {
      fill-opacity: 0;
      stroke-opacity: 0;
    }
    
    .nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check {
      opacity: 0;
    }
    
    
    /* line plus bar */
    
    .nvd3.nv-linePlusBar .nv-bar rect {
      fill-opacity: .75;
    }
    
    .nvd3.nv-linePlusBar .nv-bar rect:hover {
      fill-opacity: 1;
    }
    
    .nvd3 .nv-groups path.nv-line {
      fill: none;
    }
    
    .nvd3 .nv-groups path.nv-area {
      stroke: none;
    }
    
    .nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {
      fill-opacity: 0;
      stroke-opacity: 0;
    }
    
    .nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {
      fill-opacity: .5 !important;
      stroke-opacity: .5 !important;
    }
    
    .with-transitions .nvd3 .nv-groups .nv-point {
      transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
      -moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
      -webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
    }
    
    .nvd3.nv-scatter .nv-groups .nv-point.hover,
    .nvd3 .nv-groups .nv-point.hover {
      stroke-width: 7px;
      fill-opacity: .95 !important;
      stroke-opacity: .95 !important;
    }
    
    .nvd3 .nv-point-paths path {
      stroke: #aaa;
      stroke-opacity: 0;
      fill: #eee;
      fill-opacity: 0;
    }
    
    .nvd3 .nv-indexLine {
      cursor: ew-resize;
    }
    
    
    /********************
     * SVG CSS
     */
    
    
    /********************
      Default CSS for an svg element nvd3 used
    */
    
    svg.nvd3-svg {
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -ms-user-select: none;
      -moz-user-select: none;
      user-select: none;
      display: block;
      width: 100%;
      height: 100%;
    }
    
    
    /********************
      Box shadow and border radius styling
    */
    
    .nvtooltip.with-3d-shadow,
    .with-3d-shadow .nvtooltip {
      -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
      -webkit-border-radius: 5px;
      -moz-border-radius: 5px;
      border-radius: 5px;
    }
    
    .nvd3 text {
      font: normal 12px Arial;
    }
    
    .nvd3 .title {
      font: bold 14px Arial;
    }
    
    .nvd3 .nv-background {
      fill: white;
      fill-opacity: 0;
    }
    
    .nvd3.nv-noData {
      font-size: 18px;
      font-weight: bold;
    }
    
    
    /**********
    *  Brush
    */
    
    .nv-brush .extent {
      fill-opacity: .125;
      shape-rendering: crispEdges;
    }
    
    .nv-brush .resize path {
      fill: #eee;
      stroke: #666;
    }
    
    
    /**********
    *  Legend
    */
    
    .nvd3 .nv-legend .nv-series {
      cursor: pointer;
    }
    
    .nvd3 .nv-legend .nv-disabled circle {
      fill-opacity: 0;
    }
    
    
    /* focus */
    
    .nvd3 .nv-brush .extent {
      fill-opacity: 0 !important;
    }
    
    .nvd3 .nv-brushBackground rect {
      stroke: #000;
      stroke-width: .4;
      fill: #fff;
      fill-opacity: .7;
    }
    
    .nvd3.nv-ohlcBar .nv-ticks .nv-tick {
      stroke-width: 1px;
    }
    
    .nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover {
      stroke-width: 2px;
    }
    
    .nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive {
      stroke: #2ca02c;
    }
    
    .nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative {
      stroke: #d62728;
    }
    
    .nvd3 .background path {
      fill: none;
      stroke: #EEE;
      stroke-opacity: .4;
      shape-rendering: crispEdges;
    }
    
    .nvd3 .foreground path {
      fill: none;
      stroke-opacity: .7;
    }
    
    .nvd3 .nv-parallelCoordinates-brush .extent {
      fill: #fff;
      fill-opacity: .6;
      stroke: gray;
      shape-rendering: crispEdges;
    }
    
    .nvd3 .nv-parallelCoordinates .hover {
      fill-opacity: 1;
      stroke-width: 3px;
    }
    
    .nvd3 .missingValuesline line {
      fill: none;
      stroke: black;
      stroke-width: 1;
      stroke-opacity: 1;
      stroke-dasharray: 5, 5;
    }
    
    .nvd3.nv-pie path {
      stroke-opacity: 0;
      transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
      -moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
      -webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
    }
    
    .nvd3.nv-pie .nv-pie-title {
      font-size: 24px;
      fill: rgba(19, 196, 249, 0.59);
    }
    
    .nvd3.nv-pie .nv-slice text {
      stroke: #000;
      stroke-width: 0;
    }
    
    .nvd3.nv-pie path {
      stroke: #fff;
      stroke-width: 1px;
      stroke-opacity: 1;
    }
    
    .nvd3.nv-pie .hover path {
      fill-opacity: .7;
    }
    
    .nvd3.nv-pie .nv-label {
      pointer-events: none;
    }
    
    .nvd3.nv-pie .nv-label rect {
      fill-opacity: 0;
      stroke-opacity: 0;
    }
    
    
    /* scatter */
    
    .nvd3 .nv-groups .nv-point.hover {
      stroke-width: 20px;
      stroke-opacity: .5;
    }
    
    .nvd3 .nv-scatter .nv-point.hover {
      fill-opacity: 1;
    }
    
    .nv-noninteractive {
      pointer-events: none;
    }
    
    .nv-distx,
    .nv-disty {
      pointer-events: none;
    }
    
    
    /* sparkline */
    
    .nvd3.nv-sparkline path {
      fill: none;
    }
    
    .nvd3.nv-sparklineplus g.nv-hoverValue {
      pointer-events: none;
    }
    
    .nvd3.nv-sparklineplus .nv-hoverValue line {
      stroke: #333;
      stroke-width: 1.5px;
    }
    
    .nvd3.nv-sparklineplus,
    .nvd3.nv-sparklineplus g {
      pointer-events: all;
    }
    
    .nvd3 .nv-hoverArea {
      fill-opacity: 0;
      stroke-opacity: 0;
    }
    
    .nvd3.nv-sparklineplus .nv-xValue,
    .nvd3.nv-sparklineplus .nv-yValue {
      stroke-width: 0;
      font-size: .9em;
      font-weight: normal;
    }
    
    .nvd3.nv-sparklineplus .nv-yValue {
      stroke: #f66;
    }
    
    .nvd3.nv-sparklineplus .nv-maxValue {
      stroke: #2ca02c;
      fill: #2ca02c;
    }
    
    .nvd3.nv-sparklineplus .nv-minValue {
      stroke: #d62728;
      fill: #d62728;
    }
    
    .nvd3.nv-sparklineplus .nv-currentValue {
      font-weight: bold;
      font-size: 1.1em;
    }
    
    
    /* stacked area */
    
    .nvd3.nv-stackedarea path.nv-area {
      fill-opacity: .7;
      stroke-opacity: 0;
      transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
      -moz-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
      -webkit-transition: fill-opacity 250ms linear, stroke-opacity 250ms linear;
    }
    
    .nvd3.nv-stackedarea path.nv-area.hover {
      fill-opacity: .9;
    }
    
    .nvd3.nv-stackedarea .nv-groups .nv-point {
      stroke-opacity: 0;
      fill-opacity: 0;
    }
    
    .nvtooltip {
      position: absolute;
      background-color: rgba(255, 255, 255, 1.0);
      color: rgba(0, 0, 0, 1.0);
      padding: 1px;
      border: 1px solid rgba(0, 0, 0, .2);
      z-index: 10000;
      display: block;
      font-family: Arial;
      font-size: 13px;
      text-align: left;
      /* MODIFICATION TO MAKE THE TOOLTIP CLICKABLE */
      /*pointer-events: none;*/
      white-space: nowrap;
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    
    .nvtooltip {
      background: rgba(255, 255, 255, 0.8);
      border: 1px solid rgba(0, 0, 0, 0.5);
      border-radius: 4px;
    }
    
    
    /*Give tooltips that old fade in transition by
        putting a "with-transitions" class on the container div.
    */
    
    .nvtooltip.with-transitions,
    .with-transitions .nvtooltip {
      transition: opacity 50ms linear;
      -moz-transition: opacity 50ms linear;
      -webkit-transition: opacity 50ms linear;
      transition-delay: 200ms;
      -moz-transition-delay: 200ms;
      -webkit-transition-delay: 200ms;
    }
    
    .nvtooltip.x-nvtooltip,
    .nvtooltip.y-nvtooltip {
      padding: 8px;
    }
    
    .nvtooltip h3 {
      margin: 0;
      padding: 4px 14px;
      line-height: 18px;
      font-weight: normal;
      background-color: rgba(247, 247, 247, 0.75);
      color: rgba(0, 0, 0, 1.0);
      text-align: center;
      border-bottom: 1px solid #ebebeb;
      -webkit-border-radius: 5px 5px 0 0;
      -moz-border-radius: 5px 5px 0 0;
      border-radius: 5px 5px 0 0;
    }
    
    .nvtooltip p {
      margin: 0;
      padding: 5px 14px;
      text-align: center;
    }
    
    .nvtooltip span {
      display: inline-block;
      margin: 2px 0;
    }
    
    .nvtooltip table {
      margin: 6px;
      border-spacing: 0;
    }
    
    .nvtooltip table td {
      padding: 2px 9px 2px 0;
      vertical-align: middle;
    }
    
    .nvtooltip table td.key {
      font-weight: normal;
    }
    
    .nvtooltip table td.value {
      text-align: right;
      font-weight: bold;
    }
    
    .nvtooltip table tr.highlight td {
      padding: 1px 9px 1px 0;
      border-bottom-style: solid;
      border-bottom-width: 1px;
      border-top-style: solid;
      border-top-width: 1px;
    }
    
    .nvtooltip table td.legend-color-guide div {
      width: 8px;
      height: 8px;
      vertical-align: middle;
    }
    
    .nvtooltip table td.legend-color-guide div {
      width: 12px;
      height: 12px;
      border: 1px solid #999;
    }
    
    .nvtooltip .footer {
      padding: 3px;
      text-align: center;
    }
    
    .nvtooltip-pending-removal {
      pointer-events: none;
      display: none;
    }
    
    
    /****
    Interactive Layer
    */
    
    .nvd3 .nv-interactiveGuideLine {
      pointer-events: none;
    }
    
    .nvd3 line.nv-guideline {
      stroke: #ccc;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"></script>
    <button onClick="updateTheChart()">Update</button>
    <div id="chart3"></div>

    【讨论】:

      猜你喜欢
      • 2016-11-26
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多