2016-02-14 8 views
2

Предположим, я создаю гистограмму из некоторых данных, которые у меня есть. Эта гистограмма создается на множестве осей x и y. Как я могу построить функцию (в форме y=f(x)) как линию над этим же набором осей? Я хочу сделать это, чтобы вы могли легко сравнить тенденции, показанные гистограммой и функцией.Наложение функции на гистограмму в D3

+0

Может кто-нибудь, пожалуйста, скажите мне, почему это заслуживает ниспровержения/закрытия? У меня есть проблема, которую я не могу решить, так как я не нашел ни одной части документации D3, которая отвечает на это. Я думал, что есть хороший шанс, что кто-то из нас, веб-сайт для программистов, возможно, столкнулся с этим раньше, и придумал или нашел решение. – Bluefire

+1

Я угадываю, что люди занижены/проголосовали за закрытие, потому что у вас нет [минимального рабочего примера] (http://stackoverflow.com/help/mcve). Вы можете опубликовать код для своего баррикада, с некоторыми данными и примерную функцию, которую вы хотели бы построить. – NicE

+0

Код не имеет значения: я хочу знать, как это сделать для общей гистограммы. Функция не имеет значения по той же причине: она может быть x, sin x, cos x, exp (x), она может быть djdjcdhbf (x) в этом отношении. – Bluefire

ответ

2

Я использования D3 и Math.js.

Причина Я использую Math.js в том, что функция может быть очень сложным от:

  • 4 * Sin (х) + 5 * загар (х/2)
  • 4 * греха (х^2) + 5 * соз (х/2)^3
  • Что угодно, но е (х) :)

Вы можете определить любой домен на ваш выбор здесь:

//define xDomain change it domain of your choice  
var xDomain = [-10, 10]; 
//define yDomain change it domain of your choice  
var yDomain = [-10, 10]; 

Затем сделайте обычную гистограмму для домена ничего особенного, это стандартный код D3 для создания гистограмм.

//make the bar chart by loading the tsv 
d3.tsv("data.tsv", type, function(error, data) { 
    if (error) throw error; 
    //make x axis 
    svg.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + y(0) + ")") 
    .call(xAxis); 
    //make y axis 
    svg.append("g") 
    .attr("class", "y axis") 
    .attr("transform", "translate(" + x(0) + ",0)") 
    .call(yAxis) 
    .append("text") 
    .attr("transform", "rotate(-90)") 
    .attr("y", 6) 
    .attr("dy", ".71em") 
    .style("text-anchor", "end") 
    .text("Frequency"); 
    //make bar chart rectangle 
    svg.selectAll(".bar") 
    .data(data) 
    .enter().append("rect") 
    .attr("class", "bar") 
    .attr("x", function(d) { 
     return x(d.letter) - 10; 
    }) 
    .attr("width", 20) 
    .attr("y", function(d) { 
     return y(d.frequency); 
    }) 
    .attr("height", function(d) { 
     return height/2 - y(d.frequency); 
    }); 
    makeLineFunction(); 

}); 

Это моя функция, которая будет делать линейный график на основе значения, введенного в текстовое поле (для xdomain):

function makeLineFunction() { 
    //remove any line if present 
    d3.selectAll(".line").remove(); 
    //make an array of all x points 
    var xArray = d3.range(xDomain[0], xDomain[1], 0.5); 
    //get the formula from the text box above 
    var value = d3.select("#function_text").node().value; 
    //generate the data using math.js 
    var data = xArray.map(function(x1) { 
    return { 
     x: x1, 
     //using math.js for evaluating y point for the given x 
     y: math.eval(value, { 
     x: x1 
     }) 
    }; 
    }); 
    //make the path 
    svg.append("path") 
    .datum(data) 
    .attr("class", "line") 
    .attr("d", line); 
} 

Рабочий код here, необходимые комментарии, добавленные за помощью.

Надеюсь, это поможет!

