From 0a6af18588930acfd17a924431242273958fd40b Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 11:49:04 -0800 Subject: [PATCH 01/11] feat: added ticks that are placed at even numbers. --- resources/BaseComponents/SwiftValueAxis.qml | 27 +++++++++++++++++ .../SolutionPositionTab.qml | 30 ++++++++++++++----- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 1cce60273..0cd03a96e 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -32,4 +32,31 @@ ValueAxis { labelsColor: Constants.commonChart.labelsColor titleFont: Constants.commonChart.axisTitleFont labelsFont: Constants.commonChart.axisLabelsFont + + // A function that can be placed in onRangeChanged signal + // slot to get that good tick spacing. It requires the + // tickType to be `ValueAxis.TicksDynamic` otherwise it + // does nothing but spin yer CPU + // + // adapted from + // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks + + function getGoodTicks (new_min, new_max) { + const ticksRange = (new_max - new_min)/(tickCount - 1); + const exponent = Math.floor(Math.log10(ticksRange)); + const fraction = ticksRange/Math.pow(10, exponent); + var niceFraction = 10; + if (fraction < 1.5) { + niceFraction = 1; + } else if (fraction < 3) { + niceFraction = 2; + } else if (fraction < 7) { + niceFraction = 5; + } + + const tickSpacing = niceFraction * Math.pow(10, exponent); + + tickAnchor = Math.ceil(new_min / tickSpacing) * tickSpacing; + tickInterval = tickSpacing; + } } diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index e361b036e..fd9bc6227 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -193,11 +193,13 @@ Item { function resetChartZoom() { solutionPositionChart.zoomReset(); - solutionPositionXAxis.max = orig_lon_max; + // for some reason if you set the max first here it locks the + // GUI. solutionPositionXAxis.min = orig_lon_min; + solutionPositionXAxis.max = orig_lon_max; solutionPositionYAxis.max = orig_lat_max; solutionPositionYAxis.min = orig_lat_min; - } + } function centerToSolution() { solutionPositionChart.zoomReset(); @@ -293,12 +295,20 @@ Item { id: solutionPositionXAxis titleText: Constants.solutionPosition.xAxisTitleText + " (" + available_units[solutionPositionSelectedUnit.currentIndex] + ")" + tickType: ValueAxis.TicksDynamic + onRangeChanged: (new_min, new_max) => { + solutionPositionXAxis.getGoodTicks(new_min, new_max); + } } SwiftValueAxis { id: solutionPositionYAxis titleText: Constants.solutionPosition.yAxisTitleText + " (" + available_units[solutionPositionSelectedUnit.currentIndex] + ")" + tickType: ValueAxis.TicksDynamic + onRangeChanged: (new_min, new_max) => { + solutionPositionYAxis.getGoodTicks(new_min, new_max); + } } MouseArea { @@ -357,15 +367,19 @@ Item { running: true repeat: true onTriggered: { - if (!solutionPositionTab.visible) + if (!solutionPositionTab.visible) { return; + } solution_position_model.fill_console_points(solutionPositionPoints); - if (!solutionPositionPoints.points.length) + if (!solutionPositionPoints.points.length) { return; - if (available_units != solutionPositionPoints.available_units) + } + if (available_units != solutionPositionPoints.available_units) { available_units = solutionPositionPoints.available_units; - if (!line || !scatters.length || !cur_scatters.length) + } + if (!line || !scatters.length || !cur_scatters.length) { [scatters, cur_scatters, line] = SolutionPlotLoop.setupScatterSeries(solutionPositionChart, Constants, Globals, solutionPositionXAxis, solutionPositionYAxis, Constants.solutionPosition.legendLabels, Constants.solutionPosition.colors, false, true); + } var combined = [line, scatters, cur_scatters]; solutionPositionPoints.fill_series(combined); let point = SolutionPlotLoop.getCurSolution(solutionPositionPoints.cur_points); @@ -405,8 +419,10 @@ Item { orig_lat_max = new_lat_max; orig_lon_min = new_lon_min; orig_lon_max = new_lon_max; - if (zoom_all) + + if (zoom_all) { solutionPositionChart.resetChartZoom(); + } } } } From 408c66e581838a58d8020104e4140dedde9d77ff Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 14:48:00 -0800 Subject: [PATCH 02/11] fixed race condition --- resources/BaseComponents/SwiftValueAxis.qml | 11 ++++++++--- .../SolutionPositionTab.qml | 16 +++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 0cd03a96e..077ebaae9 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -41,8 +41,8 @@ ValueAxis { // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - function getGoodTicks (new_min, new_max) { - const ticksRange = (new_max - new_min)/(tickCount - 1); + function getGoodTicks () { + const ticksRange = (max - min)/(tickCount - 1); const exponent = Math.floor(Math.log10(ticksRange)); const fraction = ticksRange/Math.pow(10, exponent); var niceFraction = 10; @@ -56,7 +56,12 @@ ValueAxis { const tickSpacing = niceFraction * Math.pow(10, exponent); - tickAnchor = Math.ceil(new_min / tickSpacing) * tickSpacing; + tickAnchor = Math.ceil(min / tickSpacing) * tickSpacing; tickInterval = tickSpacing; + tickType = ValueAxis.TicksDynamic; + } + + function fixTicks () { + tickType = ValueAxis.TicksFixed; } } diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index fd9bc6227..c2dd83755 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -195,8 +195,9 @@ Item { solutionPositionChart.zoomReset(); // for some reason if you set the max first here it locks the // GUI. - solutionPositionXAxis.min = orig_lon_min; solutionPositionXAxis.max = orig_lon_max; + solutionPositionXAxis.min = orig_lon_min; + solutionPositionYAxis.max = orig_lat_max; solutionPositionYAxis.min = orig_lat_min; } @@ -296,9 +297,6 @@ Item { titleText: Constants.solutionPosition.xAxisTitleText + " (" + available_units[solutionPositionSelectedUnit.currentIndex] + ")" tickType: ValueAxis.TicksDynamic - onRangeChanged: (new_min, new_max) => { - solutionPositionXAxis.getGoodTicks(new_min, new_max); - } } SwiftValueAxis { @@ -306,9 +304,6 @@ Item { titleText: Constants.solutionPosition.yAxisTitleText + " (" + available_units[solutionPositionSelectedUnit.currentIndex] + ")" tickType: ValueAxis.TicksDynamic - onRangeChanged: (new_min, new_max) => { - solutionPositionYAxis.getGoodTicks(new_min, new_max); - } } MouseArea { @@ -407,6 +402,11 @@ Item { new_lat_max = solutionPositionPoints.lat_max_; new_lon_min = solutionPositionPoints.lon_min_; new_lon_max = solutionPositionPoints.lon_max_; + + // fix the interval so tick number cannot overflow + // freeze ticks incase too many would be produced + solutionPositionXAxis.fixTicks(); + solutionPositionYAxis.fixTicks(); } else { zoom_all = true; center_solution = false; @@ -424,6 +424,8 @@ Item { solutionPositionChart.resetChartZoom(); } } + solutionPositionXAxis.getGoodTicks(); + solutionPositionYAxis.getGoodTicks(); } } } From d172c4f280f1eb0050ec61074a56c1f0cd7dc217 Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 15:15:48 -0800 Subject: [PATCH 03/11] found another place where rendering too many ticks can cause a lot of lag --- .../SolutionPositionTab.qml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index c2dd83755..922ecd1d9 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -213,10 +213,22 @@ Item { } function chartZoomByDirection(delta) { - if (delta > 0) + + // fix ticks before zooming because if you don't and the user spins + // their mouse wheel really fast you can get a situation where it + // tries to render a ton of ticks + + solutionPositionYAxis.fixTicks(); + solutionPositionXAxis.fixTicks(); + + if (delta > 0) { solutionPositionChart.zoom(Constants.commonChart.zoomInMult); - else + } else { solutionPositionChart.zoom(Constants.commonChart.zoomOutMult); + } + + solutionPositionYAxis.getGoodTicks(); + solutionPositionXAxis.getGoodTicks(); } function stopZoomFeatures() { From ed524ba9613f0135a9e5daca4f4caae39a8d1fdc Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 15:26:28 -0800 Subject: [PATCH 04/11] update documentation --- resources/BaseComponents/SwiftValueAxis.qml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 077ebaae9..2a8eb3d84 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -33,10 +33,16 @@ ValueAxis { titleFont: Constants.commonChart.axisTitleFont labelsFont: Constants.commonChart.axisLabelsFont - // A function that can be placed in onRangeChanged signal - // slot to get that good tick spacing. It requires the - // tickType to be `ValueAxis.TicksDynamic` otherwise it - // does nothing but spin yer CPU + // A function that can be used to get that good tick spacing. + // + // WARNING! if the tickType is dynamic, and you drastically change + // the size of the plot via zooming or plotting a new series, it is + // NOT ENOUGH to have the getGoodTicks function on the onRangeChanged + // slot of the ValueAxis to avoid your plot trying to render thousands + // of tick lines. I think there may be a way around that, but instead + // what I chose to do is manually call the fixTicks function below before + // the big change in range, and then calling the getGoodTicks() function + // after. // // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks @@ -61,6 +67,8 @@ ValueAxis { tickType = ValueAxis.TicksDynamic; } + // Kind of a throwaway function, but it is used whenever you + // need to make sure you won't render too many ticks. function fixTicks () { tickType = ValueAxis.TicksFixed; } From 8e95e875edc6003cbbfab9829ebb8cee29ae701e Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 16:42:05 -0800 Subject: [PATCH 05/11] delete old comment, fix whitespace --- resources/BaseComponents/SwiftValueAxis.qml | 14 ++++++-------- .../SolutionTabComponents/SolutionPositionTab.qml | 9 +-------- 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 2a8eb3d84..02049f566 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -34,7 +34,7 @@ ValueAxis { labelsFont: Constants.commonChart.axisLabelsFont // A function that can be used to get that good tick spacing. - // + // -- // WARNING! if the tickType is dynamic, and you drastically change // the size of the plot via zooming or plotting a new series, it is // NOT ENOUGH to have the getGoodTicks function on the onRangeChanged @@ -43,14 +43,14 @@ ValueAxis { // what I chose to do is manually call the fixTicks function below before // the big change in range, and then calling the getGoodTicks() function // after. - // + // -- // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - function getGoodTicks () { - const ticksRange = (max - min)/(tickCount - 1); + function getGoodTicks() { + const ticksRange = (max - min) / (tickCount - 1); const exponent = Math.floor(Math.log10(ticksRange)); - const fraction = ticksRange/Math.pow(10, exponent); + const fraction = ticksRange / Math.pow(10, exponent); var niceFraction = 10; if (fraction < 1.5) { niceFraction = 1; @@ -59,9 +59,7 @@ ValueAxis { } else if (fraction < 7) { niceFraction = 5; } - const tickSpacing = niceFraction * Math.pow(10, exponent); - tickAnchor = Math.ceil(min / tickSpacing) * tickSpacing; tickInterval = tickSpacing; tickType = ValueAxis.TicksDynamic; @@ -69,7 +67,7 @@ ValueAxis { // Kind of a throwaway function, but it is used whenever you // need to make sure you won't render too many ticks. - function fixTicks () { + function fixTicks() { tickType = ValueAxis.TicksFixed; } } diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index 922ecd1d9..5d9384935 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -193,14 +193,11 @@ Item { function resetChartZoom() { solutionPositionChart.zoomReset(); - // for some reason if you set the max first here it locks the - // GUI. solutionPositionXAxis.max = orig_lon_max; solutionPositionXAxis.min = orig_lon_min; - solutionPositionYAxis.max = orig_lat_max; solutionPositionYAxis.min = orig_lat_min; - } + } function centerToSolution() { solutionPositionChart.zoomReset(); @@ -217,16 +214,13 @@ Item { // fix ticks before zooming because if you don't and the user spins // their mouse wheel really fast you can get a situation where it // tries to render a ton of ticks - solutionPositionYAxis.fixTicks(); solutionPositionXAxis.fixTicks(); - if (delta > 0) { solutionPositionChart.zoom(Constants.commonChart.zoomInMult); } else { solutionPositionChart.zoom(Constants.commonChart.zoomOutMult); } - solutionPositionYAxis.getGoodTicks(); solutionPositionXAxis.getGoodTicks(); } @@ -431,7 +425,6 @@ Item { orig_lat_max = new_lat_max; orig_lon_min = new_lon_min; orig_lon_max = new_lon_max; - if (zoom_all) { solutionPositionChart.resetChartZoom(); } From 04a12983870b407ee3537c3c9bd2685308907509 Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 17:00:24 -0800 Subject: [PATCH 06/11] fix whitespace --- resources/BaseComponents/SwiftValueAxis.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 02049f566..4de88ea9a 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -46,7 +46,6 @@ ValueAxis { // -- // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - function getGoodTicks() { const ticksRange = (max - min) / (tickCount - 1); const exponent = Math.floor(Math.log10(ticksRange)); From 1ba86bbc6aafd9f5c4344f4914c7eed6cde2e022 Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Wed, 11 Jan 2023 17:08:04 -0800 Subject: [PATCH 07/11] fix whitespace --- resources/BaseComponents/SwiftValueAxis.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 4de88ea9a..4b30acc54 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -44,7 +44,7 @@ ValueAxis { // the big change in range, and then calling the getGoodTicks() function // after. // -- - // adapted from + // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks function getGoodTicks() { const ticksRange = (max - min) / (tickCount - 1); From cee1b4d5f83bea740d38e6931cdc1388aa2d9bdf Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Thu, 12 Jan 2023 09:38:21 -0800 Subject: [PATCH 08/11] fix two more edge cases where plot could render too many ticks --- .../SolutionPositionTab.qml | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index 5d9384935..12381303d 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -192,14 +192,27 @@ Item { id: solutionPositionChart function resetChartZoom() { + // fix the interval so tick number cannot overflow + // freeze ticks incase too many would be produced + solutionPositionXAxis.fixTicks(); + solutionPositionYAxis.fixTicks(); + // update the chart lims solutionPositionChart.zoomReset(); solutionPositionXAxis.max = orig_lon_max; solutionPositionXAxis.min = orig_lon_min; solutionPositionYAxis.max = orig_lat_max; solutionPositionYAxis.min = orig_lat_min; + // update ticks + solutionPositionXAxis.getGoodTicks(); + solutionPositionYAxis.getGoodTicks(); } function centerToSolution() { + // fix the interval so tick number cannot overflow + // freeze ticks incase too many would be produced + solutionPositionXAxis.fixTicks(); + solutionPositionYAxis.fixTicks(); + // update chart lims solutionPositionChart.zoomReset(); if (cur_scatters.length) { solutionPositionXAxis.max = cur_solution.x + x_axis_half; @@ -207,6 +220,9 @@ Item { solutionPositionYAxis.max = cur_solution.y + y_axis_half; solutionPositionYAxis.min = cur_solution.y - y_axis_half; } + // update ticks + solutionPositionXAxis.getGoodTicks(); + solutionPositionYAxis.getGoodTicks(); } function chartZoomByDirection(delta) { @@ -408,11 +424,6 @@ Item { new_lat_max = solutionPositionPoints.lat_max_; new_lon_min = solutionPositionPoints.lon_min_; new_lon_max = solutionPositionPoints.lon_max_; - - // fix the interval so tick number cannot overflow - // freeze ticks incase too many would be produced - solutionPositionXAxis.fixTicks(); - solutionPositionYAxis.fixTicks(); } else { zoom_all = true; center_solution = false; @@ -429,8 +440,6 @@ Item { solutionPositionChart.resetChartZoom(); } } - solutionPositionXAxis.getGoodTicks(); - solutionPositionYAxis.getGoodTicks(); } } } From c5dbde7195fda4b213901111975220a92bece46a Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Thu, 12 Jan 2023 11:25:56 -0800 Subject: [PATCH 09/11] share the tick interval accross the x & y axes --- resources/BaseComponents/SwiftValueAxis.qml | 31 ++++++++------- .../SolutionPositionTab.qml | 38 ++++++++++--------- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/resources/BaseComponents/SwiftValueAxis.qml b/resources/BaseComponents/SwiftValueAxis.qml index 4b30acc54..95f1610a0 100644 --- a/resources/BaseComponents/SwiftValueAxis.qml +++ b/resources/BaseComponents/SwiftValueAxis.qml @@ -33,20 +33,12 @@ ValueAxis { titleFont: Constants.commonChart.axisTitleFont labelsFont: Constants.commonChart.axisLabelsFont - // A function that can be used to get that good tick spacing. - // -- - // WARNING! if the tickType is dynamic, and you drastically change - // the size of the plot via zooming or plotting a new series, it is - // NOT ENOUGH to have the getGoodTicks function on the onRangeChanged - // slot of the ValueAxis to avoid your plot trying to render thousands - // of tick lines. I think there may be a way around that, but instead - // what I chose to do is manually call the fixTicks function below before - // the big change in range, and then calling the getGoodTicks() function - // after. + // A function that returns the best tick interval for the + // plot to have ticks that land on round numbers // -- // adapted from // https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks - function getGoodTicks() { + function getGoodTickInterval(): real { const ticksRange = (max - min) / (tickCount - 1); const exponent = Math.floor(Math.log10(ticksRange)); const fraction = ticksRange / Math.pow(10, exponent); @@ -58,7 +50,20 @@ ValueAxis { } else if (fraction < 7) { niceFraction = 5; } - const tickSpacing = niceFraction * Math.pow(10, exponent); + return niceFraction * Math.pow(10, exponent); + } + + // A function that can be used to get that good tick spacing. + // -- + // WARNING! if the tickType is dynamic, and you drastically change + // the size of the plot via zooming or plotting a new series, it is + // NOT ENOUGH to have the getGoodTicks function on the onRangeChanged + // slot of the ValueAxis to avoid your plot trying to render thousands + // of tick lines. I think there may be a way around that, but instead + // what I chose to do is manually call the freezeTicks function below before + // the big change in range, and then calling the setGoodTicks() function + // after. + function setGoodTicks(tickSpacing: real) { tickAnchor = Math.ceil(min / tickSpacing) * tickSpacing; tickInterval = tickSpacing; tickType = ValueAxis.TicksDynamic; @@ -66,7 +71,7 @@ ValueAxis { // Kind of a throwaway function, but it is used whenever you // need to make sure you won't render too many ticks. - function fixTicks() { + function freezeTicks() { tickType = ValueAxis.TicksFixed; } } diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index 12381303d..7fb328f3f 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -191,11 +191,23 @@ Item { ChartView { id: solutionPositionChart - function resetChartZoom() { + function freezeTicks() { // fix the interval so tick number cannot overflow // freeze ticks incase too many would be produced - solutionPositionXAxis.fixTicks(); - solutionPositionYAxis.fixTicks(); + solutionPositionXAxis.freezeTicks(); + solutionPositionYAxis.freezeTicks(); + } + + function setTicks() { + const min_tick_interval = Math.min( + solutionPositionXAxis.getGoodTickInterval(), + solutionPositionYAxis.getGoodTickInterval()); + solutionPositionXAxis.setGoodTicks(min_tick_interval); + solutionPositionYAxis.setGoodTicks(min_tick_interval); + } + + function resetChartZoom() { + solutionPositionChart.freezeTicks(); // update the chart lims solutionPositionChart.zoomReset(); solutionPositionXAxis.max = orig_lon_max; @@ -203,15 +215,11 @@ Item { solutionPositionYAxis.max = orig_lat_max; solutionPositionYAxis.min = orig_lat_min; // update ticks - solutionPositionXAxis.getGoodTicks(); - solutionPositionYAxis.getGoodTicks(); + solutionPositionChart.setTicks(); } function centerToSolution() { - // fix the interval so tick number cannot overflow - // freeze ticks incase too many would be produced - solutionPositionXAxis.fixTicks(); - solutionPositionYAxis.fixTicks(); + solutionPositionChart.freezeTicks(); // update chart lims solutionPositionChart.zoomReset(); if (cur_scatters.length) { @@ -221,24 +229,18 @@ Item { solutionPositionYAxis.min = cur_solution.y - y_axis_half; } // update ticks - solutionPositionXAxis.getGoodTicks(); - solutionPositionYAxis.getGoodTicks(); + solutionPositionChart.setTicks(); } function chartZoomByDirection(delta) { - // fix ticks before zooming because if you don't and the user spins - // their mouse wheel really fast you can get a situation where it - // tries to render a ton of ticks - solutionPositionYAxis.fixTicks(); - solutionPositionXAxis.fixTicks(); + solutionPositionChart.freezeTicks(); if (delta > 0) { solutionPositionChart.zoom(Constants.commonChart.zoomInMult); } else { solutionPositionChart.zoom(Constants.commonChart.zoomOutMult); } - solutionPositionYAxis.getGoodTicks(); - solutionPositionXAxis.getGoodTicks(); + solutionPositionChart.setTicks(); } function stopZoomFeatures() { From a15ead619f027c0015aa927df3e264c46a6b3ca3 Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Thu, 12 Jan 2023 11:42:25 -0800 Subject: [PATCH 10/11] add documentation --- .../SolutionPositionTab.qml | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index 7fb328f3f..edf0e1676 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -192,18 +192,30 @@ Item { id: solutionPositionChart function freezeTicks() { - // fix the interval so tick number cannot overflow - // freeze ticks incase too many would be produced + // fix the interval so tick number will not be too large. solutionPositionXAxis.freezeTicks(); solutionPositionYAxis.freezeTicks(); } + // This function make the ticks on the x & y axes have the + // same interval, and have them land on evenish numbers. + // It also ensures the ranges of the two axes are the same. function setTicks() { - const min_tick_interval = Math.min( + const max_tick_interval = Math.max( solutionPositionXAxis.getGoodTickInterval(), solutionPositionYAxis.getGoodTickInterval()); - solutionPositionXAxis.setGoodTicks(min_tick_interval); - solutionPositionYAxis.setGoodTicks(min_tick_interval); + const x_range = Math.abs(solutionPositionXAxis.max - solutionPositionXAxis.min); + const y_range = Math.abs(solutionPositionYAxis.max - solutionPositionYAxis.min); + const range_diff = Math.abs(x_range - y_range); + if (x_range < y_range) { + solutionPositionXAxis.min -= range_diff / 2; + solutionPositionXAxis.max += range_diff / 2; + } else { + solutionPositionYAxis.min -= range_diff / 2; + solutionPositionYAxis.max += range_diff / 2; + } + solutionPositionXAxis.setGoodTicks(max_tick_interval); + solutionPositionYAxis.setGoodTicks(max_tick_interval); } function resetChartZoom() { From 45babce79c410bb7db4fb4f7345df4abe154bb12 Mon Sep 17 00:00:00 2001 From: Patrick Crumley Date: Thu, 12 Jan 2023 11:49:59 -0800 Subject: [PATCH 11/11] fix whitespace --- resources/SolutionTabComponents/SolutionPositionTab.qml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/SolutionTabComponents/SolutionPositionTab.qml b/resources/SolutionTabComponents/SolutionPositionTab.qml index edf0e1676..feb362ead 100644 --- a/resources/SolutionTabComponents/SolutionPositionTab.qml +++ b/resources/SolutionTabComponents/SolutionPositionTab.qml @@ -201,9 +201,9 @@ Item { // same interval, and have them land on evenish numbers. // It also ensures the ranges of the two axes are the same. function setTicks() { - const max_tick_interval = Math.max( - solutionPositionXAxis.getGoodTickInterval(), - solutionPositionYAxis.getGoodTickInterval()); + const x_tick_interval = solutionPositionXAxis.getGoodTickInterval(); + const y_tick_interval = solutionPositionYAxis.getGoodTickInterval(); + const max_tick_interval = Math.max(x_tick_interval, y_tick_interval); const x_range = Math.abs(solutionPositionXAxis.max - solutionPositionXAxis.min); const y_range = Math.abs(solutionPositionYAxis.max - solutionPositionYAxis.min); const range_diff = Math.abs(x_range - y_range); @@ -245,7 +245,6 @@ Item { } function chartZoomByDirection(delta) { - solutionPositionChart.freezeTicks(); if (delta > 0) { solutionPositionChart.zoom(Constants.commonChart.zoomInMult);