chart range selection on crop slider change

This commit is contained in:
vcoppe
2024-06-12 12:46:59 +02:00
parent 9ad16ac294
commit 3c687a6608
5 changed files with 62 additions and 68 deletions

View File

@@ -251,87 +251,49 @@
overlay.width = canvas.width;
overlay.height = canvas.height;
let selectionContext = overlay.getContext('2d');
let selectionRect = {
w: 0,
startX: 0,
startY: 0
};
let startIndex = 0,
endIndex = 0;
let startIndex = 0;
let endIndex = 0;
function getIndex(evt) {
const points = chart.getElementsAtEventForMode(
evt,
'index',
{
intersect: false
},
true
);
const rect = canvas.getBoundingClientRect();
return (
points.find((point) => point.datasetIndex === 0)?.element.raw.index ??
(evt.x - rect.left <= chart.chartArea.left ? 0 : get(gpxStatistics).local.points.length - 1)
);
}
canvas.addEventListener('pointerdown', (evt) => {
dragging = true;
canvas.style.cursor = 'col-resize';
const points = chart.getElementsAtEventForMode(
evt,
'index',
{
intersect: false
},
true
);
startIndex = points.find((point) => point.datasetIndex === 0)?.element.raw.index ?? 0;
const rect = canvas.getBoundingClientRect();
selectionRect.startX = Math.min(
Math.max(evt.clientX - rect.left, chart.chartArea.left),
chart.chartArea.right
);
selectionRect.startY = chart.chartArea.top;
startIndex = getIndex(evt);
});
canvas.addEventListener('pointermove', (evt) => {
if (dragging) {
const rect = canvas.getBoundingClientRect();
selectionRect.w =
Math.min(Math.max(evt.clientX - rect.left, chart.chartArea.left), chart.chartArea.right) -
selectionRect.startX;
if (selectionContext) {
selectionContext.globalAlpha = 0.2;
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
selectionContext.fillRect(
Math.max(selectionRect.startX, chart.chartArea.left),
selectionRect.startY,
selectionRect.w,
chart.chartArea.bottom - chart.chartArea.top
);
}
const points = chart.getElementsAtEventForMode(
evt,
'index',
{
intersect: false
},
true
);
endIndex = points.find((point) => point.datasetIndex === 0)?.element.raw.index ?? 0;
endIndex = getIndex(evt);
if (startIndex !== endIndex) {
slicedGPXStatistics.set(
get(gpxStatistics).slice(Math.min(startIndex, endIndex), Math.max(startIndex, endIndex))
);
slicedGPXStatistics.set([
get(gpxStatistics).slice(
Math.min(startIndex, endIndex),
Math.max(startIndex, endIndex)
),
Math.min(startIndex, endIndex),
Math.max(startIndex, endIndex)
]);
}
}
});
canvas.addEventListener('pointerup', (evt) => {
dragging = false;
canvas.style.cursor = '';
const points = chart.getElementsAtEventForMode(
evt,
'index',
{
intersect: false
},
true
);
endIndex = points.find((point) => point.datasetIndex === 0)?.element.raw.index ?? 0;
endIndex = getIndex(evt);
if (startIndex === endIndex) {
if (selectionContext) {
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
}
slicedGPXStatistics.set(undefined);
}
});
});
@@ -506,6 +468,34 @@
}
$: if ($slicedGPXStatistics) {
let startIndex = $slicedGPXStatistics[1];
let endIndex = $slicedGPXStatistics[2];
// Draw selection rectangle
let selectionContext = overlay.getContext('2d');
if (selectionContext) {
selectionContext.globalAlpha = 0.1;
selectionContext.clearRect(0, 0, overlay.width, overlay.height);
let startPixel = chart.scales.x.getPixelForValue(
getConvertedDistance(get(gpxStatistics).local.distance.total[startIndex])
);
let endPixel = chart.scales.x.getPixelForValue(
getConvertedDistance(get(gpxStatistics).local.distance.total[endIndex])
);
selectionContext.fillRect(
startPixel,
chart.chartArea.top,
endPixel - startPixel,
chart.chartArea.bottom - chart.chartArea.top
);
}
} else if (overlay) {
let selectionContext = overlay.getContext('2d');
if (selectionContext) {
selectionContext.clearRect(0, 0, overlay.width, overlay.height);
}
}
onDestroy(() => {

View File

@@ -16,7 +16,7 @@
let statistics: GPXStatistics;
$: if ($slicedGPXStatistics !== undefined) {
statistics = $slicedGPXStatistics;
statistics = $slicedGPXStatistics[0];
} else {
statistics = $gpxStatistics;
}

View File

@@ -27,7 +27,7 @@ export class StartEndMarkers {
update() {
let tool = get(currentTool);
let statistics = get(slicedGPXStatistics) ?? get(gpxStatistics);
let statistics = get(slicedGPXStatistics)?.[0] ?? get(gpxStatistics);
if (statistics.local.points.length > 0 && tool !== Tool.ROUTING) {
this.start.setLngLat(statistics.local.points[0].getCoordinates()).addTo(this.map);
this.end.setLngLat(statistics.local.points[statistics.local.points.length - 1].getCoordinates()).addTo(this.map);

View File

@@ -28,16 +28,20 @@
let sliderValues = [0, 100];
function updateSlicedGPXStatistics() {
if (validSelection) {
slicedGPXStatistics.set(get(gpxStatistics).slice(sliderValues[0], sliderValues[1]));
if (validSelection && (sliderValues[0] != 0 || sliderValues[1] != maxSliderValue)) {
slicedGPXStatistics.set([
get(gpxStatistics).slice(sliderValues[0], sliderValues[1]),
sliderValues[0],
sliderValues[1]
]);
} else {
slicedGPXStatistics.set(get(gpxStatistics));
slicedGPXStatistics.set(undefined);
}
}
async function updateSliderLimits() {
if (validSelection) {
maxSliderValue = $gpxStatistics.local.points.length;
maxSliderValue = $gpxStatistics.local.points.length - 1;
} else {
maxSliderValue = 100;
}
@@ -45,7 +49,7 @@
sliderValues = [0, maxSliderValue];
}
$: if ($gpxStatistics.local.points.length != maxSliderValue) {
$: if ($gpxStatistics.local.points.length - 1 != maxSliderValue) {
updateSliderLimits();
}

View File

@@ -16,7 +16,7 @@ export const map = writable<mapboxgl.Map | null>(null);
export const selectFiles = writable<{ [key: string]: (fileId?: string) => void }>({});
export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics());
export const slicedGPXStatistics: Writable<GPXStatistics | undefined> = writable(undefined);
export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> = writable(undefined);
function updateGPXData() {
let statistics = new GPXStatistics();