【问题标题】:How can I add graphs/data to Rickshaw with d3.js?如何使用 d3.js 将图形/数据添加到人力车?
【发布时间】:2012-11-12 21:52:50
【问题描述】:

这是我所拥有的:

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

背景栏代码:

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重新生成的。

如何将这些数据放入人力车图中以便重新生成?

【问题讨论】:

  • 如果我理解你正确的话,至少你应该把它们放在同一个范围内

标签: javascript svg d3.js rickshaw


【解决方案1】:

解决方案是设置更新函数来计算背景条的新高度, 要获得显示的条形图,您可以使用 graph.series.active();您也可能希望将 vars 保持在同一范围内....

所以解决方案本身:

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

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

b_red,b_green,b_yellow 是 d3 个初始化背景条的选择。

【讨论】:

  • 哇,这比我预期的要多得多。我认为这只是正确放置带有变量的代码而不是条形高度的硬编码值的问题。你能解释一下为什么所有这些都是必要的吗?
  • 我不明白,有什么必要?我刚刚添加了更新处理程序,它可以更改红色、绿色、黄色条的高度,并向您展示如何获取当前显示的数据。我认为您还可以在该更新功能中使用最大数据制作单个数据图
  • 嗨@eicto。我发现您用于获取最大数据和 onUpdate 处理程序的函数非常有用。只要我没有得到更好的答案,我就会奖励你,我也会发布我的解决方案。但是有一个问题:我怎样才能获得最大 y 轴高度,而不是获得最大数据?
  • 你的意思是绝对最大值?我没有检查好,但我认为 Axis 插件有一些关于它的内容,因为 Axis 是按比例重新计算的
【解决方案2】:

在@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/

【讨论】:

  • 我意识到这不是按比例缩放的,因为堆叠的数据将 y 轴增加到每年的最大值,而不是系列的最大值。我使用了graph.renderer.unstack = true,它解开了图形,这对我的目的来说很好:jsfiddle.net/bozdoz/Q6A3L/11
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 2013-11-17
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多