Как определить атрибут x в столбчатой диаграмме с многоуровневым отклонением d3, чтобы столбики располагались справа?

#javascript #d3.js #stackedbarseries

#javascript #d3.js #stackedbarseries

Вопрос:

Я пытаюсь создать расходящуюся столбчатую диаграмму с многоуровневой диаграммой. У меня есть две области svg — одна для голосов «за» и одна для голосов «нет». Мне нужны голоса «нет» (столбики слева от изображения:https://i.stack.imgur.com/NJveR.png ) начинать с правой стороны шкалы и выдвигаться к левой стороне шкалы. Столбики создаются в разделе прямоугольники при выборочном выделении. При создании этих столбиков, как я должен определить атрибут x, чтобы столбики начинались справа? Я перепробовал всевозможные комбинации добавления и вычитания ширины, изменения масштабов, преобразования прямоугольников. Кажется, я просто не могу заставить его двигаться туда, куда я хочу!

Полный код:

 var margin = { top: 50, right: 5, bottom: 20, left: 5 },
    width = 450 - margin.left - margin.right,
    height = 800 - margin.top - margin.bottom;

var svgNo = d3.select("#chart").append("svg")
    .attr("width", width   margin.left   margin.right)
    .attr("height", height   margin.top   margin.bottom)
    .attr("id", "svgNo")
    .append("g")
    .attr("transform", "translate("   margin.left   ","   margin.top   ")");

var svgYes = d3.select("#chart").append("svg")
    .attr("width", width   margin.left   margin.right)
    .attr("height", height   margin.top   margin.bottom)
    .attr("id", "svgYes")
    .append("g")
    .attr("transform", "translate("   margin.left   ","   margin.top   ")");

var votesNo = [];
var votesYes = [];

/////////GET DATA/////////////

//access votes route in Flask app
d3.json("/votes").then(function (data) {

    //loop through objects in route
    data.forEach(function (d) {

        //convert data to numeric
        demYes =  d.democratic.yes
        demNo =  d.democratic.no
        repYes =  d.republican.yes
        repNo =  d.republican.no
        indYes =  d.independent.yes
        indNo =  d.independent.no


        //push desired data to arrays
        votesYes.push(
            {
                "id": d._id,
                "name": d.bill.bill_id,
                "question": d.question,
                "description": d.description,
                "demYes": demYes,
                "repYes": repYes,
                "indYes": indYes,
            })
        votesNo.push(
            {
                "id": d._id,
                "name": d.bill.bill_id,
                "question": d.question,
                "description": d.description,
                "demNo": demNo,
                "repNo": repNo,
                "indNo": indNo,
            })
    });
    /////////////STACK GENERATORS//////////////

    //create stack generator for YES votes
    var stackGenYes = d3.stack()
        .keys(["demYes", "repYes", "indYes"]) //keys from votesYes
        .order(d3.stackorderDescending)   
    //use generator to create data array
    var stackedSeriesYes = stackGenYes(votesYes);
    console.log(stackedSeriesYes);

    //create stack generator for NO votes
    var stackGenNo = d3.stack()
        .keys(["demNo", "repNo", "indNo"]) //keys from votesNo
    //use generator to create data array
    var stackedSeriesNo = stackGenNo(votesNo);
    console.log(stackedSeriesNo);

    /////////////SCALE FUNCTIONS////////////

    //assign colors to parties
    var colorScale = d3.scaleOrdinal()
        .domain(["demYes", "repYes", "indYes"])
        .range(["#086fad", "#c7001e", "#8A2BE2"]);

    var yScale = d3.scaleBand()
        .domain(votesYes.map(d => d.id)) //unique identifiers
        .range([0, height])
        .padding(0.1);

    var xScaleYes = d3.scaleLinear()
        .domain([0, 535]) //num members of congress
        .range([0, width]);

    var xScaleNo = d3.scaleLinear()
        .domain([0, 535])
        .range([width, 0]);

    ////////////////RECTANGLES////////////////

    //create g tags for each YES key
    var selYes = d3.select("#svgYes")
        .select('g')
        .selectAll('g.seriesYes')
        .data(stackedSeriesYes)
        .join('g')
        .classed('series', true)
        .style('fill', (d) => colorScale(d.key)); //assign color
    //create YES bars
    selYes.selectAll('rect')
        .data(d => d)
        .join('rect')
        .attr('width', d => xScaleYes(d[1]) - xScaleYes(d[0])) //length of bars
        .attr('x', d => xScaleYes(d[0])) //bar starting point (x)
        .attr('y', d => yScale(d.data.id)) //bar starting point (y)
        .attr('height', 32) //thickness of bar

    //create g tags for each NO key
    var selNo = d3.select("#svgNo")
        .select('g')
        .selectAll('g.seriesNo')
        .data(stackedSeriesNo)
        .join('g')
        .classed('series', true)
        .style('fill', (d) => colorScale(d.key));
    //create NO bars
    selNo.selectAll('rect')
        .data(d => d)
        .join('rect')
        .attr('width', d => xScaleNo(d[0]) - xScaleNo(d[1])) //length of bars
        .attr('x', d => width - xScaleNo(d[0])) //bar starting point (x)
        .attr('y', d => yScale(d.data.id)) //bar starting point(y)
        .attr('height', 32); //thickness of bar
});