Javascript D3.JS V4在添加/更新数据后更新图表元素
我正在尝试使用d3.js V4构建简单的折线图。 我从多个bl.ocks样本中获得了基本概念 我的想法是创建char,然后向其中添加数据,最多9个数据点 以下是我到目前为止构建的视图: 我可以使用以下命令更新行:Javascript D3.JS V4在添加/更新数据后更新图表元素,javascript,d3.js,Javascript,D3.js,我正在尝试使用d3.js V4构建简单的折线图。 我从多个bl.ocks样本中获得了基本概念 我的想法是创建char,然后向其中添加数据,最多9个数据点 以下是我到目前为止构建的视图: 我可以使用以下命令更新行: addValue: function(val) { chartData.push(val); if (chartData.length > 9) { chartData.shift(); } y.domain([ -2
addValue: function(val) {
chartData.push(val);
if (chartData.length > 9) {
chartData.shift();
}
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var svg = element.transition();
svg
.select(".d3-line")
.duration(750)
.attr("d", valueline(chartData));
}
但我也希望在添加新数据时添加/移动点和线,如果没有这些,我的错误图表如下所示:
我使用以下代码添加初始点和线:
var lineGuides = svg
.append("g")
.selectAll(".d3-line-guides-group")
.data(chartData);
lineGuides
.enter()
.append("line")
.attr("class", "d3-line-guides")
.attr("x1", function(t, e) {
return x(e);
})
.attr("y1", function(t, a) {
return height;
})
.attr("x2", function(t, e) {
return x(e);
})
.attr("y2", function(t, a) {
return height;
})
.style("stroke", "rgba(255,255,255,0.3)")
.style("stroke-dasharray", "4,2")
.style("shape-rendering", "crispEdges")
.transition()
.duration(1000)
.delay(function(t, x) {
return 150 * x;
})
.attr("y2", function(t) {
return y(t);
})
.transition();
var points = svg
.insert("g")
.selectAll(".d3-line-circle")
.data(chartData)
.enter()
.append("circle")
.attr("class", "d3-line-circle d3-line-circle-medium")
.attr("cx", function(t, e) {
return x(e);
})
.attr("cy", function(t) {
return y(t);
})
.attr("r", 3)
.style("stroke", "#fff")
.style("fill", "#29B6F6")
.on("mouseover", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 5);
})
.on("mouseout", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 3);
});
points
.style("opacity", 0)
.transition()
.duration(250)
.ease(d3.easeLinear, 2)
.delay(1000)
.style("opacity", 1);
如何在数据更改时添加新点和更新旧点
以下是我目前掌握的代码:
/* global window, define, module */
(function(global, factory) {
var MicroChart = factory(global);
if (typeof define === "function" && define.amd) {
// AMD support
define(function() {
return MicroChart;
});
} else if (typeof module === "object" && module.exports) {
// CommonJS support
module.exports = MicroChart;
} else {
// We are probably running in the browser
global.MicroChart = MicroChart;
}
})(typeof window === "undefined" ? this : window, function(global, undefined) {
var document = global.document;
var slice = Array.prototype.slice;
var MicroChart = (function() {
var defaultOptions = {
height: 50
};
function shallowCopy(/* source, ...targets*/) {
var target = arguments[0],
sources = slice.call(arguments, 1);
sources.forEach(function(s) {
for (k in s) {
if (s.hasOwnProperty(k)) {
target[k] = s[k];
}
}
});
return target;
}
return function MicroChart(elem, opts) {
opts = shallowCopy({}, defaultOptions, opts);
var gaugeContainer = elem,
chartHeigh = opts.height,
instance;
var xScale, yScale, valueline, x, y;
var chartData = [5, 8, 2];
var element;
function initializeMicroChart(elem, height) {
element = d3.select(elem);
var margins = { top: 0, right: 0, bottom: 0, left: 0 };
var width =
element.node().getBoundingClientRect().width -
margins.left -
margins.right;
var height = chartHeigh - margins.top - margins.bottom;
var l = 10;
x = d3
.scaleLinear()
.domain([0, 8])
.range([l, width - l]);
y = d3.scaleLinear().range([height, 0]);
valueline = d3
.line()
.x(function(d, i) {
console.log(i);
return x(i);
})
.y(function(d) {
return y(d);
});
var svg = element
.append("svg")
.attr("width", width + margins.left + margins.right)
.attr("height", height + margins.top + margins.bottom);
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var s4 =function() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
var guid = s4()+s4();
console.log(guid);
var path = svg
.append("path")
.data([chartData])
.attr("class", "d3-line d3-line-medium")
.attr("clip-path", "url(#"+guid+")")
.attr("d", valueline)
.style("stroke", "#fff");
var clipPath = svg
.append("defs")
.append("clipPath")
.attr("id", guid);
var rect = clipPath
.append("rect")
.attr("class", "clip")
.attr("width", 0)
.attr("height", height)
.attr("transform", null)
.transition()
.duration(1000)
.ease(d3.easeLinear, 2)
.attr("width", width);
var lineGuides = svg
.append("g")
.selectAll(".d3-line-guides-group")
.data(chartData);
lineGuides
.enter()
.append("line")
.attr("class", "d3-line-guides")
.attr("x1", function(t, e) {
return x(e);
})
.attr("y1", function(t, a) {
return height;
})
.attr("x2", function(t, e) {
return x(e);
})
.attr("y2", function(t, a) {
return height;
})
.style("stroke", "rgba(255,255,255,0.3)")
.style("stroke-dasharray", "4,2")
.style("shape-rendering", "crispEdges")
.transition()
.duration(1000)
.delay(function(t, x) {
return 150 * x;
})
.attr("y2", function(t) {
return y(t);
})
.transition();
var points = svg
.insert("g")
.selectAll(".d3-line-circle")
.data(chartData)
.enter()
.append("circle")
.attr("class", "d3-line-circle d3-line-circle-medium")
.attr("cx", function(t, e) {
return x(e);
})
.attr("cy", function(t) {
return y(t);
})
.attr("r", 3)
.style("stroke", "#fff")
.style("fill", "#29B6F6")
.on("mouseover", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 5);
})
.on("mouseout", function(t) {
d3
.select(this)
.transition()
.duration(250)
.attr("r", 3);
});
points
.style("opacity", 0)
.transition()
.duration(250)
.ease(d3.easeLinear, 2)
.delay(1000)
.style("opacity", 1);
}
instance = {
addValue: function(val) {
chartData.push(val);
if (chartData.length > 9) {
chartData.shift();
}
y.domain([
-2,
d3.max(chartData, function(d) {
return d + 2;
})
]);
var svg = element.transition();
svg
.select(".d3-line")
.duration(750)
.attr("d", valueline(chartData));
}
};
initializeMicroChart(gaugeContainer, chartHeigh);
return instance;
};
})();
return MicroChart;
});
var gauge1 = MicroChart(document.getElementById("chart1"));
var gauge2 = MicroChart(document.getElementById("chart2"), {
height: 70
});
var randomInt = function(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
$("#update").on("click", function() {
gauge1.addValue(randomInt(5, 15));
gauge2.addValue(randomInt(5, 15));
});
这里是codepen以查看我的代码:使用.enter().append()
添加新节点,.merge()
合并现有节点和附加节点,然后更新所有节点并调用.exit().remove()
删除不必要的节点。因此,您可以使用以下更新模式:
d3.选择(窗口).on('load',function()){
//连接数据
var=d3。选择('div')。选择全部('p')。数据([1,2,3,4,5]);
加入
//添加新元素
.enter().append('p')
//合并新元素和现有元素
.合并(已加入)
//更新新的和现有的元素
.text(d=>d);
//去除多余的元素
joined.exit().remove();
});代码>
a
b
c
使用.enter().append()
添加新节点,.merge()
合并现有节点和附加节点,然后更新所有节点并调用.exit().remove()
删除不必要的节点。因此,您可以使用以下更新模式:
d3.选择(窗口).on('load',function()){
//连接数据
var=d3。选择('div')。选择全部('p')。数据([1,2,3,4,5]);
加入
//添加新元素
.enter().append('p')
//合并新元素和现有元素
.合并(已加入)
//更新新的和现有的元素
.text(d=>d);
//去除多余的元素
joined.exit().remove();
});代码>
a
b
c
感谢您的快速回复。我不必删除节点。大多数时候,我将不得不添加新的,然后只更新点的位置相同的虚线。我会想办法和大家分享我的想法results@Misiu,我已在我的答案后面附上了一个例子。如果您不需要删除节点,那么您可以忽略删除模式的一部分。这非常有效。以下是我当前的结果:(单击页脚中的添加Bata)。最后缺少的是响应能力,但这是另一个故事:)感谢您的快速回复。我不必删除节点。大多数时候,我将不得不添加新的,然后只更新点的位置相同的虚线。我会想办法和大家分享我的想法results@Misiu,我已在我的答案后面附上了一个例子。如果您不需要删除节点,那么您可以忽略删除模式的一部分。这非常有效。以下是我当前的结果:(单击页脚中的添加Bata)。最后缺少的是响应能力,但这是另一个故事:)