Javascript D3阵列分组条形图

Javascript D3阵列分组条形图,javascript,d3.js,Javascript,D3.js,我在使用D3时遇到了一些问题,需要一些帮助才能将现有的条形图更改为分组条形图。条形图正在工具提示中使用,目前看起来像: 每种颜色都代表一个行业(粉红色=零售,青色=杂货等)。 我需要更改条形图,以便将每个行业的百分比变化与该行业的世界平均百分比变化进行比较 此时,条形图是从一组数据创建的。我还有一个带有世界百分比值的数组 想象一下: countryData=[10,-20,-30,-63,-23,20], 世界数据=[23,-40,-23,-42,-23,40] 其中,指数0=零售业,指数1=

我在使用D3时遇到了一些问题,需要一些帮助才能将现有的条形图更改为分组条形图。条形图正在工具提示中使用,目前看起来像:

每种颜色都代表一个行业(粉红色=零售,青色=杂货等)。 我需要更改条形图,以便将每个行业的百分比变化与该行业的世界平均百分比变化进行比较

此时,条形图是从一组数据创建的。我还有一个带有世界百分比值的数组

想象一下:

countryData=[10,-20,-30,-63,-23,20], 世界数据=[23,-40,-23,-42,-23,40]

其中,指数0=零售业,指数1=杂货业等

我需要绘制一个分组条形图,将每个部门与世界平均水平进行比较(用红色显示世界平均水平)。这是一个有点棘手的解释,所以我为你画了它(…请原谅我画得不好)

