franshej / custommatplot Goto Github PK
View Code? Open in Web Editor NEWPlot library for the JUCE Framework
License: MIT License
Plot library for the JUCE Framework
License: MIT License
line 539
switch (grid_line.direction) {
g.setColour(findColour(Plot::grid_colour));
case ....
g,setColour is never executed, because of the case statements
the correct solution ( IMHO) is to exchange the two lines
g.setColour(findColour(Plot::grid_colour));
switch (grid_line.direction) {
Overall: Great Work.
Hi,
thanks for this tool. I'm very happy with it. I have a small issue. I can't seem to set the grid_colour. In the example below the grid will be white. I expected it to be red. Maybe someone could look into it?
m_lnf.setColour(cmp::Plot::x_grid_label_colour, juce::Colours::white);
m_lnf.setColour(cmp::Plot::y_grid_label_colour, juce::Colours::white);
m_lnf.setColour(cmp::Plot::grid_colour, juce::Colours::red);
CPMAddPackage("gh:franshej/CustomMatPlot#1.1.2")
cmp::SemiLogX m_plot;
Cheers!
Hi,
I get a crash when there are different size of points to plot. It is based on commit 98195da
If the input size changes, there will be a crash, even if we pass it to plot.
The crash is at line "auto y = y_data[j];" in calculateXYBasedDSIdxs()
*(i + 1) -1 is out of the shrinked vector, so I guess that there is a size that is not updated from new set on x_based_ds_idxs.
I just discovered your tool so maybe I'm doing something wrong ;)
Ex (You can use realtime example and change the callback). It will crash when gCount is 11, so from 36000 to 34000 points.
// mRecordForm is just initialized by "mRecordForm{ cmp::Plot() }" in constructor and "addAndMakeVisible(mRecordForm);"
void NewProjectAudioProcessorEditor::timerCallback() {
std::vector<std::vector<float>> x, y;
static int gCount = 0;
size_t pointsCount = ( (gCount = (gCount + 1 )%30) < 10 ? 36000 : gCount < 20 ? 34000 : 38000);
x.resize(2);
y.resize(2);
for (size_t i = 0; i < 2; ++i) {
x[i].reserve(pointsCount);
for (size_t j = 0; j < pointsCount; ++j) {
x[i].push_back(j);
}
y[i] = cmp::generateUniformRandomVector(pointsCount, -1.0f, 1.0f);
}
mRecordForm.plot(y, x);
}
Stack trace :
NewProject.vst3!std::vector<float,std::allocator<float>>::operator[](const unsigned __int64 _Pos) Line 1575 C++
NewProject.vst3!cmp::Downsampler<float>::calculateXYBasedDSIdxs(const cmp::CommonPlotParameterView common_params, const std::vector<unsigned __int64,std::allocator<unsigned __int64>> & x_based_ds_idxs, const std::vector<float,std::allocator<float>> & y_data, std::vector<unsigned __int64,std::allocator<unsigned __int64>> & xy_based_ds_idxs) Line 210 C++
NewProject.vst3!cmp::GraphLine::updateYIndicesAndGraphPointsIntern(const std::vector<unsigned __int64,std::allocator<unsigned __int64>> & update_only_these_indices) Line 295 C++
NewProject.vst3!cmp::GraphLine::updateYIndicesAndGraphPoints(const std::vector<unsigned __int64,std::allocator<unsigned __int64>> & update_only_these_indices) Line 242 C++
NewProject.vst3!cmp::Plot::updateYData(const std::vector<std::vector<float,std::allocator<float>>,std::allocator<std::vector<float,std::allocator<float>>>> & y_data, const std::vector<cmp::GraphAttribute,std::allocator<cmp::GraphAttribute>> & graph_attribute_list) Line 620 C++
NewProject.vst3!cmp::Plot::plot(const std::vector<std::vector<float,std::allocator<float>>,std::allocator<std::vector<float,std::allocator<float>>>> & y_data, const std::vector<std::vector<float,std::allocator<float>>,std::allocator<std::vector<float,std::allocator<float>>>> & x_data, const std::vector<cmp::GraphAttribute,std::allocator<cmp::GraphAttribute>> & graph_attributes) Line 321 C++
NewProject.vst3!NewProjectAudioProcessorEditor::timerCallback() Line 303 C++
NewProject.vst3!juce::Timer::TimerThread::callTimers() Line 120 C++
NewProject.vst3!juce::Timer::TimerThread::CallTimersMessage::messageCallback() Line 182 C++
NewProject.vst3!juce::InternalMessageQueue::dispatchMessage(juce::MessageManager::MessageBase * message) Line 196 C++
NewProject.vst3!juce::InternalMessageQueue::dispatchMessages() Line 234 C++
NewProject.vst3!juce::InternalMessageQueue::messageWndProc(HWND__ * h, unsigned int message, unsigned __int64 wParam, __int64 lParam) Line>
NewProject.vst3!std::vector<float,std::allocator<float>>::operator[](const unsigned __int64 _Pos) Line 1575 C++
NewProject.vst3!cmp::Downsampler<float>::calculateXYBasedDSIdxs(const cmp::CommonPlotParameterView common_params, const std::vect 157 C++
Regards
There are situations where divisions by 0 occur in the library which cause JUCE assertions, inf
or NaN
values which could be prevented by some trivial checks.
Take for example the situation where you might plot 2 points, with different X values, but the same Y value and are using linear scaling. In this case for example, in getYScaleAndOffset
we can see that y_lim.max - y_lim.min
is 0
, which causes y_scale
and y_offset
to be inf
.
The subsequent JUCE assertion is in:
void Path::startNewSubPath (const float x, const float y)
{
JUCE_CHECK_COORDS_ARE_VALID (x, y)
Which occurs because JUCE checks for NaN
s:
I suggest adding some perfunctory checks around these cases to set things like scale factors to sensical values in these cases or to at least prevent the JUCE assertions.
Such as:
y_scale = height / (y_lim.max - y_lim.min);
y_offset = height + (y_lim.min * y_scale);
if (std::isinf(y_scale))
y_scale = 1.0f;
if (std::isinf(y_offset))
y_offset = 0.0f;
or if
checks for things like if (0 != y_lim.max - y_lim.min)
then do something else.
This repo doesn't have a CONTRIBUTING
file to explain if/how you accept PRs from random other people, but if you'd accept outside contributions I could put together a PR to catch some of these situations, otherwise checking these cases would be much appreciated, since plotting 2 points with the same Y value is a "normal" or at least "valid" use case I think.
Hi,
I am able to compile this library on Windows but not on Ubuntu.
/home/xxxx/arthur/CustomMatPlot/source/cmp_plot.cpp:201:30: error: no match for ‘operator!=’ (operand types are ‘const Lim_f’ {aka ‘const cmp::Lim’} and ‘cmp::Lim’)
201 | if (new_x_lim && new_x_lim != m_x_lim) {
| ~~~~~~~~~ ^~ ~~~~~~~
| | |
| Lim<[...]> Lim<[...]>
/home/xxxxx/arthur/CustomMatPlot/source/cmp_plot.cpp:201:30: note: candidate: ‘operator!=(int, int)’
201 | if (new_x_lim && new_x_lim != m_x_lim) {
| ~~~~~~~~~~^~~~~~~~~~
/home/xxxx/arthur/CustomMatPlot/source/cmp_plot.cpp:201:30: note: no known conversion for argument 2 from ‘cmp::Lim’ to ‘int’
/home/xxxx/arthur/CustomMatPlot/source/cmp_plot.cpp:228:28: error: no match for ‘operator!=’ (operand types are ‘cmp::Lim’ and ‘const Lim_f’ {aka ‘const cmp::Lim’})
228 | if (new_y_lim && m_y_lim != new_y_lim) {
| ~~~~~~~ ^~ ~~~~~~~~~
| | |
| Lim<[...]> Lim<[...]>
I have to put this change to compile it properly:
diff --git a/include/include/cmp_datamodels.h b/include/include/cmp_datamodels.h
index 43604a0..850a862 100644
--- a/include/include/cmp_datamodels.h
+++ b/include/include/cmp_datamodels.h
@@ -121,6 +121,10 @@ struct Lim {
return min == rhs.min && max == rhs.max;
}
+ bool operator!=(const Lim<ValueType>& rhs) const noexcept {
+ return min != rhs.min || max != rhs.max;
+ }
+
constexpr explicit operator bool() const noexcept {
constexpr auto zero = static_cast<ValueType>(0);
In file included from CustomMatPlot/source/cmp_trace.cpp:8:
CustomMatPlot/include/include_internal/cmp_trace.h: In member function ‘constexpr bool cmp::TracePoint<ValueType>::operator<=>(const cmp::TracePoint<ValueType>&)’:
CustomMatPlot/include/include_internal/cmp_trace.h:43:32: error: no match for ‘operator<=>’ (operand types are ‘juce::Point<int>’ and ‘juce::Point<int>’)
43 | return this->getPosition() <=> rhs.getPosition();
| ~~~~~~~~~~~~~~~~~~~ ^~~ ~~~~~~~~~~~~~~~~~
| | |
| Point<[...]> Point<[...]>
and
CustomMatPlot/source/cmp_lookandfeel.cpp: In function ‘constexpr std::pair<float, float> getFirstEndFromPreviousTicks(const std::vector<float>&, cmp::Lim_f)’:
CustomMatPlot/source/cmp_lookandfeel.cpp:48:35: error: call to non-‘constexpr’ function ‘std::vector<_Tp, _Alloc>::const_iterator std::vector<_Tp, _Alloc>::begin() const [with _Tp = float; _Alloc = std::allocator<float>; std::vector<_Tp, _Alloc>::const_iterator = std::vector<float>::const_iterator]’
48 | auto it = previous_ticks.begin();
| ~~~~~~~~~~~~~~~~~~~~^~
my environment
After minor changes, got the compilation working though.
diff --git a/include/include/cmp_datamodels.h b/include/include/cmp_datamodels.h
index bf9b647..8fa6b9c 100644
--- a/include/include/cmp_datamodels.h
+++ b/include/include/cmp_datamodels.h
@@ -21,7 +21,7 @@
#if (__cpp_impl_three_way_comparison >= 201907L)
#include <compare>
-#define THREE_WAY_COMP true
+#define THREE_WAY_COMP false
#else
#define THREE_WAY_COMP false
#endif
diff --git a/source/cmp_lookandfeel.cpp b/source/cmp_lookandfeel.cpp
index cf0d24b..5c4701b 100644
--- a/source/cmp_lookandfeel.cpp
+++ b/source/cmp_lookandfeel.cpp
@@ -41,7 +41,7 @@ static std::vector<float> getLinearTicks(
return ticks;
};
-static constexpr std::pair<float, float> getFirstEndFromPreviousTicks(
+static const std::pair<float, float> getFirstEndFromPreviousTicks(
const std::vector<float>& previous_ticks, const cmp::Lim_f lim) {
auto start_value = 0.0f;
{
@@ -1101,4 +1101,4 @@ template class PlotLookAndFeelDefault<Scaling::linear, Scaling::logarithmic>;
The static library should be compiled with -fPIC (Linux). To do so, you should add in your CMakeLists.txt after line 46 (add_library)
set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.