Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 基于数据的多svg条件填充_Javascript_D3.js - Fatal编程技术网

Javascript 基于数据的多svg条件填充

Javascript 基于数据的多svg条件填充,javascript,d3.js,Javascript,D3.js,在下面的代码中,我有两年的日历,两个用户在每个日历上显示同一年 在下面的代码中,我对日期是否为周末进行了条件填充检查,并将其填充为灰色,效果非常好 .attr("fill", function(d) { var value = new Date(d).getDay(); var check = (value === 6 || value === 0) // Check if weekend if (check) return "#E0E0E

在下面的代码中,我有两年的日历,两个用户在每个日历上显示同一年

在下面的代码中,我对日期是否为周末进行了条件填充检查,并将其填充为灰色,效果非常好

    .attr("fill", function(d) {
        var value = new Date(d).getDay();
        var check = (value === 6 || value === 0) // Check if weekend
        if (check) return "#E0E0E0"
        else return "none"; 
    });
如果提供了某个日期,我现在要做的是填写一个红色方框,例如:

if (d == "2018-10-12") return "red"
这里的问题是,它显然将两个日历都填充为红色,因为它们都有那个日期

我不确定如何将日期与每个svg的数据数组进行比较,这是我想要比较日期的测试数据

var data = [
    {id: "Some_Name", dates: ["2018-01-01", "2018-02-11"]},    // <-- svg1
    {id: "Another_Name", dates: ["2018-03-01", "2018-04-11"]}, // <-- svg2
]
正文{
保证金:自动;
宽度:1000px;
字体:12px arial;
}

2017
2018
2019

因此,我根据jonnys的评论提出了我自己的解决方案,我将数据包含在更新参数中,并进行forEach循环,根据id选择svg,并使用与以前大致相同的逻辑

allData.forEach(function(data, i) {

    d3.selectAll("#" + user[i]).selectAll(".fillDays").attr("fill", function(d) {
        var value = new Date(d).getDay();
        var check = (value === 6 || value === 0) // Check if weekend
        if (check) return "#E0E0E0"
        if (data.dates.includes(d)) return "red"
        else return "none"; 
    })
})
这是目前我能想到的最干净的解决方案,如果你有更好的,请随意回答

var formatDay=d3.timeFormat(“%d”);
var formatDate=d3.timeFormat(“%Y-%m-%d”);
var sqlData=[
{id:“一些名字”,日期:[“2018-01-01”,“2018-02-12”]},
{id:“另一个名字”,日期:[“2018-03-01”,“2018-04-11”],
]
可变宽度=1000,
高度=196,
单元大小=18,
transCell1=((宽度-单元大小*53)/2),
transCell2=(高度-单元大小*7-1);
var currentYear=新日期().getFullYear()
var id=[…新集合(sqlData.map)(函数(d){
返回d.id
}))];
var svg=d3。选择(“日历”)。选择全部(“svg”)
.数据(id)
.enter().append(“svg”)
.attr(“类”、“我的日历”)
.attr(“id”,d=>d)
.attr(“宽度”,宽度)
.attr(“高度”,高度)
.附加(“g”)
.attr(“转换”,
“翻译”(“+transCell1+”,“+transCell2+”);
var name=svg.append(“文本”)
.attr(“dx”,-5)
.attr(“dy”,-35)
.attr(“字体大小”,14)
.attr(“文本锚定”、“开始”)
.文本(功能(d){
var值=d.split(“u3;”)
返回值[0]+“”+值[1]
});
d3.选择所有(“.year”)。在(“单击”,函数()上){
更新(编号(this.value)、id、sqlData)
})
更新(当前年份、id、sqlData);
功能更新(年份、用户、所有数据){
var getDays=function(){
返回d3.timeDays(
新日期(年,0,1),新日期(年+1,0,1)
);
}
var fillDays=svg.selectAll(“.fillDays”)
.数据(getDays)
fillDays.exit().remove()
fillDays=fillDays
.enter().append(“rect”)
.attr(“类”、“填充日”)
.attr(“笔划”,“#ccc”)
.attr(“宽度”,单元格大小)
.attr(“高度”,单元格大小)
.merge(fillDays)
.attr(“x”,函数(d){
返回d3.timeWeek.count(d3.timeYear(d),d)*单元大小;
})
.attr(“y”,函数(d){return d.getDay()*cellSize;})
.基准(d3.时间格式(“%Y-%m-%d”))
var days=svg.selectAll(“.days”)
.数据(getDays)
天=天
.enter().append(“文本”)
.attr(“班级”、“天数”)
.attr(“字体大小”,11)
.attr(“dy”,13)
.attr(“dx”,3)
.style(“指针事件”、“无”)
.attr(“填充”,“#333”)
.attr(“笔划”、“无”)
.合并(天)
.attr(“x”,函数(d){
返回d3.timeWeek.count(d3.timeYear(d),d)*单元大小;
})
.attr(“y”,函数(d){return d.getDay()*cellSize;})
.文本(功能(d){
返回日期(d)
})
var lines=svg.selectAll(“路径”)
.data(函数(){
返回d3.timeMonths(
新日期(年,0,1),新日期(年+1,0,1)
); 
})
lines.exit().remove()
线条=线条
.enter().append(“路径”)
.attr(“填充”、“无”)
.attr(“笔划”,“千”)
.合并(行)
.attr(“d”,路径月);
//
//硬编码文本
//
var months=svg.selectAll(“.months”)
.数据([
“一月”、“二月”、“三月”、“四月”、“主要”、“六月”,
“7月”、“8月”、“9月”、“Okt”、“11月”、“12月”])
月=月
.输入()
.append(“文本”)
.attr(“类别”、“月份”)
.attr(“dx”,函数(d,i){返回i*80+25;})
.attr(“dy”,-6)
.attr(“字体大小”,12)
.attr(“填充”,“#333”)
.attr(“笔划”、“无”)
.合并(个月)
.text(d=>d)
var weeks=svg.selectAll(“.weeks”)
.数据([“Sö”、“Mö229”、“Ti”、“On”、“To”、“Fr”、“Lö])
周=周
.输入()
.append(“文本”)
.attr(“班级”、“周”)
.attr(“dy”,函数(d,i){返回i*18+13;})
.attr(“dx”,-22)
.attr(“字体大小”,11)
.attr(“填充”,“#333”)
.attr(“笔划”、“无”)
.合并(周)
.text(d=>d)
forEach(函数(数据,i){
d3.selectAll(“#”+用户[i])。selectAll(.fillDays”).attr(“fill”,函数(d){
var值=新日期(d).getDay();
变量检查=(值===6 | |值===0)//检查周末
如果(检查)返回“#e0”
如果(数据日期包括(d))返回“红色”
否则返回“无”;
})
})
}
功能路径月(t0){
变量t1=新日期(t0.getFullYear(),t0.getMonth()+1,0),
d0=t0.getDay(),w0=d3.timeWeek.count(d3.timeYear(t0),t0),
d1=t1.getDay(),w1=d3.timeWeek.count(d3.timeYear(t1),t1);
返回“M”+(w0+1)*cellSize+”,“+d0*cellSize”
+“H”+w0*单元尺寸+V”+7*单元尺寸
+“H”+w1*单元尺寸+“V”+(d1+1)*单元尺寸
+“H”+(w1+1)*单元尺寸+“V”+0
+“H”+(w0+1)*单元大小+“Z”;
}
正文{
保证金:自动;
宽度:1000px;
字体:12px arial;
}

2017
2018
2019
关于:根据经验,请勿在D3代码中使用循环。大多数情况下,它们是不必要的,甚至更糟糕的是,它们可能成为障碍,甚至使事情破裂

这里更简单和惯用的解决方案是将数据绑定到每个SVG

对于start,不要仅用两个字符串绑定该数组。而不是绑定
数据
数组本身,该数组包含以下日期:

var svg = d3.select("#calendars").selectAll("svg")
    .data(data)
    //etc...
然后,只需在矩形中获取每个用户的日期

var userDates = d3.select(this.parentNode).datum().dates;
。。。并使用
if
填充它们:

if (userDates.indexOf(d) > -1) return "red";
以下是仅包含这些更改的代码:

var formatDay=d3.timeFormat(“%d”);
var formatDate=d3.timeFormat(“%Y-%m-%d”);
风险值数据=[{
id:“某个名字”,
日期:[“2018-01-01”、“2018-02-11”]
},
{
id:“另一个名字”,
日期:[“2018-03-