2017-03-17 1 views
1

vizwit을 Chart.js를 사용하여 다시 작성하고 싶습니다. 날짜/시간 차트 상호 작용을 얻는 방법을 파악하는 데 어려움을 겪고 있습니다. 작업. this demo에서 기간을 선택하면 다른 차트를 필터링하는 것으로 나타납니다. Chart.js에서 시간 스케일 차트에서 범위를 선택할 수있게하려면 어떻게해야합니까? 기본적으로 특정 날짜 지점을 클릭 만 할 수 있습니다.날짜 범위를 선택하는 방법 (예 : onClick과 같이 드래그/선택)

감사합니다.

답변

3

@ jordanwillis와 답을 바탕으로 차트 위에 다른 캔버스를 배치하여 원하는 것을 쉽게 얻을 수 있습니다.
pointer-events:none을 차트의 이벤트와 일치하지 않는 스타일로 추가하기 만하면됩니다.
주석 플러그인을 사용할 필요가 없습니다. 예를 들어
(이 예 canvas의 원래 차트 캔버스와 overlay 새 상단에 배치 캔버스) :

var options = { 
 
    type: 'line', 
 
    data: { 
 
    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"], 
 
    datasets: [{ 
 
     label: '# of Votes', 
 
     data: [12, 19, 3, 5, 2, 3], 
 
     borderWidth: 1 
 
     }, 
 
     { 
 
     label: '# of Points', 
 
     data: [7, 11, 5, 8, 3, 7], 
 
     borderWidth: 1 
 
     } 
 
    ] 
 
    }, 
 
    options: { 
 
    scales: { 
 
     yAxes: [{ 
 
     ticks: { 
 
      reverse: false 
 
     } 
 
     }] 
 
    } 
 
    } 
 
} 
 

 
var canvas = document.getElementById('chartJSContainer'); 
 
var ctx = canvas.getContext('2d'); 
 
var chart = new Chart(ctx, options); 
 
var overlay = document.getElementById('overlay'); 
 
var startIndex = 0; 
 
overlay.width = canvas.width; 
 
overlay.height = canvas.height; 
 
var selectionContext = overlay.getContext('2d'); 
 
var selectionRect = { 
 
    w: 0, 
 
    startX: 0, 
 
    startY: 0 
 
}; 
 
var drag = false; 
 
canvas.addEventListener('pointerdown', evt => { 
 
    const points = chart.getElementsAtEventForMode(evt, 'index', { 
 
    intersect: false 
 
    }); 
 
    startIndex = points[0]._index; 
 
    const rect = canvas.getBoundingClientRect(); 
 
    selectionRect.startX = evt.clientX - rect.left; 
 
    selectionRect.startY = chart.chartArea.top; 
 
    drag = true; 
 
    // save points[0]._index for filtering 
 
}); 
 
canvas.addEventListener('pointermove', evt => { 
 

 
    const rect = canvas.getBoundingClientRect(); 
 
    if (drag) { 
 
    const rect = canvas.getBoundingClientRect(); 
 
    selectionRect.w = (evt.clientX - rect.left) - selectionRect.startX; 
 
    selectionContext.globalAlpha = 0.5; 
 
    selectionContext.clearRect(0, 0, canvas.width, canvas.height); 
 
    selectionContext.fillRect(selectionRect.startX, 
 
     selectionRect.startY, 
 
     selectionRect.w, 
 
     chart.chartArea.bottom - chart.chartArea.top); 
 
    } else { 
 
    selectionContext.clearRect(0, 0, canvas.width, canvas.height); 
 
    var x = evt.clientX - rect.left; 
 
    if (x > chart.chartArea.left) { 
 
     selectionContext.fillRect(x, 
 
     chart.chartArea.top, 
 
     1, 
 
     chart.chartArea.bottom - chart.chartArea.top); 
 
    } 
 
    } 
 
}); 
 
canvas.addEventListener('pointerup', evt => { 
 

 
    const points = chart.getElementsAtEventForMode(evt, 'index', { 
 
    intersect: false 
 
    }); 
 
    drag = false; 
 
    console.log('implement filter between ' + options.data.labels[startIndex] + ' and ' + options.data.labels[points[0]._index]); 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.js"></script> 
 

 
<body> 
 
    <canvas id="overlay" width="600" height="400" style="position:absolute;pointer-events:none;"></canvas> 
 
    <canvas id="chartJSContainer" width="600" height="400"></canvas> 
 
</body>

공지 사항 우리가 우리의 이벤트를 내놓고있는 원래의 좌표 캔버스이지만 오버레이를 그립니다. 이렇게하면 차트의 기능이 엉망이되지 않습니다.

+0

고마워요! 보기는에 반점 본다. –

+0

도움이 되니, 반갑습니다. –

2

불행히도이 같은 것은 chart.js에 내장되어 있지 않습니다. 차트에서 강조 표시된 섹션을 렌더링하는 고유 한 이벤트 후크 및 처리기를 구현 한 다음 .getElementsAtEvent(e) 프로토 타입 메서드를 사용하여 어떤 데이터가 강조되었는지 파악해야합니다. 내장되어있는 이러한 갈고리조차도 원하는 것을 구현하기에는 충분하지 않을 수 있습니다.

이벤트 후크 옵션은 다음과 같습니다

  • (아래 예 참조)

    canvas.onclick = function(evt){ 
        var activePoints = myLineChart.getElementsAtEvent(evt); 
        // => activePoints is an array of points on the canvas that are at the same position as the click event. 
    }; 
    
  • onClick를 사용하여 chart.js 차트 개체에 이벤트 처리기를 추가 캔버스 요소 자체에 이벤트 처리기를 추가 구성 옵션 (explained here).

  • 일부 핵심 차트 이벤트 후크를 확장하고 자신을 추가하십시오. (지침은 here 참조).

, 당신은 그에 따라 원래 차트 데이터 배열을 필터링 할 수있는 작품이 방법 (기본 chart.js에서 객체) 가정 및 새 차트를 그리기 위해 .update() 프로토 타입 메서드를 호출합니다.

1

@jordanwillis의 답변에 따라 몇 달 후 업데이트 : 범위 선택의 시작점이 있습니다.

canvas.onpointerdown = function (evt) { 
    clearAnnotations() 
    const points = chart.getElementsAtEventForMode(evt, 'index', { intersect: false }) 
    const label = chart.data.labels[points[0]._index] 
    addAnnotation(label) 
} 

canvas.onpointerup = function (evt) { 
    const points = chart.getElementsAtEventForMode(evt, 'index', { intersect: false }) 
    const label = chart.data.labels[points[0]._index] 
    addAnnotation(label) 
} 

function clearAnnotations() { 
    if (chart.options.annotation) { 
    chart.options.annotation.annotations = [] 
    } 
} 

function addAnnotation (label) { 
    const annotation = { 
    scaleID: 'x-axis-0', 
    type: 'line', 
    mode: 'vertical', 
    value: label, 
    borderColor: 'red' 
    } 
    chart.options.annotation = chart.options.annotation || {} 
    chart.options.annotation.annotations = chart.options.annotation.annotations || [] 
    chart.options.annotation.annotations.push(annotation) 
    chart.update() 
} 

질문에 링크 된 데모와 같이 시각적 호버 표시기를 표시하는 방법을 알아야하지만 시작일뿐입니다.

관련 문제