有人能帮我更改现有的工具提示吗? 这是当前的代码。如果要模拟数据值的变化。 如果你想废弃我现有的代码,那没关系

 .on('mouseover', ({ properties }) => {
        // get county data
        const mobilityData = covid.data[properties[key]] || {};


      const {
        retailAverage,
        groceryAverage,
        parksAverage,
        transitAverage,
        workplaceAverage,
        residentialAverage,
      } = getAverage(covid1);



      let avgArray = [retailAverage, groceryAverage, parksAverage, transitAverage, workplaceAverage, retailAverage];
      let categoriesNames = ["Retail", "Grocery", "Parks", "Transit", "Workplaces", "Residential"];




        // create tooltip
        div = d3.select('body')
          .append('div')
          .attr('class', 'tooltip')
          .style('opacity', 0);

        div.html(properties[key]);

        div.transition()
          .duration(200)
          .style('opacity', 0.9);

        // calculate bar graph data for tooltip
        const barData = [];

        Object.keys(mobilityData).forEach((industry) => {
          const stringMinusPercentage = mobilityData[industry].slice(0, -1);
          barData.push(+stringMinusPercentage); // changing it to an integer value, from string
        });

        //combine the two lists for the combined bar graph
        var combinedList = [];
        for(var i = 0; i < barData.length; i++) {
          const stringMinusPercentage2 = +(avgArray[i].slice(0, -1));
          const object = {category: categoriesNames[i], country: barData[i], world: stringMinusPercentage2}
          combinedList.push(object); //Push object into list
        }
        console.log(combinedList);

        // barData = barData.sort(function (a, b) {  return a - b;  });
        // sort into ascending ^ keeping this in case we need it later
        const height2 = 220;
        const width2 = 250;
        const margin = {
          left: 50, right: 10, top: 20, bottom: 15,
        };

        // create bar chart svg
        const svgA = div.append('svg')
          .attr('height', height2)
          .attr('width', width2)
          .style('border', '1px solid')
          .append('g')
        // apply the margins:
          .attr('transform', `translate(${[`${margin.left},${margin.top}`]})`);

        const barWidth = 30; // Width of the bars

        // plot area is height - vertical margins.
        const chartHeight = height2 - margin.top - margin.left;

        // set the scale:
        const yScale = d3.scaleLinear()
          .domain([-100, 100])
          .range([chartHeight, 0]);

        // draw some rectangles:
        svgA
          .selectAll('rect')
          .data(barData)
          .enter()
          .append('rect')
          .attr('x', (d, i) => i * barWidth)
          .attr('y', (d) => {
            if (d < 0) {
              return yScale(0); // if the value is under zero, the top of the bar is at yScale(0);
            }

            return yScale(d); // otherwise the rectangle top is above yScale(0) at yScale(d);
          })
          .attr('height', (d) => Math.abs(yScale(0) - yScale(d))) // the height of the rectangle is the difference between the scale value and yScale(0);
          .attr('width', barWidth)
          .style('fill', (d, i) => colours[i % 6]) // colour the bars depending on index
          .style('stroke', 'black')
          .style('stroke-width', '1px');

        // Labelling the Y axis
        const yAxis = d3.axisLeft(yScale);
        svgA.append('text')
          .attr('class', 'y label')
          .attr('text-anchor', 'end')
          .attr('x', -15)
          .attr('y', -25)
          .attr('dy', '-.75em')
          .attr('transform', 'rotate(-90)')
          .text('Percentage Change (%)');

        svgA.append('g')
          .call(yAxis);
      })
      .on('mouseout', () => {
        div.style('opacity', 0);
        div.remove();
      })
      .on('mousemove', () => div
        .style('top', `${d3.event.pageY - 140}px`)
        .style('left', `${d3.event.pageX + 15}px`));

    svg.append('g')
      .attr('transform', 'translate(25,25)')
      .call(colorLegend, {
        colorScale,
        circleRadius: 10,
        spacing: 30,
        textOffset: 20,
      });

  };

  drawMap(svg1, geoJson1, geoPath1, covid1, key1, 'impact1');
  drawMap(svg2, geoJson2, geoPath2, covid2, key2, 'impact2');
};
.on('mouseover',({properties})=>{
//获取县数据
const mobilityData=covid.data[properties[key]]| |{};
常数{
零售平均,
杂货店,
公园储蓄,
平均值,
平均工作时间,
居住权,
}=获取平均值(covid1);
设avgaray=[零售平均值、杂货平均值、停车平均值、交通平均值、工作平均值、零售平均值];
let categoriesNames=[“零售”、“杂货店”、“公园”、“交通”、“工作场所”、“住宅”];
//创建工具提示
div=d3。选择('body')
.append('div'))
.attr('类','工具提示')
.style('opacity',0);
div.html(属性[key]);
过渡部()
.持续时间(200)
.样式(“不透明度”,0.9);
//计算工具提示的条形图数据
常数barData=[];
Object.keys(mobilityData).forEach((行业)=>{
常量stringMinusPercentage=mobilityData[industry]。切片(0,-1);
push(+stringMinusPercentage);//将其从字符串更改为整数值
});
//组合组合条形图的两个列表
var组合列表=[];
对于(变量i=0;ii*barWidth)
.attr('y',(d)=>{
if(d<0){
返回yScale(0);//如果值小于零,则条的顶部位于yScale(0);
}
返回yScale(d);//否则矩形顶部在yScale(d)处高于yScale(0);
})
.attr('height',(d)=>Math.abs(yScale(0)-yScale(d))//矩形的高度是刻度值和yScale(0)之间的差值;
.attr('width',barWidth)
.style('fill',(d,i)=>colors[i%6])//根据索引为条形图上色
.style('笔划','黑色')
.样式(“笔划宽度”、“1px”);
//标记Y轴
常数yAxis=d3.axisLeft(yScale);
svgA.append('text')
.attr('class','y标签')
.attr('text-anchor','end')
.attr('x',-15)
.attr('y',-25)
.attr('dy','-.75em'))
.attr('transform'、'rotate(-90'))
.text(“百分比变化(%)”);
svgA.append('g')
.呼叫(yAxis);
})
.on('mouseout',()=>{
div.style('opacity',0);
div.remove();
})
.on('mousemove',()=>div
.style('top',`${d3.event.pageY-140}px`)
.style('left',`${d3.event.pageX+15}px`);
append('g')
.attr('transform','translate(25,25'))
.呼叫(彩色图例{
色阶,
循环:10,
间距:30,
文本偏移量:20,
});
};
绘图图(svg1、geoJson1、geoPath1、covid1、key1,‘影响1’);
绘图图(svg2、geoJson2、geoPath2、covid2、key2,‘影响2’);
};

你能在线上传小提琴吗?我该怎么做?你能在线上传小提琴吗?我该怎么做?