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,18 +251,9 @@
overlay.width = canvas.width; overlay.width = canvas.width;
overlay.height = canvas.height; overlay.height = canvas.height;
let selectionContext = overlay.getContext('2d'); let startIndex = 0;
let selectionRect = { let endIndex = 0;
w: 0, function getIndex(evt) {
startX: 0,
startY: 0
};
let startIndex = 0,
endIndex = 0;
canvas.addEventListener('pointerdown', (evt) => {
dragging = true;
canvas.style.cursor = 'col-resize';
const points = chart.getElementsAtEventForMode( const points = chart.getElementsAtEventForMode(
evt, evt,
'index', 'index',
@@ -271,67 +262,38 @@
}, },
true true
); );
startIndex = points.find((point) => point.datasetIndex === 0)?.element.raw.index ?? 0;
const rect = canvas.getBoundingClientRect(); const rect = canvas.getBoundingClientRect();
selectionRect.startX = Math.min( return (
Math.max(evt.clientX - rect.left, chart.chartArea.left), points.find((point) => point.datasetIndex === 0)?.element.raw.index ??
chart.chartArea.right (evt.x - rect.left <= chart.chartArea.left ? 0 : get(gpxStatistics).local.points.length - 1)
); );
selectionRect.startY = chart.chartArea.top; }
canvas.addEventListener('pointerdown', (evt) => {
dragging = true;
canvas.style.cursor = 'col-resize';
startIndex = getIndex(evt);
}); });
canvas.addEventListener('pointermove', (evt) => { canvas.addEventListener('pointermove', (evt) => {
if (dragging) { if (dragging) {
const rect = canvas.getBoundingClientRect(); endIndex = getIndex(evt);
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;
if (startIndex !== endIndex) { if (startIndex !== endIndex) {
slicedGPXStatistics.set( slicedGPXStatistics.set([
get(gpxStatistics).slice(Math.min(startIndex, endIndex), Math.max(startIndex, endIndex)) get(gpxStatistics).slice(
); Math.min(startIndex, endIndex),
Math.max(startIndex, endIndex)
),
Math.min(startIndex, endIndex),
Math.max(startIndex, endIndex)
]);
} }
} }
}); });
canvas.addEventListener('pointerup', (evt) => { canvas.addEventListener('pointerup', (evt) => {
dragging = false; dragging = false;
canvas.style.cursor = ''; canvas.style.cursor = '';
endIndex = getIndex(evt);
const points = chart.getElementsAtEventForMode(
evt,
'index',
{
intersect: false
},
true
);
endIndex = points.find((point) => point.datasetIndex === 0)?.element.raw.index ?? 0;
if (startIndex === endIndex) { if (startIndex === endIndex) {
if (selectionContext) { slicedGPXStatistics.set(undefined);
selectionContext.clearRect(0, 0, canvas.width, canvas.height);
}
} }
}); });
}); });
@@ -506,6 +468,34 @@
} }
$: if ($slicedGPXStatistics) { $: 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(() => { onDestroy(() => {

View File

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

View File

@@ -27,7 +27,7 @@ export class StartEndMarkers {
update() { update() {
let tool = get(currentTool); 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) { if (statistics.local.points.length > 0 && tool !== Tool.ROUTING) {
this.start.setLngLat(statistics.local.points[0].getCoordinates()).addTo(this.map); 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); 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]; let sliderValues = [0, 100];
function updateSlicedGPXStatistics() { function updateSlicedGPXStatistics() {
if (validSelection) { if (validSelection && (sliderValues[0] != 0 || sliderValues[1] != maxSliderValue)) {
slicedGPXStatistics.set(get(gpxStatistics).slice(sliderValues[0], sliderValues[1])); slicedGPXStatistics.set([
get(gpxStatistics).slice(sliderValues[0], sliderValues[1]),
sliderValues[0],
sliderValues[1]
]);
} else { } else {
slicedGPXStatistics.set(get(gpxStatistics)); slicedGPXStatistics.set(undefined);
} }
} }
async function updateSliderLimits() { async function updateSliderLimits() {
if (validSelection) { if (validSelection) {
maxSliderValue = $gpxStatistics.local.points.length; maxSliderValue = $gpxStatistics.local.points.length - 1;
} else { } else {
maxSliderValue = 100; maxSliderValue = 100;
} }
@@ -45,7 +49,7 @@
sliderValues = [0, maxSliderValue]; sliderValues = [0, maxSliderValue];
} }
$: if ($gpxStatistics.local.points.length != maxSliderValue) { $: if ($gpxStatistics.local.points.length - 1 != maxSliderValue) {
updateSliderLimits(); 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 selectFiles = writable<{ [key: string]: (fileId?: string) => void }>({});
export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics()); 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() { function updateGPXData() {
let statistics = new GPXStatistics(); let statistics = new GPXStatistics();