2017-01-29 2 views
2

Я работал над диаграммой, где весь объект svg и значения тика должны находиться в заданных пределах высоты. Мне было интересно, почему мои повернутые значения тика не отображаются полностью. Высота 100px, и я хочу, чтобы моя диаграмма и значения тика были внутри этого 100. Я пробовал .attr("transform", "scale(1,1.4)")Почему мои повернутые значения тиков не отображаются полностью d3js?

функция, но не используется. Вот код до сих пор!

Данные таковы, и код для диаграммы рендеринга ниже этого.

{ 
    "Height" : 100, 
    "Width" : 250, 
"margins" : { 
    "top": 10, 
    "left": 20, 
    "right": 10, 
    "bottom": 20 
    }, 

    "data":[ 
      { 
      "fruit" : "apple", 
      "initialsale" : 40, 
      "totalsale": 600 
      }, 
      { 
       "fruit" : "orange", 
       "initialsale" : 40, 
       "totalsale": 60 
      }, 
      { 
      "fruit" : "mango", 
      "initialsale" : 1420, 
      "totalsale": 6000 
      } 
     ] 
} 

function stackChart(){ 
 

 
    
 
    
 
data = { 
 
     "Height" : 100, 
 
     "Width" : 250, 
 
    "margins" : { 
 
     "top": 10, 
 
     "left": 20, 
 
     "right": 10, 
 
     "bottom": 20 
 
     }, 
 

 
     "data":[ 
 
       { 
 
       "fruit" : "apple", 
 
       "initialsale" : 40, 
 
       "totalsale": 600 
 
       }, 
 
       { 
 
        "fruit" : "orange", 
 
        "initialsale" : 40, 
 
        "totalsale": 60 
 
       }, 
 
       { 
 
       "fruit" : "mango", 
 
       "initialsale" : 1420, 
 
       "totalsale": 6000 
 
       } 
 
      ] 
 
    }; 
 

 
var margin = data.margins; 
 

 
var top = margin.top, 
 
    bottom = margin.bottom, 
 
    left = margin.left, 
 
    right = margin.right, 
 
    Width = data.Width, 
 
    Height = data.Height, 
 
    data = data.data; 
 

 
var width = Width -left -right, 
 
    height = Height -top - bottom; 
 

 

 
var svg = d3.select("#stackChart") 
 
    .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 + ")"); 
 

 

 
// Divider functionality 
 
var div = 0; 
 
if(Width>50&&Width<=100){ 
 
    div = 1.2 
 
} 
 
else if(Width>100&&Width<=200) 
 
{ 
 
    div = 1.5 
 
} 
 
else if(Width>200&&Width<=300){ 
 
    div = 2.0 
 
} 
 
else if(Width>300&&Width<=400){ 
 
    div = 2.2 
 
} 
 
else if(Width>400&&Width<=500){ 
 
    div = 2.4 
 
} 
 
else if(Width>500&&Width<=600){ 
 
    div = 2.6 
 
} 
 
else if(Width>600&&Width<=800){ 
 
    div = 2.8 
 
} 
 
else if(Width>800){ 
 
    div = 3.0 
 
} 
 

 

 
var par = Width/div; 
 

 
// var scale_parameter = Width/par; 
 

 

 

 
var dataset = []; 
 
var arr1 = []; 
 
var arr2 = []; 
 
data.forEach(function(d) { 
 
       var currentObj = {} 
 
       currentObj["os"] = d.os; 
 
       currentObj["value"] = d.total; 
 
       currentObj["percent"] = (d.initial/d.total)*100; 
 
       arr1.push(currentObj); 
 
       currentObj = {} 
 
       currentObj["os"] = d.os; 
 
       currentObj["value"] = d.total; 
 
       currentObj["percent"] = ((d.total - d.initial)/d.total)*100; 
 
       arr2.push(currentObj); 
 
       } 
 
      ); 
 
dataset = [{ 
 
    data: arr1, 
 
    name: 'initial' 
 
},{ 
 
    data: arr2, 
 
    name: 'remaining' 
 
}]; 
 

 
var series = dataset.map(function (d) { 
 
    return d.name; 
 
}), 
 
