Skip to content

[Bug] BAR Chart with Log Axis enabled, seems to perform log transformation on the DataSet Itself and therefore Renders incorrect chart. #20868

Open
@tuhinkarmakar3882

Description

@tuhinkarmakar3882

Version

5.6.0

Link to Minimal Reproduction

https://echarts.apache.org/examples/en/editor.html?c=bar-simple&code=PYBwLglsB2AEC8sDeAoWtJgDYFMBcya6GOAHmAQOQBqOATpAMYCGWsAQs3bAMIAWXMLADuEMH1gAZYAHNYAZRa5KAGiLowZMPLABPXAVTFiAMxjaIAL3ywATAAZ1sAL5FnajcGBZIIQ07A6CBkZeipmUggAZ1UnCOiABWAIaE06f2MNXRAbSiiBABNgYUonV3R3IhkggoziXBMKWEoAZgBSWOMgmT4mygAWDo9iACNgMDBgAFsqds7iRnNmFMlmEZwsAkCAVxw3YdIAQUiouqycqhZNGWA6XXn0AuYwZgIAbUoeZ5wbu9hD1TNL7XW66DiAz7fX5gngQ4E_UGwAAilAAusN0NBmFNcvDfhAcDEMbAsTjpFcoNAqFMIAUCspiaScABxZh-WAtACsxPiUVW602hEysDMqXkVhsAEZ-mV9kRdMdomcMNlclhZA8SdjctRWLsorAABTquRRJQ4ACUmqZ5OelOptPpOGt2tZ7M59mJNKpsHsADp7IHJTyTvyNsr0KKLNYCJLbLKKsMovQCadYG8nEZMkyqPIU4TYJLNedciMuMXYE8Xu9_UGVL6A8GG03JeinOgxDgpjp9DYs8LFur0s0AMS2EwAdhwBQAHBX0GM6AV6AAlZgFCDbNNvbmwXee32o9suYnoLBrcNC4WwfLFLZ0Xan4ggYBRMT25qTEClYXlYh_o9nAAbiAA

Steps to Reproduce

As you can see in the example, the dataset contains data: [0.001, 0.01, 0.1, 1].

Issue 1: When using Log axis, The Chart seems to transform the dataset into the following => [0.001, 0.01, 0.1, 1].map(Math.log). This should not happen. Ideally only the Scale is supposed to be adjusted and not the data.

I tried the same thing with HighCharts and there it seems to work fine.

Issue 2: The Y axis min cannot be set to 0. Why would that be the case? It should not shift the chart. Rather it should just start rendering the bar chart from there itself.

Image

Below is a sample HTML code to show highcharts & Echarts together to prove the point and issue:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Highcharts vs ECharts Comparison</title>

    <!-- Include both libraries -->
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>

    <style>
        .container-wrapper {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            padding: 20px;
            justify-content: center;
        }

        .chart-container {
            width: 800px;
            height: 500px;
        }

        .chart-title {
            text-align: center;
            font-family: Arial, sans-serif;
            font-size: 24px;
            margin-bottom: 10px;
            color: #333;
        }
    </style>
</head>
<body>
    <div class="container-wrapper">
        <div>
            <div class="chart-title">Highcharts Implementation</div>
            <div id="highcharts-container" class="chart-container"></div>
        </div>
        <div>
            <div class="chart-title">ECharts Implementation</div>
            <div id="echarts-container" class="chart-container"></div>
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // Highcharts Implementation
            Highcharts.chart('highcharts-container', {
                chart: {
                    type: 'column'
                },
                title: {
                    text: 'Vertical Bar Chart with Log Scale',
                    style: {
                        fontSize: '20px'
                    }
                },
                xAxis: {
                    categories: ['Category A', 'Category B', 'Category C', 'Category D'],
                    title: {
                        text: 'Categories'
                    },
                    labels: {
                        style: {
                            fontSize: '14px'
                        }
                    }
                },
                yAxis: {
                    type: 'logarithmic',
                    title: {
                        text: 'Values (log scale)'
                    },
                    minorTickInterval: 0.1,
                    gridLineWidth: 1,
                    min: 0.0001,
                    labels: {
                        style: {
                            fontSize: '12px'
                        }
                    }
                },
                tooltip: {
                    headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
                    pointFormat: '<tr><td style="color:{series.color};padding:0">{series.name}: </td>' +
                        '<td style="padding:0"><b>{point.y}</b></td></tr>',
                    footerFormat: '</table>',
                    shared: true,
                    useHTML: true
                },
                plotOptions: {
                    column: {
                        pointPadding: 0.2,
                        borderWidth: 0,
                        borderRadius: 5,
                        dataLabels: {
                            enabled: true,
                            format: '{point.y}'
                        }
                    }
                },
                series: [{
                    name: 'Series 1',
                    data: [0.001, 0.01, 0.1, 1],
                    color: '#2f7ed8'
                }],
                credits: {
                    enabled: false
                }
            });

            // ECharts Implementation
            const eChart = echarts.init(document.getElementById('echarts-container'));

            const eChartOption = {
                title: {
                    text: 'Vertical Bar Chart with Log Scale',
                    textStyle: {
                        fontSize: 20
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'shadow'
                    }
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: ['Category A', 'Category B', 'Category C', 'Category D'],
                    name: 'Categories',
                    nameLocation: 'middle',
                    nameGap: 35,
                    axisLabel: {
                        fontSize: 14
                    }
                },
                yAxis: {
                    type: 'log',
                    name: 'Values (log scale)',
                    nameLocation: 'middle',
                    nameGap: 50,
                    min: 0.0001,
                    axisLabel: {
                        fontSize: 12
                    }
                },
                series: [{
                    name: 'Series 1',
                    type: 'bar',
                    data: [0.001, 0.01, 0.1, 1],
                    itemStyle: {
                        color: '#2f7ed8',
                        borderRadius: [5, 5, 0, 0]
                    },
                    label: {
                        show: true,
                        position: 'top'
                    }
                }]
            };

            eChart.setOption(eChartOption);

            // Make both charts responsive
            window.addEventListener('resize', function() {
                eChart.resize();
            });
        });
    </script>
