制作堆积条形图可拖动CanvasJS

时间:2018-02-01 03:42:22

标签: jquery graph charts canvasjs

我想单独拖动每一列(黄油,花,牛奶,鸡蛋)并用鼠标点击调整它们的数量。

我使用的资源是: https://canvasjs.com/javascript-charts/interactive-draggable-chart/

https://canvasjs.com/docs/charts/how-to/make-data-points-on-chart-draggable/

到目前为止,这是我的JSFiddle:https://jsfiddle.net/mmfhq9d3/

window.onload = function () {

var chart = new CanvasJS.Chart("chartContainer", {
    animationEnabled: true,
    theme: "light2",
    title:{
        text: "Cost Of Pancake Ingredients"
    },
    axisY2:{
        prefix: "$",
        lineThickness: 0                
    },
    toolTip: {
        shared: true
    },
    legend:{
        verticalAlign: "top",
        horizontalAlign: "center"
    },
    data: [
    {     
        type: "stackedBar",
        showInLegend: true,
        name: "Butter (500gms)",
        axisYType: "secondary",
        color: "#7E8F74",
        dataPoints: [
            { y: 3, label: "India" },
            { y: 5, label: "US" },
            { y: 3, label: "Germany" },
            { y: 6, label: "Brazil" },
            { y: 7, label: "China" }
        ]
    },
    {
        type: "stackedBar",
        showInLegend: true,
        name: "Flour (1kg)",
        axisYType: "secondary",
        color: "#F0D6A7",
        dataPoints: [
            { y: .5, label: "India" },
            { y: 1.5, label: "US" },
            { y: 1, label: "Germany" },
            { y: 2, label: "Brazil" },
            { y: 2, label: "China" }
        ]
    },
    {
        type: "stackedBar",
        showInLegend: true,
        name: "Milk (2l)",
        axisYType: "secondary",
        color: "#EBB88A",
        dataPoints: [
            { y: 2, label: "India" },
            { y: 3, label: "US" },
            { y: 3, label: "Germany" },
            { y: 3, label: "Brazil" },
            { y: 4, label: "China" }
            ]
    },
    {
        type: "stackedBar",
        showInLegend: true,
        name: "Eggs (20)",
        axisYType: "secondary",
        color:"#DB9079",
        indexLabel: "$#total",
        dataPoints: [
            { y: 2, label: "India" },
            { y: 3, label: "US" },
            { y: 6, label: "Germany"},
            { y: 4, label: "Brazil" },
            { y: 4, label: "China" }
        ]
    }
    ]
});

chart.render();

var xSnapDistance = chart.axisX[0].convertPixelToValue(chart.get("dataPointWidth")) / 2;
var ySnapDistance = 3;

var xValue, yValue;

var mouseDown = false;
var selected = null;
var changeCursor = false;

var timerId = null;

function getPosition(e) {
    var parentOffset = $("#chartContainer > .canvasjs-chart-container").offset();           
    var relX = e.pageX - parentOffset.left;
    var relY = e.pageY - parentOffset.top;
    xValue = Math.round(chart.axisX[0].convertPixelToValue(relX));
    yValue = Math.round(chart.axisY[0].convertPixelToValue(relY));
}

function searchDataPoint() {
    var dps = chart.data[0].dataPoints;
    for(var i = 0; i < dps.length; i++ ) {
        if( (xValue >= dps[i].x - xSnapDistance && xValue <= dps[i].x + xSnapDistance) && (yValue >= dps[i].y - ySnapDistance && yValue <= dps[i].y + ySnapDistance) ) 
        {
            if(mouseDown) {
                selected = i;
                break;
            } else {
                changeCursor = true;
                break; 
            }
        } else {
            selected = null;
            changeCursor = false;
        }
    }
}

jQuery("#chartContainer > .canvasjs-chart-container").on({
    mousedown: function(e) {
        mouseDown = true;
        getPosition(e);  
        searchDataPoint();
    },
    mousemove: function(e) {
        getPosition(e);
        if(mouseDown) {
            clearTimeout(timerId);
            timerId = setTimeout(function(){
                if(selected != null) {
                    chart.data[0].dataPoints[selected].y = yValue;
                    chart.render();
                }   
            }, 0);
        }
        else {
            searchDataPoint();
            if(changeCursor) {
                chart.data[0].set("cursor", "n-resize");
            } else {
                chart.data[0].set("cursor", "default");
            }
        }
    },
    mouseup: function(e) {
        if(selected != null) {
            chart.data[0].dataPoints[selected].y = yValue;
            chart.render();
            mouseDown = false;
        }
    }
});

}

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

以下是Draggable stackedBar Chart的示例。

