2013-08-31 6 views
1

24 시간 동안 알람 분포가있는 그래프를 작성하는 작은 웹 페이지를 작성했습니다.이 시간 동안 보낼 알람 수를 결정하는 변수가 알람 수입니다.html 양식의 데이터로 내 d3.js 차트를 다시 그리는 방법은 무엇입니까?

는 그 후 나는 알람을 복용

<input id="alarm_count_input" type="number"/>

은 이제 페이지를 다시로드하지 않고 d3.js 그래프를 다시 그릴 수 있도록하고 싶습니다 입력 필드에 알람 카운트 변수가됩니다 작은 양식을 작성했습니다 사용자가 양식/입력란을 사용하여 제출하는 횟수.

JsFiddle : http://jsfiddle.net/L42LU/

코드 :

<script type="text/javascript"> 
$(function(){ 

........ 

function createDataForD3(alarm_cnt, array) { 
    var data = []; 
    for(var i = 0, n=array.length; i< n; i++) 
    { 
     data.push({ "hour": i, 
        "alarms": getRatioForHour(i, array) * alarm_cnt 
        }); 
    } 
    return data; 
} 

var schedule = [1, 1, 1, 1, 4, 1, 1, 3, 2, 3, 4, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1]; 
var alarm_count = 1000; 

var margin = {top: 20, right: 20, bottom: 30, left: 50}, 
    width = 0.85 * document.width - margin.left - margin.right, 
    height = 0.9 * document.height - margin.top - margin.bottom; 

var x_extent = [-0.5, 23.5]; 
var y_extent = [0, Math.round(
        getMaxAlarmCountForHourInArray(alarm_count, schedule)[1] * 1.2) ]; 

var x_scale = d3.scale.linear() 
    .range([0, width]) 
    .domain(x_extent); 

var y_scale = d3.scale.linear() 
    .range([ height, 0]) 
    .domain(y_extent); 


var data = createDataForD3(alarm_count , schedule); 

var xAxis = d3.svg.axis() 
    .scale(x_scale) 
    .orient("bottom") 
    .ticks(24); 

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

var line = d3.svg.line() 
    .x(function(d) { return x_scale(d.hour) ; }) 
    .y(function(d) { return y_scale(Math.round(d.alarms)) ; }); 

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


    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
    .append("text") 
     .attr("y", margin.bottom) 
     .attr("x", (width)/2) 
     .text("Hour"); 

    svg.append("g") 
     .classed("x grid ", true) 
     .attr("transform", "translate(0,"+height+")") 
     .call(xAxis 
      .tickSize(-height,0,0) 
      .tickFormat("") 
    ); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 8) 
     .attr("x", -20) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Alarms per hour"); 

    svg.append("g") 
     .classed("y grid", true) 
     .call(yAxis 
      .tickSize(-width,0,0) 
      .tickFormat("") 
    ) 

    svg.append("path") 
     .datum(data) 
     .attr("class", "line") 
     .attr("d", line); 

    svg.append("g") 
     .selectAll("circle") 
     .data(data) 
     .enter() 
     .append("circle"); 

    d3.selectAll("circle") 
     .attr("cx", function(d){ return x_scale(d.hour); }) 
     .attr("cy", function(d){ return y_scale(d.alarms); }) 
     .attr("r", 6); 

    $("#alarm_count_input").val(alarm_count); 
}); 
</script> 
<form id="form1" role="form" onSubmit="return false;"> 
    <div class=form-group"> 
     <label for="alarm_count_input" >Alarm count</label><br> 
     <input id="alarm_count_input" class="form-control" type="number" placeholder="Alarm count" min="0" max="999999" step="1" /> 
    </div> 
</form> 
</body> 
+0

jsfiddle이 좋을 것입니다. :) – Yogesh

+0

@ Yogesh 나는 그것을 추가했다 :) – Patryk

답변

1

Here, 업데이트 된 코드로 jsfiddle입니다. 알람 카운트 값이 변경 될 때마다 호출되는 별도의 함수로 알람 카운트에 의존하는 코드의 모든 부분을 이동했습니다.

