2012-11-12 64 views
4

这是我有:如何使用d3.js将图形/数据添加到Rickshaw?

http://jsfiddle.net/bozdoz/Q6A3L/

rickshaw d3.js graph

代码为背景吧:

maxData = 80000000; 
maxHeight = 250; 
var yScale = d3.scale.linear(). 
    domain([0, maxData]). // your data minimum and maximum 
    range([0, maxHeight]); // the pixels to map to, e.g., the height of the diagram. 

var riskpoints = [62000000,48000000,30000000]; 
var rectDemo = d3.select("#chart"). 
    append("svg:svg"). 
    attr("width", 400). 
    attr("height", maxHeight). 
    attr('class','risk'); 

rectDemo.append("svg:rect"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[0])). 
    attr("height", yScale(riskpoints[0]) - yScale(riskpoints[1])). 
    attr("width", '100%'). 
    attr("fill", "rgba(0,100,0,.3)"); 

rectDemo.append("svg:rect"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[1])). 
    attr("height", yScale(riskpoints[1]) - yScale(riskpoints[2])). 
    attr("width", '100%'). 
    attr("fill", "rgba(100,100,0,.3)"); 

rectDemo.append("svg:rect"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[2])). 
    attr("height", yScale(riskpoints[2])). 
    attr("width", '100%'). 
    attr("fill", "rgba(100,0,0,.3)"); 

这正是我想要的,除了把我所造红色,黄色,绿色背景限定固定高度。

当您使用滑块时,或者更重要的是,当图形重新生成时(它将与实际数据一起),我希望背景条调整到正确的高度。

例如,在图像中,绿色条位于300M和200M之间。如果除去红色(垂直)条以外的所有图形数据,则绿色条(水平)仅略高于40M。这是因为背景条的位置/高度不会重新生成,而图形数据的位置/高度是通过人力车javascript重新生成的。

我怎么能把这些数据放入人力车图形中以便重新生成?

+0

没有D3.js专家? – bozdoz

+0

至少你应该把它们放在图形所在的相同范围内,如果我理解你正确 –

回答

3

解决的办法是设置更新函数来计算背景条的新高度, 以获得可以使用的显示条graph.series.active();你可能也想保持瓦尔在同一范围内....

因此该解决方案本身:

var maxHeight; 
var background_update = function(graph) { 
    //skip 1st time; 
    if (maxHeight === undefined) {return;} 
    var series=graph.series.active(); 
    maxHeight=yScale(get_maximum_all(series)); 
    //console.log(maxHeight); 
    var red_riskpoint=get_maximum("y",series[0]); 
    var yellow_riskpoint=get_maximum("y",series[1]); 
    var green_riskpoint=get_maximum("y",series[2]); 
    //console.log(graph.series.active()); 
    console.log(yScale(red_riskpoint),yScale(yellow_riskpoint),yScale(green_riskpoint)); 
     
   // return; 
     
    b_red.attr("y", maxHeight - yScale(red_riskpoint)).attr("height", yScale(red_riskpoint)); 
    b_yellow.attr("y", maxHeight - yScale(yellow_riskpoint)).attr("height", Math.abs(yScale(yellow_riskpoint) - yScale(red_riskpoint))); 
    b_green.attr("y", maxHeight - yScale(green_riskpoint)).attr("height", Math.abs(yScale(green_riskpoint) - yScale(yellow_riskpoint))); 
    console.log(maxHeight-yScale(green_riskpoint)); 
}; 
var get_maximum_all=function(series) { 
    var max=0; 
    for (var i in series) { 
        var stack=series[i].stack; 
        for (n in stack) { 
            if (stack[n].y>max) {max=stack[n].y;} 
            if (stack[n].y0>max) {max=stack[n].y0;} 
        } 
    } 
    return max; 
} 
    var get_maximum=function(tag,object){ 
    var max=0; 
    for (var i in object.stack) { 
        if (object.stack[i][tag]>max) {max=object.stack[i][tag];} 
    } 
return max; 
    } 
