wxIshiko/wxCharts

StackedColumnChart can't take more than 3 datasets

gismowdd opened this issue · 7 comments

Compiled using mingw32 with wxWidgets-3.1.3 on Windows 10 . When i add more than 3 datasets it compiles but at runtime I get the error:

sharedptr.h(85):assert "m_ref!=_null" failed in operator().

I can run any combination of 3 of the 4 datasets just fine using the sample code.

That's because default theme has only 3 sets of predefined datasets options value.

So if you going to use more than 3 datasets just update default theme:

    wxChartsDatasetTheme* datasettheme = new wxChartsDatasetTheme();
    datasettheme->SetStackedColumnChartDatasetOptions(wxStackedColumnChartDatasetOptions(
        wxChartsPenOptions(*wxBLACK, 2),
        wxChartsBrushOptions(*wxRED)
    ));
    wxChartsDefaultTheme->SetDatasetTheme(wxChartsDatasetId::CreateImplicitId(3), wxSharedPtr<wxChartsDatasetTheme>(datasettheme));

where Id is index of dataset.

I tried to modifie the default theme but that did not work. I have the same issues with the wxLinechart wher i need 10 datasets insteed of the three. Can You please explain a little deeper how to update the chartsDefault, because it did'nt work the right way for me.

The code above should worked for wxLineChartCtrl too. Try to change wxlinechartframe.cpp from sample with this code:

#include "wxlinechartframe.h"
#include <wx/panel.h>
#include <wx/sizer.h>
#include <wx/charts/wxcharts.h>
#include <random>

wxLineChartFrame::wxLineChartFrame(const wxString& title)
    : wxFrame(NULL, wxID_ANY, title)
{
    // Create a top-level panel to hold all the contents of the frame
    wxPanel* panel = new wxPanel(this, wxID_ANY);

    // Create the data for the line chart widget
    wxVector<wxString> labels;
    labels.push_back("January");
    labels.push_back("February");
    labels.push_back("March");
    labels.push_back("April");
    labels.push_back("May");
    labels.push_back("June");
    labels.push_back("July");
    wxChartsCategoricalData::ptr chartData = wxChartsCategoricalData::make_shared(labels);

    std::ranlux48 rng(std::random_device{}());
    auto dist = std::uniform_real_distribution<double>(0, 100);
    auto dist2 = std::uniform_int_distribution<unsigned long>(0, 3000000);

    wxVector<wxVector<wxDouble>> points;

    for (std::size_t i = 0; i < 10; i++)
    {
        wxVector<wxDouble> vec(labels.size());
        for (std::size_t j = 0; j < labels.size(); j++)
        {
            vec[j] = dist(rng);//generate random data
        }
        points.push_back(vec);
        // update default theme for dataset 
        if (i >= 3)
        {
            wxColor color = dist2(rng); //generate random color

            wxChartsDatasetTheme* datasettheme = new wxChartsDatasetTheme();
            datasettheme->SetLineChartDatasetOptions(wxLineChartDatasetOptions(
                color,
                color,
                wxTransparentColor
            ));
            wxChartsDefaultTheme->SetDatasetTheme(wxChartsDatasetId::CreateImplicitId(i), wxSharedPtr<wxChartsDatasetTheme>(datasettheme));
        }
    }

    for (std::size_t i = 0; i < points.size(); i++)
    {
        wxChartsDoubleDataset::ptr dataset(
            new wxChartsDoubleDataset(
                wxString::Format("%d dataset", i), points[i]));
        chartData->AddDataset(dataset);
    }

    // Create the line chart widget from the constructed data
    wxLineChartCtrl* lineChartCtrl = new wxLineChartCtrl(panel, wxID_ANY, chartData,
        wxCHARTSLINETYPE_STRAIGHT, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);

    // Create the legend widget
    wxChartsLegendData legendData(chartData->GetDatasets());
    wxChartsLegendCtrl* legendCtrl = new wxChartsLegendCtrl(panel, wxID_ANY, legendData,
        wxDefaultPosition, wxDefaultSize, wxBORDER_NONE);

    // Set up the sizer for the panel
    wxBoxSizer* panelSizer = new wxBoxSizer(wxHORIZONTAL);
    panelSizer->Add(lineChartCtrl, 1, wxEXPAND);
    panelSizer->Add(legendCtrl, 1, wxEXPAND);
    panel->SetSizer(panelSizer);

    // Set up the sizer for the frame
    wxBoxSizer* topSizer = new wxBoxSizer(wxHORIZONTAL);
    topSizer->Add(panel, 1, wxEXPAND);
    SetSizerAndFit(topSizer);
}

Thank You for the help. I can see all 10 datasets. Now I have only to make the fill for the fist two lines disappear.

I have one more question where can I find documentation about ChartsDefaultTheme

Now I have only to make the fill for the fist two lines disappear.

            auto options = wxChartsDefaultTheme->GetDatasetTheme(
                wxChartsDatasetId::CreateImplicitId(i))->GetLineChartDatasetOptions();
            
            wxChartsDefaultTheme->GetDatasetTheme(
                wxChartsDatasetId::CreateImplicitId(i))->SetLineChartDatasetOptions(wxLineChartDatasetOptions(
                options->GetLineColor(),
                options->GetLineColor(),
                wxTransparentColor
            ));

I have one more question where can I find documentation about ChartsDefaultTheme

Unfortunately, there isn't documentation for that.

Thanks again for the help