折线图中没有显示工具提示行 - dc.js,d3 v4.2.8,React

时间:2016-11-02 15:52:09

标签: reactjs d3.js charts line dc.js

有兴趣在折线图中渲染垂直和水平工具提示线。使用dc.js,d3.js ver 4.2.8,React。在原始版本中,它运作良好 Tootltip lines are being displayed ,但不是在React版本中: Tooltip lines are not being displayed 。代码:

//////Line.js


import React, { PropTypes } from 'react';
import ReactDOM from "react-dom";
import * as d3 from 'd3';
import dc from "dc";
import * as crossfilter from 'crossfilter';
import {Jumbotron } from 'react-bootstrap'; 
import functionDCHelper from './functionDCHelper';
import {scaleTime, scaleLinear} from 'd3-scale';
import { axisLeft, axisBottom } from 'd3-axis';
import TableChart from "../components/TableChart.js";

class LineChart extends React.Component {

    componentDidMount() {
        var bitrateLineChart = dc.compositeChart(this.refs.lineChart);
        var { min15, minDate, maxDate, bitrateWeekMinIntervalGroupMove, maxbit } = functionDCHelper.generateValues(this.props.data);
        bitrateLineChart 
        .xUnits(min15.range) 
        .x(d3.scaleTime().domain([new Date(minDate), new Date(maxDate)]))
        .yAxisPadding('5%')     
        .elasticY(true)
        .width(990)
        .height(200)
        .transitionDuration(500)
        .margins({ top: 30, right: 50, bottom: 25, left: 50, padding: 1 })
        .mouseZoomable(true)
        .brushOn(false)
        .renderHorizontalGridLines(true)
        .legend(dc.legend().x(800).y(10).itemHeight(13).gap(5))
        //Render max bitrate horizontal line copied from bar-extra-line.html
         .yAxisLabel("Total Bitrate per 15 minutes")
        .on('renderlet', function (chart) {
            chart.svg().selectAll('.chart-body').attr('clip-path', null)
            var left_y = 10, right_y = 70; // use real statistics here!
            var extra_data = [{ x: chart.x().range()[0], y: chart.y()(left_y) }, { x: chart.x().range()[1], y: chart.y()(right_y) }];
            var line = d3.line()
                .x(function (d) { return d.x; })
                .y(function (d) { return maxbit; })
                .curve(d3.curveLinear); //.interpolate('linear');
            var chartBody = chart.select('g.chart-body');
            var path = chartBody.selectAll('path.extra').data([extra_data]);
            path.enter().append('path').attr({
                class: 'extra',
                stroke: 'red',
                id: 'extra-line',
            });
            path.attr('d', line);
            // Label the max line
            var text = chartBody.selectAll('text.extra-label').data([0]);
            text.enter().append('text')
                    .attr('text-anchor', 'middle')
                    .append('textPath').attr({
                     class: 'extra-label',   
                    'xlink:href': '#extra-line',
                     startOffset: '50%'
                })
                .text('Total Bitrate Max Value');      
        })
       // Title can be called by any stack layer.
        .title(function (d) {
            var value = d.value.total ? d.value.total : d.value;
            if (isNaN(value)) {
                value = 0;
            }
            return functionDCHelper.dateFormat(d.key) + ' \n Total Bit:' + functionDCHelper.numberFormat(value)
        })

      //Creating dynamic Y axis with min max ticks' values depending on min max of data - copied from http://jsfiddle.net/gordonwoodhull/7anae5c5/1/
     .compose([
      functionDCHelper.nonzero_min(dc.lineChart(bitrateLineChart)
          .dimension(min15)
          .colors('green')
          .group(bitrateWeekMinIntervalGroupMove, 'Bitrate Total')
           .valueAccessor(function (d) {
               return d.value.total;
           })
         // .dashStyle([2,2])
         .interpolate('d3.curveStepAfter') 
          .renderArea(false)
          .brushOn(false)
          .renderDataPoints(false)         
          .clipPadding(10)),
     ])
        bitrateLineChart.render();
    }

    render() {
        return(
            <div  ref="lineChart">
            </div>
        );
    }

}

export default LineChart;

//////functionDCHelper.js

import crossfilter from 'crossfilter';
import * as d3 from 'd3';
import dc from 'dc';

var minDate,min15,bitrateWeekMinIntervalGroupMove,maxDate,minIntervalWeekBitrateGroup,dateDimension,dateFormat,numberFormat,maxbit;

