This is the 14th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021


See the Data Visualization column for a series of articles


Reference:

  • Learn D3: Shapes
  • Shapes (d3-shape)
  • D3-shape (Unofficial Chinese Translation)

Stacked bar charts and river charts (a variant of bar charts and area charts, respectively) are suitable for comparing multiple series of data at the same time. Stacks are available in D3. Instead of directly generating shapes, the stack generator converts raw data into data that is convenient for generating this type of chart. The stack generator is commonly used in conjunction with the area generator (for generating river charts, or can be used directly to manually generate bar charts).

Method of used3.stack()Create a stack generator (hereinafter calledstack)

It is both a method that can be called directly, passing data that needs to be visualized. The default data format passed is an array in which each element is an object containing multiple series of data (the property name is the series name and the property value is the specific data corresponding to that series in the current record)

// Sample raw data
// Each element of the array is a data record, which contains multiple series of data (sales of different types of fruit in that month)
const data = [
  {month: new Date(2015.0.1), apples: 3840.bananas: 1920},
  {month: new Date(2015.1.1), apples: 1600.bananas: 1440},];Copy the code

It is also an object that has several ways to set different parameters. It is usually used as a chain call, where the parameter must be the name of the series (default is an empty array, so the data is not converted to produce the corresponding series).

const stack = d3.stack()
    .keys(["apples"."bananas"])
Copy the code

Then, when the stack generator is called, the raw data is transformed, generating an array for each series in the returned result

const series = stack(data);
Copy the code
// Return the result, after the conversion to get each series of data
[
  // Each series of data is individually "extracted" to form an array
  // Apple series data
  [
    // Each element is apple's monthly sales data point
    // The first two values are similar to the lower and upper boundaries in the area diagram
    // The data object retains the original data source corresponding to the data point before the conversion
    [0.3840.data: {month: 2014-12-31T16:00Z, apples: 3840.bananas: 1920}].// Sales in December
    [0.1600.data: {month: 2015-01-31T16:00Z, apples: 1600.bananas: 1440}].// January sales
    key: "apples".// The key corresponding to this series (name)
    index: 0 // The sequence of the series in the series (i.e. corresponding to the sequence of the series stacked in the stack bar chart)].// bananas series data[[3840.5760.data: {month: 2014-12-31T16:00Z, apples: 3840.bananas: 1920}],
    [1600.3040.data: {month: 2015-01-31T16:00Z, apples: 1600.bananas: 1440}].key: "bananas".index: 1]]Copy the code

💡 As you can see from the simple example above, the stack generator is actually used to transform the raw data: Based on the order of the series, through the way of accumulation, from the original data are “stacked” data in the form of * * * * (if the original data is not coordinate variables such as graphics, convert the data cannot be directly used for “drawing”, may also need to be passed to the area of the generator, with the aid of appropriate scale transform map processing), and according to the series returns the result

Stack generators provide several ways to set different parameters:

  • Stack.keys ([keys]) sets the name of the series, passing an array of keys or a function that returns array keys. The usual data type for an array element is a string, but it can be any other data type.

  • Stack. value(valueFunc) Sets the series of data reading functions. When the stack generator is called to transform the raw data, each raw data d and the series name key (which is the element in stack.keys([keys]) array) are called as input arguments to get the corresponding series of data, so the default read function is as follows

    function value(d, key) {
      return d[key];
    }
    Copy the code

    If the series name in the original data is different from the set series name key; Or the format of the raw data is different from the default format (D3 default raw data each element of the array is a data record (an object), it contains multiple properties, and the property name is the name of the series, and the property value is the specific value of the series in the current record), the data read function needs to be set manually.

  • Stack.order (orderFunc) sets the sequence of stack sort functions corresponding to the sequence of stacks in the stack bar diagram. This function takes a series as an input parameter and returns an array with an index corresponding to the sort order of each series in keys.

    By default, stack.order(d3.stackOrderNone) is used to sort by an array of series names

    function orderNone(series) {
      let n = series.length;
      const o = new Array(n);
      while (--n >= 0) o[n] = n;
      return o;
    }
    Copy the code

    D3 also provides a variety of sorting functions:

    • d3.stackOrderAppearanceOf all the data points, the series with the largest value is at the bottom
    • d3.stackOrderAscendingThe sum of the values of the series is the smallest at the bottom
    • d3.stackOrderDescendingThe maximum sum of all values in the series is at the bottom
    • d3.stackOrderInsideOutOf all data points, the series with the largest value is in the middle (generally usedThe river chartC)
    • d3.stackOrderNoneDefault value, stack order by series name arraykeysThe order of
    • d3.stackOrderReverseArray of stack order and series nameskeysOrder instead

    If the built-in sorting function does not meet the requirements, you can also customize the sorting function

    💡 after running the sort function, each element in a series of data (also an array, also an object) has the index property. The collation function is run before the baseline function, so the default baseline value for each series of data is zero after the collation function is executed.

  • Stack. offset(offsetFunc) Sets a series of stack baseline functions. The input arguments to this function are series and order

    By default, stack.offset(d3.stackOffsetNone) is used to base zero.

    D3 also provides a variety of baseline functions:

    • d3.stackOffsetExpandTo standardize the data, the baseline is zero and the upper boundary is 1
    • d3.stackOffsetDivergingAllow positive and negative values to be stacked separately, with positive values stacked above zero and negative values stacked below zero
    • d3.stackOffsetNoneThe default value is zero as the baseline
    • d3.stackOffsetSilhouetteMove the baseline down so that the center of the river map is always zero
    • d3.stackOffsetWiggleMove the baseline to minimize the “wobble” of the series in the horizontal direction, generally used inThe river chartwithd3.stackOrderInsideOutCollation functions are used together.

    If the built-in baseline function does not meet the requirements, you can also customize the baseline function