Hi Syam, I am trying to use the MarkArea in a line graph but without any s

Hi Syam,
I am trying to use the MarkArea in a line graph but without any success;
I have added the MarkArea in this way:

lcAngPos = new LineChart(xData, yDataAngPos);
Block blockBreaking = new Block();
blockBreaking.setName("Breaking Area");
blockBreaking.setSides(xAxis, "min", "max");
lcAngPos.getMarkArea(true).add(blockBreaking);

But in the send Json I read:

"markArea":{"data":3}

What that 3 means? is the output of data.getSerial() I read in the code but how to render the correct Json?

Regards,
Stefano

Hi,

Yes, what you are doing is correct and it should work. Since you are marking the whole X-axis (from “min” to “max”), the whole chart will be marked as “Breaking Area”. If you change that to some other range, you may be able to visualize it better.

The “data” part you are seeing in the generated JSON is internal to the mark area and it is being built as an internal data stream based on the “blocks” definitions. If you really want to see the JSON generated for the data part, you can override customizeDataJSON(...) method.

I have added an example of Mark Area in the demo. Please see [EXAMPLES]
(https://storedobject.com/examples/). (Search for the term Mark Area there).

Login: guest
Password: Welcome2System$

Thanks Syam,

your example bring me to the right path. Initially I didn’t get that in my code the problem isn’t with the initial draw of the graph but in the successive refresh of the data (with your suggestions now I got this important point);
In the first draw I have correctly the send of:

customizeDataJSON() - {"d":[[{"name":"Area (20 to 30)","xAxis":20},{"xAxis":30}]
]}

and the graph is clearly draw.
After that I would like to refresh the data and I call:

soChart.updateData(xData, yDataAngPos, yDataVelocity, yDataAcc);

but the info about the Mark Area was not send which bring me to a Javascript error:

(TypeError) : Cannot read properties of null (reading 'function')

which I suppose is because the Mark Area data are missing.
How could I send an update of that data too?
Do I have to implement some sort of data provider refreshable by the update methon?

Again, many thanks for your precious help.

Regards,

S.

Hi,

Since the MarkArea is not changed, there is no need to invoke updateData for that. But, there could be some bug related to this. (If you can create a simple test program, I will try to resolve it.)

However, the MarkArea data can be updated by invoking:

MarkArea markArea = lcAngPos.getMarkArea(true); // Keep a reference to the Mark Area
...
...
// Later somewhere in the code
soChart.updateData(markArea);

Hi Syam,

I was able to reproduce the problem with a very simple app.
The problem rise only if you have 2 lines in the same chart, not with a single one!!!
Here is the java code to reproduce the problem.

public class MainView extends VerticalLayout {

    private static Logger logger = LogManager.getLogger();
    private Data yData = new Data();
    private Data yData2 = new Data();
    private Data xData = new Data();
    private transient XAxis xAxis = new XAxis(DataType.NUMBER);
    private transient YAxis yAxis = new YAxis(DataType.NUMBER);
    private transient LineChart lineChart1;
    private transient LineChart lineChart2;
    private transient MarkArea.Block markAreaBlock = new MarkArea.Block();
    private transient MarkArea markArea;
    Random random = new Random();
    private SOChart soChart = new SOChart();

    public MainView() {
        this.setAlignItems(Alignment.CENTER);
        Button button = new Button("Random", e -> updateData());
        button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
        addClassName("centered-content");
        add(button);

        // DEBUG 
        soChart = new SOChart() {
            @Override
            protected String customizeJSON(String json) throws Exception {
                logger.warn(json);
                return super.customizeJSON(json);
            }

            @Override
            protected String customizeDataJSON(String json, @SuppressWarnings("unused") AbstractDataProvider<?> data) throws Exception {
                logger.warn("Data for Serial {}: {}", data.getSerial(), json);
                return super.customizeDataJSON(json, data);
            }
        };
        // DEBUG
        
        soChart.setSize("100%", "900px");
        
        // Generating some random values for a LineChart
        for (int x = 0; x < 40; x++) {
            xData.add(x);
            yData.add(random.nextDouble());
            yData2.add(random.nextDouble());
        }
        xData.setName("X Values");
        yData.setName("Random Values");

        // Line chart is initialized with the generated XY values
        lineChart1 = new LineChart(xData, yData);
        lineChart2 = new LineChart(xData, yData2);
        lineChart1.setName("40 Random Values");

        // Add random Mark Area
        markAreaBlock.setName("Random Mark Area");
        markAreaBlock.setSides(xAxis, random.nextInt(40), random.nextInt(40));
        markAreaBlock.getItemStyle(true).setColor(new Color(255, 173, 177, 50));
        markArea = lineChart1.getMarkArea(true);
        markArea.add(markAreaBlock);

        RectangularCoordinate rc = new RectangularCoordinate(xAxis, yAxis);
        lineChart1.plotOn(rc);
        lineChart2.plotOn(rc);

        soChart.add(lineChart1, lineChart2);

        add(soChart);
    }

    private void updateData() {
        try {
            // Refresh Line Chart Angular Position
            yData.clear();
            yData2.clear();
            
            for (int x = 0; x < 40; x++) {
                yData.add(random.nextDouble());
                yData2.add(random.nextDouble());
            }
            yData.addAll(yData.stream().toList());

            markAreaBlock.setSides(xAxis, random.nextInt(40) , random.nextInt(40));
            soChart.updateData(markArea);
            soChart.updateData(xData, yData, yData2);
        } catch (Exception e) {
            logger.error(e);
        }
    }
}

Did you find something wrong in my code?

Regards,

S.

Hi,
You code looks fine (However, the line yData.addAll(yData.stream().toList()) inside the method updateData() doesn’t look logical to me).

I found a bug in my LitElement code and corrected it now in the latest version. Due to this, there was an exception thrown in the JS console when invoking updateData(...) methods. Can you please check your code in the latest version? v2.3.7

Hi Syam,

IT WORKS !!! I’m really happy !

Just to answer your questions:

  • yes definitely the code yData.addAll(yData.stream().toList()) is silly and not useful; just some copy & paste error;
  • your LitElement patch fix the problem at all!!! that was really the problem;
  • as I wrote in a previous discussion the use of Java Record brake the use of Jetty 9 but this is Jetty problem not your… I could survive recompiling your code.

Many thanks for your help!

Regards,

S.

Are you sure you are using the latest jetty version with all the recent patches?
You should at least use:

        <jetty.version>9.4.44.v20210927</jetty.version>

I am currently using this:

        <jetty.version>9.4.45.v20220203</jetty.version>

WOW,

you are right again, my problem I was using an old version of jetty the new one is fine with java record too !!!

Great!

Thanks a lot,
S.