Mostafa Rahmati
Mostafa Rahmati

Reputation: 302

have different bar colors in vuetify sparkline

I have this sparkline component in my vue/vuetify project and I want to change the bars according to the value that the bar holds here is what I have: What I have

I want to change the color of bars less than 0 to red

here's a simplified version of my code:

 <v-sparkline
     :gradient="['#5EF7B7','#0CBB72']"
     type="bar"
     show-labels
     auto-line-width
     :value="value"
  ></v-sparkline>

data that holds the values:

value: [0, 2, 5, 9, 5, 10, 3, 5, -4, -10, 1, 8, 2, 9, 0]

my question is that is there a way to have different bar colors for different values?

Upvotes: 1

Views: 2157

Answers (1)

User 28
User 28

Reputation: 5158

Since VSparkline did not just draw a bar and fill gradient directly instead it uses clipPath to see the gradient behind so I don't think there is an easy way to do this.

Fortunately, Vuetify is allow us to extend their components easily. So we can extend VSparkline to achieve your requirement.

Example Code:

import { VSparkline } from "vuetify/lib";
import { genBars } from "vuetify/src/components/VSparkline/helpers/core";

export default {
  extends: VSparkline,
  props: {
    barColors: {
      type: Array
    }
  },
  methods: {
    genBars() {
      if (!this.value || this.totalValues < 2) return;

      let bars = genBars(this.normalizedValues, this.boundary);
      let offsetX = (Math.abs(bars[0].x - bars[1].x) - this._lineWidth) / 2;
      let width = this._lineWidth;

      bars = bars.map((bar, index) => ({
        ...bar,
        fill: this.barColors[index]
      }));

      return this.$createElement(
        "svg",
        {
          attrs: {
            display: "block",
            viewBox: `0 0 ${this.totalWidth} ${this.totalHeight}`
          }
        },
        [
          ...bars.map(item =>
            this.$createElement("rect", {
              attrs: {
                x: item.x + offsetX,
                y: item.y,
                width,
                height: item.height,
                fill: item.fill
              }
            })
          ),
          this.hasLabels ? this.genLabels(offsetX) : undefined
        ]
      );
    }
  }
};

In this example I remove some unnecessary code to make a bit easier to demonstrate but you might need in your real project. See VSparkline.ts.

CodeSandbox

Upvotes: 1

Related Questions