2016-06-11 216 views
0

HTMLD3.js条形图

<div id="searchVolume"></div> 

CSS

#tooltip { 
    position: absolute; 
    width: 50px; 
    height: auto; 
    padding: 10px; 
    background-color: white; 
    -webkit-border-radius: 10px; 
    -moz-border-radius: 10px; 
    border-radius: 10px; 
    -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
    -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); 
    pointer-events: none; 
} 
#tooltip.hidden { 
    display: none; 
} 
#tooltip p { 
    margin: 0; 
    font-family: sans-serif; 
    font-size: 12px; 
    line-height: 16px; 
} 
.indent{ 
    padding-left: 5px; 
} 

rect { 
    -moz-transition: all 0.3s; 
    -webkit-transition: all 0.3s; 
    -o-transition: all 0.3s; 
    transition: all 0.3s; 
} 
rect:hover{ 
    fill: orange; 
} 
.axis path, 
.axis line { 
    fill: none; 
    stroke: black; 
    shape-rendering: crispEdges; 
} 
.axis text { 
    font-family: sans-serif; 
    font-size: 11px; 
} 

脚本

var margin = {top: 25, right: 40, bottom: 35, left: 85}, 
       w = 500 - margin.left - margin.right, 
       h = 350 - margin.top - margin.bottom; 
var padding = 10; 

var colors = [ ["Morning", "#F64BEE"], 
        ["Midday", "#25B244"], 
      ["Afternoon", "#2BA3F4"], 
      ["Evening","#FD7680"]]; 

var dataset = [ 
       { "Morning": 1400000, "Midday": 673000, "Afternoon": 43000, "Evening":50000}, 
       { "Morning": 165000, "Midday": 160000, "Afternoon": 21000, "Evening":23000 }, 
       {"Morning": 550000, "Midday": 301000, "Afternoon": 34000, "Evening":43000}, 
     {"Morning": 550320, "Midday": 351000, "Afternoon": 24000, "Evening":38000}, 
     {"Morning": 55000, "Midday": 3010, "Afternoon": 24000, "Evening":43054}, 
     {"Morning": 750000, "Midday": 401000, "Afternoon": 84000, "Evening":42100}, 
     {"Morning": 578000, "Midday": 306000, "Afternoon": 54000, "Evening":43400}, 
          ]; 

var xScale = d3.scale.ordinal() 
       .domain(d3.range(dataset.length)) 
       .rangeRoundBands([0, w], 0.05); 
// ternary operator to determine if global or local has a larger scale 
var yScale = d3.scale.linear() 
       .domain([0, d3.max(dataset, function(d) { return Math.max(d.Morning,d.Midday,d.Afternoon,d.Evening);})]) 
       .range([h, 0]); 
var xAxis = d3.svg.axis() 
       .scale(xScale) 
       .orient("bottom"); 
var yAxis = d3.svg.axis() 
       .scale(yScale) 
       .orient("left") 
       .ticks(5); 




var commaFormat = d3.format(','); 

//SVG element 
var svg = d3.select("#searchVolume") 
      .append("svg") 
      .attr("width", w + margin.left + margin.right) 
      .attr("height", h + margin.top + margin.bottom) 
      .append("g") 
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

// Graph Bars 
var sets = svg.selectAll(".set") 
    .data(dataset) 
    .enter() 
    .append("g") 
    .attr("class","set") 
    .attr("transform",function(d,i){ 
     return "translate(" + xScale(i) + ",0)"; 
    }) 
    ; 

sets.append("rect") 
    .attr("class","Morning") 
    .attr("width", xScale.rangeBand()/4) 
    .attr("y", function(d) { 
     return yScale(d.Morning); 
    }) 
    .attr("x", xScale.rangeBand()/4) 
    .attr("height", function(d){ 
     return h - yScale(d.Morning); 
    }) 
    .attr("fill", colors[0][1]) 
    .append("text") 
    .text(function(d) { 
     return commaFormat(d.Morning); 
    }) 
    .attr("text-anchor", "middle") 
    .attr("x", function(d, i) { 
     return xScale(i) + xScale.rangeBand()/4; 
    }) 
    .attr("y", function(d) { 
     return h - yScale(d.Morning) + 14; 
    }) 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "black") 
    ; 

