问题
Recently I started working on Google Charts. Till now it is fine but now I am facing an issue with multiple selection. I am able to select multiple points by mouse clicks but I need to select range of points by dragging the mouse.
Could you please help me in this?
回答1:
using this answer to draw the selection range --> Select area/rectangle in javascript
use chart method --> chart.getChartLayoutInterface().getBoundingBox()
to find the bounds for each point...
chart.getChartLayoutInterface().getBoundingBox('point#0#0')
where the first #0
represents the series column,
and the second #0
represents the row index
if the bounds fall within the selection range,
add the point to the selection...
see following working snippet...
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'y'],
[10, 15],
[15, 13],
[18, 20],
[24, 26],
[34, 30],
[40, 43],
[49, 48],
[50, 55],
[65, 67],
[70, 70],
[72, 70],
[73, 70],
[80, 85]
]);
var container = document.getElementById('chart_div');
var chart = new google.visualization.ScatterChart(container);
var options = {
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 32,
right: 16,
bottom: 32
},
height: '100%',
width: '100%',
legend: {
position: 'top'
},
selectionMode: 'multiple'
};
google.visualization.events.addListener(chart, 'ready', function () {
var chartLayout = chart.getChartLayoutInterface();
var divSelect = document.getElementById('select_div');
var x1 = 0;
var y1 = 0;
var x2 = 0;
var y2 = 0;
var x3 = 0;
var y3 = 0;
var x4 = 0;
var y4 = 0;
function reCalc() {
x3 = Math.min(x1,x2);
x4 = Math.max(x1,x2);
y3 = Math.min(y1,y2);
y4 = Math.max(y1,y2);
divSelect.style.left = x3 + 'px';
divSelect.style.top = y3 + 'px';
divSelect.style.width = x4 - x3 + 'px';
divSelect.style.height = y4 - y3 + 'px';
}
function selectPoints() {
var selection = [];
for (var row = 0; row < data.getNumberOfRows(); row++) {
for (var col = 1; col < data.getNumberOfColumns(); col++) {
var point = chartLayout.getBoundingBox('point#' + (col - 1) + '#' + row);
if (((point.left >= (x3 - point.width)) && ((point.left + point.width) <= (x4 + point.width))) &&
((point.top >= (y3 - point.height)) && ((point.top + point.height) <= (y4 + point.height)))) {
selection.push({row: row, column: col});
}
}
}
chart.setSelection(selection);
}
window.addEventListener('mousedown', function (e) {
divSelect.className = '';
x1 = e.pageX;
y1 = e.pageY;
reCalc();
}, false);
window.addEventListener('mousemove', function (e) {
x2 = e.pageX;
y2 = e.pageY;
reCalc();
}, false);
window.addEventListener('mouseup', function (e) {
divSelect.className = 'hidden';
selectPoints();
}, false);
});
chart.draw(data, options);
});
html, body {
height: 100%;
margin: 0px 0px 0px 0px;
overflow: hidden;
padding: 0px 0px 0px 0px;
}
#select_div {
border: 1px dashed #3366cc;
position: absolute;
z-index: 1000;
}
.chart {
height: 100%;
}
.hidden {
display: none;
visibility: hidden;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="hidden" id="select_div"></div>
<div class="chart" id="chart_div"></div>
note: if your chart is not located at top = 0
& left = 0
on the page,
you will need to adjust the point's bounds,
based on the position of the chart on the page...
EDIT - update for multiple charts...
google.charts.load('current', {
packages: ['controls', 'corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['x', 'y'],
[10, 15],
[15, 13],
[18, 20],
[24, 26],
[34, 30],
[40, 43],
[49, 48],
[50, 55],
[65, 67],
[70, 70],
[72, 70],
[73, 70],
[80, 85]
]);
var options = {
chartArea: {
height: '100%',
width: '100%',
top: 32,
left: 32,
right: 16,
bottom: 32
},
height: '100%',
width: '100%',
legend: {
position: 'top'
},
selectionMode: 'multiple'
};
var charts = [];
var container = document.getElementById('charts');
for (var i = 0; i < 4; i++) {
var chartContainer = container.appendChild(document.createElement('div'));
chartContainer.id = 'chart_' + i;
var chart = new google.visualization.ChartWrapper({
chartType: 'ScatterChart',
containerId: chartContainer.id,
dataTable: data,
options: options
});
google.visualization.events.addListener(chart, 'ready', function () {
charts.push(chart);
});
chart.draw();
}
var divSelect = document.getElementById('select');
var x1 = 0;
var y1 = 0;
var x2 = 0;
var y2 = 0;
var x3 = 0;
var y3 = 0;
var x4 = 0;
var y4 = 0;
window.addEventListener('mousedown', function (e) {
divSelect.className = '';
x1 = e.pageX;
y1 = e.pageY;
reCalc();
}, false);
window.addEventListener('mousemove', function (e) {
x2 = e.pageX;
y2 = e.pageY;
reCalc();
}, false);
window.addEventListener('mouseup', function (e) {
divSelect.className = 'hidden';
selectPoints();
}, false);
function reCalc() {
x3 = Math.min(x1,x2);
x4 = Math.max(x1,x2);
y3 = Math.min(y1,y2);
y4 = Math.max(y1,y2);
divSelect.style.left = x3 + 'px';
divSelect.style.top = y3 + 'px';
divSelect.style.width = x4 - x3 + 'px';
divSelect.style.height = y4 - y3 + 'px';
}
function selectPoints() {
charts.forEach(function (chart, index) {
var chartLayout = chart.getChart().getChartLayoutInterface();
var chartContainer = document.getElementById(chart.getContainerId());
var chartBounds = chartContainer.getBoundingClientRect();
if ((((chartBounds.left + window.pageXOffset) <= x3) &&
((chartBounds.left + chartBounds.width + window.pageXOffset) >= x4)) &&
(((chartBounds.top + window.pageYOffset) <= y3) &&
((chartBounds.top + chartBounds.height + window.pageYOffset) >= y4))) {
var selection = [];
var dataTable = chart.getDataTable();
for (var row = 0; row < dataTable.getNumberOfRows(); row++) {
for (var col = 1; col < dataTable.getNumberOfColumns(); col++) {
var point = chartLayout.getBoundingBox('point#' + (col - 1) + '#' + row);
if ((((chartBounds.left + point.left + window.pageXOffset) >= (x3 - point.width)) &&
((chartBounds.left + point.left + point.width + window.pageXOffset) <= (x4 + point.width))) &&
(((chartBounds.top + point.top + window.pageYOffset) >= (y3 - point.height)) &&
((chartBounds.top + point.top + point.height + window.pageYOffset) <= (y4 + point.height)))) {
selection.push({row: row, column: col});
}
}
}
chart.getChart().setSelection(selection);
}
});
}
});
#select {
border: 1px dashed #3366cc;
position: absolute;
z-index: 1000;
}
.hidden {
display: none;
visibility: hidden;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="hidden" id="select"></div>
<div id="charts"></div>
来源:https://stackoverflow.com/questions/49849902/need-to-select-the-range-of-points-in-google-scatter-chart-by-dragging-the-mouse