Home > Mobile >  D3 Sunburst - How to map custom color to path
D3 Sunburst - How to map custom color to path

Time:11-25

I’m currently building a D3 Sunburst Vue component and I’m using the npm package vue-d3-sunburst for that. The documentation for the package can be found here:

https://www.npmjs.com/package/vue-d3-sunburst

The documentation says there is a get-category-for-color function which is used to map an item and its color like this: (nodeD3: Object) => category: Number | String By default use the node name

I’m completely having a moment here and just can’t figure out how to get the color value of each node applied to each path and I'm wondering if anybody can help?

const {
  sunburst,
  highlightOnHover
} = window['vue-d3-sunburst'];
window.Vue.config.productionTip = false;

/**
 * FlavorWheel Component.
 */
new window.Vue({
  el: "#app",
  name: "flavor-wheel",
  components: {
    highlightOnHover,
    sunburst,
  },
  props: {
    /**
     * Cupping notes.
     */
    cuppingNotes: {
      type: Object,
      default () {
        return {
          name: "base",
          children: [{
              name: "Fruity",
              color: "#da1f24",
              children: [{
                  name: "Berry",
                  color: "#de4b52",
                  children: [{
                      name: "Blackberry",
                      color: "#3e0316",
                      size: 1,
                    },
                    {
                      name: "Blueberry",
                      color: "#6469af",
                      size: 1,
                    },
                  ],
                },
                {
                  name: "Dried fruit",
                  color: "#ca4a44",
                  children: [{
                      name: "Raisin",
                      color: "#b43b54",
                      size: 1,
                    },
                    {
                      name: "Prune",
                      color: "#a4456e",
                      size: 1,
                    },
                  ],
                },
                {
                  name: "Other fruit",
                  color: "#f2684b",
                  children: [{
                      name: "Cherry",
                      color: "#e73351",
                      size: 1,
                    },
                    {
                      name: "Pineapple",
                      color: "#f99a18",
                      size: 1,
                    },
                    {
                      name: "Peach",
                      color: "#f68a5b",
                      size: 1,
                    },
                  ],
                },
              ],
            },
            {
              name: "Sour/Fermented",
              color: "#ebb20f",
              children: [{
                name: "Sour",
                color: "#e1c217",
                children: [{
                    name: "Alcohol/Fermented",
                    color: "#9fa81a",
                    size: 1,
                  },
                  {
                    name: "Citric acid",
                    color: "#f9ee01",
                    size: 1,
                  },
                ],
              }, ],
            },
          ],
        };
      },
    },
  },
  data() {
    return {
      data: this.cuppingNotes,
    };
  },
  methods: {
    /**
     * Function used to map an item and its color
     */
    getColorValue() {},
  },
  template: `
    <div >
      <sunburst
        
        :data="data"
        :showLabels="true"
        :centralCircleRelativeSize="10"
        :getCategoryForColor="getColorValue()"
      >
        <template slot-scope="{ on, actions }">
          <highlightOnHover v-bind="{ on, actions }" />
        </template>
      </sunburst>
    </div>
  `
});
.flavor-wheel {
  width: 500px !important;
  height: 500px !important;
  margin: 0 auto;
}

.flavor-wheel text {
  fill: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-d3-sunburst.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vue-d3-sunburst.css">


<div id="app"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I'm not incredibly familiar with Vue, but I'm pretty sure the problem is as follows:

Instead of calling the function in the HTML, you need to pass it as a property. The difference is that if you add the brackets, the result of the function will be passed to VueJS, not the function itself. Then, you'll be able to access the arguments of the function just the way you'd expect.


EDIT

The name getCategoryForColor should have tipped me off, but what happens is actually not what you expect. The getCategoryForColor function expects to receive any string or value that represents that "category" to which the cell belongs. Those categories are then mapped to a colorScale function which makes sure a valid color is generated for every category, and that elements with the same category get the same value.

You actually jumped the gun a little on that bit, because you already specified what the color should be! So in order to fix that part, I also overwrote the color scheme to simply return whatever it was passed. Now, the correct colors are applied.

const {
  sunburst,
  highlightOnHover
} = window['vue-d3-sunburst'];
window.Vue.config.productionTip = false;

/**
 * FlavorWheel Component.
 */
new window.Vue({
  el: "#app",
  name: "flavor-wheel",
  components: {
    highlightOnHover,
    sunburst,
  },
  props: {
    /**
     * Cupping notes.
     */
    cuppingNotes: {
      type: Object,
      default () {
        return {
          name: "base",
          children: [{
              name: "Fruity",
              color: "#da1f24",
              children: [{
                  name: "Berry",
                  color: "#de4b52",
                  children: [{
                      name: "Blackberry",
                      color: "#3e0316",
                      size: 1,
                    },
                    {
                      name: "Blueberry",
                      color: "#6469af",
                      size: 1,
                    },
                  ],
                },
                {
                  name: "Dried fruit",
                  color: "#ca4a44",
                  children: [{
                      name: "Raisin",
                      color: "#b43b54",
                      size: 1,
                    },
                    {
                      name: "Prune",
                      color: "#a4456e",
                      size: 1,
                    },
                  ],
                },
                {
                  name: "Other fruit",
                  color: "#f2684b",
                  children: [{
                      name: "Cherry",
                      color: "#e73351",
                      size: 1,
                    },
                    {
                      name: "Pineapple",
                      color: "#f99a18",
                      size: 1,
                    },
                    {
                      name: "Peach",
                      color: "#f68a5b",
                      size: 1,
                    },
                  ],
                },
              ],
            },
            {
              name: "Sour/Fermented",
              color: "#ebb20f",
              children: [{
                name: "Sour",
                color: "#e1c217",
                children: [{
                    name: "Alcohol/Fermented",
                    color: "#9fa81a",
                    size: 1,
                  },
                  {
                    name: "Citric acid",
                    color: "#f9ee01",
                    size: 1,
                  },
                ],
              }, ],
            },
          ],
        };
      },
    },
  },
  data() {
    return {
      data: this.cuppingNotes,
    };
  },
  methods: {
    /**
     * Function used to map an item and its color
     */
    getColorValue(v) {
      return v.color;
    },
    colorScale(col) {
      return col;
    }
  },
  template: `
    <div >
      <sunburst
        
        :data="data"
        :showLabels="true"
        :centralCircleRelativeSize="10"
        :getCategoryForColor="getColorValue"
        :colorScale="colorScale"
      >
        <template slot-scope="{ on, actions }">
          <highlightOnHover v-bind="{ on, actions }" />
        </template>
      </sunburst>
    </div>
  `
});
.flavor-wheel {
  width: 500px !important;
  height: 500px !important;
  margin: 0 auto;
}

.flavor-wheel text {
  fill: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-d3-sunburst.umd.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vue-d3-sunburst.css">


<div id="app"></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related