</body>
</html>

Current Behavior

As you can see in the example, the dataset contains data: [0.001, 0.01, 0.1, 1].

For Issue 1: When using Log axis, The Chart seems to transform the dataset into the following => [0.001, 0.01, 0.1, 1].map(Math.log)

For Issue 2: The Y axis min cannot be set to 0. Why would that be the case? It should not shift the chart. Rather it should just start rendering the bar chart from there itself.


Image

Expected Behavior

As you can see in the example, the dataset contains data: [0.001, 0.01, 0.1, 1].

For Issue 1: Ideally only the Scale is supposed to be adjusted and not the data. I tried the same thing with HighCharts and there it seems to work fine.

For Issue 2: The Y axis min should be allowed to be set as any number. As it's just the axis value and no Log should be performed there.

Environment

- OS: MacOS
- Browser: Chrome 134.0.6998.118 (Official Build) (arm64)
- Framework: Vanilla JS

Any additional comments?

No response

Activity

added
enThis issue is in English
pendingWe are not sure about whether this is a bug/new feature.
on Mar 27, 2025
helgasoft

helgasoft commented on Mar 27, 2025

@helgasoft

replace min with startValue
📌 please close issue if problem solved.

tuhinkarmakar3882

tuhinkarmakar3882 commented on Mar 28, 2025

@tuhinkarmakar3882
Author

@helgasoft Thank you so much for the reply. I just tried this and here're the results.

  1. Using StartValue instead of min indeed make the chart look normal. But, I'm curious to know, why would this fixes this?
  2. If the data set contains negative values e.g. this example, then that doesn't work. Shouldn't just a bar just come down below? In this example, the entire chart breaks.
  3. Why would setting min to 0 changes the Chart completely, by removing the other bars? See Example
  4. Why does setting startValue to 0 fails to render the chart? See Example
tuhinkarmakar3882

tuhinkarmakar3882 commented on Mar 28, 2025

@tuhinkarmakar3882
Author

FYI. Just found this JSFiddle Link for HighCharts which showcases, Log Axis with Negative values.

Can we take any inspiration from here? May be add something like this as part of the ECharts Library?


At the core, the script listens for the axis initialization event. When an axis is created and if it is a logarithmic axis with the custom option enabled (allowNegativeLog: true), the extension adjusts several core functions. First, it disables the usual constraint that only positive values are permitted, allowing the chart to process negative inputs without errors.

Two key functions are overridden: the conversion from logarithmic to linear space (log2lin) and its inverse (lin2log). In these functions, the absolute value of the input is used to perform the logarithmic transformation. Additionally, if the value is negative, the result of the transformation is negated. There are also adjustments for numbers less than 10, ensuring that the conversion produces a smoother transition between negative and positive values.

Another significant change is made to how tick positions are calculated on the logarithmic axis. The method for determining tick marks (getLogTickPositions) is wrapped with custom logic that accounts for negative values. Instead of using the standard procedure—which would normally exclude negative values—the extension generates tick positions symmetrically for negative and positive parts of the axis, ensuring that the ticks are appropriately placed even when the data spans both sides of zero.

Finally, the code demonstrates the usage of the modified axis by creating a Highcharts chart. In the chart configuration, the y-axis is set to a logarithmic type and the custom option is enabled. The data series includes a range of values from -1000 to 1000, illustrating how the chart can now display both negative and positive values on a logarithmic scale.

helgasoft

helgasoft commented on Mar 29, 2025

@helgasoft

@tuhinkarmakar3882, good of you to investigate this. I am unable to respond to all of your questions, but negative values has been a long-standing feature request #17459, #15558.
Noticed @Antti-Palola did already work on a fix PR#20872. Hope it gets approved ASAP, why not even for incoming v.6.0.

Got inspired to hack a workaround - Demo. It works for scatter and bar series, but not for line (and log line crossing zero does not make much sense anyway).
Image

tuhinkarmakar3882

tuhinkarmakar3882 commented on Apr 3, 2025

@tuhinkarmakar3882
Author

@helgasoft Interesting finding! Let's hope for the that the changes gets merged. Until then, we'll have to use such workaround.

The example code that you provided, uses ECharts to render a dual-grid logarithmic bar chart that distinguishes positive and negative values. It first imports the ECharts library, selects an HTML element with the id "main," and initializes the chart instance.

A set of sample data and category labels is defined. A helper function computes the closest power of 10 for each data point to determine a suitable starting value for the logarithmic y-axes. The data is then split into two arrays: one for positive values and one for negative values (converted to their absolute values for proper logarithmic scaling).

The configuration defines two grids and matching axes. The top grid (with a hidden x-axis) displays positive values using a standard logarithmic scale, while the bottom grid displays negative values on an inverted logarithmic scale with custom tooltips and labels that prepend a minus sign. Finally, the chart is rendered by applying this configuration to the initialized ECharts instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugenThis issue is in EnglishpendingWe are not sure about whether this is a bug/new feature.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @helgasoft@tuhinkarmakar3882

        Issue actions

          [Bug] BAR Chart with Log Axis enabled, seems to perform log transformation on the DataSet Itself and therefore Renders incorrect chart. · Issue #20868 · apache/echarts