How to build a combo bar/line chart

I’m having some trouble creating a combo bar/line chart. Per the linked sample, I believe I just need to add 2 datasets to the datasets formula. I’m able to get 2 datasets created as 2 bars (see attached Figure1.png) but as soon as I change the second dataset to type:line the chart breaks (see attached Figure2p.png). Am I doing something wrong, is this a limitation, or is this a bug?

For added context, I am trying to create a bar chart that illustrates current data point compared to a goal data point. Picture those fund raising scales where your goal might be $1,000 and current fundraising is at $750. The bar would be $750 here, the line would be $1,000, and the bar would be able to exceed the $1,000 goal. I imagine it would be easy to do with the ChartJS annotation plugin, but I’m not fluent enough to register and install that plugin.

Figure 1

Figure 2

Hi @archenia_jsanchez :wave:

2 questions:

1- Have you tried testing your two data sets in the Charts.js docs directly?

This can help a lot because once you know what Charts.js expects to display the data in a way you want, it’s easier to write the correct formula in WeWeb.

2- Could you “unfold” the objects in the Current value of your Labels, Datassets, and Options in WeWeb?

This will help us see what data is being passed to the Charts.js plugin and help you identify where things might be going wrong.

Hi Joyce. My apologies for not getting back to you sooner. So, the above solution was a alternative solution to something that I have since explored ChartJS Annotation plugin to solve (see my post here for more on that). I don’t have the work to go back to and reference to answer your questions, but I can try to answer from memory.

  1. I had not tried testing the 2 datasets in ChartJS directly; it wasn’t until after that I really started building my charts in VS Code first and then importing them in

  2. This is where my memory will mostly fail me. Labels was likely an empty array given I didn’t want axis labels or a legend to appear. Figure 2 above shows what was in Datasets and as for Options thats the one that is probably lost.

We probably don’t need to resolve this one, given I found a workaround with the Annotations plugin, but I wanted to close the loop and provide some insight for future community members.

1 Like

Awesome! Thanks so much for taking the time to provide some feedback on this topic for future readers. Really appreciate it :pray:

Hi !
Any idea on how to di that ?
The chartjs component works well in advanced mode if I configure all the dataset data without specifying the “type”. It then displays 2 datasets in “bar” mode. But if I specify the chart type, it doesn’t display anything.


If I do the same thing on the chartjs doc, it works:

Hi @Geoffroy :wave:

For some reason, it seems that:

  • when you use the bar chart UI element in WeWeb in combination with a type: "line" chart in the dataset it doesn’t work BUT…
  • when you use the line chart UI element in combination with a type: "bar" it does :point_down:

Not sure if it’s intended or not. I’ll create an internal bug ticket so the team can investigate.

In the meantime, I think you’ll be able to build your chart if you try the same thing with a Chart - Line UI element in WeWeb and add the type: "bar" to your first dataset (instead of type: "line" to your second dataset).

Let me know if not!

1 Like

Yes, it works with line chart. Thanks @Joyce

1 Like

Hey everyone. I was about to create a seprate post but found this post already existed. To be clear:

If you want to create a combination chart in WeWeb then you HAVE to use the line chart and add bars, not the other way around or the chart will break (and become unrecoverable).

I think it’s important to make clear because like most, by default, I was selected the bar chart and trying to add a line object, which does not work.

2 Likes

is there a way to use charts.js for custom charts that are not in plugin and how can we do it ?

I’m assuming by “custom” you’re looking to do either a Bubble or a Radar chart, given those are the 2 that aren’t available in the plugin. Otherwise, it looks like most of the charts listed on Chart.js Samples | Chart.js should be possible with whats available in the plugin (at least according to the config > type) with some advanced tinkering.

When you toggle to “Advanced” you’ll get more granular control over the Labels, Datasets, and Options properties, which is where I’ve been able to apply a lot of my customizations. In the screenshot below, you’ll see where to change your “Mode” and how I’ve got no-code formulas (better readability for non-technical folks, particularly when mapping a collection to the property) mapped to the Labels and Datasets and a JS formula mapped to the Options. More on each below.

Labels - This is the simplest. In the example below this is the array of label values across the horizontal axis, eg [Jul 15, Jul 16, Jul 17, etc] .

Datasets - an array of object(s), where each object can be its own dataset, and where you can control the styling of each dataset. In the example below, I have a dataset for each bar, as well as one for the line, for a total of 3 objects. Some of the properties used here include: data (obviously the most important), type, order, label, stack, grouped, backgroundColor, categoryPercentage, barPercentage, borderColor, yAxisID, tension, and pointRadius. Note, some of these are applied to type:bar and some to type:line but I wanted to introduce the range of control you can apply. I recommend inspecting the Setup tab of the code snippets that accompany all the samples on Chart JS for additional ideas.

Options - this is where I do MOST of my customizations and have found its easier to switch from the no-code formula to JS formulas instead. This, plus a bit of knowledge of what is available in Chart JS, and some assistance from an AI like ChatGPT or Claude has unlocked a lot. Just take a look at the “formula” below to see what I’m

function formatPercentage(value) {
  // Use Intl.NumberFormat to format as a percentage with no decimal places
  const formatter = new Intl.NumberFormat('en-US', {
    style: 'percent',
    minimumFractionDigits: 0,
    maximumFractionDigits: 0,
  });
  return formatter.format(value);
}

const options = {
  responsive: true,
  maintainAspectRatio: false,
  interaction: {
    mode: 'index',
    intersect: false,
  },
  stacked: false,
  borderRadius: 2,
  plugins: {
    title: {
      display: true,
      text: "Lorem Ipsum",
      font: {
        size: 15,
        family: "'Inter', 'Helvetica', 'Arial', sans-serif"
      }
    },
    legend: {
      display: true,
      onClick: null,
      position: "bottom",
      reverse: true,
      labels: {
        boxWidth: 10
      }
    },
    tooltip: {
      callbacks: {
        label: (context) => {
          // Check if the dataset index is associated with the y1 axis
          if (context.datasetIndex === 2) {
            // Format the tooltip label as a percentage
            const formattedPercentage = formatPercentage(context.parsed.y);
            return context.dataset.label + ': ' + formattedPercentage;
          } else {
            // For other datasets, use the default label
            return context.dataset.label + ': ' + context.parsed.y;
          }
        },
      },
    }
  },
  scales: {
    x: {
      grid: {
        display: false
      }
    },
    y: {
      type: 'linear',
      display: true,
      grid: {
        display: false
      },
      position: 'left',
    },
    y1: {
      type: 'linear',
      display: true,
      grid: {
        display: false
      },
      position: 'right',
      beginAtZero: true,
      ticks: {
        callback: (value) => {
          return formatPercentage(value);
        }
      }
    },
  }
};

return options;

Sorry for the novel, but I hope this sheds light on the possibilities. Hope it helps.

1 Like

Hey John,

great example, thank you!