簡體   English   中英

我想在 d3 中更改以下代碼中的域

[英]I want to change the domain in th below code in d3

var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom,
padding = 0.3;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], padding);

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

var xAxis = d3.svg.axis()
       .scale(x)
        .orient("bottom");

var yAxis = d3.svg.axis()
        .scale(y)
         .orient("left")
        .tickFormat(function(d) { return percentage(d); })

var tooltip = d3.select("body").append("div")   
.attr("class", "tooltip")               
.style("opacity", 0)
 .attr("align","middle");

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

data = [
 {"name":"Product Revenue","value":420000},
 {"name":"Services Revenue","value":210000},
 {"name":"Employee Revenue","value":190000}, 
 {"name":"Fixed Costs","value":-170000},
 {"name":"Variable Costs","value":-140000}

  ];


//function to find all the positive values
var positive_val = data.filter(function(d) { return d.value > 0; });
console.log(JSON.stringify(positive_val));

//function to calculate the sum of all the positive values
var maxSum = positive_val.reduce(function(sum, d) {
return sum + d.value;
}, 0);
console.log("The maximum sum is "+maxSum);

//to calculate the new Domain by adding 120 
var yaxisRange=maxSum+120;
console.log("The y axis sum is "+yaxisRange);
var newDomain=percentage(yaxisRange);
console.log(newDomain);
var newDomain = newDomain.replace(/[!@#$%^&*]/g, "");
console.log(newDomain);

// Transform data (i.e., finding cumulative values and total)   
var cumulative = 0;
for (var i = 0; i < data.length; i++) {
data[i].start = cumulative;
cumulative += data[i].value;
data[i].end = cumulative;

data[i].class = ( data[i].value >= 0 ) ? 'positive' : 'negative'
}
data.push({
name: 'Total',
end: cumulative,
start: 0,
class: 'total',
value: cumulative
 });

 x.domain(data.map(function(d) { return d.name; }));
 y.domain([0, d3.max(data, function(d) { return d.end; })]);
//WHen i try to use this as my new domain,the bar increase the height 
//y.domain([0,newDomain]);


debugger;

 chart.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

 chart.append("g")
  .attr("class", "y axis")
  .call(yAxis);

  var bar = chart.selectAll(".bar")
  .data(data)
   .enter().append("g")
  .attr("class", function(d) { return "bar " + d.class })
  .attr("transform", function(d) { return "translate(" + x(d.name) +    ",0)"; });

  bar.append("rect")
   //.attr("y", function(d) { return y(d.value); })
  .attr("y", function(d) { return y( Math.max(d.start, d.end) ); })
  .attr("height", function(d) { return Math.abs( y(d.start) - y(d.end) );  })
  //function to draw the tooltip
  .attr("width", x.rangeBand()).on("mouseover", function(d) {
 // to find the parent node,to calculate the x position
 var parentG = d3.select(this.parentNode);
 var barPos = parseFloat(parentG.attr('transform').split("(")[1]);
 var xPosition = barPos+x.rangeBand()/2;
  //to find the y position
 var yPosition = parseFloat(d3.select(this).attr("y"))+ Math.abs( y(d.start) - y(d.end))/2;
       tooltip.transition()     
            .duration(200)      
            .style("opacity", .9);  
      tooltip.html(d.name + "<br/>"  + percentage(d.value)) 
            .style("left", xPosition + "px")        
            .style("top",  yPosition + "px");   
        }).on("mouseout", function(d) {     
        tooltip.transition()        
            .duration(500)      
            .style("opacity", 0);   
    });

    bar.append("text")
  .attr("x", x.rangeBand() / 2)
  .attr("y", function(d) { return y(d.end) + 5; })
  .attr("dy", function(d) { return ((d.class=='negative') ? '-' : '') + ".75em" })
  .text(function(d) { return percentage(d.end - d.start);});


   bar.filter(function(d) { return d.class != "total" }).append("line")
  .attr("class", "connector")
  .attr("x1", x.rangeBand() + 5 )
  .attr("y1", function(d) { return y(d.end) } )
  .attr("x2", x.rangeBand() / ( 1 - padding) - 5 )
  .attr("y2", function(d) { return y(d.end) } )


  function type(d) {
  d.value = +d.value;
   return d;
   }

 function percentage(n) {
  n = Math.round(n);
  var result = n;
  if (Math.abs(n) > 100) {
  result = Math.round(n/100) + '%';
  }
   return  result;
   }

-這是更新的小提琴http://jsfiddle.net/7mkq4k8k/21/ -我想讓 yaxis 標簽增加。例如 9000,9500。我已經計算了 newDomian。 - 如果我嘗試添加此域,我的圖表無法正確繪制。條形的高度增加,因此其他條形未繪制。請在此問題上幫助我。

因此,您最初繪制的圖表基於此域:

    y.domain([0, d3.max(data, function (d) {
        return d.end;
    })]);

嘗試console.log(d3.max(data, function (d) {return d.end;})) ,你會發現它返回820000,這是你累積計算的最大值。 這意味着您的圖表是用 0 到 820000 的域繪制的。

現在讓我們談談您的 newDomain。 您正在計算 maxSum 的百分比,這意味着您的 newDomain 等於 8201。所以現在您嘗試繪制從 0 到 8201 的圖表。但是您的條形高度的計算方式如下: Math.abs(y(d.start) - y(d.end)) ,這意味着您正在計算從 y(0) 到 y(820000) 的范圍(d.end 最大等於 820000)。

y(820000) 不適合,因為您在域中指定它最多可以轉到 y(8201)。 這就是為什么您的條形超過圖表頂部的原因,因為您提供的域與里面的數字不對應:y(這個數字太大,不適合,因為它不在 0 和 newDomain 之間) .

如何解決這個問題? 您正確定義了域,刪除了百分比線

//function to calculate the sum of all the positive values
var maxSum = positive_val.reduce(function (sum, d) {
    return sum + d.value;
}, 0);
console.log("The maximum sum is " + maxSum);

//to calculate the new Domain by adding 520000 (big number to show you it works) 
var newDomain = maxSum + 520000;
console.log(newDomain); //1340000

y.domain([0,newDomain]); 

下面的工作片段:

 var margin = { top: 20, right: 30, bottom: 30, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom, padding = 0.3; var x = d3.scale.ordinal() .rangeRoundBands([0, width], padding); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(function (d) { return percentage(d); }) var tooltip = d3.select("body").append("div") .attr("class", "tooltip") .style("opacity", 0) .attr("align", "middle"); var chart = d3.select(".chart") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); data = [{ "name": "Product Revenue", "value": 420000 }, { "name": "Services Revenue", "value": 210000 }, { "name": "Employee Revenue", "value": 190000 }, { "name": "Fixed Costs", "value": -170000 }, { "name": "Variable Costs", "value": -140000 } ]; //function to find all the positive values var positive_val = data.filter(function (d) { return d.value > 0; }); console.log(JSON.stringify(positive_val)); //function to calculate the sum of all the positive values var maxSum = positive_val.reduce(function (sum, d) { return sum + d.value; }, 0); console.log("The maximum sum is " + maxSum); //to calculate the new Domain by adding 120 var newDomain = maxSum + 520000; console.log(newDomain); // Transform data (ie, finding cumulative values and total) var cumulative = 0; for (var i = 0; i < data.length; i++) { data[i].start = cumulative; cumulative += data[i].value; data[i].end = cumulative; data[i].class = (data[i].value >= 0) ? 'positive' : 'negative' } data.push({ name: 'Total', end: cumulative, start: 0, class: 'total', value: cumulative }); x.domain(data.map(function (d) { return d.name; })); console.log(d3.max(data, function (d) { return d.end; })); /*y.domain([0, d3.max(data, function (d) { return d.end; })]);*/ //WHen i try to use this as my new domain,the bar increase the height y.domain([0,newDomain]); debugger; chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); chart.append("g") .attr("class", "y axis") .call(yAxis); var bar = chart.selectAll(".bar") .data(data) .enter().append("g") .attr("class", function (d) { return "bar " + d.class }) .attr("transform", function (d) { return "translate(" + x(d.name) + ",0)"; }); bar.append("rect") //.attr("y", function(d) { return y(d.value); }) .attr("y", function (d) { return y(Math.max(d.start, d.end)); }) .attr("height", function (d) { return Math.abs(y(d.start) - y(d.end)); }) //function to draw the tooltip .attr("width", x.rangeBand()).on("mouseover", function (d) { // to find the parent node,to calculate the x position var parentG = d3.select(this.parentNode); var barPos = parseFloat(parentG.attr('transform').split("(")[1]); var xPosition = barPos + x.rangeBand() / 2; //to find the y position var yPosition = parseFloat(d3.select(this).attr("y")) + Math.abs(y(d.start) - y(d.end)) / 2; tooltip.transition() .duration(200) .style("opacity", .9); tooltip.html(d.name + "<br/>" + percentage(d.value)) .style("left", xPosition + "px") .style("top", yPosition + "px"); }).on("mouseout", function (d) { tooltip.transition() .duration(500) .style("opacity", 0); }); bar.append("text") .attr("x", x.rangeBand() / 2) .attr("y", function (d) { return y(d.end) + 5; }) .attr("dy", function (d) { return ((d.class == 'negative') ? '-' : '') + ".75em" }) .text(function (d) { return percentage(d.end - d.start); }); bar.filter(function (d) { return d.class != "total" }).append("line") .attr("class", "connector") .attr("x1", x.rangeBand() + 5) .attr("y1", function (d) { return y(d.end) }) .attr("x2", x.rangeBand() / (1 - padding) - 5) .attr("y2", function (d) { return y(d.end) }) function type(d) { d.value = +d.value; return d; } function percentage(n) { n = Math.round(n); var result = n; if (Math.abs(n) > 100) { result = Math.round(n / 100) + '%'; } return result; }
 .bar.total rect { fill: steelblue; } .bar:hover rect { fill:orange; } .bar.positive rect { fill: darkolivegreen; } .bar:hover rect { fill:orange; } .bar.negative rect { fill: crimson; } .bar:hover rect { fill:orange; } .bar line.connector { stroke: grey; stroke-dasharray: 3; } .bar text { fill: white; font: 12px sans-serif; text-anchor: middle; } .axis text { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } div.tooltip { position:absolute; text-align: center; padding: 2px; font: 12px sans-serif; background: #33CC00; border: 0px; border-radius: 8px; pointer-events: none; width: 90px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <svg class="chart"></svg>

希望這可以幫助 !

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM