2013-11-14 4 views
0

В этом простом примере: http://jsfiddle.net/2VeGY/1/D3 шкала терпит неудачу, если первое значение отличается от нуля

<!doctype html> 
<meta charset="utf-8"> 
<title>single column</title> 
<style> 
    *{margin:0,padding:0} 
    input{width:800px;} 
    nav{border:1px solid gray; width:850px;} 
    li{display:inline-block; height:30px; } 
    li:hover{opacity:0.8} 
</style> 
<script src="http://d3js.org/d3.v3.min.js"></script> 
<body> 

<input value="[{&quot;v&quot;:0,&quot;c&quot;:&quot;red&quot;},{&quot;v&quot;:100,&quot;c&quot;:&quot;#005&quot;},{&quot;v&quot;:200,&quot;c&quot;:&quot;#12d&quot;}, {&quot;v&quo\ 
t;:300,&quot;c&quot;:&quot;#1dd&quot;}, {&quot;v&quot;:400,&quot;c&quot;:&quot;red&quot;} ]"> 
    <nav> 
    <ul> 
    </ul> 
    </nav> 

    <script> 

    var wscale = d3.scale.linear().range(["0px","800px"]) 

    update() 
    d3.select("input").on("change",update) 

    function update(){ 
     var data = JSON.parse(d3.select("input").property("value")); 
     var li=d3.select("ul").selectAll("li").data(data); 

     wscale.domain(d3.extent(data,function(d){return d.v})) 

     li.enter().append("li") 

     li 
     .style("width",function(d,i){ 
      start=d.v 
      i+1 == data.length ? end=d.v : end=data[i+1].v; 
      return wscale(end-start) 
     }) 
     .style("background-image",function(d,i){ 
      start=d.c; 
      i+1 == data.length ? end=d.c : end=data[i+1].c; 
      return "linear-gradient(to right, "+start+","+end+")"}); 

     li.exit().remove() 

    } 

    </script> 

вы можете изменить цветовую гамму шагов data[...].c и их положение data[...].v. Шкала обновляется динамически.

Моя проблема в следующем: почему это беспорядок, если первое значение отличается от нуля?

Большое спасибо за помощь!

+0

Я не уверен, что вы просите. Какое первое значение? Как не работает масштаб? –

+0

Посмотрите в поле ввода: http://jsfiddle.net/2VeGY/1/, если вы измените последнее значение 'v: 400' в, например,' v: 1000', градиенты будут автоматически обновлены, но если вы измените значение ** first ** 'v: 0' на что-то другое, ширина не рассчитана правильно –

ответ

1

Вы видите это поведение, потому что с текущим кодом, вы всегда проход 0 как вход значение до wscale. Для последнего элемента liend будет таким же, как start в вашей функции, чтобы установить width, и поэтому то, что вы переходите на wscale, будет равно 0. Входной домен wscale определяется как степень входных значений и не учитывает эту дополнительную ценность.

Вы можете легко исправить это путем изменения, как определяется область:

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

Это предполагает, что все ваши v значений положительны.

Тем не менее, что вы действительно хотите сделать, это учитывать различия между значениями, так как это то, что вы переходите в шкалу. То есть общая сумма разностей должна быть равна максимальной ширине. Вы можете вычислить это следующим образом.

var sumdiff = 0; 
for(var i = 0; i < data.length - 1; i++) { 
    sumdiff += data[i+1].v - data[i].v; 
} 

Тогда шкала становится

wscale.domain([0, sumdiff]); 

Полный пример here.

+0

Большое спасибо за то, объясните мне ошибку. Я не понимаю, почему это не работает с негативами. Как я могу это исправить? –

+0

В приведенном выше коде предполагается, что 0 - это начало (т. Е. Наименьшее значение) шкалы. Если у вас есть отрицательные значения, вам нужно поставить наименьшее значение в качестве начала. В принципе, вам нужно убедиться, что 0 находится в домене, чтобы он работал. –

+0

Извините, но здесь http: // jsfiddle.net/2VeGY/3 после учета ваших предложений, результат все еще имеет некоторые проблемы, в частности ** сумма ** ширины больше не равна 600px, поскольку она должна быть в диапазоне '[0px, 600px]' –

0

вы не должны поставить кавычки в пределах, так и должно быть так:

.range([0,800]) 
+0

Что вы предлагаете, подразумевает использование' .attr ("width") ', и оно не работает, или использование '.style (" width ")' добавление '+" px "к значению, и он не работает либо –

+0

вы также пробовали с .range ([0 +" px ", 800 +" px "]) ? – tomtomtom

+0

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

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