Rickshaw.Graph.RangeSlider = function(args) { 

    var element = this.element = args.element; 
    var graph = this.graph = args.graph; 


    $(element).slider({ 

        range: true, 
        min: graph.dataDomain()[0], 
        max: graph.dataDomain()[1], 
        values: [ 
            graph.dataDomain()[0], 
            graph.dataDomain()[1] 
            ], 
        slide: function(event, ui) { 

            graph.window.xMin = ui.values[0]; 
            graph.window.xMax = ui.values[1]; 
            graph.update(); 

            // if we're at an extreme, stick there 
            if (graph.dataDomain()[0] == ui.values[0]) { 
                graph.window.xMin = undefined; 
            } 
            if (graph.dataDomain()[1] == ui.values[1]) { 
                graph.window.xMax = undefined; 
            } 
        } 
    }); 


    element.style.width = graph.width + 'px'; 

    graph.onUpdate(function() { 

        var values = $(element).slider('option', 'values'); 

        $(element).slider('option', 'min', graph.dataDomain()[0]); 
        $(element).slider('option', 'max', graph.dataDomain()[1]); 

        if (graph.window.xMin == undefined) { 
            values[0] = graph.dataDomain()[0]; 
        } 
        if (graph.window.xMax == undefined) { 
            values[1] = graph.dataDomain()[1]; 
        } 

        $(element).slider('option', 'values', values); 
        background_update(graph); 
    }); 
} 

其他代码几乎是相同的,你放在拨弄,

我的小提琴here

请注意,我不知道如何计算风险点,我只是试图获得最大值。我确信你可以通过查看b_red,b_green,b_yellow来查看console.log(series)

的计算风险点,它是d3选择初始化的背景条。

+0

哇,这比我预期的要多得多。我认为这只是代码的适当位置,而不是高度的硬编码值。你能解释为什么所有这些都是必要的吗? – bozdoz

+0

我不明白,有什么必要?我只是添加了更新处理程序,它可以改变红色,绿色和黄色条的高度,并向您展示如何获取当前显示的数据。我认为你也可以用最大数据做一个数据图表,在那个更新函数 –

+0

Hi @ eicto。我发现你的函数获取最大数据和onUpdate处理程序非常有用。只要我没有得到更好的答案,我会奖励你的赏金,我也会发布我的解决方案。但有一个问题:我怎么才能获得最大的y轴高度? – bozdoz

1

我在@ eicto的答案的帮助下发现了一些解决方案。

var maxHeight = 250; 
var theSVG = d3.select("#chart svg"); 

//from @eicto: get the maximum value on the current chart 
function get_maximum_all(series) { 
    var max=0; 
    for (var i in series) { 
     var stack=series[i].stack; 
     for (n in stack) { 
      if (stack[n].y>max) {max=stack[n].y;} 
      if (stack[n].y0>max) {max=stack[n].y0;} 
     } 
    } 
    return parseInt(max); 
} 

//create a function to call on graph update event 
function createRiskPoints(riskpoints){ 
//these variables need to change on each graph update 
    var series = graph.series.active(); 
//this variable should be get_max_y_axis, but I don't know how to do that 
    var maxData = get_maximum_all(series); 
    var yScale = d3.scale.linear(). 
    domain([0, maxData]). 
    range([0, maxHeight]); 

//using dummy values for now 
    var riskpoints = (riskpoints) ? riskpoints : [300000000,200000000,100000000]; 

//insert the bars so they go behind the data values 
theSVG.insert("svg:rect", ":first-child"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[0])). 
    attr("height", yScale(riskpoints[0]) - yScale(riskpoints[1])). 
    attr("width", '100%'). 
    attr("fill", "rgba(0,100,0,.2)"); 

theSVG.insert("svg:rect", ":first-child"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[1])). 
    attr("height", yScale(riskpoints[1]) - yScale(riskpoints[2])). 
    attr("width", '100%'). 
    attr("fill", "rgba(100,100,0,.2)"); 

theSVG.insert("svg:rect", ":first-child"). 
    attr("x",0). 
    attr("y", maxHeight - yScale(riskpoints[2])). 
    attr("height", yScale(riskpoints[2])). 
    attr("width", '100%'). 
    attr("fill", "rgba(100,0,0,.2)"); 
} 
//call the function 
    createRiskPoints(); 
//call the function on graph update: thanks to @eicto 
    graph.onUpdate(createRiskPoints);​ 

现在当图形发生变化时条形图会发生变化;但是,它们不是按比例的。这将是我的下一个任务。

http://jsfiddle.net/bozdoz/Q6A3L/

+0

我意识到它只是没有规模,因为数据被堆叠,将y轴增加到每年的最大总数,而不是系列的最大值。我使用了graph.renderer.unstack = true,并且它解开了这个图表,这对我的目的来说很好:http://jsfiddle.net/bozdoz/Q6A3L/11/ – bozdoz