+1

Ввод текста для принятия/рисования произвольной функции - приятное прикосновение! –

+0

@halfer, если вы хотите отредактировать что-то прекрасное и исправить грамматики, сделайте это ... но почему вы отказали в этом без каких-либо причин. Ответ может быть бесполезным для вас, но он полезен для других, и, кроме того, он совершенно ясно о том, что я пытаюсь объяснить. Это очень низко на вашей стороне. – Cyril

+0

Привет Кирилл. Я отказался, потому что я сделал вам запрос [14 февраля] (http://stackoverflow.com/a/32883524/472495), чтобы не добавлять умышленные ошибки к вопросам (из которых я нашел 90 или около того примеров через ваши полезные ответы). Мало того, что вы не ответили, как было бы вежливо, но на посту выше вы продолжали это делать. – halfer

3

Вы только что генерируете данные для подачи на d3, запустив функцию над требуемыми значениями домена, а затем, например, используйте для рисования линию, например, для создания линий.

var w = 400; 
 
var h = 400; 
 
var padding = 50; 
 

 
var svg = d3.select('svg').attr('width', w + padding * 2).attr('height', h + padding * 2); 
 

 
var xScale = d3.scale.linear().domain([-10, 10]).range([0, w]); 
 
var yScale = d3.scale.linear().domain([2, -2]).range([0, h]); 
 

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

 
var g = svg.append("g").attr("transform", "translate(" + padding + "," + padding + ")"); 
 

 
g.append("g").attr("transform", "translate(0, " + w/2 + ")").call(xAxis); 
 
g.append("g").attr("transform", "translate(" + h/2 + ", 0)").call(yAxis); 
 

 
var line = d3.svg.line().interpolate("basis") 
 
    .x(function(d, i) { 
 
    return xScale(d.x); 
 
    }) 
 
    .y(function(d, i) { 
 
    return yScale(d.y); 
 
    }) 
 
g.append('path') 
 
    .data([fn1()]) 
 
    .attr("d", line); 
 

 
g.append('path') 
 
    .data([fn2()]) 
 
    .attr("d", line); 
 

 
g.append('path') 
 
    .data([fn3()]) 
 
    .attr("d", line); 
 

 
g.append('path') 
 
    .data([fn4()]) 
 
    .attr("d", line); 
 

 
function fn1() { 
 
    function f(x) { 
 
    return Math.cos(x); 
 
    } 
 
    return _.chain(_.range(-10, 10)).map(function(x) { 
 
    return { 
 
     y: f(x), 
 
     x: x 
 
    }; 
 
    }).value(); 
 
} 
 

 
function fn2() { 
 
    function f(x) { 
 
    return Math.sin(x); 
 
    } 
 
    return _.chain(_.range(-10, 10)).map(function(x) { 
 
    return { 
 
     y: f(x), 
 
     x: x 
 
    }; 
 
    }).value(); 
 
} 
 

 
function fn3() { 
 
    function f(x) { 
 
    return Math.exp(x); 
 
    } 
 
    return _.chain(_.range(-10, 10)).map(function(x) { 
 
    return { 
 
     y: f(x), 
 
     x: x 
 
    }; 
 
    }).value(); 
 
} 
 

 
function fn4() { 
 
    function f(x, m, b) { 
 
    return m * x + b; 
 
    } 
 
    return _.chain(_.range(-10, 10)).map(function(x) { 
 
    return { 
 
     y: f(x, 1, 1), 
 
     x: x 
 
    }; 
 
    }).value(); 
 
}
path { 
 
    stroke: black; 
 
    fill: none; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 

 
<body> 
 

 
    <svg></svg> 
 

 
</body>

+0

Я не уверен, откуда приходит * fn1() *. Это опускается в вашем примере, или я просто ослеп? –

+0

@KonradViltersten Все функции, fn1() через fn4(), перечислены внизу того, что в настоящий момент является 1-м блоком кода в ответе (также как секция js/d3). Мне пришлось прокручивать вниз, чтобы увидеть, что может быть, как вы его пропустили. –

+0

@SteveLadavich Ах, прокрутка ... Да. Я слышал об этом один или два раза ... Правильно ... (теперь я чувствую себя таким глупым - конечно, он был там, хе-хе.) –

1

Ниже приведен пример, который иллюстрирует диаграмму линии над баром чатом. Вы можете генерировать значения y = f (x) с использованием jsp или php во время выполнения. обновление части данных

series: [ 
    { 
     title: 'Column', 
     type: 'column', 
     axisY: 'y1', 
     data: [['A', 1], ['B', 4], ['C', 3], 
       ['D', 5], ['E', 2], ['F', 1]] 
    }, 
    { 
     title: 'Line', 
     type: 'line', 
     axisY: 'y2', 
     data: [['A', 40], ['B', 60], ['C', 62], 
       ['D', 52], ['E', 70], ['F', 75]] 
    } 
] 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
 
<html xmlns="http://www.w3.org/1999/xhtml"> 
 
<head> 
 
    <title> 
 
    Multiple Axes Example 
 
</title> 
 

 
<link rel="stylesheet" type="text/css" href="http://www.jqchart.com/css/jquery.jqChart.css" /> \t 
 
    
 
    <link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.21/themes/smoothness/jquery-ui.css" /> 
 
    <script src="http://www.jqchart.com/js/jquery-1.11.1.min.js" type="text/javascript"></script> 
 
    <script src="http://www.jqchart.com/js/jquery.mousewheel.js" type="text/javascript"></script> 
 
    <script src="http://www.jqchart.com/js/jquery.jqChart.min.js" type="text/javascript"></script> 
 
    <script src="http://www.jqchart.com/js/jquery.jqRangeSlider.min.js" type="text/javascript"></script> 
 
    
 
    <script lang="javascript" type="text/javascript"> 
 
     $(document).ready(function() { 
 

 
      var background = { 
 
       type: 'linearGradient', 
 
       x0: 0, 
 
       y0: 0, 
 
       x1: 0, 
 
       y1: 1, 
 
       colorStops: [{ offset: 0, color: '#d2e6c9' }, 
 
          { offset: 1, color: 'white' }] 
 
      }; 
 

 
      $('#jqChart').jqChart({ 
 
       title: { text: 'Multiple Axes' }, 
 
       border: { strokeStyle: '#6ba851' }, 
 
       background: background, 
 
       animation: { duration: 1 }, 
 
       shadows: { 
 
        enabled: true 
 
       }, 
 
       axes: [ 
 
        { 
 
         name: 'y1', 
 
         location: 'left' 
 
        }, 
 
        { 
 
         name: 'y2', 
 
         location: 'right', 
 
         strokeStyle: '#FCB441', 
 
         majorGridLines: { 
 
          strokeStyle: '#FCB441' 
 
         }, 
 
         majorTickMarks: { 
 
          strokeStyle: '#FCB441' 
 
         } 
 
        } 
 
       ], 
 
       series: [ 
 
        { 
 
         title: 'Column', 
 
         type: 'column', 
 
         axisY: 'y1', 
 
         data: [['A', 1], ['B', 4], ['C', 3], 
 
           ['D', 5], ['E', 2], ['F', 1]] 
 
        }, 
 
        { 
 
         title: 'Line', 
 
         type: 'line', 
 
         axisY: 'y2', 
 
         data: [['A', 40], ['B', 60], ['C', 62], 
 
           ['D', 52], ['E', 70], ['F', 75]] 
 
        } 
 
       ] 
 
      }); 
 
     }); 
 
    </script> 
 

 
</head> 
 
<body> 
 
    <div> 
 
     <div id="jqChart" style="width: 500px; height: 300px;"></div> 
 
    </div> 
 
</body> 
 
</html>

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