2015-10-09 2 views
2

Экспорт в PDF для пользовательского виджета не работает из отчетов icCube. Версия сервера версии 5.0.3 и отчет 5.0.3 (6: 2163).Экспорт в PDF из отчетов icCube с пользовательским виджетами

В журнале не было сообщений об ошибках, процесс остается застрявшим на вкладке Мониторинг -> Активные запросы.

Включенный отчет основан на демонстрационной схеме продаж icCube.

Виджет код:

FishboneChart.js:

test = { 
    module : {} 
} 

test.module.FishboneChart = (function (_super) { 

    __extends(FishboneChart, _super); 

    function FishboneChart(container, options) { 
     _super.call(this, container, options); 

     this.options = options; 
     this.container = container; 

     var chartContainer = $("<div class='ic3w-fishbone-chart'></div>"); 
     var contentContainer = $("<div class='ic3w-fishbone-chart-content'></div>"); 

     var ct = $(this.container); 
     ct.append(chartContainer); 
     chartContainer.append(contentContainer); 
    }; 

    $.extend(FishboneChart.prototype, { 

     buildInHtml : function (gviTable) { 

      var chartData = buildChartDataJson(gviTable); 
      renderFishboneChart(chartData); 
     } 
    }); 

    return FishboneChart; 

})(viz.GviChartBase); 

test.module.FishboneChartAdapterFactory = (function (_super) { 
    __extends(FishboneChartAdapterFactory, _super); 

    function FishboneChartAdapterFactory() { 
     _super.call(this, "test.module.FishboneChartAdapter"); 
    } 

    FishboneChartAdapterFactory.prototype.getId = function() { 
     return 'testFishboneChart'; 
    }; 

    FishboneChartAdapterFactory.prototype.getMenuGroupName = function() { 
     return "testMenu" 
    }; 

    FishboneChartAdapterFactory.prototype.getTag = function() { 
     return "testFishboneChart" 
    }; 

    return FishboneChartAdapterFactory; 

})(ic3.WidgetAdapterFactory); 

test.module.FishboneChartAdapter = (function (_super) { 
    __extends(FishboneChartAdapter, _super); 

    function FishboneChartAdapter(context) { 
     _super.call(this, context); 

     this.classID = "test.module.FishboneChartAdapter"; 
    } 

    FishboneChartAdapter.prototype.reportTypeName = function() { 
     return 'Test fishbone-chart'; 
    }; 

    FishboneChartAdapter.prototype.getWidgetGroupName = function() { 
     return 'chart'; 
    }; 

    FishboneChartAdapter.prototype.getNameForCssClass = function() { 
     return 'test-chart'; 
    }; 

    FishboneChartAdapter.prototype.gutsMeta = function() { 
     return [ 
      { 
       name: 'title', 
       type: 'text' 
      } 
     ] 
    }; 

    FishboneChartAdapter.prototype.createWidget = function (options, container) { 
     return new test.module.FishboneChart(container, options); 
    }; 

    return FishboneChartAdapter; 

})(ic3.ChartAdapter); 


