abstract: D3允許你將任意的數(shù)據(jù)綁定到文檔對象模型(DOM),然后運用數(shù)據(jù)驅(qū)動轉(zhuǎn)換到文檔上。例如,你可以使用D3將一個數(shù)組生成一個HTML表格。或者,使用相同的數(shù)據(jù)來創(chuàng)建一個有平滑過渡和交互的交互式SVG條形圖。 D3不是一個旨在提供每一個可能想到的功能的單一框架。相反的,D3所解決的問題的關(guān)鍵是:高效操作基于數(shù)據(jù)的文檔。它提供了顯著的靈活性,展現(xiàn)了web標(biāo)準(zhǔn)的全部功能,比如HTML、
D3允許你將任意的數(shù)據(jù)綁定到文檔對象模型(DOM),然后運用數(shù)據(jù)驅(qū)動轉(zhuǎn)換到文檔上。例如,你可以使用D3將一個數(shù)組生成一個HTML表格?;蛘?,使用相同的數(shù)據(jù)來創(chuàng)建一個有平滑過渡和交互的交互式SVG條形圖。
D3不是一個旨在提供每一個可能想到的功能的單一框架。相反的,D3所解決的問題的關(guān)鍵是:高效操作基于數(shù)據(jù)的文檔。它提供了顯著的靈活性,展現(xiàn)了web標(biāo)準(zhǔn)的全部功能,比如HTML、SVG 和 CSS。D3非???,它以最小的開銷支持大型數(shù)據(jù)集以及交互與動畫的動態(tài)行為。D3的函數(shù)式風(fēng)格使代碼通過組件和插件的多元化集合得以重用。
Pentaho中引入D3圖形庫
通過Pentaho的插件倉庫Marketplace下載D3軟件包,具體操作加下圖:
重啟Pentaho軟件,然后查看D3可視化庫是否正確引入,見下圖:
如果出現(xiàn)上述的情況,說明D3可視化庫引入成功,小編恭喜你可以進入D3的可視化編程啦!
D3圖形間聯(lián)動實戰(zhàn)
繪圖效果展示和圖形聯(lián)動說明
通過點擊右邊的門店柱狀圖,左邊的時段柱狀圖做相應(yīng)的聯(lián)動, 其中在圖形之間傳遞的參數(shù)是門店的ID;在此處,我想要強調(diào)的是:較之于Pentaho CDE的繪圖原則,D3的繪圖更顯得自由;Pentaho CDE繪制的圖形適用于一般意義上的大數(shù)據(jù)展現(xiàn),但是我們有時候需要為我們的客戶定制個性化的圖形,一旦圖形追求個性化必然會導(dǎo)致我們Pentaho提供的圖形的樣式無法滿足我們的需求,此時D3的繪圖將是我們的一條出路,但由于D3的學(xué)習(xí)曲線較為陡峭,所以國內(nèi)的大數(shù)據(jù)攻城獅一般會選擇容易實現(xiàn)的圖形庫,譬如Echarts(https://my.oschina.net/u/2453090/blog/777048)或HighCharts,但是這些都不是很好的選擇,掌握D3圖形庫的編程將成為大數(shù)據(jù)攻城獅必不可少的技能,接下來我們將通過代碼的講解對D3的可視化編程做簡單的介紹,希望的小編的這篇文章對您有所幫助!
核心代碼講解
通過上文,我們假設(shè)您已將D3組件庫集成到Pentaho,那我們?nèi)绾问褂眠@個圖形庫喃?接下來小編將介紹這個強大的圖形庫的使用。
如上圖,它的使用更CDE的圖形庫組件沒什么區(qū)別,與CDE繪圖有所區(qū)別的是,D3的繪圖代碼需要開發(fā)者手寫,不像CDE通過屬性設(shè)置的,具體見下圖:
時段柱狀圖代碼:
function f(dataset){ var data = this.cdaResultToD3Array(dataset); var margin = {top: 50, right: 20, bottom: 30, left: 100}, width = this.getWidth() - margin.left - margin.right - 40, height = this.getHeight() - margin.top - margin.bottom; var formatPercent = d3.format("/1000K"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1, .5); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(formatPercent); var svg = d3.select("#"+this.htmlObject).append("svg") .classed("svg-container", true) //container class to make it responsive .attr("preserveAspectRatio", "xMinYMin meet") .attr("viewBox", "0 0 600 400") .classed("svg-content-responsive", true) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); data.forEach( function(d) { d.ItemSaleAmt = +d.ItemSaleAmt; } ); x.domain(data.map(function(d) { return d.HourNo; })); y.domain([0, d3.max(data, function(d) { return d.ItemSaleAmt; })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("時段銷售額"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.HourNo); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.ItemSaleAmt); }) .attr("height", function(d) { return height - y(d.ItemSaleAmt); }); function resize(e){ var width = $('#HourNoHtmlObj').width(); var height = $('#HourNoHtmlObj').height(); svg.attr('width', width); svg.attr('height', height); force.size([width, height]).resume(); } }
門店柱狀圖代碼:
function f(dataset){ var data = this.cdaResultToD3Array(dataset); console.log(data); var margin = {top: 50, right: 20, bottom: 30, left: 100}, width = this.getWidth() - margin.left - margin.right - 10, height = this.getHeight() - margin.top - margin.bottom; var formatPercent = d3.format(".00"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1, .2); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(formatPercent); var svg = d3.select("#"+this.htmlObject).append("svg") .classed("svg-container", true) .attr("preserveAspectRatio", "xMinYMin meet") .attr("viewBox", "0 0 600 400") .classed("svg-content-responsive", true) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); data.forEach( function(d) { d.Amount = +d.Amount; } ); x.domain(data.map(function(d) { return d.Name; })); y.domain([0, d3.max(data, function(d) { return d.Amount; })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("門店銷售額"); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("class", "bar") .attr("x", function(d) { return x(d.Name); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.Amount); }) .attr("height", function(d) { return height - y(d.Amount); }); svg.selectAll(".bar").on("click", function(d/*,event*/) { if($("#HourNoHtmlObj > svg").length > 0){ $('#HourNoHtmlObj svg').remove(); Dashboards.fireChange('OutletId', d.Id); }else{ Dashboards.fireChange('OutletId', d.Id); } }); }