Pentaho中D3可视化库的集成及数据联动的实现

原创 2016-11-02 16:20:15 872
摘要: D3允许你将任意的数据绑定到文档对象模型(DOM),然后运用数据驱动转换到文档上。例如,你可以使用D3将一个数组生成一个HTML表格。或者,使用相同的数据来创建一个有平滑过渡和交互的交互式SVG条形图。 D3不是一个旨在提供每一个可能想到的功能的单一框架。相反的,D3所解决的问题的关键是:高效操作基于数据的文档。它提供了显著的灵活性,展现了web标准的全部功能,比如HTML、

 D3允许你将任意的数据绑定到文档对象模型(DOM),然后运用数据驱动转换到文档上。例如,你可以使用D3将一个数组生成一个HTML表格。或者,使用相同的数据来创建一个有平滑过渡和交互的交互式SVG条形图。

 D3不是一个旨在提供每一个可能想到的功能的单一框架。相反的,D3所解决的问题的关键是:高效操作基于数据的文档。它提供了显著的灵活性,展现了web标准的全部功能,比如HTML、SVG 和 CSS。D3非常快,它以最小的开销支持大型数据集以及交互与动画的动态行为。D3的函数式风格使代码通过组件和插件的多元化集合得以重用。

Pentaho中引入D3图形库

通过Pentaho的插件仓库Marketplace下载D3软件包,具体操作加下图:

2.jpg

2.jpg

重启Pentaho软件,然后查看D3可视化库是否正确引入,见下图:

2.jpg

2.jpg

如果出现上述的情况,说明D3可视化库引入成功,小编恭喜你可以进入D3的可视化编程啦!

D3图形间联动实战

绘图效果展示和图形联动说明

2.jpg

2.jpg

    通过点击右边的门店柱状图,左边的时段柱状图做相应的联动, 其中在图形之间传递的参数是门店的ID;在此处,我想要强调的是:较之于Pentaho CDE的绘图原则,D3的绘图更显得自由;Pentaho CDE绘制的图形适用于一般意义上的大数据展现,但是我们有时候需要为我们的客户定制个性化的图形,一旦图形追求个性化必然会导致我们Pentaho提供的图形的样式无法满足我们的需求,此时D3的绘图将是我们的一条出路,但由于D3的学习曲线较为陡峭,所以国内的大数据攻城狮一般会选择容易实现的图形库,譬如Echarts(https://my.oschina.net/u/2453090/blog/777048)或HighCharts,但是这些都不是很好的选择,掌握D3图形库的编程将成为大数据攻城狮必不可少的技能,接下来我们将通过代码的讲解对D3的可视化编程做简单的介绍,希望的小编的这篇文章对您有所帮助!

核心代码讲解

       通过上文,我们假设您已将D3组件库集成到Pentaho,那我们如何使用这个图形库喃?接下来小编将介绍这个强大的图形库的使用。

2.jpg

如上图,它的使用更CDE的图形库组件没什么区别,与CDE绘图有所区别的是,D3的绘图代码需要开发者手写,不像CDE通过属性设置的,具体见下图:

2.jpg

时段柱状图代码:

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);
        }
    });    
}


发布手记

热门词条