var initializeFishbone = function(d3){ 
    "use strict"; 
    d3.fishbone = function(){ 

     var _margin = 50, 
      _marginRoot = 20, 
      _marginTail = 100, 
      _marginTop = 30, 
      _nodes, 
      _links, 
      _node, 
      _link, 
      _root, 
      _arrowId = function(d){ return "arrow"; }, 
      _children = function(d){ return d.children; }, 
      _label = function(d){ return d.name; }, 
      _perNodeTick = function(d){}, 
      _linkScale = d3.scale.log() 
       .domain([1, 5]) 
       .range([20, 10]), 
      _chartSize = getChartSize(), 
      _force = d3.layout.force() 
       .gravity(0) 
       .size([ 
        _chartSize.width, 
        _chartSize.height 
       ]) 
       .linkDistance(_linkDistance) 
       .chargeDistance([10]) 
       .on("tick", _tick); 

     var fb1 = function($){ 

      _links = []; 
      _nodes = []; 

      _build_nodes($.datum()); 

      _force 
       .nodes(_nodes) 
       .links(_links); 

      _link = $.selectAll(".link") 
       .data(_links); 

      _link.enter().append("line"); 

      _link 
       .attr({ 
        "class": function(d){ return "link link-" + d.depth; }, 
        "marker-end": function(d){ 
         return d.arrow ? "url(#" + _arrowId(d) + ")" : null; 
        } 
       }); 

      _link.exit().remove(); 

      _node = $.selectAll(".node").data(_nodes); 
      _node.enter().append("g") 
       .attr({ 
        "class": function(d){ return "node" + (d.root ? " root" : ""); } 
       }) 
       .append("text"); 

      _node.select("text") 
       .attr({ 
        "class": function(d){ return "label-" + d.depth; }, 
        "text-anchor": function(d){ 
         return !d.depth ? "start" : d.horizontal ? "end" : "middle"; 
        }, 
        dy: function(d){ 
         return d.horizontal ? ".35em" : d.region === 1 ? "1em" : "-.2em"; 
        } 
       }) 
       .text(_label); 

      _node.exit().remove(); 
      _node 
       .call(_force.drag) 
       .on("mousedown", function(){ d3.event.stopPropagation(); }); 

      _root = $.select(".root").node(); 
     }; 

     function _arrow($){ 
      var defs = $.selectAll("defs").data([1]); 

      defs.enter().append("defs"); 
      defs.selectAll("marker#" + _arrowId()) 
       .data([1]) 
       .enter().append("marker") 
       .attr({ 
        id: _arrowId(), 
        viewBox: "0 -5 10 10", 
        refX: 10, 
        refY: 0, 
        markerWidth: 10, 
        markerHeight: 10, 
        orient: "auto" 
       }) 
       .append("path") 
       .attr({d: "M0,-5L10,0L0,5"}); 
     } 

     function _build_nodes(node){ 

      _nodes.push(node); 

      var cx = 0; 
      var between = [node, node.connector], 
       nodeLinks = [{ 
        source: node, 
        target: node.connector, 
        arrow: true, 
        depth: node.depth || 0 
       }], 
       prev, 
       childLinkCount; 

      if(!node.parent){ 
       _nodes.push(prev = {tail: true}); 
       between = [prev, node]; 
       nodeLinks[0].source = prev; 
       nodeLinks[0].target = node; 
       node.horizontal = true; 
       node.vertical = false; 
       node.depth = 0; 
       node.root = true; 
       node.totalLinks = [] 
      }else{ 
       node.connector.maxChildIdx = 0; 
       node.connector.totalLinks = []; 
      } 

      node.linkCount = 1; 

      (_children(node) || []).forEach(function(child, idx){ 
       child.parent = node; 
       child.depth = (node.depth || 0) + 1; 
       child.childIdx = idx; 
       child.region = node.region ? node.region : (idx & 1 ? 1 : -1); 
       child.horizontal = !node.horizontal; 
       child.vertical = !node.vertical; 

       if(node.root && prev && !prev.tail){ 
        _nodes.push(child.connector = { 
         between: between, 
         childIdx: prev.childIdx 
        }) 
        prev = null; 
       }else{ 
        _nodes.push(prev = child.connector = {between: between, childIdx: cx++}); 
       } 

       nodeLinks.push({ 
        source: child, 
        target: child.connector, 
        depth: child.depth 
       }); 

       childLinkCount = _build_nodes(child); 
       node.linkCount += childLinkCount; 
       between[1].totalLinks.push(childLinkCount); 
      }); 

      between[1].maxChildIdx = cx; 

      Array.prototype.unshift.apply(_links, nodeLinks); 

      return node.linkCount; 
     } 


     function _linePosition($){ 
      $.attr({ 
       x1: function(d){ return d.source.x; }, 
       y1: function(d){ return d.source.y; }, 
       x2: function(d){ return d.target.x; }, 
       y2: function(d){ return d.target.y; } 
      }) 
     } 


     function _nodePosition($){ 
      $.attr("transform", function(d){ 
       return "translate(" + d.x + "," + d.y + ")"; 
      }) 
     } 


     function _linkDistance(d){ 
      return (d.target.maxChildIdx + 1) * _linkScale(d.depth === 0 ? 1 : d.depth); 
     } 


     function _tick(e){ 

      var k = 6 * e.alpha, 
       size = _force.size(), 
       width = size[0], 
       height = size[1], 
       a, 
       b; 

      _nodes.forEach(function(d){ 
       if(d.root){ d.x = width - (_marginRoot + _root.getBBox().width); } 
       if(d.tail){ d.x = _marginTail; d.y = height/2; } 

       if(d.depth === 1){ 
        d.y = d.region === -1 ? _marginTop : (height - _marginTop); 
        d.x -= 10 * k; 
       } 

       if(d.vertical){ d.y += k * d.region; } 

       if(d.depth){ d.x -= k; } 

       if(d.between){ 
        a = d.between[0]; 
        b = d.between[1]; 

        d.x = b.x - (1 + d.childIdx) * (b.x - a.x)/(b.maxChildIdx + 1); 
        d.y = b.y - (1 + d.childIdx) * (b.y - a.y)/(b.maxChildIdx + 1); 
       } 

       _perNodeTick(d); 
      }); 

      _node.call(_nodePosition); 
      _link.call(_linePosition); 
     } 

     fb1.links = function(){ return _links; }; 
     fb1.nodes = function(){ return _nodes; }; 
     fb1.force = function(){ return _force; }; 

     fb1.defaultArrow = _arrow; 

     fb1.margin = function(_){ 
      if(!arguments.length){ return _margin; } 
      _margin = _; 
      return my; 
     }; 

     fb1.children = function(_){ 
      if(!arguments.length){ return _children; } 
      _children = _; 
      return my; 
     }; 

     fb1.label = function(_){ 
      if(!arguments.length){ return _label; } 
      _label = _; 
      return my; 
     }; 

     fb1.perNodeTick = function(_){ 
      if(!arguments.length){ return _perNodeTick; } 
      _perNodeTick = _; 
      return my; 
     }; 

     return fb1; 
    }; 
}; 

