Custom HeatMap Chart Example

Code

const getDaysArray = function (start, end) {
  const arr = [];
  var curMonth;
  var monthData = {};
  var days = [];
  for (const dt = new Date(start); dt <= new Date(end); dt.setDate(dt.getDate() + 1)) {
    var curDate = new Date(dt);

    var newMonth = (curDate.getMonth() + 1) + '/' + curDate.getFullYear();

    if (curMonth && curMonth !== newMonth) {
      monthData = {
        value: curMonth,
        children: days
      };
      arr.push(monthData);
      days = [];
    }

    days.push(curDate.getDate() + '/' + (curDate.getMonth() + 1) + '/' + curDate.getFullYear());


    curMonth = newMonth;
  }

  if (days.length) {
    monthData = {
      value: curMonth,
      children: days
    };
    arr.push(monthData);
  }
  return arr;
};

const chartConfig = {
  visualMap: {
    type: 'continuous',
    min: 0,
    max: 1,
    dimension: 2,
    calculable: true,
    orient: 'horizontal',
    top: 5,
    left: 'center',
    color: ['#0f0', '#f00']
  },
  legend: {
    show: true,
    bottom: 10
  },
  matrix: {
    x: {
      data: [],
      levelSize: 40,
    },
    y: {
      label: {
        show: true,
        width: 150
      },
      levelSize: 150,
      data: []
    },
    top: 70,
    bottom: 40,
    left: 2,
    right: 2
  },
  series: {
    type: 'heatmap',
    coordinateSystem: 'matrix',
    data: [],
    label: {
      show: false
    }
  },
  tooltip: {
    show: true
  }
};

// busqueda de todas las entidades
var entitiesBuilder = $api.entitiesSearchBuilder().limit(1000, 1);
var entitiesFilter = {
  and: [{
    eq: {
      'provision.device.specificType': 'METER'
    }
  }]
};
if (filters && filters.generic) {
  entitiesFilter.and.push({
    eq: {
      'provision.administration.identifier': filters.generic
    }
  });
}

entitiesBuilder.filter(entitiesFilter);

const tempData = {};

var initDate = new Date(new Date().getDate() - 30);
var endDate = new Date();

var filter = {
  and: [{
    eq: {
      "datapoints.datastreamId": "volTot"
    }
  }]
};


if (filters && filters.period) {
  if (filters.period.from) {
    initDate = new Date(filters.period.from);
    filter.and.push({
      gte: {
        'datapoints._current.at': filters.period.from
      }
    });
  }

  if (filters.period.to) {
    endDate = new Date(filters.period.to);
    filter.and.push({
      lt: {
        'datapoints._current.at': filters.period.to
      }
    });
  }
}

chartConfig.matrix.x.data = getDaysArray(initDate, endDate);

var response = await entitiesBuilder.flattened().build().execute();

if (response && response.data && response.data.entities && response.data.entities.length > 0) {
  response.data.entities.forEach((entityDataTmp) => {
    const entityIdentifier = entityDataTmp['provision.administration.identifier']._value._current.value;

    if (!tempData[entityIdentifier]) {
      tempData[entityIdentifier] = [];

      chartConfig.matrix.x.data.forEach((monthData) => {
        monthData.children.forEach((dayData) => {
          tempData[entityIdentifier].push([dayData, entityIdentifier, 0]);
        });
      });
    }
  });
}


var builder = $api.datapointsSearchBuilder().limit(2000, 1).addSortBy('datapoints._current.at', 'DESCENDING');


builder.filter(filter).build().executeWithAsyncPaging('datapoints').then(
  function endFunction() {
    //drawChart(datapointsBuffer, true)
    chartConfig.matrix.y.data = Object.keys(tempData);

    let finalData = [];
    chartConfig.matrix.y.data.forEach((deviceId) => {
      finalData = finalData.concat(tempData[deviceId]);
    });
    chartConfig.series.data = finalData;
    callback(chartConfig);
  },
  function cancelado(err) {
    console.error(err);
    //drawChart(datapointsBuffer, true)
    callback(chartConfig);
  },
  function notify(notifyData) {
    if (notifyData && notifyData.length > 0) {
      notifyData.forEach((datapoint) => {
        if (!tempData[datapoint.entityIdentifier]) {
          tempData[datapoint.entityIdentifier] = [];

          chartConfig.matrix.x.data.forEach((monthData) => {
            monthData.children.forEach((dayData) => {
              tempData[datapoint.entityIdentifier].push([dayData, datapoint.entityIdentifier, 0]);
            });
          });
        }

        const currentAt = new Date(datapoint._current.at);
        const currentAtTxt = currentAt.getDate() + '/' + (currentAt.getMonth() + 1) + '/' + currentAt.getFullYear();
        const atIndex = tempData[datapoint.entityIdentifier].findIndex((element) => element[0] === currentAtTxt);
        tempData[datapoint.entityIdentifier][atIndex][2] = 1;
      });
    }
  }
).catch(function (err) {
  console.error(err);
});