Заливка того же цвета строки в круг на многострочной диаграмме при наведении курсора мыши и удаление цвета из круга при наведении курсора мыши

#angularjs #d3.js

#angularjs #d3.js

Вопрос:

Здесь у меня есть 2 разные строки с разными цветами и круг на многострочной диаграмме в D3.js Я хочу заполнить круг одним и тем же цветом при наведении курсора мыши и удалить цвет при наведении курсора мыши.

Атрибут цвета заливки работает, но не заполняет тот же цвет, что и соответствующая строка.

 .on("mouseenter", function (event, d) {
    d3.selectAll("g.circle")
      .attr('class', 'quadrantBorder') //style with a custom class and CSS
       .style('stroke', 'red')
       .style('fill', (d, i) => colors(i));

    //alert('enter mouseenter')
    // Show the tooltip and position it correctly
    var x = xScaleTest(new Date(d.date));
    var y = yScaleTest(d.stock);
    console.log("This "  d3.select(this));
    d3.select(this).style("fill",(d,i) => colors(i));
  

 var data = [{
  depotID: 123,
  depotName: "All Depots",
  materials: [{
      materialName: "M7824 (MSB0011359C) 600 mg",
      materialTypeID: 1234,
      materialStock: [{
          date: "2020-10-01",
          stock: 100
        },
        {
          date: "2020-11-01",
          stock: 200
        },
        {
          date: "2020-12-01",
          stock: 300
        },
        {
          date: "2021-01-01",
          stock: 400
        },
        {
          date: "2021-02-01",
          stock: 500
        },
        {
          date: "2021-03-01",
          stock: 600
        },
        {
          date: "2021-04-01",
          stock: 700
        },
        {
          date: "2021-05-01",
          stock: 800
        },
        {
          date: "2021-06-01",
          stock: 900
        },
        {
          date: "2021-07-01",
          stock: 1000
        },
        {
          date: "2021-08-01",
          stock: 1100
        },
        {
          date: "2021-09-01",
          stock: 1200
        },

      ]
    },
    {
      materialName: "M7824 (MSB0011359C) 500 mg",
      materialID: 1232,
      materialStock: [{
          date: "2020-10-01",
          stock: 200
        },
        {
          date: "2020-11-01",
          stock: 300
        },
        {
          date: "2020-12-01",
          stock: 400
        },
        {
          date: "2021-01-01",
          stock: 500
        },
        {
          date: "2021-02-01",
          stock: 560
        },
        {
          date: "2021-03-01",
          stock: 870
        },
        {
          date: "2021-04-01",
          stock: 800
        },
        {
          date: "2021-05-01",
          stock: 900
        },
        {
          date: "2021-06-01",
          stock: 1000
        },
        {
          date: "2021-07-01",
          stock: 1100
        },
        {
          date: "2021-08-01",
          stock: 1200
        },
        {
          date: "2021-09-01",
          stock: 1300
        },

      ]
    }
  ]
}]
let width = 900,
  height = 400,
  margin = 100;

var dates = [];
for (let obj of data[0].materials[0].materialStock) {
  dates.push(obj.date);
}

var domain = d3.extent(dates);
var newStartDate = new Date(domain[0]).setDate(new Date(domain[0]).getDate() - 15);
var newEndtDate = new Date(domain[1]).setDate(new Date(domain[1]).getDate()   15);

var xScaleTest = d3.scaleTime()
  .domain([new Date(newStartDate), new Date(newEndtDate)])
  .range([0, width - margin * 2]);


var yScaleTest = d3.scaleLinear()
  .domain([0, d3.max(data[0].materials, function(d) {
    return d3.max(d.materialStock, function(d) {
      return d.stock;
    })
  })])
  .range([height - margin, 0]);

/* Add SVG */
var svg = d3.select("#xyAxes").append("svg")
  .attr("width", (width   margin)   "px")
  .attr("height", (height   margin)   "px")
  .attr("style", "outline: thin solid black;")
  .append('g')
  .attr("transform", `translate(${margin}, ${margin})`);

//Add Line
var line = d3.line()
  .x(function(d) {
    return xScaleTest(new Date(d.date))
  })
  .y(function(d) {
    return yScaleTest(d.stock)
  });

let lines = svg.append('g')
  .attr('class', 'lines');

var groups = lines.selectAll('.line-group')
  .data(data[0].materials).enter()
  .append('g');

var colors = d3.scaleOrdinal((d3.schemeCategory10));

//line
groups.append("path")
  .attr("d", function(d) {
    return line(d.materialStock)
  })
  .attr("fill", "none")
  .attr("stroke", (d, i) => colors(i))
  .style("stroke-dasharray", "5,5") //dashed array for line;

//dot on line
svg.selectAll("dot")
  .data(data[0].materials)
  .enter().append("g")
  .attr("fill", "none")
  .style("stroke", (d, i) => colors(i))
  .attr("class", "dot")
  .selectAll("dot")
  .data(function(d) {
    return d.materialStock;
  })
  .enter().append("circle")
  .attr("class", "circle")
  .attr("r", 4)
  .attr("cx", function(d) {
    return xScaleTest((new Date(d.date)));
  })
  .attr("cy", function(d) {
    return yScaleTest(d.stock);
  })
  .on("mouseover", function(d) {
    d3.select(this).style("fill", (d, i) => colors(i));
  })
  .on("mouseout", function() {
    d3.select(this).style("fill", "none");
  });

/* Add Axis into SVG */
var xAxis = d3.axisBottom(xScaleTest)
  .ticks(d3.timeMonth.every(1))
  .tickSizeOuter(0)
  .tickSizeInner(-height   margin)
  .tickFormat(d3.timeFormat("%b -%Y"));

var yAxis = d3.axisLeft(yScaleTest)
  .ticks(12)
  .tickSize(-width   margin   100)

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis)
  .call(g => g.selectAll(".tick:first-of-type line")
    .attr("class", "axis_bar")
    .attr("stroke", "#BEBEBE"))
  .call(g => g.selectAll(".tick:not(:first-of-type) line")
    .attr("class", "axis_y_tick")
    .attr("stroke", "#E8E8E8"));


svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .call(g => g.selectAll(".tick:first-of-type line")
    .attr("class", "axis_bar")
    .attr("stroke", "black"))
  .call(g => g.selectAll(".tick:not(:first-of-type) line")
    .attr("class", "axis_y_tick")
    .attr("stroke", "#E8E8E8"));  
 svg {
  font-family: Sans-Serif, Arial;
}

.line {
  stroke-width: 2;
  fill: none;
}

.text {
  font-size: 12px;
}

text.title {
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  font-size: 14px;
  color: #353535;
  ;
}  
 <script src="https://d3js.org/d3.v5.min.js"></script>
<div id="xyAxes"></div>  

Комментарии:

1. @@ Ruben Helsloot не могли бы вы, пожалуйста, разобраться в этом? JSFiddle также прилагается

Ответ №1:

i может означать разные вещи. Это просто итератор. Когда вы рисуете линии, вы selectAll(".dot") , что дает вам одну группу на строку. При запуске вы d3.select(this) выбираете только одну вещь, и это означает, что i она всегда равна нулю.

Чтобы исправить это, добавьте цвет в качестве свойства к точкам, когда вы их рисуете. Или вы можете использовать materialName or materialTypeID в качестве идентификатора вместо числа. Затем вы добавляете свойство materialName as ко всем кругам, и вы можете раскрасить их оттуда:

 var data = [{
  depotID: 123,
  depotName: "All Depots",
  materials: [{
      materialName: "M7824 (MSB0011359C) 600 mg",
      materialTypeID: 1234,
      materialStock: [{
          date: "2020-10-01",
          stock: 100
        },
        {
          date: "2020-11-01",
          stock: 200
        },
        {
          date: "2020-12-01",
          stock: 300
        },
        {
          date: "2021-01-01",
          stock: 400
        },
        {
          date: "2021-02-01",
          stock: 500
        },
        {
          date: "2021-03-01",
          stock: 600
        },
        {
          date: "2021-04-01",
          stock: 700
        },
        {
          date: "2021-05-01",
          stock: 800
        },
        {
          date: "2021-06-01",
          stock: 900
        },
        {
          date: "2021-07-01",
          stock: 1000
        },
        {
          date: "2021-08-01",
          stock: 1100
        },
        {
          date: "2021-09-01",
          stock: 1200
        },

      ]
    },
    {
      materialName: "M7824 (MSB0011359C) 500 mg",
      materialID: 1232,
      materialStock: [{
          date: "2020-10-01",
          stock: 200
        },
        {
          date: "2020-11-01",
          stock: 300
        },
        {
          date: "2020-12-01",
          stock: 400
        },
        {
          date: "2021-01-01",
          stock: 500
        },
        {
          date: "2021-02-01",
          stock: 560
        },
        {
          date: "2021-03-01",
          stock: 870
        },
        {
          date: "2021-04-01",
          stock: 800
        },
        {
          date: "2021-05-01",
          stock: 900
        },
        {
          date: "2021-06-01",
          stock: 1000
        },
        {
          date: "2021-07-01",
          stock: 1100
        },
        {
          date: "2021-08-01",
          stock: 1200
        },
        {
          date: "2021-09-01",
          stock: 1300
        },

      ]
    }
  ]
}]
let width = 900,
  height = 400,
  margin = 100;

var dates = [];
for (let obj of data[0].materials[0].materialStock) {
  dates.push(obj.date);
}

var domain = d3.extent(dates);
var newStartDate = new Date(domain[0]).setDate(new Date(domain[0]).getDate() - 15);
var newEndtDate = new Date(domain[1]).setDate(new Date(domain[1]).getDate()   15);

var xScaleTest = d3.scaleTime()
  .domain([new Date(newStartDate), new Date(newEndtDate)])
  .range([0, width - margin * 2]);


var yScaleTest = d3.scaleLinear()
  .domain([0, d3.max(data[0].materials, function(d) {
    return d3.max(d.materialStock, function(d) {
      return d.stock;
    })
  })])
  .range([height - margin, 0]);

/* Add SVG */
var svg = d3.select("#xyAxes").append("svg")
  .attr("width", (width   margin)   "px")
  .attr("height", (height   margin)   "px")
  .attr("style", "outline: thin solid black;")
  .append('g')
  .attr("transform", `translate(${margin}, ${margin})`);

//Add Line
var line = d3.line()
  .x(function(d) {
    return xScaleTest(new Date(d.date))
  })
  .y(function(d) {
    return yScaleTest(d.stock)
  });

let lines = svg.append('g')
  .attr('class', 'lines');

var groups = lines.selectAll('.line-group')
  .data(data[0].materials).enter()
  .append('g');

var colors = d3.scaleOrdinal((d3.schemeCategory10))
  .domain(data[0].materials.map(function(d) {
    return d.materialName;
  }));

//line
groups.append("path")
  .attr("d", function(d) {
    return line(d.materialStock)
  })
  .attr("fill", "none")
  .attr("stroke", (d, i) => colors(i))
  .style("stroke-dasharray", "5,5") //dashed array for line;

//dot on line
svg.selectAll("dot")
  .data(data[0].materials)
  .enter()
  .append("g")
  .attr("fill", "none")
  .style("stroke", (d) => colors(d.materialName))
  .attr("class", "dot")
  .selectAll("dot")
  .data(function(d) {
    d.materialStock.forEach(function(v) {
      v.materialName = d.materialName;
    });
    return d.materialStock;
  })
  .enter().append("circle")
  .attr("class", "circle")
  .attr("r", 4)
  .attr("cx", function(d) {
    return xScaleTest((new Date(d.date)));
  })
  .attr("cy", function(d) {
    return yScaleTest(d.stock);
  })
  .on("mouseover", function(d) {
    d3.select(this).style("fill", colors(d.materialName));
  })
  .on("mouseout", function() {
    d3.select(this).style("fill", "none");
  });

/* Add Axis into SVG */
var xAxis = d3.axisBottom(xScaleTest)
  .ticks(d3.timeMonth.every(1))
  .tickSizeOuter(0)
  .tickSizeInner(-height   margin)
  .tickFormat(d3.timeFormat("%b -%Y"));

var yAxis = d3.axisLeft(yScaleTest)
  .ticks(12)
  .tickSize(-width   margin   100)

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", `translate(0, ${height-margin})`)
  .call(xAxis)
  .call(g => g.selectAll(".tick:first-of-type line")
    .attr("class", "axis_bar")
    .attr("stroke", "#BEBEBE"))
  .call(g => g.selectAll(".tick:not(:first-of-type) line")
    .attr("class", "axis_y_tick")
    .attr("stroke", "#E8E8E8"));


svg.append("g")
  .attr("class", "y axis")
  .call(yAxis)
  .call(g => g.selectAll(".tick:first-of-type line")
    .attr("class", "axis_bar")
    .attr("stroke", "black"))
  .call(g => g.selectAll(".tick:not(:first-of-type) line")
    .attr("class", "axis_y_tick")
    .attr("stroke", "#E8E8E8"));  
 svg {
  font-family: Sans-Serif, Arial;
}

.line {
  stroke-width: 2;
  fill: none;
}

.text {
  font-size: 12px;
}

text.title {
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  font-size: 14px;
  color: #353535;
  ;
}  
 <script src="https://d3js.org/d3.v5.min.js"></script>
<div id="xyAxes"></div>