mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-01 08:12:32 +00:00
chart range selection on crop slider change
This commit is contained in:
@@ -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(() => {
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
Reference in New Issue
Block a user