1

The website I'm developing needs to comply with the WCAG 2.0 guidelines, meaning a person should be able to access all information on the site using a screen reader. Since it's a BI dashboard making heavy use of Kendo Charts it failed the test.

I need a way for screen readers to be able to read the Kendo Charts on my website, while reusing the chart's datasource.

Nic
  • 12,220
  • 20
  • 77
  • 105

1 Answers1

0

I solved this by automatically generating a table for each chart on the page.

Create partial view which generates HTML table

@{
    var divId = Guid.NewGuid().ToString();
    var tableId = Guid.NewGuid().ToString();
    var templateId = Guid.NewGuid().ToString();
}
/* Chart ID */
@model string

<div id="@divId" class="hiddenTable"></div>

<script>
    (function () {
        var template = kendo.template($("#@templateId").html());
        var chartData = $("#@Model").data("kendoChart").dataSource;
        $("#@divId").prepend(template(chartData.data()));
    })();
</script>

<script id="@templateId" type="text/x-kendo-tmpl">
    # var columnNames = Chart.getColumnNamesFromData(data) #
    <table id="@tableId">
        <thead>
            <tr>
                # for(var columnIndex = 0; columnIndex < columnNames.length; columnIndex++) { #
                    <th scope="col">#= S(columnNames[columnIndex]).humanize().s #</th>
                # } #
            </tr>
        </thead>
        <tbody>
            # for(var i = 0, len = data.length; i < len; i++) { #
                # if (data[i][columnNames[0]] != undefined) { #
                    <tr>
                        # for(var columnIndex = 0; columnIndex < columnNames.length; columnIndex++) { #
                            # if(columnNames[columnIndex] == 'Date') { #
                                <th scope="row">#= kendo.toString(data[i][columnNames[columnIndex]], "MMMM yyyy") #</th>
                            #} else { #
                                <td>#= kendo.toString(data[i][columnNames[columnIndex]] != undefined ? data[i][columnNames[columnIndex]] : 0, "n1") #</td>
                            # } #
                        # } #
                    </tr>
                # } #
            # } #
        </tbody>
  </table>
</script>

Add CSS to hide table from view

.hiddenTable {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

Add img role to chart

@(Html.Kendo().Chart<MyModel>()
    .Name(Guid.NewGuid().ToString())
    .HtmlAttributes(new { role = "img" })
    .DataSource(ds => ds
        .Read("GetData", "Home")
    )
)

Result

Result HTML

Nic
  • 12,220
  • 20
  • 77
  • 105