1

私はJavaScriptとD3の初心者です。

データを絶対目盛とパーセント目盛で表示する積み上げ面グラフを作成しようとしています。これには、いじることが含まれることに気づきました

d3.layout.stack().offset("zero") および d3.layout.stack().offset("expand")。

私はチャートに私が望むことをさせることに成功しました:

http://jsfiddle.net/dSJ4E/

...しかし、私は自分のアプローチを誇りに思っているわけではなく、それを行うためのより良い方法があると確信しています. 何か案は?知っているかもしれない簡単な例はありますか?

if/else ステートメントを設定するときに、それまでに書いたものをすべて再宣言し、オフセット変数だけを変更するだけなので、自分のコードに満足していません。それは不格好なアプローチのようです。また、これでトランジションを設定できるとは思いません。

data = [{"type": "Group1",
             "values": [
                {"x":0, "y": 2.5},
                {"x":1, "y": 2.4},
                {"x":2, "y": 0.3}]},
            {"type": "Group2",
             "values": [
                {"x":0, "y": 1.5},
                {"x":1, "y": 1.3},
                {"x":2, "y": 1.1}]}
            ];
var stackZero = d3.layout.stack()
        .values(function(d){return d.values;})  
        .offset("zero");

stackZero(data);
var xScale = d3.scale.linear()
        .domain([0,2])
        .range([0, width]);

    var yScale = d3.scale.linear()
        .range([height,0])
        .domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);

    var area = d3.svg.area()
        .x(function(d){return xScale(d.x);})
        .y0(function(d){return yScale(d.y0);})
        .y1(function(d){return yScale(d.y0 + d.y);});       

    var svg = d3.selectAll("body")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top +")");

    svg.selectAll(".layers")
        .data(data)
        .enter()
        .append("path")
        .attr("class", "layer")
        .attr("d", function(d){return area(d.values);})
        .style("fill", function (d,i){return colors(i)});

    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left");

    svg.append("g")
        .attr("class", "y axis")
        .attr("transform", "translate(0,0)")
        .call(yAxis);   

    d3.select("p") //now we start to interact with the chart
        .on("click", function() { 

            console.log("entering variable is " + stackType);

            svg.selectAll("path").data([]).exit().remove();
            svg.selectAll(".y.axis").data([]).exit().remove();
if(stackType){ //enter true, or expanded data

            var stackExpand = d3.layout.stack()
                .values(function(d){return d.values;})
                .offset("expand");

            stackExpand(data);

            console.log(data);

            var yScale = d3.scale.linear()
                .range([height,0])
                .domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);

            var area = d3.svg.area()
                .x(function(d){return xScale(d.x);})
                .y0(function(d){return yScale(d.y0);})
                .y1(function(d){return yScale(d.y0 + d.y);});

            svg.selectAll(".layers")
                //.data(stackZero(data))
                .data(stackExpand(data))
                .enter()
                .append("path")
                .attr("class", "layer")
                .attr("d", function(d){return area(d.values);})
                .style("fill", function (d,i){return colors(i)});

            formatter = d3.format(".0%");

            var yAxis = d3.svg.axis()
                .scale(yScale)
                .orient("left")
                .tickFormat(formatter);

            svg.append("g")
                .attr("class", "y axis")
                .attr("transform", "translate(0,0)")
                .call(yAxis);


            stackType = false;
            console.log("exiting variable is " + stackType);

            } else { //enter false, or zero data

            data = [{"type": "Group1",
             "values": [
                {"x":0, "y": 2.5},
                {"x":1, "y": 2.4},
                {"x":2, "y": 0.3}]},
            {"type": "Group2",
             "values": [
                {"x":0, "y": 1.5},
                {"x":1, "y": 1.3},
                {"x":2, "y": 1.1}]}
            ];

            var stackZero = d3.layout.stack()
                .values(function(d){return d.values;})
                .offset("zero");

            stackZero(data);

            console.log(data);

            var yScale = d3.scale.linear()
                .range([height,0])
                .domain([0, d3.max(data, function(d){return d3.max(d.values, function(d){return d.y0 + d.y;});})]);

            var area = d3.svg.area()
                .x(function(d){return xScale(d.x);})
                .y0(function(d){return yScale(d.y0);})
                .y1(function(d){return yScale(d.y0 + d.y);});

            svg.selectAll(".layers")
                .data(stackZero(data))
                //.data(stackExpand(data))
                .enter()
                .append("path")
                .attr("class", "layer")
                .attr("d", function(d){return area(d.values);})
                .style("fill", function (d,i){return colors(i)});   

            stackType = true;
            console.log("exiting variable is" + stackType);

            var yAxis = d3.svg.axis()
                .scale(yScale)
                .orient("left");

            svg.append("g")
                .attr("class", "y axis")
                .attr("transform", "translate(0,0)")
                .call(yAxis);

            };  

});
    </script>
4

1 に答える 1