//- The inline SVG graph is generated dynamically in Jade, based on JSON-formatted data. This makes it possible to generate a static illustration (as opposed to using a JS library that modifies the DOM on the client), while preserving the original data in the source.

// originally developed for: https://explosion.ai/blog/spacy-user-survey

// inspired by: https://css-tricks.com/how-to-make-charts-with-svg/


//- Graph data as JSON

- var graph = { title: "Do you use spaCy at work?", data: [ { label: "Yes, we use it in production.", value: 0.20, segment: 0.18 }, { label: "Yes, we use it in development.", value: 0.13, segment: 0.12 }, { label: "Yes, we use it for research.", value: 0.31, segment: 0.18 }, { label: "No, but we're planning to.", value: 0.17, segment: 0.14 }, { label: "No, and we're currently not planning to.", value: 0.14, segment: 0.14 } ], segments: { value: "everyone", segment: "non-researchers" } }


//- Settings

- bar_height = 30
- label_height = 40
- legend_height = 20
- spacing = 10
- bars = graph.data.length

- width = 800
- height = bars * (bar_height + label_height + spacing) + (legend_height + 4 * spacing) * (graph.segments ? 2 : 0)

- fill_value = "#1e1935"
- fill_segment = "url(#pattern)"


//- Markup

figure.c-graph
    figcaption.c-graph__title=graph.title

    svg(version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="chart" width=width height=height role="img" viewBox="0 0 #{width} #{height}" preserveAspectRatio="xMinYMin meet")

        defs
            pattern#pattern(patternUnits="userSpaceOnUse" width="10" height="10")
                image(xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+ICA8cmVjdCB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9IiMxRTE5MzUiLz4gIDxwYXRoIGQ9Ik0tMSwxIGwyLC0yICAgICAgICAgICBNMCwxMCBsMTAsLTEwICAgICAgICAgICBNOSwxMSBsMiwtMiIgc3Ryb2tlPSIjZmZmIiBzdHJva2Utd2lkdGg9IjEuNSIvPjwvc3ZnPg==" x="0" y="0" width="10" height="10")

        each bar, i in graph.data
            - y = (bar_height + spacing) * i + label_height * (i + 1) + spacing

            text.c-graph__label(x="0" y=(y - spacing))=bar.label

            g.c-graph__value
                - value = Math.round(bar.value * 100)
                - dy = bar_height / 1.35

                rect.c-graph__bar(width=(width / 100 * value) height=bar_height y=y fill=fill_value)
                text.c-graph__number.c-graph__number--value(x=(width * value / 100 + spacing) y=y dy=dy)
                    if bar.value_label
                        |  #{bar.value_label}

                    else
                        |  #{value}%

            if bar.segment && graph.segments
                - segment = Math.round(bar.segment * 100)

                g.c-graph__segment
                    rect.c-graph__bar(width=(width / 100 * segment) height=bar_height y=y fill=fill_segment)
                    text.c-graph__number(x=spacing y=y dy=dy)
                        if bar.segment_label
                            |  #{bar.segment_label}

                        else
                            |  #{segment}%

        if graph.segments
            g.c-graph__footer(x="0" y=(height - legend_height) height=legend_height dy=spacing)

                - y_value = height - 2 * (legend_height + spacing)
                - y_segment = height - legend_height - spacing

                rect.c-graph__legend-value(y=y_value width=legend_height height=legend_height fill=fill_value)
                text(x=(legend_height + spacing) y=y_value dy="1em")=graph.segments.value

                rect.c-graph__legend-segment(y=y_segment width=legend_height height=legend_height fill=fill_segment)
                text(x=(legend_height + spacing) y=y_segment dy="1em")=graph.segments.segment
View Compiled
$color-front: #1e1935
$color-back: #fff
$color-highlight: desaturate(lighten($color-front, 15), 5)
$font: "Poppins", Arial, sans-serif

.c-graph
    max-width: 100%
    padding: 25px
    
.c-graph__bar
    cursor: pointer
    transition: fill 0.15s ease

    .c-graph__value:hover &,
    .c-graph__segment:hover &
        fill: $color-highlight

.c-graph__value:hover
    .c-graph__number,
    & + .c-graph__segment .c-graph__bar
        fill: $color-highlight

.c-graph__number
    cursor: pointer
    font-weight: bold
    transition: opacity 0.25s ease

    .c-graph__value &
        fill: $color-front

    .c-graph__segment &
        fill: $color-back
        opacity: 0

    .c-graph__segment:hover &
        opacity: 1

.c-graph__value .c-graph__bar,
.c-graph__legend-value
    fill: $color-front

.c-graph__title
    font: bold 22px/#{1.375} $font

.c-graph__label
    font: 16px $font
 
.c-graph__footer
    font: 14px $font
    
.c-graph__number
    font: bold 18px $font

// Demo container and reset

body
    width: 100%
    height: 100%
    max-width: 100%
    display: flex
    justify-content: center
    align-items: center

*
    box-sizing: border-box
    -webkit-font-smoothing: antialiased
    border: 0
    margin: 0
    padding: 0
View Compiled

External CSS

  1. https://fonts.googleapis.com/css?family=Poppins:400,700

External JavaScript

This Pen doesn't use any external JavaScript resources.