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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
tuhinkarmakar3882 opened this issue Mar 27, 2025 · 5 comments
Labels
bug en This issue is in English pending We are not sure about whether this is a bug/new feature.

Comments

@tuhinkarmakar3882
Copy link

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

@echarts-bot echarts-bot bot added en This issue is in English pending We are not sure about whether this is a bug/new feature. labels Mar 27, 2025
@helgasoft
Copy link

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

@tuhinkarmakar3882
Copy link
Author

tuhinkarmakar3882 commented Mar 28, 2025

@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
Copy link
Author

tuhinkarmakar3882 commented Mar 28, 2025

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
Copy link

helgasoft commented Mar 29, 2025

@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
Copy link
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
Labels
bug en This issue is in English pending We are not sure about whether this is a bug/new feature.
Projects
None yet
Development

No branches or pull requests

2 participants