sets.append("rect") 
    .attr("class","Midday") 
    .attr("width", xScale.rangeBand()/4) 
    .attr("y", function(d) { 
     return yScale(d.Midday); 
    }) 
    .attr("height", function(d){ 
     return h - yScale(d.Midday); 
    }) 
    .attr("fill", colors[1][1]) 
    .append("text") 
    .text(function(d) { 
     return commaFormat(d.Midday); 
    }) 
    .attr("text-anchor", "middle") 
    .attr("x", function(d, i) { 
     return xScale(i) + xScale.rangeBand()/4; 
    }) 
    .attr("y", function(d) { 
     return h - yScale(d.Midday) + 14; 
    }) 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "red") 
    ; 

    sets.append("rect") 
    .attr("class","Afternoon") 
    .attr("width", xScale.rangeBand()/4) 
    .attr("y", function(d) { 
     return yScale(d.Afternoon); 
    }) 
    .attr("height", function(d){ 
     return h - yScale(d.Afternoon); 
    }) 
    .attr("fill", colors[2][1]) 
    .append("text") 
    .text(function(d) { 
     return commaFormat(d.Afternoon); 
    }) 
    .attr("text-anchor", "middle") 
    .attr("x", function(d, i) { 
     return xScale(i) + xScale.rangeBand()/4; 
    }) 
    .attr("y", function(d) { 
     return h - yScale(d.Afternoon) + 14; 
    }) 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "red") 
    ; 

    sets.append("rect") 
    .attr("class","Evening") 
    .attr("width", xScale.rangeBand()/4) 
    .attr("y", function(d) { 
     return yScale(d.Evening); 
    }) 
    .attr("height", function(d){ 
     return h - yScale(d.Evening); 
    }) 
    .attr("fill", colors[3][1]) 
    .append("text") 
    .text(function(d) { 
     return commaFormat(d.Evening); 
    }) 
    .attr("text-anchor", "middle") 
    .attr("x", function(d, i) { 
     return xScale(i) + xScale.rangeBand()/4; 
    }) 
    .attr("y", function(d) { 
     return h - yScale(d.Evening) + 14; 
    }) 
    .attr("font-family", "sans-serif") 
    .attr("font-size", "11px") 
    .attr("fill", "red") 
    ; 
// xAxis 
svg.append("g") // Add the X Axis 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + (h) + ")") 
    .call(xAxis) 
     ; 
// yAxis 
svg.append("g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(0 ,0)") 
    .call(yAxis) 
    ; 
// xAxis label 
svg.append("text") 
    .attr("transform", "translate(" + (w/4) + " ," + (h + margin.bottom - 5) +")") 
    .style("text-anchor", "middle") 
    .text("Keyword"); 
//yAxis label 
svg.append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 0 - margin.left) 
     .attr("x", 0 - (h/4)) 
     .attr("dy", "1em") 
     .style("text-anchor", "middle") 
     .text("Searches"); 

// Title 
svg.append("text") 
     .attr("x", (w/2)) 
     .attr("y", 0 - (margin.top/2)) 
     .attr("text-anchor", "middle") 
     .style("font-size", "16px") 
     .style("text-decoration", "underline") 
     .text("Weekly Consumption"); 


// add legend 
var legend = svg.append("g") 
     .attr("class", "legend") 
     //.attr("x", w - 65) 
     //.attr("y", 50) 
     .attr("height", 100) 
     .attr("width", 100) 
     .attr('transform', 'translate(-20,50)'); 

var legendRect = legend.selectAll('rect').data(colors); 

legendRect.enter() 
    .append("rect") 
    .attr("x", w - 65) 
    .attr("width", 10) 
    .attr("height", 10); 

legendRect 
    .attr("y", function(d, i) { 
     return i * 20; 
    }) 
    .style("fill", function(d) { 
     return d[1]; 
    }); 

var legendText = legend.selectAll('text').data(colors); 

legendText.enter() 
    .append("text") 
    .attr("x", w - 52); 

legendText 
    .attr("y", function(d, i) { 
     return i * 20 + 9; 
    }) 
    .text(function(d) { 
     return d[0]; 
    }); 

D3 Fiddle

在上面的小提琴中,我试图用d3.js库制作条形图。我坚持以下基本的东西,甚至不应该花太多时间。我无法掌握d3的功能。你可以在小提琴上玩耍,任何帮助都会非常有益:
1.我想要将四个不同的小节组合在一个x值上。像'0'一样,它们中的四个不同于当前将所有东西合并为二的一个。
2.将x轴的内容从周一到周五从数字更改为日期。
3.对于y轴,我试图显示的值是,而不是20000,它应该显示20k和栏应识别,而动态创建它。这可能吗?

