Improve this doc View source

SPARQL Faceter - Client-Side Faceted Search Using SPARQL

The module provides a set of directives that work as facets, and a service that synchronizes them.

There are four different built-in facet types:

Custom facets can be implemented reasonably easily.

How it works

Facets are implemented as a directives. Each facet listens on its scope for changes in other facets, and emits its state when its value changes. The facets are responsible for maintaining their own state. In the following, "constraint" means a triple pattern that narrows the resultset down based on a facet value.

FacetHandler mediates the facet changes by listening to the facets' change events, and broadcasting the resulting constraints to all facets in the scope.

The facets are configured using the options attribute of the directive. Configuration options that are common to all facets are:

For other options, see the facets' individual documentation.

To make use of the constraints generated by the facets, a controller should listen for the update event sf-facets-changed (and possibly for the initial sf-initial-constraints). The argument sent with the event is an objectfollowing fields:

Example

Setup in the controller:

var vm = this;

// Define facets
vm.facets = {
    // Text facet
    name: {
        name: 'Name',
        facetId: 'name',
        predicate: '<http://www.w3.org/2004/02/skos/core#prefLabel>',
        enabled: true
    },
    // Date facet
    deathDate: {
        name: 'Time of Death',
        facetId: 'death',
        startPredicate: '<http://ldf.fi/schema/narc-menehtyneet1939-45/kuolinaika>',
        endPredicate: '<http://ldf.fi/schema/narc-menehtyneet1939-45/kuolinaika>',
        min: '1939-10-01',
        max: '1989-12-31',
        enabled: true
    },
    // Basic facet
    profession: {
        name: 'Ammatti',
        facetId: 'occupation',
        predicate: '<http://ldf.fi/schema/narc-menehtyneet1939-45/ammatti>',
        enabled: true
    },
    // Basic facet with property path
    source: {
        name: 'Source',
        facetId: 'source',
        predicate: '^<http://www.cidoc-crm.org/cidoc-crm/P70i_is_documented_in>/<http://purl.org/dc/elements/1.1/source>',
        enabled: true
    },
    // Basic facet with labels in another service.
    birthMunicipality: {
        name: 'Birth Municipality',
        services: ['<http://ldf.fi/pnr/sparql>'],
        facetId: 'birthplace',
        predicate: '<http://ldf.fi/schema/narc-menehtyneet1939-45/synnyinkunta>',
        enabled: false
    },
    // Hierarchical facet
    rank: {
        name: 'Rank',
        facetId: 'rank',
        predicate: '<http://ldf.fi/schema/narc-menehtyneet1939-45/sotilasarvo>',
        hierarchy: '<http://purl.org/dc/terms/isPartOf>*|(<http://rdf.muninn-project.org/ontologies/organization#equalTo>/<http://purl.org/dc/terms/isPartOf>*)',
        enabled: true,
        classes: [
            '<http://ldf.fi/warsa/actors/ranks/Upseeri>',
            '<http://ldf.fi/warsa/actors/ranks/Aliupseeri>',
            '<http://ldf.fi/warsa/actors/ranks/Miehistoe>',
            '<http://ldf.fi/warsa/actors/ranks/Jaeaekaeriarvo>',
            '<http://ldf.fi/warsa/actors/ranks/Virkahenkiloestoe>',
            '<http://ldf.fi/warsa/actors/ranks/Lottahenkiloestoe>',
            '<http://ldf.fi/warsa/actors/ranks/Muu>'
        ]
    }
};

// Define common options
vm.options = {
    scope: $scope,
    endpointUrl: 'http://ldf.fi/warsa/sparql',
    rdfClass: '<http://ldf.fi/schema/narc-menehtyneet1939-45/DeathRecord>',
    constraint: '?id skos:prefLabel ?name .',
    preferredLang : 'fi'
};

// Define a function that handles updates.
// 'dataService' is some service that fetches results based on the facet selections.
function updateResults(event, facetState) {
    dataService.getResults(facetState.constraints).then(function(results) {
        vm.results = results;
    }
}

// Listen for the update event
$scope.$on('sf-facet-constraints', updateResults);

// Listen for initial state
var initListener = $scope.$on('sf-initial-constraints', function(event, state) {
    updateResults(event, state);
    // Only listen once for the init event
    initListener();
});

// Initialize the facet handler:
vm.handler = new FacetHandler(vm.options);

Setup the facets in the template:

<seco-text-facet
  data-options="vm.facets.name">
</seco-text-facet>
<seco-timespan-facet
  data-options="vm.facets.deathDate">
</seco-timespan-facet>
<seco-basic-facet
  data-options="vm.facets.source">
</seco-basic-facet>
<seco-basic-facet
  data-options="vm.facets.profession">
</seco-basic-facet>
<seco-basic-facet
  data-options="vm.facets.birthMunicipality">
</seco-basic-facet>
<seco-basic-facet
  data-options="vm.facets.principalAbode">
</seco-basic-facet>
<seco-hierarchy-facet
  data-options="vm.facets.rank">
</seco-hierarchy-facet>