2014-07-15 2 views
1

http://bost.ocks.org/mike/treemap/을 사용하여 D3 트리 맵을 Splunk에 통합하려고합니다. 그러나 파일을 찾을 수 없으므로 d3.JSON ("flare.json")에서 오류가 발생합니다. JSON 배열을 js에 넣고 root = JSON.parse (myjson)를 호출하려고 시도했지만 예기치 않은 문자 JSON.parse가 배열됩니다. Bostick의 페이지에서 j를 보면, 실제로 트리 맵을 렌더링하는 함수를 호출하기 때문에 d3.JSON을 제거 할 수 없다는 것을 알 수 있습니다.GET을 사용하지 않고 JSON을 d3 트리 맵에로드하려고합니다

해결 방법에 대한 의견이 있으십니까?

renderResults: function($super, results) { 

    if(!results) { 
    this.resultsContainer.html('No content available.'); 
     return; 
    } 
    var margin = {top: 20, right: 0, bottom: 0, left: 0}, 
     width = 960, 
     height = 500 - margin.top - margin.bottom, 
     formatNumber = d3.format(",d"), 
     transitioning; 

    var x = d3.scale.linear() 
     .domain([0, width]) 
     .range([0, width]); 

    var y = d3.scale.linear() 
     .domain([0, height]) 
     .range([0, height]); 

    var treemap = d3.layout.treemap() 
     .children(function(d, depth) { return depth ? null : d._children; }) 
     .sort(function(a, b) { return a.value - b.value; }) 
     .ratio(height/width * 0.5 * (1 + Math.sqrt(5))) 
     .round(false); 

    var svg = d3.select("#chart").append("svg") 
     .attr("width", width + margin.left + margin.right) 
     .attr("height", height + margin.bottom + margin.top) 
     .style("margin-left", -margin.left + "px") 
     .style("margin.right", -margin.right + "px") 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
     .style("shape-rendering", "crispEdges"); 

    var grandparent = svg.append("g") 
     .attr("class", "grandparent"); 

    grandparent.append("rect") 
     .attr("y", -margin.top) 
     .attr("width", width) 
     .attr("height", margin.top); 

    grandparent.append("text") 
     .attr("x", 6) 
     .attr("y", 6 - margin.top) 
     .attr("dy", ".75em"); 

    var myjson = not including the actual array to save space 

      root = JSON.parse(myjson); 




    d3.json("flare.json", function(root) { 
     initialize(root); 
     accumulate(root); 
     layout(root); 
     display(root); 

     function initialize(root) { 
     root.x = root.y = 0; 
     root.dx = width; 
     root.dy = height; 
     root.depth = 0; 
     } 

     // Aggregate the values for internal nodes. This is normally done by the 
     // treemap layout, but not here because of our custom implementation. 
     // We also take a snapshot of the original children (_children) to avoid 
     // the children being overwritten when when layout is computed. 
     function accumulate(d) { 
     return (d._children = d.children) 
      ? d.value = d.children.reduce(function(p, v) { return p + accumulate(v); }, 0) 
      : d.value; 
     } 

     // Compute the treemap layout recursively such that each group of siblings 
     // uses the same size (1×1) rather than the dimensions of the parent cell. 
     // This optimizes the layout for the current zoom state. Note that a wrapper 
     // object is created for the parent node for each group of siblings so that 
     // the parent’s dimensions are not discarded as we recurse. Since each group 
     // of sibling was laid out in 1×1, we must rescale to fit using absolute 
     // coordinates. This lets us use a viewport to zoom. 
     function layout(d) { 
     if (d._children) { 
      treemap.nodes({_children: d._children}); 
      d._children.forEach(function(c) { 
      c.x = d.x + c.x * d.dx; 
      c.y = d.y + c.y * d.dy; 
      c.dx *= d.dx; 
      c.dy *= d.dy; 
      c.parent = d; 
      layout(c); 
      }); 
     } 
     } 

     function display(d) { 
     grandparent 
      .datum(d.parent) 
      .on("click", transition) 
      .select("text") 
      .text(name(d)); 

     var g1 = svg.insert("g", ".grandparent") 
      .datum(d) 
      .attr("class", "depth"); 

     var g = g1.selectAll("g") 
      .data(d._children) 
      .enter().append("g"); 

     g.filter(function(d) { return d._children; }) 
      .classed("children", true) 
      .on("click", transition); 

     g.selectAll(".child") 
      .data(function(d) { return d._children || [d]; }) 
      .enter().append("rect") 
      .attr("class", "child") 
      .call(rect); 

     g.append("rect") 
      .attr("class", "parent") 
      .call(rect) 
      .append("title") 
      .text(function(d) { return formatNumber(d.value); }); 

     g.append("text") 
      .attr("dy", ".75em") 
      .text(function(d) { return d.name; }) 
      .call(text); 

     function transition(d) { 
      if (transitioning || !d) return; 
      transitioning = true; 

      var g2 = display(d), 
       t1 = g1.transition().duration(750), 
       t2 = g2.transition().duration(750); 

      // Update the domain only after entering new elements. 
      x.domain([d.x, d.x + d.dx]); 
      y.domain([d.y, d.y + d.dy]); 

      // Enable anti-aliasing during the transition. 
      svg.style("shape-rendering", null); 

      // Draw child nodes on top of parent nodes. 
      svg.selectAll(".depth").sort(function(a, b) { return a.depth - b.depth; }); 

      // Fade-in entering text. 
      g2.selectAll("text").style("fill-opacity", 0); 

      // Transition to the new view. 
      t1.selectAll("text").call(text).style("fill-opacity", 0); 
      t2.selectAll("text").call(text).style("fill-opacity", 1); 
      t1.selectAll("rect").call(rect); 
      t2.selectAll("rect").call(rect); 

      // Remove the old node when the transition is finished. 
      t1.remove().each("end", function() { 
      svg.style("shape-rendering", "crispEdges"); 
      transitioning = false; 
      }); 
     } 

     return g; 
     } 

     function text(text) { 
     text.attr("x", function(d) { return x(d.x) + 6; }) 
      .attr("y", function(d) { return y(d.y) + 6; }); 
     } 

     function rect(rect) { 
     rect.attr("x", function(d) { return x(d.x); }) 
      .attr("y", function(d) { return y(d.y); }) 
      .attr("width", function(d) { return x(d.x + d.dx) - x(d.x); }) 
      .attr("height", function(d) { return y(d.y + d.dy) - y(d.y); }); 
     } 

     function name(d) { 
     return d.parent 
      ? name(d.parent) + "." + d.name 
      : d.name; 
     } 
    }; 

} 

나는 아직도이 두 사람이 어떻게 상호 작용할 수 있는지 확실하지 않습니다. 약간의 자바 스크립트 경험이 있지만 파이썬 경험은 없습니다. Splunk가 이러한 모든 스크립트를 통합하는 방식은 당황 스럽습니다.

import cherrypy 
import controllers.module as module 

import splunk, splunk.search, splunk.util, splunk.entity 
import json 
from splunk.appserver.mrsparkle.lib import jsonresponse 
import lib.util as util 
import lib.i18n as i18n 

import logging 
logger = logging.getLogger('splunk.module.TreeMap1') 

import math 
import cgi 

class TreeMap1(module.ModuleHandler): 

def generateResults(self, host_app, client_app, sid, count=1000, 
     offset=0, entity_name='results'): 

    count = max(int(count), 0) 
    offset = max(int(offset), 0) 
    if not sid: 
     raise Exception('TreeMap1.generateResults - sid not passed!') 

    try: 
     job = splunk.search.getJob(sid) 
    except splunk.ResourceNotFound, e: 
     logger.error('TreeMap could not find job %s. Exception: %s' % (sid, e)) 
     return _('<p class="resultStatusMessage">Could not get search data.</p>') 

    dataset = getattr(job, entity_name)[offset: offset+count] 

    outputJSON = {} 
    for i, result in enumerate(dataset): 
     tdict = {} 
     tdict[str(result.get('itemName', None))] = str(result.get('totalCPU', None)) 
     name = str(result.get('itemCat', None)) 
     if name not in outputJSON: 
      outputJSON[name] = dict() 
     outputJSON[name].update(tdict) 

    cherrypy.response.headers['Content-Type'] = 'text/json' 
    return json.dumps(outputJSON, sort_keys=True) 

def render_json(self, response_data, set_mime='text/json'): 
    cherrypy.response.headers['Content-Type'] = set_mime 

    if isinstance(response_data, jsonresponse.JsonResponse): 
     response = response_data.toJson().replace("</", "<\\/") 
    else: 
     response = json.dumps(response_data).replace("</", "<\\/") 

    return ' ' * 256 + '\n' + response 

답변

1

D3의 d3.JSON(url, ...) 그대로 GET 요청을 수행하고 JSON *로 응답을 구문 분석을 시도; jQuery의 $.getJSON(url, ...)과 비슷합니다. 트리 맵을 생성하는 데 필요한 JSON이 이미있는 경우에는 호출을 모두 무시하고 바로 콜백으로 이동하십시오. 이미 배열/객체가있는 경우 JSON.parse이 필요하지 않습니다. JSON.parse는 유효한 JSON 문자열을 배열/객체로 변환합니다.

* 이미 데이터가있는 경우, 당신은 그냥 사용할 수 있습니다, 같은 라인을 따라

... 이상 d3.json에 설명서를 참조하십시오 :

... 

    var myJSON = [ ... ] //The actual array you're loading. 
    initialize(myJSON); 
    accumulate(myJSON); 
    layout(myJSON); 
    display(myJSON); 

    ... 

그러나 통지를 무엇을 위의 코드에서 실제로 수행하고 있습니다. 당신은 배열initialize에 전달하는 - 객체를 원하는 나타납니다

function initialize(root) { //Root in this case is myVar -- an ARRAY. 
    root.x = root.y = 0; //Arrays don't have fields. This is BAD. 
    root.dx = width; 
    root.dy = height; 
    root.depth = 0; 
    } 

따라서, 당신이해야 할 것은 구조 myJSON의 유형을 사용해야합니다 알아낼 수 있습니다. 수정하려는 오류가 실제로 "flare.json"파일을 찾을 수 없다는 경우


은, 당신의 문제는 실제로 서버 측입니다. 너 플레어를 어떻게 대접하니? 슨 파일? 브라우저에서 액세스하여 자신이 생각하는 위치에 있는지 확인하십시오.

+0

오류는 발생하지 않았지만 트리 맵은 여전히 ​​표시되지 않습니다. 이것은 splunk 검색을 처리하기위한 python 스크립트와 관련된 문제 일 수 있다고 생각합니다. 필자는 결국 flare.json을 사용하지 않고 splunk 검색의 결과를 사용하여 트리 맵을 작성하기 때문에이 경우가 거의 예상됩니다. – user3699465

+0

관련 파이썬 코드를 게시 할 수 있습니까? 이 문제는 flare.json을 사용하고 싶지 않다는 사실에 불가 지합니다. 문제는 D3을 지나치게 틀린 대상이 거의 확실하다는 것입니다. myJSON/flare.json의 정확한 구조는 무엇입니까? –

+0

파이썬 스크립트를 포함하도록 편집했습니다. – user3699465

관련 문제