function render(){  
    yAxis = yAxis.tickFormat(d3.format(",")); 
    y_extent = [0, Math.round(
        getMaxAlarmCountForHourInArray(alarm_count, schedule)[1] * 1.2) ]; 

    y_scale.domain(y_extent); 

    var data = createDataForD3(alarm_count , schedule); 


    svg.select("g.y.axis").call(yAxis); 

    gridAxis.tickFormat(""); 
    svg.select("g.y.grid").call(gridAxis); 

    var lineData = svg.selectAll(".line").data([data]); 

    lineData.enter().append("path") 
     .attr("d", line(data)) 
    .attr("class", "line"); 

    lineData.exit().remove(); 

    var svgData = svg.selectAll("circle") 
     .data(data); 

    var svgEnter = svgData.enter().append("circle") 
     .attr("cx", function(d){ return x_scale(d.hour); }) 
     .attr("cy", function(d){ return y_scale(d.alarms); }) 
     .attr("r", 6); 

    svgData.exit().remove(); 

    } 
render(); 
+0

Ok thanks a lot. 당신이 제공 한 바이올린은 원하는대로 작동하지 않습니다. 내 솔루션도 살펴볼 수 있습니다. 코드에 대해 조금 설명해 주시겠습니까? 특히'var lineData = ...'뒤에 오는 줄은? – Patryk

+0

@ Patryk : 내 솔루션이 원하는대로 작동하지 않는 이유를 설명해 주시겠습니까? 무슨 일을하지 않았습니까? 나는 현재의 라인을 선택하고 데이터에 따라 그것을 업데이트하고있다. D3.js 위키에서 enter()와 exit()에 대해 더 많이 읽을 수 있습니다 – Yogesh

+0

피들을 실행하면 눈금이 일정합니다 (0.1에서 1.0까지). 알람 횟수가 변경되면 아무 것도 바뀌지 않으며 Enter 키를 누르십시오. – Patryk

0

나는 (내게 도움이 될만한) 해결책을 게시하고 있습니다. 나는 Yogesh 's와 유사한 접근법을 수행했다. 그러나 나는 요소를 명시 적으로 제거하고 추가한다. (그것이 올바른 접근인지 아닌지는 모른다. 누군가가 나에게 약간의 오류를 지적 할지도 모른다.)

function drawY(alarm_cnt, array) { 

    d3.selectAll(".circles").remove(); 
    d3.selectAll(".y").remove(); 
    d3.selectAll(".line").remove(); 

    var data = createDataForD3(alarm_cnt , array); 

    var y_extent = [0, Math.round(
        getMaxAlarmCountForHourInArray(alarm_cnt, array)[1] * 1.2) ]; 

    var y_scale = d3.scale.linear() 
     .range([ height, 0]) 
     .domain(y_extent); 

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

    var line = d3.svg.line() 
     .x(function(d) { return x_scale(d.hour) ; }) 
     .y(function(d) { return y_scale(Math.round(d.alarms)) ; }); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 8) 
     .attr("x", -20) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Alarms per hour"); 

    svg.append("g") 
     .classed("y grid", true) 
     .call(yAxis 
      .tickSize(-width,0,0) 
      .tickFormat("") 
    ) 

    svg.append("path") 
     .datum(data) 
     .attr("class", "line") 
     .attr("d", line); 

    svg.append("g") 
     .attr("class", "circles") 
     .selectAll("circle") 
     .data(data) 
     .enter() 
     .append("circle"); 

    d3.selectAll("circle") 
     .attr("cx", function(d){ return x_scale(d.hour); }) 
     .attr("cy", function(d){ return y_scale(Math.round(d.alarms)); }) 
     .attr("r", 6); 
} 

var margin = {top: 20, right: 20, bottom: 30, left: 70}, 
    width = 0.85 * document.width - margin.left - margin.right, 
    height = 0.9 * document.height - margin.top - margin.bottom; 

var schedule = [1, 2, 1, 2, 2, 2, 1, 4, 4, 3, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; 
var alarm_count = 1000; 

var data = createDataForD3(alarm_count , schedule); 

var x_extent = [-0.8, 23.5]; 

var x_scale = d3.scale.linear() 
    .range([0, width]) 
    .domain(x_extent); 

var xAxis = d3.svg.axis() 
    .scale(x_scale) 
    .orient("bottom") 
    .ticks(24); 


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


    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
    .append("text") 
     .attr("y", margin.bottom) 
     .attr("x", (width)/2) 
     .text("Hour"); 

    svg.append("g") 
     .classed("x grid ", true) 
     .attr("transform", "translate(0,"+height+")") 
     .call(xAxis 
      .tickSize(-height,0,0) 
      .tickFormat("") 
    ); 


    drawY(alarm_count, schedule); 
    $("#alarm_count_input").val(alarm_count); 

    $("#alarm_count_input").change(function(){ 
     drawY($("#alarm_count_input").val(), schedule); 
    }); 
});