var getChartSize = function() { 
    var chart = $('.ic3w-fishbone-chart'); 
    return { 
     width : chart.width() || 0, 
     height : chart.height() || 0 
    }; 
}; 

var renderFishboneChart = function(chartData) { 

    if (!d3.fishbone) { 
     initializeFishbone(d3); 
    } 

    d3.selectAll('.ic3w-fishbone-chart-content svg').remove(); 

    var fishbone = d3.fishbone(); 
    d3.select('.ic3w-fishbone-chart-content') 
     .append("svg") 
     .attr(getChartSize()) 
     .datum(chartData) 
     .call(fishbone.defaultArrow) 
     .call(fishbone); 

    fishbone.force().start(); 
}; 

var buildChartDataJson = function(gviTable) { 

    var rowCount = gviTable.getRowCount(); 
    var colCount = gviTable.getColumnCount(); 

    var currentLevel, levelDepthStr; 
    var currentBranch = []; 
    for (var i = 0; i < colCount; i++) { 
     levelDepthStr = gviTable.getPropertyForColumnHeader(i, 0, "a_ld"); 
     currentLevel = parseInt(levelDepthStr); 

     if (!isNaN(currentLevel)) { 

      var currentEl = { 
       name: gviTable.getColumnLabel(i), 
       children: [] 
      }; 

      if (currentLevel <= currentBranch.length - 1) { 
       removeElements(currentBranch, currentLevel); 
      } 

      currentBranch[currentLevel] = currentEl; 

      if (currentLevel != 0) { 
       var parent = currentBranch[currentLevel - 1]; 
       parent.children.push(currentEl); 
      } 
     } 
    } 

    return currentBranch.length > 0 ? currentBranch[0] : {}; 
}; 

var removeElements = function(array, targetLength) { 

    if (array) { 
     while (array.length > targetLength) { 
      array.pop(); 
     } 
    } 
}; 

FishBonePlugin.js:

