Как изменить цвет, нажав на график? - PullRequest
0 голосов
/ 27 сентября 2018

Мне удалось сделать эффект изменения цвета с помощью функции onclick, однако я должен следовать следующей логике:

1) Последний столбец всегда будет отличаться от других цветов. Для запускана графике это похоже на нажатие первой полосы.

2) При нажатии на другие полосы цвета должны меняться, чтобы показать пользователю, что панель была нажата, однако предыдущие полосы должны вернуться к своей нормальнойcolor ..

У меня проблемы с этой логикой, и я использую chartjs 2.x

class ChartVenda {
    constructor(_id, _dataJSON){
        this.id           = _id;
        this.dataJSON     = _dataJSON;
        this.chartElement = document.getElementById(_id).getContext('2d');
    }

    set chartObject(_object){ this.object = _object; }
    get chartObject(       ){ return this.object;    }

    get labels(){
        return ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez'];
    }

    get bgColors(){
        return [
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)',
            'rgb(202, 216, 229)'
        ]
    }

    get borderColors(){
        return [
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
            'rgba(0,0,0,0.3)',
        ]
    }

    createChart(){
        this.generateChart();
        this.addChartOptions();
        this.addDataJsonInChart();
        this.addChartLabels();
        this.addChartDatasets();
        this.addAnimation();

        this.chartObject.update();
        console.log(this.chartObject.data.datasets)
    }

    generateChart(){
        let chartVenda = new Chart(this.chartElement, { type: 'bar'});
        this.chartObject = chartVenda;
    }

    addDataJsonInChart(){
        this.chartObject.data.dataJSON = this.dataJSON;
    }

    addChartLabels(){
        let counterLabels = 0;
        this.dataJSON.records.forEach( () => {
            counterLabels += 1;
            this.chartObject.data.labels.push(this.labels[counterLabels-1]);
        });
    }

    addChartDatasets(){
        let arrDeltaVendam2 = [];
        this.dataJSON.records.forEach( (_item) => {
            arrDeltaVendam2.push(_item['Δ% Venda m²']);
        });

        this.chartObject.data.datasets.push({
            label:           `ae`,
            data:            arrDeltaVendam2,
            backgroundColor: 'rgb(202, 216, 229)',
            borderColor:     'rgb(202, 216, 229)',
        });

        this.chartObject.update();
    }

    addChartOptions(){
        this.chartObject.options = {
            responsive:          true,
            maintainAspectRatio: false,
            legend: { display:   false },
            scales: {
                yAxes: [{ ticks: {display: false, fontColor: 'white'},  gridLines: {display: false, drawBorder: false} }],
                xAxes: [{ ticks: {fontSize: 15,   fontColor: 'white' }, gridLines: {display: false, drawBorder: false} }],
            },
            onClick: function(_event, _value) {
                let datasetIndex,
                    dataset;

                if (_value.length) {
                    this.chart.data.dataJSON.records.forEach( (item) => {
                        if(item['Competência'] === _value[0]._model.label){
                            const VENDA_METROS_TESTE = document.getElementById('primary-jumbotron-subtitle-indicator-m²'),
                                  VENDA_ABS_TESTE    = document.getElementById('primary-jumbotron-subtitle-indicator-abs');

                            VENDA_METROS_TESTE.innerHTML = `${item['Venda m²']} m²`;
                            VENDA_ABS_TESTE.innerHTML    = `${item['Venda']} abs`;
                        }
                      });

                      datasetIndex = _value[0]._datasetIndex;

                      // Reset old state
                      dataset = this.chart.data.datasets[datasetIndex];
                      dataset.backgroundColor = dataset.backgroundColor.slice();
                      dataset.backgroundColor = 'rgb(133, 222, 252)'; // click color
                  } else {
                    // remove hover styles
                    for (datasetIndex = 0; datasetIndex < myChart.data.datasets.length; ++datasetIndex) {
                      dataset = this.chart.data.datasets[index];
                      dataset.backgroundColor = dataset.backgroundColor.slice();
                    }
                }
            }
        }
    }

    addAnimation(){
        this.chartObject.options.animation = {
            duration: 1000,
            onProgress: function() {
                /** @description <CRIA O EFEITO DE TEXTO EM CIMA DAS BARRAS> **/
                const CHART_OBJECT = this.chart;
                CHART_OBJECT.ctx.font         = Chart.helpers.fontString('17', 'normal', Chart.defaults.global.defaultFontFamily);
                CHART_OBJECT.ctx.fillStyle    = 'white';
                CHART_OBJECT.ctx.textAlign    = 'center';
                CHART_OBJECT.ctx.textBaseline = 'bottom';
                Chart.helpers.each(this.data.datasets.forEach(function (_dataset, _index1) {
                    Chart.helpers.each(CHART_OBJECT.getDatasetMeta(_index1).data.forEach(function (_bar, _index2) {
                        let centerPoint = _bar.getCenterPoint();
                        CHART_OBJECT.ctx.fillText(_dataset.data[_index2], centerPoint.x, centerPoint.y);
                    }), this);
                }), this);
            },
        }
    }


}

1 Ответ

0 голосов
/ 28 сентября 2018

Я не понимаю вашу первую точку зрения, но обращаюсь к вашей второй точке:

В приведенном ниже фрагменте задается цвет по умолчанию для каждой полосы («светло-серый»).При щелчке по панели все полосы имеют свой первоначальный цвет, а по нажатой полосе - красный.Преимущество этого подхода заключается в том, что начальный цвет каждой полосы может быть разным и будет правильно переключаться на «красный» и обратно.

let background = ['lightgrey', 'lightgrey', 'lightgrey', 'lightgrey'],
  myChart = new Chart(document.getElementById('chart'), {
    type: 'bar',
    data: {
      labels: ['a', 'b', 'c', 'd'],
      datasets: [{
        label: 'series1',
        data: [7, 10, 8, 2],
        backgroundColor: background.slice() // using .slice here 'clones' the array.
      }]
    },
    options: {
      maintainAspectRatio: false,
      onClick: function(e, elems) {
        if (elems.length) {
          elems[0]._chart.config.data.datasets[0].data.forEach((value, index) => {

            // set element to the original colour (resets all).
            elems[0]._chart.config.data.datasets[0].backgroundColor[index] = background[index];
            if (index == elems[0]._index) {
              // set the clicked element to red.
              elems[0]._chart.config.data.datasets[0].backgroundColor[index] = 'red';
            }
          });
          myChart.update(); // if you don't want the animation use 'myChart.update(0);' instead.
        }
      }
    }
  });
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
<canvas id="chart"></canvas>

Примечания:

  • легенда использует цвета первой точки, поэтому при нажатии на легендутакже меняется цвет.
  • это работает только для первого набора данных (elems[0]...datasets[0]).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...