import * as d3 from 'd3'
import * as d3Tip from 'd3-tip'
import * as scaleRadial from '../../../utils/d3-scale-radial'

/**
 * data 图数据 例如：[{ date: '2011', q1: 155, q2: 200, q3: 214, q4: 234 }]
 * names 数据字段对应说明 例如：{ q1: '第一季度', q2: '第二季度', q3: '第三季度', q4: '第四季度' }
 * id 图id
 * height 图高 例如：500
 * margin 例如：{ top: 80, right: 80, bottom: 30, left: 60 }
 * title  图的标题 例如：XX省2016年各季度GDP汇总
 * titleY  Y轴标题 例如：GDP(亿)
 * formatFunY 格式化y函数
 * barColors 柱形颜色 例如：['#98abc5', '#7b6888', '#a05d56', '#ff8c00']
 */
const D3RadialStackedBarChart = (params) => {
  const {
    data,
    names,
    id,
    height,
    margin,
    title,
    titleY,
    formatFunY,
    barColors
  } = params;
  const container = document.getElementById(`${id}`);
  if (!container) return;

  const width = container.offsetWidth;
  const marginTop = margin && margin.top ? margin.top : 0;
  const marginBottom = margin && margin.bottom ? margin.bottom : 0;
  const marginLeft = margin && margin.left ? margin.left : 0;
  const marginRight = margin && margin.right ? margin.right : 0;

  const _width = width - marginLeft - marginRight;
  const _height = height - marginTop - marginBottom;

  // 设置总宽高
  let svg = d3.select(`#${id}`)
    .append('svg')
    .attr('width', width)
    .attr('height', height);

    const innerRadius = 180;
    const outerRadius = Math.min(_width, _height) * 0.5;

    let x = d3.scaleBand() // 定义x轴
      .range([0, 2 * Math.PI])
      .align(0)

    let y = scaleRadial().range([innerRadius, outerRadius]); // 定义y轴

    let z = d3.scaleOrdinal() //通用颜色
      .range(d3.schemeCategory10);
      
    let keys = Object.keys(names);

    let series = d3.stack() // 定义堆栈图
      .keys(keys)
      .offset(d3.stackOffsetDiverging)(data);

    x.domain(
      data.map(function(d) {
        return d.label
      })
    ); // x与y轴的值域

    y.domain([
      0,
      d3.max(series, function(serie) {
        return d3.max(serie, function(d) {
          return d[1]
        })
      })
    ])

    let tip = d3Tip.default() // 设置tip
      .attr('class', 'd3-tip stacked-demo')
      .offset([-10, 0])
      .html(function(d) {
        const currentData = d.target.__data__;
        let total = 0;
        let items = '<strong>' +currentData.data.label +'</strong><br>';
        for(let index = 0; index < keys.length; index++) {
          const item = keys[index];
          let itemColor =  z(item);
          if(isArray(barColors) && barColors[index]) {
            itemColor = barColors[index];
          }
          const label = names[item];
          const value = isFun(formatFunY) ? formatFunY(currentData.data[item]) : currentData.data[item];
          items += '<span style="color:' + itemColor + '">' + label + ': ' + value + '</span><br>';
          total += currentData.data[item];
        }
        total = isFun(formatFunY) ? formatFunY(total) : total;
        items += '<span style="color:#fff">汇总: ' + total + '</span>';
        return items;
      })

    svg.call(tip);

    let g = svg.append('g')
      .attr(
        'transform',
        'translate(' + width / 2 + ',' + height * 0.5 + ')'
      ); // 设最外包层在总图上的相对位置

    svg.append('defs')
      .append('clipPath') // 添加圆形遮罩
      .attr('id', 'clip')
      .append('circle')
      .attr('r', 0)
      .transition()
      .duration(800)
      .attr('r', outerRadius);

    let label = g.append('g') // 画x轴
      .selectAll('g')
      .data(data)
      .enter()
      .append('g')
      .attr('text-anchor', 'middle')
      .attr('transform', function(d) {
        return (
          'rotate(' +
          (((x(d.label) + x.bandwidth() / 2) * 180) / Math.PI - 90) +
          ')translate(' +
          innerRadius +
          ',0)'
        )
      });

    label.append('line')
      .attr('x2', -5)
      .attr('stroke', '#000');

    label.append('text')
      .attr('transform', function(d) {
        return (x(d.label) + x.bandwidth() / 2 + Math.PI / 2) % (2 * Math.PI) < Math.PI ? 'rotate(90)translate(0,16)' : 'rotate(-90)translate(0,-9)';
      })
      .text(function(d) {
        return d.label
      });

    let yAxis = g.append('g') // 画y轴圈圈及文字
      .attr('text-anchor', 'end');

    let yTick = yAxis.selectAll('g')
      .data(y.ticks(6).slice(1))
      .enter()
      .append('g');

    yTick.append('circle')
      .attr('fill', 'none')
      .attr('stroke', '#000')
      .attr('stroke-opacity', 0.5)
      .attr('r', y);

    yTick.append('text')
      .attr('x', -6)
      .attr('y', function(d) {
        return -y(d)
      })
      .attr('dy', '0.35em')
      .attr('fill', 'none')
      .attr('stroke', '#fff')
      .attr('stroke-width', 5)
      .text(y.tickFormat(6, 'r'));

    yTick.append('text')
      .attr('x', -6)
      .attr('y', function(d) {
        return -y(d)
      })
      .attr('dy', '0.35em')
      .text(y.tickFormat(6, 'r'));

    yAxis.append('text')
      .attr('x', -6)
      .attr('y', function(d) {
        return -y(y.ticks(6).pop())
      })
      .attr('dy', '-1em')
      .text(titleY);

    g.append('g') // 画柱状图
      .selectAll('g')
      .data(series)
      .enter()
      .append('g')
      .attr('clip-path', 'url(#clip)')
      .attr('fill', function(d) {
        let currentColor = z(d.key);
        const index = keys.indexOf(d.key);
        if(isArray(barColors) && barColors[index]) {
          currentColor = barColors[index];
        }
        return currentColor;
      })
      .selectAll('path')
      .data(function(d) {
        return d
      })
      .enter()
      .append('path')
      .on('mouseover', tip.show)
      .on('mouseout', tip.hide)
      .attr('cursor', 'pointer')
      .attr('d', d3.arc()
        .innerRadius(function(d) {
          return y(d[0])
        })
        .outerRadius(function(d) {
          return y(d[1])
        })
        .startAngle(function(d) {
          return x(d.data.label)
        })
        .endAngle(function(d) {
          return x(d.data.label) + x.bandwidth()
        })
        .padAngle(0.01)
        .padRadius(innerRadius)
      );

    let legend = g.append('g') // 画legend
      .selectAll('g')
      .data(keys.slice())
      .enter()
      .append('g')
      .attr('transform', function(d, i) {
        return 'translate(-40,' + (i - (keys.length - 1) / 2) * 20 + ')'
      });

    legend.append('rect')
      .attr('width', 18)
      .attr('height', 18)
      .attr('fill', function (d) {
        let currentColor = z(d.key);
        const index = keys.indexOf(d.key);
        if(isArray(barColors) && barColors[index]) {
          currentColor = barColors[index];
        }
        return currentColor;
      });

    legend.append('text')
      .attr('x', 24)
      .attr('y', 9)
      .attr('dy', '0.35em')
      .text(function(d) {
        return names[d]
      });

    svg.append('g') // 输出标题
      .attr('class', 'grouped-bar--title')
      .append('text')
      .attr('fill', '#000')
      .attr('font-size', '16px')
      .attr('font-weight', '700')
      .attr('text-anchor', 'middle')
      .attr('x', width / 2)
      .attr('y', 20)
      .text(title);
}

export default D3RadialStackedBarChart;
