无法在D3条形图/折线图中显示线条

时间:2015-12-01 22:52:58

标签: d3.js

我正在尝试创建组合条和折线图。条形图是表示data.total的主y轴,线条是表示data.percent的辅助y轴。

免责声明:我对javascript和D3非常陌生。

我已经花了好几个小时试图弄清楚为什么图表不会渲染系列。这些代码中的一些是基于我在网上找到的其他示例模板,因此可能会有一些内容与我的修改无关,我完全错过了它。

提前感谢您的帮助!!!

以下是我所拥有的:

<!DOCTYPE HTML>
<HTML>
<HEAD>
<STYLE>`enter code here`
svg{ padding-left: 100 px}
path {
    stroke: Black;
    stroke-width: 1;
    fill: none;
}
 .chartTitle{ 
    color: #002b80;
    font-size: 32pt;
    font-weight: bold;
    text-align: left;
    padding-left: 20px;

}
</STYLE>
</HEAD>
<BODY>
<div class="chartTitle">Estimate of "Everything is Awesome"</div>
<SCRIPT SRC = 'd3.min.js'></SCRIPT>
<SCRIPT>

var data =  [
    {'date': '4/1/2015', 'total':500, 'percent':0.535},
    {'date': '5/1/2015', 'total': 650, 'percent': 0.593},
    {'date': '6/1/2015', 'total': 700, 'percent': 0.687},
    {'date': '7/1/2015', 'total': 750, 'percent': 0.734},
    {'date': '8/1/2015', 'total': 800, 'percent': 0.988},
    {'date': '9/1/2015', 'total': 850, 'percent': 0.99},
    {'date': '10/1/2015', 'total': 900, 'percent': 1.0}
    ];

var margin = {top: 70, right: 70, bottom: 70, left:60},
    width = 600,
    height = 500;   


var toolTip = d3.select('body').append('div')
        .style('position', 'absolute')
        .style('background', 'white')
        .style('opacity', .9)
        .style('padding', '0 20px') 
        .style('border-radius', '25px')
        .style('border', ' 2px solid dodgerblue')

// X and Y Axis         
var xScale = d3.time.scale()
    .domain([new Date(data[0].date), d3.time.month.offset(new Date(data[data.length - 1].date), 0)])
    .rangeRound([0, width - margin.left - margin.right ]);

var y1Scale = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.total;})])
    .range([height - margin.top - margin.bottom, 0]);

var y2Scale = d3.scale.linear()
    .domain([0, d3.max(data, function(d) { return d.percent;})])
    .range([height - margin.top - margin.bottom, 0]);


var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient('bottom')
    .ticks(d3.time.month, 1)
    .tickFormat(d3.time.format('%b -%y'))
    .tickSize(1)
    .tickPadding(8);

var y1Axis = d3.svg.axis()
    .scale(y1Scale)
    .orient('left')
    .tickPadding(8)
    .tickSize(1);

var y2Axis = d3.svg.axis()
    .scale(y2Scale)
    .orient('right')
    .tickPadding(8)
    .tickSize(1);   

var lineData = d3.svg.line()
    .x(function(d) { return xScale(d.date); })
    .y(function(d) { return -1 * y2Scale(d.percent); });

//Chart Body    
var svg = d3.select('body').append('svg')
    .attr('class', 'chart')
    .attr('width', width)
    .attr('height', height)
    .append('g')
        .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');

//Chart Body Creation
svg.selectAll('.chart')
    .data(data)
  .enter().append('rect')
    .style('fill', 'dodgerblue')
    .attr('class', 'bar')
    .attr('x', function(d) { return xScale(new Date(d.date)); })
    .attr('y', function(d) { return height - margin.top - margin.bottom - (height - margin.top - margin.bottom - y1Scale(d.total)) })
    .attr('width', 20)
    .attr('height', function(d) { return height - margin.top - margin.bottom - y1Scale(d.total) })
// Roll over SFX    
    .on('mouseover', function (d) {
       toolTip.transition()
       .style('opacity', .9)
       toolTip.html(d.total)
         .style('left', (d3.event.pageX - 40) + 'px')  
         .style('top', (d3.event.pageY - 30) + 'px') 
       d3.select(this)
       .style('opacity', 0.5)
        })
    .on('mouseout', function (d) {
       toolTip.transition()
        .delay(100)
        .duration(600)
        .style('opacity', 0)
        .style('pointer-events', 'none')
       d3.select(this)
       .style('opacity', 1)
        });

//lDraw Line        
svg.append("path")
    .attr("d", lineData(data))
    .style('stroke', 'DarkOrange');

//Draw the X Axis
svg.append('g')
    .attr('class', 'x axis')
    .attr('transform', 'translate(0, ' + (height - margin.top - margin.bottom) + ')')
    .call(xAxis);
//Draw the Y1 Axis
svg.append('g')
  .attr('class', 'y axis')
  .call(y1Axis);

//Draw the Y2 Axis
svg.append('g')
  .attr('class', 'y axis')
  .attr("transform", "translate(" + (height ) + " ,0)") 
  .call(y2Axis); 
   </SCRIPT>
</BODY>
</HTML>

1 个答案:

答案 0 :(得分:0)

问题1:

您的JSON中的日期格式为{'date': '10/1/2015', 'total': 900, 'percent': 1.0},您需要将其转换为日期对象。

var format = d3.time.format("%d/%m/%Y");
data.forEach(function(d){
  d.date = format.parse(d.date);
});

用于解析refer

的各种日期格式

Problem2:

您正在错误地定义域名

var xScale = d3.time.scale()
    .domain([new Date(data[0].date), d3.time.month.offset(new Date(data[data.length - 1].date), 0)])
    .rangeRound([0, width - margin.left - margin.right ]);

域名应该是日期的最小值/最大值。

var xScale = d3.time.scale()
  .domain([d3.min(data, function(d){return d.date}), d3.max(data, function(d){return d.date})])
  .rangeRound([0, width - margin.left - margin.right]);

为什么线不起草的原因

var lineData = d3.svg.line()
    .x(function(d) { return xScale(d.date); })//this date is not in the correct format so d3 does not know what to do and so gives NaN.
    .y(function(d) { return -1 * y2Scale(d.percent); });

现在问题1将解决此问题,因为我们已将数据转换为日期。

工作示例here

希望这有帮助!