dataset = dataset.map(function (d) { 
 
    return d.data.map(function (o, i) { 
 
     // Structure it so that your numeric 
 
     // axis (the stacked amount) is y 
 
     return { 
 
      y: o.percent, 
 
      x: o.os, 
 
      v: o.value 
 
     }; 
 
    }); 
 
}), 
 
stack = d3.layout.stack(); //.layout in v3 
 

 
stack(dataset); 
 

 

 
var h1= Width * 0.7; 
 
// Set x, y and colors 
 
var x = d3.scale.ordinal() 
 
    .domain(dataset[0].map(function(d) { return d.x; })) 
 
    .rangeRoundBands([0, width], 0.15); 
 

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

 
var colors = ["#14a900", "#cccccc"]; 
 

 

 
// Define and draw axes 
 
var yAxis = d3.svg.axis() 
 
    .scale(y) 
 
    .orient("left") 
 
    .ticks(5) 
 
    .tickSize(1) 
 
    .tickFormat(function(d) { return d }) 
 

 

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

 
// Create groups for each series, rects for each segment 
 

 
var groups = svg.selectAll("g.cost") 
 
    .data(dataset) 
 
    .enter().append("g") 
 
    .attr("class", "cost") 
 
    .style("fill", function(d, i) { return colors[i]; }); 
 

 

 
    // Height Calculation of the stack bars 
 
    // y0 will be the base, y is the stacked up bar on y0 
 

 
var crucial = 0; 
 
var cr = 0; 
 
var heightsof = []; 
 
var rects = groups.selectAll("rect") 
 
    .data(function(d) { return d; }) 
 
    .enter() 
 
    .append("rect") 
 
    // .attr("transform","scale(1,1.4)") 
 
    .attr("x", function(d) { return x(d.x); }) 
 
    .attr("y", function(d) { 
 
    crucial = y(d.y0 + d.y); 
 
    return crucial; 
 
    }) 
 
    .attr("height", function(d) { 
 
    return height - y(d.y); 
 
    }) 
 
    .attr("width", x.rangeBand()) 
 

 
// Getting the length of the total bar 
 
// For tilt angle 
 

 
var calh=0; 
 
    for(i=0;i<data.length+1;i++){ 
 
    var j = data.length; 
 
    if(i==j){ 
 
     calh = heightsof[j]+heightsof[0]; 
 
    } 
 
    } 
 

 
    console.log(calh); 
 
    var rect_width = Math.round($("rect").outerWidth()); 
 

 
    svg.append("g") 
 
    .attr("class", "y axis") 
 
    .call(yAxis) 
 
    // .attr("transform","scale(1,)") 
 

 

 
    var bool = [], 
 
     counter = 0, 
 
     y = [], 
 
     x = 0, 
 
     z = 0; // max value of y[] 
 

 
    svg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", function(){ 
 
     return "translate(0,"+(h1)+")"; 
 
    }) 
 
    .call(xAxis) 
 
    .selectAll("text") 
 
      .style("fill","black") 
 
      .each(function(d,i) { 
 
        var thisWidth = this.getComputedTextLength(); 
 
        var x = Math.round(thisWidth); 
 
        y.push(x); 
 
        if(rect_width>x){ 
 
         bool.push(true); 
 
        } 
 
        else{ 
 
         bool.push(false); 
 
         counter++; 
 
        } 
 
        z = Math.max.apply(Math, y); 
 
        }) 
 
        .style("text-anchor",function(d,i){ 
 
        if(rect_width<=20){ 
 
         return "end"; 
 
        } 
 
        else { 
 
         return "middle"; 
 
        } 
 
        }) 
 
        .attr("transform", function(d,i) {  // Rotation Code 
 
        if(rect_width<=20) { 
 
         x = -90; 
 
         return "translate(-13,8) rotate("+x+")"; // Minimum width rotation 
 
        } 
 
        else if (rect_width>z) { 
 
         return "rotate(0)"; 
 
        } 
 
        else if(rect_width>20&&rect_width<z) { 
 
         var tilt = data.length; 
 
         var angle = Math.cos(z/rect_width) 
 
         console.log(angle); 
 
         if(angle>0&&bool[i]==false){ 
 
         return "translate(-10,"+((y[i]/3)+12)+") rotate(-45)";// -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment 
 
         } 
 
         if(angle>0&&bool[i]==true){ 
 
         return "translate(-10,"+((y[i]/3)+8)+") rotate(-45)"//"+ -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment 
 
         } 
 
         else{ 
 
         return "translate(-10,"+((y[i]/3)+12)+") rotate("+ -(90+angle*10) +")"; // Rotating based on the maximum angle for proper alignment 
 
         } 
 
         } 
 
        }); 
 

 
    
 
}
<div id="stackChart"> 
 
    </div> 
 

 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<script> 
 
    stackChart(); 
 
    </script>

