目標:創建一個網格,其中X軸包含作業標題,Y軸包含每個作業的零件編號。如果一項工作需要一個以上的特定零件號碼,它將把該單元格垂直分割爲2/3/4/5 ...個不同的單元格,但仍然適合同一行/列。用多種顏色填充D3.js矩形或將矩形分割成多個矩形
問題:我無法爲特定數據點附加多個rects。我試着用這個答案here,但沒有運氣。我試着用每個循環都沒有運氣。任何建議?
進展情況:
目標:在問題
代碼片段:
dayOffset = dayFormat(dateExtent[0]);
rect = heatmap.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function (d) {
return Xcellscale/d.NumberofPart;
})
.attr('height', Ycellscale)
.attr('x', function (d) {
return xAxisScale(d.JobNumber);
})
.attr('y', function (d) {
return yAxisScale(d.PartNumber);
})
.attr('fill', '#000FF0');
JSON:
{
"data": [
{
"PartNumber": "a",
"JobNumber": "a",
"NumberofPart": "2",
"timestamp": "2014-09-25T00:00:00",
"value": {
"PM2.5": 30.22
}
},
{
"PartNumber": "b",
"JobNumber": "b",
"NumberofPart": "1",
"timestamp": "2014-09-25T01:00:00",
"value": {
"PM2.5": 41.61
}
},
{
"PartNumber": "c",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T02:00:00",
"value": {
"PM2.5": 50.71
}
},
{
"PartNumber": "d",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T02:00:00",
"value": {
"PM2.5": 50.71
}
},
{
"PartNumber": "e",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T02:00:00",
"value": {
"PM2.5": 50.71
}
},
{
"PartNumber": "f",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T02:00:00",
"value": {
"PM2.5": 50.71
}
},
{
"PartNumber": "g",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T02:00:00",
"value": {
"PM2.5": 1000.71
}
},
{
"PartNumber": "h",
"JobNumber": "c",
"NumberofPart": "1",
"timestamp": "2014-09-25T03:00:00",
"value": {
"PM2.5": 250.34
}
},
{
"PartNumber": "i",
"JobNumber": "d",
"NumberofPart": "1",
"timestamp": "2014-09-25T04:00:00",
"value": {
"PM2.5": 79.64
}
},
{
"PartNumber": "j",
"JobNumber": "e",
"NumberofPart": "2",
"timestamp": "2014-09-25T05:00:00",
"value": {
"PM2.5": 76.93
}
},
{
"PartNumber": "k",
"JobNumber": "f",
"NumberofPart": "2",
"timestamp": "2014-09-30T06:00:00",
"value": {
"PM2.5": 106.45
}
}
]
}
這是我所有的代碼。它基於這個D3.js Example,並且對於我沒有刪除關於時間戳的額外代碼感到抱歉。
$(document).ready(function() {
//UI configuration
var itemSize = 18,
cellSize = itemSize - 1,
width = 800,
height = 800,
margin = { top: 20, right: 20, bottom: 20, left: 25 };
//formats
var hourFormat = d3.time.format('%H'),
dayFormat = d3.time.format('%j'),
timeFormat = d3.time.format('%Y-%m-%dT%X'),
monthDayFormat = d3.time.format('%m.%d');
//data vars for rendering
var dateExtent = null,
data = null,
dayOffset = 0,
colorCalibration = ['#00ff00', '#0033cc', '#ffcc00', '#ff6600', '#ff0000', '#9E0142'],
dailyValueExtent = {};
data = jsondata.data;
//axises and scales
var axisWidth = 0,
axisHeight = itemSize * 24,
xAxisScale = d3.scale.ordinal()
.domain(data.map(function (d) { return d["JobNumber"]; }))
.rangePoints([0, width]);
xAxis = d3.svg.axis()
.scale(xAxisScale)
.orient('top'),
yAxisScale = d3.scale.ordinal()
.domain(data.map(function (d) { return d["PartNumber"]; }))
.rangePoints([0, width]),
yAxis = d3.svg.axis()
.scale(yAxisScale)
.orient('left');
initCalibration();
var svg = d3.select('[role="heatmap"]');
var heatmap = svg
.attr('width', width)
.attr('height', height)
.append('g')
.attr('width', width - margin.left - margin.right)
.attr('height', height - margin.top - margin.bottom)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var rect = null;
data.forEach(function (valueObj) {
valueObj['date'] = timeFormat.parse(valueObj['timestamp']);
});
dateExtent = d3.extent(data, function (d) {
return d.date;
});
svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.attr('class', 'x axis')
.call(xAxis)
.append('text')
.text('JobNumber')
.attr('transform', 'translate(' + axisWidth + ',-10)');
svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
.attr('class', 'y axis')
.call(yAxis)
.append('text')
.text('PartNumber')
.attr('transform', 'translate(-10,' + axisHeight + ') rotate(-90)');
//render heatmap rects
Xcellscale = width/(xAxisScale.domain().length -1);
Ycellscale = height/(yAxisScale.domain().length - 1);
console.log(Xcellscale + " " + Ycellscale);
console.log(width + " " + height);
console.log(xAxisScale.domain().length + " " + data.map(function (d) { return d["PartNumber"]; }).length);
dayOffset = dayFormat(dateExtent[0]);
rect = heatmap.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('width', function (d) {
return Xcellscale/d.NumberofPart;
})
.attr('height', Ycellscale)
.attr('x', function (d) {
return xAxisScale(d.JobNumber);
})
.attr('y', function (d) {
return yAxisScale(d.PartNumber);
})
.attr('fill', '#000FF0');
rect.filter(function (d) { return d.value['PM2.5'] > 0; })
.append('title')
.text(function (d) {
return monthDayFormat(d.date) + ' ' + d.value['PM2.5'];
});
//renderColor();
function initCalibration() {
d3.select('[role="calibration"] [role="example"]').select('svg')
.selectAll('rect').data(colorCalibration).enter()
.append('rect')
.attr('width', cellSize)
.attr('height', cellSize)
.attr('x', function (d, i) {
return i * itemSize;
})
.attr('fill', function (d) {
return d;
});
//bind click event
d3.selectAll('[role="calibration"] [name="displayType"]').on('click', function() {
renderColor();
});
}
function renderColor() {
var renderByCount = document.getElementsByName('displayType')[0].checked;
rect
.attr('width', function (d) {
return Xcellscale/d.NumberofPart;
})
.filter(function (d) {
return (d.value['PM2.5'] >= 0);
})
.transition()
.delay(function (d) {
return 1;
})
.duration(500)
.attrTween('fill', function (d, i, a) {
//choose color dynamicly
var colorIndex = d3.scale.quantize()
.range([0, 1, 2, 3, 4, 5])
.domain(([0, 500]));
return d3.interpolate(a, '#00ff00');
})
}
//extend frame height in `http://bl.ocks.org/`
d3.select(self.frameElement).style("height", "600px");
});
可以通過的LinearGradient填充兩種顏色一個矩形與4點停止,一個在開始,中間2個相同停止並且一個在末端。 –
有沒有辦法增加線性漸變的停靠量? – Mark
您可以根據需要添加它們,並通過DOM直接動態添加它們,或者使用d3 –