function nonzero_min(chart) {
    dc.override(chart, 'yAxisMin', function () {
        var min = d3.min(chart.data(), function (layer) {            
            return d3.min(layer.values, function (p) {
                return p.y + p.y0;
            });
        });
        return dc.utils.subtract(min, chart.yAxisPadding());
    });
    return chart;
}
// 15 Min Interval - copied from https://github.com/mbostock/d3/blob/master/src/time/interval.js
var d3_date = Date;
function d3_time_interval(local, step, number) {
    function round(date) {
        var d0 = local(date), d1 = offset(d0, 1);
        return date - d0 < d1 - date ? d0 : d1;
    }
    function ceil(date) {
        step(date = local(new d3_date(date - 1)), 1);
        return date;
    }
    function offset(date, k) {
        step(date = new d3_date(+date), k);
        return date;
    }
    function range(t0, t1, dt) {
        var time = ceil(t0), times = [];
        if (dt > 1) {
            while (time < t1) {
                if (!(number(time) % dt)) times.push(new Date(+time));
                step(time, 1);
            }
        } else {
            while (time < t1) times.push(new Date(+time)), step(time, 1);
        }
        return times;
    }
    function range_utc(t0, t1, dt) {
        try {
            d3_date = d3_date_utc;
            var utc = new d3_date_utc();
            utc._ = t0;
            return range(utc, t1, dt);
        } finally {
            d3_date = Date;
        }
    }
    local.floor = local;
    local.round = round;
    local.ceil = ceil;
    local.offset = offset;
    local.range = range;
    var utc = local.utc = d3_time_interval_utc(local);
    utc.floor = utc;
    utc.round = d3_time_interval_utc(round);
    utc.ceil = d3_time_interval_utc(ceil);
    utc.offset = d3_time_interval_utc(offset);
    utc.range = range_utc;
    return local;
}
function d3_time_interval_utc(method) {
    return function (date, k) {
        try {
            d3_date = d3_date_utc;
            var utc = new d3_date_utc();
            utc._ = date;
            return method(utc, k)._;
        } finally {
            d3_date = Date;
        }
    };
}
// generalization of d3.time.minute copied from- https://github.com/mbostock/d3/blob/master/src/time/minute.js
function n_minutes_interval(nmins) {
    var denom = 6e4 * nmins;
    return d3_time_interval(function (date) {
        return new d3_date(Math.floor(date / denom) * denom);
    }, function (date, offset) {
        date.setTime(date.getTime() + Math.floor(offset) * denom); // DST breaks setMinutes
    }, function (date) {
        return date.getMinutes();
    });
}


min15 = n_minutes_interval(15);
dateFormat = d3.timeFormat('%Y/%m/%d/%H:%M');
numberFormat = d3.format('d');

//### Crossfilter Dimensions 
function generateValues(data) {

    data.forEach(function (d) {
        d.bitdate = new Date(d.DATETIME);    //d.DATETIME = dateFormat.parse(d.DATETIME);
       // d.month = d3.time.month(d.bitdate);
      //  d.week = d3.time.week(d.bitdate);
        d.BITRATE = +d.BITRATE.match(/\d+/); //d.BITRATE = +d.BITRATE; 
    });

    var crossFilteredData = crossfilter(data);
    var all = crossFilteredData.groupAll();
    // Dimension by full date
     dateDimension = crossFilteredData.dimension(function (d) {
        return d.bitdate;
     });


     maxbit = d3.max(data, function (d) { return +d["BITRATE"]; }); //alert(maxbit);  

    //Group bitrate per week, 15 minInterval - maintain running tallies 
     bitrateWeekMinIntervalGroupMove = dateDimension.group(min15).reduce(
       /* callback for when data is added to the current filter results */
       function (p, v) {
           ++p.count;
           p.BITRATE = +v.BITRATE;
           p.total += +v.BITRATE;
           p.avg = p.count ? Math.round(p.total / p.count) : 0;
           return p;
       },
       /* callback for when data is removed from the current filter results */
       function (p, v) {
           --p.count;
           p.BITRATE = +v.BITRATE;
           p.total -= +v.BITRATE;
           p.avg = p.count ? Math.round(p.total / p.count) : 0;
           return p;
       },
       /* initialize p */
       function () {
           return {
               count: 0,
               bitrate: 0,
               total: 0,
               avg: 0
           };
       }
    );


    try {
        minDate = dateDimension.bottom(1)[0].DATETIME;
    } catch(err) {
        minDate = new Date("2016-06-14 0:00"); 
    }

   
    try {
        maxDate = dateDimension.top(1)[0].DATETIME;
    } catch(err) {
         maxDate = new Date("2016-06-18 23:55");
    }

    return {
        min15, minDate, maxDate, bitrateWeekMinIntervalGroupMove,minIntervalWeekBitrateGroup,dateDimension,maxbit
    };
}

export default {
    generateValues,
    nonzero_min,
    dateFormat,
    numberFormat
};
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
     <style>
          path.line {
          fill: none;
          stroke: green;
          stroke-width: 1.5px;
          }
          .y.axis line,
          .y.axis path {
          fill: none;
          stroke: black;
        }
          .x.axis line,
          .x.axis path {
          fill: none;
          stroke: black;
        }

    </style>
    <title>Line Chart DC.js,React</title>
  </head>
  <body>
    <div id="App"></div>
    <script src="/bundle.js"></script>
  </body>

</html>

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

目前的解决方案是在index.html中放置以下样式:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
     <style>
           path.yRef{
               storke-width:2;
               stroke:red;
               dislplay:inline;
          }

           path.xRef{
               storke-width:2;
               stroke:red;
               dislplay:inline;
          }
     
    </style>
    <title>Line Chart DC.js,React</title>
  </head>
  <body>
    <div id="App"></div>
    <script src="/bundle.js"></script>
  </body>

</html>

宁愿在图表的js(Line.js)或css类中处理它,任何建议都会受到欢迎。显示:

Dc.js, tooltip lines displayed