+0

Привет, я старался как можно больше отредактировать сообщение. @AndreiGheorghiu –

+0

@AndreiGheorghiu Вот скрипка для диаграммы https://jsfiddle.net/okdfhhvp/2/ –

+0

@GerardoFurtado, пожалуйста, восстановите свой ответ. Это было лучше, чем мое. Саи, если вы не можете поместить свою легенду в высоту 100 пикселей, просто используйте этот CSS: 'transform: scale (factor)' на нем, где коэффициент должен быть меньше, чем '1', чтобы уменьшить масштаб. Если вы хотите масштабировать высоту, используйте 'scaleY' вместо' scale'. Кроме того, комментарий Херардо о том, что у него нет двух разных svg, но все же в одном и том же 'svg' имеет смысл, если вы не хотите, чтобы легенда вела себя реагировать. –

ответ

2

Что вам нужно сделать, это изменить значение height второго <svg> (легенды) один из 100 в 120. Я не знаю достаточно о d3.js или вашем скрипте, чтобы это произошло внутри вашего скрипта. Я мог бы написать фрагмент , чтобы сделать это на лету, после того, как был создан <svg>, но это было бы hack -ish.
Я предполагаю, что с этой информацией и тем, что вы знаете о своем собственном скрипте, вы можете получить это исправление от источника этой легенды.

С любезного Херардо Фуртадо, это то, что вам нужно сделать для того, чтобы ваш legend SVG, чтобы иметь достаточно места (по высоте), чтобы правильно отображать метки:

в D3, генератор оси всегда созданный в начале координат (0,0) SVG. Затем он переводится в любую позицию, которую хочет пользователь, и тики создаются ниже оси. Прямо сейчас, OP переводит его на "translate(0,"+(height)+")", а высота Height -top - bottom;. Таким образом, решение просто увеличивает значение data.margins.bottom. Чтобы не искажать бары, скажите, что нужно было бы увеличить data.height соответственно.


Если вы должны соответствовать вашей легенде в 100px высоты, вам нужно будет применить это правило CSS к нему:

transform: scale(factor); 
transform-origin:left; /* keep it aligned on left side */ 

, где factor ниже, чем 1 для того, чтобы сокращаться. Если вы не заботитесь о масштабировании пропорционально, вы можете ограничить масштабный коэффициент только осью Y. (используя scaleY вместо scale), но это исказит все в вашей легенде svg, включая текст.

+0

Привет, я уменьшил свою ось y и стек стека ниже 1, но я столкнулся с проблемой искажения. Я предполагаю, что единственная работа вокруг будет заключаться в увеличении данных. пожалуйста, поправьте меня, если я ошибаюсь. –

+0

Если вы не хотите искажения, просто используйте «масштаб», чтобы вы уменьшили обе оси, а не только «Y». С одним аргументом он будет масштабировать обе оси одинаково. С двумя аргументами будет масштабироваться '(sx, sy)'. Используйте «transform-origin: left;», чтобы масштабировать его по направлению к стороне. –

+0

@GerardoFurtado Это довольно странно. Я на самом деле потратил время с тех пор и посмотрел на некоторые из ваших ответов здесь и SOMeta и поддержал там, где это было удобно. Мои поздравления с тем, что вы делаете для 'd3.js'. Удалена ссылка. Если вы считаете, что это что-то систематическое, вы можете попросить просмотреть образец голосования по вашим ответам. Они обычно успешны, если они явно нацелены на ответчика, а не на ответ, и они удаляют оскорбительные голоса. –

Смежные вопросы