ic3globals.plugins.push(
{ 
    name: "Fishbone Chart", 

    loadCSS: function (options) { 
     var root = options.rootLocal + "plugins/"; 
     ic3css(root + 'Fishbone.css'); 
    }, 

    loadJS: function (options) { 
     var root = options.rootLocal + "plugins/"; 

     var deps = ['FishboneChart']; 

     $script(root + 'FishboneChart.js', deps[0]); 

     $script.ready(deps, function() { /* asynchronous callback */ 
      options.callback && options.callback(); 
     }); 

    }, 

    registerWidgetFactories: function (manager) { 
     manager.addWidgetFactory(new test.module.FishboneChartAdapterFactory()); 
    }, 

    registerBabylonTags: function (babylon) { 
    } 
}); 

Fishbone.css:

.ic3w-fishbone-chart { 
    height: 100%; 
    width: 100%; 
    margin: 0; 
    padding: 0; 
    overflow: hidden; 
} 

.ic3w-fishbone-chart-content *{ 
    font-family: "Gill Sans", "Gill Sans MT"; 
} 


.ic3w-fishbone-chart-content .label-0 { 
    font-size: 2em; 
} 

.ic3w-fishbone-chart-content .label-1 { 
    font-size: 1.5em; 
    fill: #111; 
} 

.ic3w-fishbone-chart-content .label-2 { 
    font-size: 1em; 
    fill: #444; 
} 

.ic3w-fishbone-chart-content .label-3 { 
    font-size: .9em; 
    fill: #888; 
} 

.ic3w-fishbone-chart-content .label-4 { 
    font-size: .8em; 
    fill: #aaa; 
} 

.ic3w-fishbone-chart-content .link-0 { 
    stroke: #000; 
    stroke-width: 2px; 
} 

.ic3w-fishbone-chart-content .link-1 { 
    stroke: #333; 
    stroke-width: 1px; 
} 

.ic3w-fishbone-chart-content .link-2, .ic3w-fishbone-chart-content .link-3, .ic3w-fishbone-chart-content .link-4 { 
    stroke: #666; 
    stroke-width: .5px; 
} 

Доклад код:

