0

Using the Blazor.ChartJs library, I have a series of horizontal stacked bar charts, the purpose of which is to show the percentage complete. The red portion is the yearly goal and the blue is actual number achieved so far:

Chart 1

The first chart could have a goal of $10,000,000, the second $3,000,000, the third $7,000,000, etc. But I would like each chart to expand to the end of the table cell in which it is contained because I don't care about the numbers, just the percentages:

Chart 2

As you can tell in the first chart, the numbers are stopping before the end of the cell. I am adding the charts to HTML table cells, one for each statistic I'm tracking:

<table>
    <tbody>
        <tr>
            <td></td>
            <td>% Complete</td>
        </tr>
        @for (int i = 0; i < typeOfProject.Count; i++)
        {
            <tr>
                <td><Chart Config="_configs[i]" Height="8" /></td>
                <td>@String.Format("{0:P0}", percentagesComplete[i])</td>
            </tr>
        }
    </tbody>
</table>

I build the _configs collection using a method that returns a BarConfig options, and the configurations are identical for all charts. I have experimented with the Responsive and MaintainAspectRatio properties, but this does not seem to affect the results.

config = new BarConfig
{
    Options = new BarOptions
    {
        MaintainAspectRatio = true,
        Responsive = true,
        Legend = new Legend
        {
            Display = false
        },
        Scales = new BarScales
        {
            XAxes = new List<CartesianAxis>
            {
                new BarLinearCartesianAxis
                {
                    Stacked = true,
                    OffsetGridLines = false,
                    Offset = false,
                    Display = AxisDisplay.False
                }
            },
            YAxes = new List<CartesianAxis>
            {
                new BarCategoryAxis
                {
                    Stacked = true,
                    OffsetGridLines = false,
                    Offset = false, 
                    Display = AxisDisplay.False,
                    BarThickness = 45
                }
            }
        }
    }

I have also add a div tag around the Canvas object in each cell as mentioned in this question, but that wasn't the solution to my problem.

How can I expand the bars to the end of the canvas in each cell?

ScottSto
  • 611
  • 10
  • 22

1 Answers1

0

I created my own code to do this because I could not get the chart width to consistently expand to the end of the table cell. The requirements changed slightly as well, so I needed to draw an empty rectangle representing 100% of the goal and then filling the rectangle with a percentage of how complete the goal was.

First, I have a JavaScript method that gets the width of the canvas, calculates how many pixels to draw based on that width and the "value" variable (which is a percentage), then uses the context to first draw a clear rectangle. It draws a filled rectangle representing the progress to the goal:

 function buildCanvas(canvasId, value) {
    var canvasWidth = document.getElementById(canvasId).offsetWidth;
    var calculatedWidth = parseInt(canvasWidth * value);

    var canvasToDraw = document.querySelector('#' + canvasId);
    const ctx1 = canvasToDraw.getContext('2d');
    ctx1.clearRect(0, 0, 300, 150);

    ctx1.fillStyle = 'rgba(173, 116, 76, 1.0)';
    ctx1.fillRect(0, 0, calculatedWidth, 150);
}

I define the chart that I want to draw:

<canvas id="chart" style="border: 1px solid #AD744C; height: 18px; width: 300px">

I then inject IJSRuntime and call the JavaScript method to draw the rectangle, the value being the goal divided by the value to get a percentage:

@inject IJSRuntime JsRuntime    
...
JsRuntime.InvokeAsync<string>("buildCanvas", $"chart", $"{value}");
ScottSto
  • 611
  • 10
  • 22