2016-06-11 219 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

簡直太棒了!萬分感謝! –