{"classID":"ic3.ReportGuts","guts_":{"ic3Version":13,"schemaName":"Sales","cubeName":"Sales","layout":{"classID":"ic3.FixedLayout","guts_":{"ic3Version":13,"grid":10,"boxes":[{"classID":"ic3.FixedLayoutBox","guts_":{"ic3Version":13,"header":"widget-0 (widgetGroup.testMenu/testFishboneChart)","behaviour":"Fixed Box","noPrint":false,"position":{"top":0,"left":170,"width":1380,"height":820},"widgetAdapterUid":"w1","zIndex":2001,"ic3_uid":"ic3-164"}}]}},"widgetMgr":{"classID":"ic3.WidgetAdapterContainerMgr","guts_":{"ic3Version":13,"items":[{"classID":"test.module.FishboneChartAdapter","guts_":{"ic3Version":13,"navigationGuts":{"classID":"ic3.NavigationStrategy","guts_":{"ic3Version":13,"menuVisibility":{"back":true,"axisXChange":"All","axisYChange":"All","filter":"All","reset":true,"widget":true,"others":"All"},"maxAxisMemberCount":25}},"ic3_name":"widget-0","ic3_uid":"w1","ic3_eventMapper":{"classID":"ic3.EventWidgetMapper","guts_":{"__ic3_widgetEventsDescription":{}}},"ic3_mdxBuilderUid":"m1","__ic3_widgetTypeName":"widgetGroup.testMenu/testFishboneChart"}}]}},"constantMgr":{"classID":"ic3.ConstantsMgr","guts_":{"ic3Version":13}},"cssMgr":{"classID":"ic3.CssMgr","guts_":{}},"javascriptMgr":{"classID":"ic3.ReportJavascriptMgr","guts_":{"ic3Version":13,"js":"/**                  \n * A function called each time an event is generated.     \n *                  \n * @param context the same object is passed between consumeEvent calls. \n *    Can be used to store information.      \n *  {                \n *   $report : jQuery context of the report container   \n *   fireEvent : a function(name, value) triggering an event \n *  }                \n *                  \n * @param event the event information         \n *                  \n   {                \n *   name : as specified in the 'Events' tab      \n *   value : (optional) actual event value      \n *   type : (optional) e.g., ic3selection      \n *  }                \n *                  \n * Check the 'Report Event Names' menu for the list of available events. \n */                  \n                  \nfunction consumeEvent(context, event) {        \n if (event.name == 'ic3-report-init') {         \n  \n  ic3globals.plugins.push(\n  {\n   name: \"Fishbone Chart\",\n\n   loadCSS: function (options) {\n   },\n\n   loadJS: function (options) {\n   },\n\n   registerWidgetFactories: function (manager) {\n    console.log('korte1');\n    manager.addWidgetFactory(new test.module.FishboneChartAdapterFactory());\n   },\n\n   registerBabylonTags: function (babylon) {\n   }\n  });\n }                  \n}"}},"calcMeasureMgr":{"classID":"ic3.CalcMeasureMgr","guts_":{"measures":[]}},"mdxQueriesMgr":{"classID":"ic3.MdxQueriesContainerMgr","guts_":{"mdxQueries":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[{"classID":"ic3.QueryBuilderWidget","guts_":{"mdxWizard":{"classID":"ic3.QueryBuilderWizardForm","guts_":{"rows":[],"cols":[{"classID":"ic3.QueryBuilderHierarchyForm","guts_":{"hierarchy":{"name":"Geography","uniqueName":"[Customers].[Geography]"},"type":"membersOf","membersOf":"all members"}}],"filters":[],"nonEmptyOnRows":false,"nonEmptyOnColumns":false}},"mdxFlat":{"classID":"ic3.QueryBuilderFlatMdxForm","guts_":{"useMdxStatement":false}},"ic3_name":"mdx Query-0","ic3_uid":"m1"}}]}},"mdxFilter":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[]}},"actionBuilders":{"classID":"ic3.BaseContainerMgr","guts_":{"ic3Version":13,"items":[]}}}}}} 

Спасибо, Балинт Ruzsa

+0

код адаптера виджет выглядит нормально; возможно, проблема в том, что плагин неправильно установлен в веб-отчетности; он должен быть доступен с помощью кода приложения Web Reporting, который используется во время процесса печати (может отличаться от приложения веб-отчетности, которое открывается при открытии в браузере). –

ответ

0
  1. Виджет адаптер код необходимо две дополнительные функции (обход внутренней ошибки):

    FishboneChartAdapter.prototype.hasNavigation = function() 
    { 
        return false; 
    }; 
    
    FishboneChartAdapter.prototype.getNavigationMenuItems = function() 
    { 
        return []; 
    }; 
    
  2. isRendered метод должен быть изменен, так как макет для диаграммы вычислительная динамика. Я предлагаю использовать простой setTimeout с эвристическим таймаутом, но вы можете реализовать пользовательскую проверку.

FishboneChart:

test.module.FishboneChart = (function (_super) { 

     __extends(FishboneChart, _super); 

     function FishboneChart(container, options) { 
      _super.call(this, container, options); 

      this.options = options; 
      this.container = container; 
      this.rendered = false; 

      var chartContainer = $("<div class='ic3w-fishbone-chart'></div>"); 
      var contentContainer = $("<div class='ic3w-fishbone-chart-content'></div>"); 

      var ct = $(this.container); 
      ct.append(chartContainer); 
      chartContainer.append(contentContainer); 
     }; 

     $.extend(FishboneChart.prototype, { 

      buildInHtml: function (gviTable) { 

       var chartData = buildChartDataJson(gviTable); 
       renderFishboneChart(chartData); 

       var self = this; 
       // wait until layout is stabilized 
       setTimeout(function(){self.rendered = true;}, 10000); 
      }, 
      isRendered: function() { 
       return this.rendered; 
      } 
     }); 

     return FishboneChart; 

    })(viz.GviChartBase); 
Смежные вопросы