任何帮助将是非常有益的。我无法弄清楚。

+0

第1点:看起来像已经解决?第2点:查找标记点D3,第3点:您需要删除最后3个零点,并用字符'k'替换。在轴 – thatOneGuy

+0

@ thatOneGuy的域名中执行此操作可能会造成混淆。刚刚更新了小提琴。这个问题属于这个小提琴 –

回答

2

主要问题是你开始正确地加入你的数据,但之后你开始做一些手动的东西,可以通过使用data函数将数据加入你的子元素来解决。让我解释一下:

首先,我们需要两个x轴比例尺,一个用来保存我们的天域,另一个用来保存我们的时间域,使用天数范围为rangeRoundBands

var day_scale = d3.scale.ordinal() 
    .domain(d3.range(dataset.length)) 
    .rangeRoundBands([0, w], 0.05); 

var time_scale = d3.scale.ordinal(); 

time_scale.domain(['Morning', 'Midday', 'Afternoon', 'Evening']) 
    .rangeRoundBands([0, day_scale.rangeBand()]); 

让我们在设置我们的比例尺时处理x轴格式。我创建了一个数组,并在我们的tickFormat函数中让我们根据传递的数据的索引返回数组中的值。

var days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; 
var day_axis = d3.svg.axis() 
    .scale(day_scale) 
    .orient("bottom") 
    .tickFormat(function(d,i) { 
    return days[i]; 
    }); 

现在y轴的格式,我们可以通过使用d3.formatPrefix更多信息解决这个here

var prefix = d3.formatPrefix(1.21e9); 
var searches_axis = d3.svg.axis() 
    .scale(searches_scale) 
    .orient("left") 
    .ticks(5) 
    .tickFormat(function(d) { 
     var prefix = d3.formatPrefix(d); 
     return prefix.scale(d) + prefix.symbol; 
    }); 

现在让我们跳过我们的SVG和轴的配置,以获取数据连接问题:

var day_groups = svg.selectAll(".day-group") 
    .data(dataset) // join data to our selection 
    .enter().append("g") 
    .attr("class", function(d, i) { 
    return 'day-group day-group-' + i; 
    }) 
    .attr("transform", function(d, i) { 
    // position a g element with our day_scale and data index 
    return "translate(" + day_scale(i) + ",0)"; 
    }); 

现在我们的日历组定位正确,现在我们可以追加我们的时间数据。

var times_g = day_groups.selectAll(".time-group") 
    .data(function(d) { 
    // this is the tricky part, we are creating an array of 
    // objects with key (time...'Morning', 'Midday', 'Afternoon', 'Evening') 
    // and value (the value of the time) 
    // in order to create a time group for each time event 
    return Object.keys(d).map(function(key) { 
     return { 
     key: key, 
     value: d[key] 
     } 
    }); 
    }) 
    .enter().append("g") 
    .attr("class", function(d) { 
    return 'time-group time-group-' + d.key; 
    }) 
    .attr("transform", function(d) { 
    // use our time scale to position 
    return "translate(" + time_scale(d.key) + ",0)"; 
    }); 

现在让我们添加我们的反应!

var rects = times_g.selectAll('.rect') 
    .data(function(d) { 
    // use as data our object 
    return [d]; 
    }) 
    .enter().append("rect") 
    .attr("class", "rect") 
    .attr("width", time_scale.rangeBand()) // get width of rect based in our time_scale 
    .attr("x", function(d) { 
    return 0; // returning 0 since the group is in charge of positioning 
    }) 
    .attr("y", function(d) { 
    return searches_scale(d.value); // use our y_scale 
    }) 
    .attr("height", function(d) { 
    return h - searches_scale(d.value); // use our y_scale 
    }) 
    .style("fill", function(d) { 
    return colors[d.key]; // map colors by using an object 
    }); 

映射颜色对象:

var colors = { 
    "Morning":"#F64BEE", 
    "Midday": "#25B244", 
    "Afternoon": "#2BA3F4", 
    "Evening": "#FD7680" 
}; 

如果你有如何在这里工作是更新的jsfiddle有任何疑问:https://jsfiddle.net/706gsjfg/3/(我删除了某些事情,但你可以将它们添加后,我猜)

+0

简直太棒了!万分感谢! –