const obj1 = { foo: 'bar'};
const obj2 = undefiend;
console.log(isSubset(obj1, obj2)); // false
var chart = new CanvasJS.Chart("chartContainer", {
  animationEnabled: true,
  title: {
    text: "Try Dragging Any Bar to Resize"
  },
  axisX: {
    minimum: 5,
    maximum: 95
  },
  data: [{
		type: "stackedBar",
		dataPoints: [
			{ x: 10, y: 71 },
			{ x: 20, y: 55 },
			{ x: 30, y: 50 },
			{ x: 40, y: 65 },
			{ x: 50, y: 95 },
			{ x: 60, y: 68 },
			{ x: 70, y: 28 },
			{ x: 80, y: 34 },
			{ x: 90, y: 14 }
		]
	},{
		type: "stackedBar",
		dataPoints: [
			{ x: 10, y: 71 },
			{ x: 20, y: 55 },
			{ x: 30, y: 50 },
			{ x: 40, y: 65 },
			{ x: 50, y: 95 },
			{ x: 60, y: 68 },
			{ x: 70, y: 28 },
			{ x: 80, y: 34 },
			{ x: 90, y: 14 }
		]
	},{
		type: "stackedBar",
		dataPoints: [
			{ x: 10, y: 71 },
			{ x: 20, y: 55 },
			{ x: 30, y: 50 },
			{ x: 40, y: 65 },
			{ x: 50, y: 95 },
			{ x: 60, y: 68 },
			{ x: 70, y: 28 },
			{ x: 80, y: 34 },
			{ x: 90, y: 14 }
		]
	}]
});
chart.render();



var xSnapDistance = 2;
var ySnapDistance = 5;

var xValue, yValue;

var mouseDown = false;
var selectedDataSeries = null;
var selectedDataPointX = null;
var selectedDatapointIndex = null;
var selectedSumIndex = null;
var changeCursor = false;
var timerId = null;
var chartType = "stackedBar";


function getPosition(e) {
  var parentOffset = $("#chartContainer > .canvasjs-chart-container").offset();
  var relX = e.pageX - parentOffset.left;
  var relY = e.pageY - parentOffset.top;
  xValue = Math.round(chart.axisX[0].convertPixelToValue(relY));
  yValue = Math.round(chart.axisY[0].convertPixelToValue(relX));
}

function searchDataPoint(stackedValues) {
  for (x in stackedValues) {
    if (stackedValues.hasOwnProperty(x) && (xValue >= Number(x) - xSnapDistance && xValue <= Number(x) + xSnapDistance)) {
      for (var i = 0; i < stackedValues[x].length; i++)
        if (yValue >= stackedValues[x][i].stackedSum - ySnapDistance && yValue <= stackedValues[x][i].stackedSum + ySnapDistance) {
          if (mouseDown) {
            selectedDataPointX = x;
            selectedDataSeries = stackedValues[x][i].dataSeries;
            selectedDatapointIndex = stackedValues[x][i].dataPointIndex;
            selectedSumIndex = i;
            return;
          } else {
            changeCursor = true;
            return;
          }
        }
    } else {
      selectedDataPointX = null;
      selectedDataSeries = null;
      selectedDatapointIndex = null;
      selectedSumIndex = null;
      changeCursor = false;
    }
  }
}

function sumUpStacked(data, type) {
  var stackedSums = {};
  for (var i = 0; i < data.length; i++) {
    if (data[i].type === type) {
      var dataSeries = data[i].dataPoints;
      for (var j = 0; j < dataSeries.length; j++) {

        if (stackedSums[dataSeries[j].x]) {
          var slectedStackSums = stackedSums[dataSeries[j].x];
          slectedStackSums.push({
            dataSeries: dataSeries,
            dataPointIndex: j,
            stackedSum: slectedStackSums[slectedStackSums.length - 1].stackedSum + dataSeries[j].y
          });
        } else {
          stackedSums[dataSeries[j].x] = [{
            dataSeries: dataSeries,
            dataPointIndex: j,
            stackedSum: dataSeries[j].y
          }]
        }

      }
    }
  }
  return stackedSums;
}


$("#chartContainer > .canvasjs-chart-container").on({
  mousedown: function(e) {
    mouseDown = true;
    getPosition(e);
    var stackedSums = sumUpStacked(chart.data, chartType);
    searchDataPoint(stackedSums);
  },
  
  mousemove: function(e) {
    getPosition(e);
    if (mouseDown) {
      clearTimeout(timerId);
      var stackedSums = sumUpStacked(chart.data, chartType);
      timerId = setTimeout(function() {
        if (selectedDataSeries != null) {
          if (selectedSumIndex === 0)
            selectedDataSeries[selectedDatapointIndex].y = yValue;
          else
            selectedDataSeries[selectedDatapointIndex].y = yValue - stackedSums[selectedDataPointX][selectedSumIndex - 1].stackedSum;
          chart.render();
        }
      }, 0);
    } else {
      searchDataPoint(sumUpStacked(chart.data, chartType));
      if (changeCursor) {
        for (var i = 0; i < chart.data.length; i++)
          chart.options.data[i].cursor = "n-resize";
      } else {
        for (var i = 0; i < chart.data.length; i++)
          chart.options.data[i].cursor = "default";
      }
      chart.render();
    }
  },
  
  mouseup: function(e) {
    var stackedSums = sumUpStacked(chart.data, chartType);
    if (selectedDataSeries != null) {
      if (selectedSumIndex === 0)
        selectedDataSeries[selectedDatapointIndex].y = yValue;
      else
        selectedDataSeries[selectedDatapointIndex].y = yValue - stackedSums[selectedDataPointX][selectedSumIndex - 1].stackedSum;
      chart.render();
    }
    mouseDown = false;
  }
});