afterAll(function() { d3.select('#' + id).remove(); })
var d3 = require('d3'); var chroniton = require('../'); d3.select(document.body).append('h3').text('Defaults'); d3.select(document.body) .append('div') .call(chroniton()); d3.select(document.body).append('h3').text('Custom Label Format'); d3.select(document.body) .append('div') .call( chroniton() .labelFormat(d3.time.format('%b %e')) .width(500)); d3.select(document.body).append('h3').text('Specifying the date Domain'); d3.select(document.body) .append('div') .call( chroniton() .domain([new Date(+new Date() - 60 * 1000), new Date()]) .labelFormat(d3.time.format('%X')) .width(500)); (function() { d3.select(document.body).append('h3').text('Play button'); d3.select(document.body) .append('div') .call(
render() { var wf = this.props.data; if(wf == null) { wf = {}; } if(wf.tasks == null){ wf.tasks = []; } let tasks = wf['tasks']; tasks.push({taskType:'final'}); //let tasks = wf['tasks'].map(task => {return task.taskType;}); var g = new dagreD3.graphlib.Graph().setGraph({rankdir: 'TD'}); tasks.forEach(function(task) { let shape = 'rect'; if(task.taskType == 'decision'){ shape = 'diamond'; }else if(task.taskType == 'final'){ shape = 'circle'; } let output = JSON.stringify(task.outputData); g.setNode(task.taskType, { label: task.taskType, shape: shape, output: output}); }); for(let i = 1; i < tasks.length; i++){ let label = ''; if(tasks[i-1].taskType == 'decision'){ label = 'Case = ' + "''" || tasks[i-1].outputData.caseOutput; }else if( (i < tasks.length - 1) && tasks[i].taskType == 'decision'){ label = JSON.stringify(tasks[i-1].outputData); } g.setEdge(tasks[i-1].taskType, tasks[i].taskType, { label: label }); } g.nodes().forEach(function(v) { var node = g.node(v); node.rx = node.ry = 5; }); // Add some custom colors based on state //g.node('CLOSED').style = "fill: #f77"; //g.node('ESTAB').style = "fill: #7f7"; var svg = d3.select("svg"), inner = svg.select("g"); // Create the renderer var render = new dagreD3.render(); // Run the renderer. This is what draws the final edges. render(inner, g); //inner.selectAll("g.node").attr("title", function(v) { return styleTooltip(v, g.node(v).output) }); return ( <div className="ui-content container-fluid"> <svg width="100%" height="600"> <g transform="translate(20,20)"></g> </svg> </div> ); }
selection.each(function (data, index) { // Allows chart to accept an array or object data = accessor.call(this, data, index); width = this.getBoundingClientRect().width; var adjustedWidth = width - margin.left - margin.right; var adjustedHeight = height - margin.top - margin.bottom; xScale = xScaleOpts.scale || d3.time.scale.utc(); xScale.domain(xScaleOpts.domain || d3.extent(d3.merge(data), xValue)); if (typeof xScale.rangeBands === "function") { xScale.rangeBands([0, adjustedWidth, 0.1]); } else { xScale.range([0, adjustedWidth]); } var yScaleDomain = yScaleOpts.domain || d3.extent(d3.merge(data), yValue); if (yScaleDomain[0] === yScaleDomain[1]) { --yScaleDomain[0]; ++yScaleDomain[1]; } yScale = yScaleOpts.scale || d3.scale.linear(); yScale.domain(yScaleDomain) .range([adjustedHeight, 0]); if (xScaleOpts.nice) { xScale.nice(); } if (yScaleOpts.nice) { yScale.nice(); } var svgEvents = events().listeners(listeners).xScale(xScale); var svg = d3.select(this).selectAll("svg") .call(svgEvents) .data([data]); if(!svg.size()) { svg.enter().append("svg") .call(svgEvents); } svg.attr("width", width) .attr("height", height); svg.selectAll("g").remove(); var g = svg.append("g"); g.attr("transform", "translate(" + margin.left + ", " + margin.top + ")"); // Brush if (listeners.brush && listeners.brush.length) { var brush = brushComponent() .height(adjustedHeight) .xScale(xScale) .brushend(listeners.brush); g.call(brush); } var X = scaleValue(xScale, xValue); var Y = scaleValue(yScale, yValue); var line = d3.svg.line(data).x(X).y(Y) .interpolate(interpolate) .tension(tension) .defined(defined); var linePath = path() .pathGenerator(line) .class(lines.lineClass) .stroke(function (d, i, j) { return color(lines.stroke.call(null, d, i, j)); }) .strokeWidth(lines.strokeWidth) .opacity(lines.opacity); if (axisX.show) { var xAxis = axis() .scale(xScale) .chartDimension(adjustedHeight) .class(axisX.gClass) .transform(axisX.transform || "translate(0," + (yScale.range()[0] + 1) + ")") .tick(axisX.tick) .title(axisX.title); g.call(xAxis); } if (axisY.show) { var yAxis = axis() .scale(yScale) .chartDimension(adjustedWidth) .orient("left") .class(axisY.gClass) .transform(axisY.transform || "translate(-1,0)") .tick(axisY.tick) .title(axisY.title); g.call(yAxis); } g.append("g") .data([data]) .attr("class", lines.groupClass) .call(linePath); if (zeroLine.add) { var zLine = zeroAxisLine() .class(zeroLine.lineClass) .x1(function () { return xScale.range()[0]; }) .x2(function () { return xScale.range()[1]; }) .y1(function () { return yScale(0); }) .y2(function () { return yScale(0); }) .stroke(zeroLine.stroke) .strokeWidth(zeroLine.strokeWidth) .opacity(zeroLine.opacity); g.call(zLine); } if (circles.show) { var clippath = clip() .width(clipPath.width || adjustedWidth) .height(clipPath.height || adjustedHeight); var points = circle() .cx(X) .cy(Y) .radius(circles.radius) .class(circles.circleClass) .fill(function (d, i, j) { return circles.fill.call(null, d, i, j); }) .stroke(circles.stroke ? circles.stroke : circles.fill) .strokeWidth(circles.strokeWidth) .opacity(circles.opacity); g.call(clippath) .append("g") .attr("clip-path", "url(#" + clippath.id() + ")") .selectAll("gCircles") .data(function (d) { return d; }) .enter().append("g") .attr("class", circles.groupClass) .datum(function (d) { return d; }) .call(points); } });
function countryMapChart(slice, payload) { // CONSTANTS const fd = payload.form_data; let path; let g; let bigText; let resultText; const container = slice.container; const data = payload.data; const format = d3.format(fd.number_format); const colorScaler = colorScalerFactory(fd.linear_color_scheme, data, v => v.metric); const colorMap = {}; data.forEach((d) => { colorMap[d.country_id] = colorScaler(d.metric); }); const colorFn = d => colorMap[d.properties.ISO] || 'none'; let centered; path = d3.geo.path(); d3.select(slice.selector).selectAll('*').remove(); const div = d3.select(slice.selector) .append('svg:svg') .attr('width', slice.width()) .attr('height', slice.height()) .attr('preserveAspectRatio', 'xMidYMid meet'); container.css('height', slice.height()); container.css('width', slice.width()); const clicked = function (d) { let x; let y; let k; let bigTextX; let bigTextY; let bigTextSize; let resultTextX; let resultTextY; if (d && centered !== d) { const centroid = path.centroid(d); x = centroid[0]; y = centroid[1]; bigTextX = centroid[0]; bigTextY = centroid[1] - 40; resultTextX = centroid[0]; resultTextY = centroid[1] - 40; bigTextSize = '6px'; k = 4; centered = d; } else { x = slice.width() / 2; y = slice.height() / 2; bigTextX = 0; bigTextY = 0; resultTextX = 0; resultTextY = 0; bigTextSize = '30px'; k = 1; centered = null; } g.transition() .duration(750) .attr('transform', 'translate(' + slice.width() / 2 + ',' + slice.height() / 2 + ')scale(' + k + ')translate(' + -x + ',' + -y + ')'); bigText.transition() .duration(750) .attr('transform', 'translate(0,0)translate(' + bigTextX + ',' + bigTextY + ')') .style('font-size', bigTextSize); resultText.transition() .duration(750) .attr('transform', 'translate(0,0)translate(' + resultTextX + ',' + resultTextY + ')'); }; const selectAndDisplayNameOfRegion = function (feature) { let name = ''; if (feature && feature.properties) { if (feature.properties.ID_2) { name = feature.properties.NAME_2; } else { name = feature.properties.NAME_1; } } bigText.text(name); }; const updateMetrics = function (region) { if (region.length > 0) { resultText.text(format(region[0].metric)); } }; const mouseenter = function (d) { // Darken color let c = colorFn(d); if (c !== 'none') { c = d3.rgb(c).darker().toString(); } d3.select(this).style('fill', c); selectAndDisplayNameOfRegion(d); const result = data.filter(region => region.country_id === d.properties.ISO); updateMetrics(result); }; const mouseout = function () { d3.select(this).style('fill', colorFn); bigText.text(''); resultText.text(''); }; div.append('rect') .attr('class', 'background') .attr('width', slice.width()) .attr('height', slice.height()) .on('click', clicked); g = div.append('g'); const mapLayer = g.append('g') .classed('map-layer', true); bigText = g.append('text') .classed('big-text', true) .attr('x', 20) .attr('y', 45); resultText = g.append('text') .classed('result-text', true) .attr('x', 20) .attr('y', 60); const url = `/static/assets/visualizations/countries/${fd.select_country.toLowerCase()}.geojson`; d3.json(url, function (error, mapData) { const features = mapData.features; const center = d3.geo.centroid(mapData); let scale = 150; let offset = [slice.width() / 2, slice.height() / 2]; let projection = d3.geo.mercator().scale(scale).center(center) .translate(offset); path = path.projection(projection); const bounds = path.bounds(mapData); const hscale = scale * slice.width() / (bounds[1][0] - bounds[0][0]); const vscale = scale * slice.height() / (bounds[1][1] - bounds[0][1]); scale = (hscale < vscale) ? hscale : vscale; const offsetWidth = slice.width() - (bounds[0][0] + bounds[1][0]) / 2; const offsetHeigth = slice.height() - (bounds[0][1] + bounds[1][1]) / 2; offset = [offsetWidth, offsetHeigth]; projection = d3.geo.mercator().center(center).scale(scale).translate(offset); path = path.projection(projection); // Draw each province as a path mapLayer.selectAll('path') .data(features) .enter().append('path') .attr('d', path) .attr('class', 'region') .attr('vector-effect', 'non-scaling-stroke') .style('fill', colorFn) .on('mouseenter', mouseenter) .on('mouseout', mouseout) .on('click', clicked); }); container.show(); }
beforeEach(function() { this.el3 = d3.select(createGraphDiv()); });
//this.tooltip.remove(); //(because it is appended to body) }, // updateFunction routine (mandatory), will be called on new data // (and usually after mainFunction) updateFunction(data, params) { let self = this; self.par = Object.assign({}, this.defaultParams, params); // here is where you do some D3 magic... // (see the examples) (for code, not magic) // make sure to use D3's enter/update/exit pattern with proper joins, to // get the full power of data updates. d3.select('something'); // if you want to pass events to the parent reactComponent, you could do something like: // .on('mouseover', (d) => { // self.mouseoverBar.call(self, d, otherArguments) // }) }, onEvent(obj) { //this function is called when this or another component fires //an event (an action) to the redux store //d is the data object of the item that triggered the event //e is the event name let {d, e} = obj; let self = this; switch (e) {
beforeEach(function() { el = document.createElement('div'); sel = d3.select(el); });
d3.select(gd).selectAll('text').each(function() { expect(d3.select(this).style('visibility')).toEqual('visible'); });
import * as d3 from 'd3' let w = 100 let h = 100 let svg = d3.select("body") .append("svg") .attr("width", "100%") .attr("height", "100%") .attr("viewBox", "0 0 " + w + " " + h) let graph = d3.forceSimulation() .force("link", d3.forceLink() .id(d => d.id) .distance(d => d.value / 250)) .force("centre", d3.forceCenter(w / 2, h / 2)) .force("size", d3.forceCollide() .radius(1) .strength(1)) .alphaDecay(0.001) let links = false d3.json('data/capital_distances.json', (e, data) => { if (e) throw e if (links) { let link = svg.append("g") .attr("class", "links") .selectAll("line") .data(data.links)
d3.json('data/capital_distances.json', (e, data) => { if (e) throw e if (links) { let link = svg.append("g") .attr("class", "links") .selectAll("line") .data(data.links) .enter() .append("line") .attr("stroke-width", d => d.value / 14000) } let countryList = new Set() for (let item of data.links) { countryList.add(item.source) countryList.add(item.target) } let nodeData = [] for (let item of countryList) { nodeData.push({ "id": item }) } let node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(nodeData) .enter() .append("circle") .attr("r", 1) .attr("cx", () => Math.random() * w) .attr("cy", () => Math.random() * h) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)) node.append("title").html(d => d.id) graph.nodes(nodeData) .on("tick", () => { if (links) { link.attr("x1", d => d.source.x) .attr("y1", d => d.source.y) .attr("x2", d => d.target.x) .attr("y2", d => d.target.y) } node.attr("cx", d => d.x) .attr("cy", d => d.y) }) graph.force("link") .links(data.links) resize(graph); d3.select(window).on("resize", resize); function resize() { w = window.innerWidth h = window.innerHeight; svg.attr("width", w).attr("height", h); } })
.on('dragend', function(d) { d3.select(this).classed('dragging', false); });
}; }, componentDidMount() { this.addEventListeners(); }, componentWillUnmount() { this.removeEventListeners(); }, addEventListeners() { var node = React.findDOMNode(this.refs.node); var mouse = []; d3.select(node) .on(Events.MOUSE_MOVE, () => { mouse = d3.mouse(node); Dispatcher[Events.MOUSE_MOVE]({ type: Events.MOUSE_MOVE, activeIndex: Math.floor(mouse[0] / this.props.tickWidth), x: mouse[0], y: mouse[1] }); }) .on(Events.MOUSE_OUT, () => { mouse = d3.mouse(node); Dispatcher[Events.MOUSE_OUT]({ type: Events.MOUSE_OUT, activeIndex: -1, x: mouse[0],
function count(id, selector, length) { expect(d3.select("#" + id) .selectAll(selector)[0].length).toEqual(length); }
function initInfo (container, graphJsonUrl) { graphJsonUrl = graphJsonUrl || 'graph.json'; $('.dep-table table', container).stacktable(); /* d3 graph */ function createNode (dep) { return { name: dep.name, version: dep.version, children: null }; } /** * Transform data from possibly cyclic structure into max 10 levels deep visual structure */ function transformData (rootDep, callback) { var transformsCount = 0 , rootNode = createNode(rootDep); // Avoid 'too much recursion' errors function scheduleTransform (dep, node, level, maxLevel) { setTimeout(function () { transform(dep, node, level, maxLevel); transformsCount--; if (!transformsCount) { callback(rootNode); } }, 0); } function transform (dep, parentNode, level, maxLevel) { level = level || 0; maxLevel = maxLevel || 10; $.each(dep.deps, function(depName, depDep) { var node = createNode(depDep); if (level < maxLevel) { transformsCount++; scheduleTransform(depDep, node, level + 1, maxLevel); } if (!parentNode.children) { parentNode.children = []; } parentNode.children.push(node); }); if (parentNode.children) { parentNode.children = parentNode.children.sort(function(a, b) { if (a.name < b.name) { return -1; } else if (a.name > b.name) { return 1; } else { return 0; } }); } } transform(rootDep, rootNode); } var m = [20, 120, 20, 120] , w = parseInt($(window).width() - $('#main').position().left, 10) - m[1] - m[3] , h = 768 - m[0] - m[2] , i = 0 , root = null , tree = d3.layout.tree().size([h, w]) , diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x] }); var vis = d3.select($('.dep-graph', container)[0]).append('svg:svg') .attr('width', w + m[1] + m[3]) .attr('height', h + m[0] + m[2]) .append('svg:g') .attr('transform', 'translate(' + m[3] + ',' + m[0] + ')'); function update (source) { var duration = d3.event && d3.event.altKey ? 5000 : 500; // Compute the new tree layout. var nodes = tree.nodes(root).reverse(); // Normalize for fixed-depth. nodes.forEach(function(d) { d.y = d.depth * 180; }); // Update the nodes... var node = vis.selectAll('g.node').data(nodes, function(d) { return d.id ? d.id : d.id = ++i; }); // Enter any new nodes at the parent's previous position. var nodeEnter = node.enter().append('svg:g').attr('class', 'node').attr('transform', function () { return 'translate(' + source.y0 + ',' + source.x0 + ')'; }).on('click', function(d) { toggle(d); update(d); }); nodeEnter.append('svg:circle').attr('r', 0.000001).style('fill', function(d) { return d._children ? '#ccc' : '#fff'; }); nodeEnter.append('svg:text').attr('x', function(d) { return d.children || d._children ? -10 : 10; }).attr('dy', '.25em').attr('text-anchor', function(d) { return d.children || d._children ? 'end' : 'start'; }).text(function(d) { return d.name + ' ' + d.version; }).style('fill-opacity', 0.000001); // Transition nodes to their new position. var nodeUpdate = node.transition().duration(duration).attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; }); nodeUpdate.select('circle').attr('r', 4.5).style('fill', function(d) { return d._children ? '#ccc' : '#fff'; }); nodeUpdate.select('text').style('fill-opacity', 1); var nodeExit = node.exit().transition().duration(duration).attr('transform', function () { return 'translate(' + source.y + ',' + source.x + ')'; }).remove(); // Transition exiting nodes to the parent's new position. nodeExit.select('circle').attr('r', 0.000001); nodeExit.select('text').style('fill-opacity', 0.000001); // Update the links... var link = vis.selectAll('path.link').data(tree.links(nodes), function(d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert('svg:path', 'g').attr('class', 'link').attr('d', function () { var o = { x: source.x0, y: source.y0 }; return diagonal({ source: o, target: o }); }).transition().duration(duration).attr('d', diagonal); // Transition links to their new position. link.transition().duration(duration).attr('d', diagonal); // Transition exiting nodes to the parent's new position. link.exit().transition().duration(duration).attr('d', function () { var o = { x: source.x, y: source.y }; return diagonal({ source: o, target: o }); }).remove(); // Stash the old positions for transition. nodes.forEach(function(d) { d.x0 = d.x; d.y0 = d.y; }); } // Toggle children. function toggle (d) { if (d.children) { d._children = d.children; d.children = null; } else { d.children = d._children; d._children = null; } } // Load the graph data and render when change view var graphLoaded = false , graphContainer = $('.dep-graph', container) , tableContainer = $('.dep-table', container); graphContainer.hide(); function initGraph () { var loading = david.createLoadingEl(); graphContainer.prepend(loading); d3.json(pathname + graphJsonUrl, function(er, json) { if (er) { return loading.empty().text('Error occurred retrieving graph data'); } transformData(cycle.retrocycle(json), function(node) { root = node; root.x0 = h / 2; root.y0 = 0; function toggleAll (d) { if (d.children) { d.children.forEach(toggleAll); toggle(d); } } // Initialize the display to show a few nodes. root.children.forEach(toggleAll); update(root); loading.remove(); }); }); } var viewSwitchers = $('.switch a', container); viewSwitchers.click(function(event) { event.preventDefault(); merge(state, $.deparam.fragment($(this).attr('href'))); $.bbq.pushState(state); }); function onHashChange () { merge(state, $.bbq.getState()); viewSwitchers.removeClass('selected'); if (state.view !== 'tree') { graphContainer.hide(); tableContainer.fadeIn(); viewSwitchers.first().addClass('selected'); } else { tableContainer.hide(); graphContainer.fadeIn(); viewSwitchers.last().addClass('selected'); if (!graphLoaded) { graphLoaded = true; initGraph(); } } } /* Init changes links */ $('.changes', container).click(function(event) { event.preventDefault(); var row = $(this).closest('tr'), container = $('<div class="changes-popup"/>').append(david.createLoadingEl()); var name, from, to; if (row.closest('table').is('.stacktable')) { name = $('a:first-child', row).text(); from = $('.st-val', row.next()).text(); to = $('.st-val', row.next().next()).text(); } else { name = $('.dep a:first-child', row).text(); from = $('.required', row).text(); to = $('.stable', row).text(); } $.fancybox.open(container); $.ajax({ url: '/package/' + name + '/changes.json', dataType: 'json', data: {from: from, to: to}, success: function(data) { data.from = from; data.to = to; var tpl = fs.readFileSync(__dirname + '/../../dist/inc/changes.html'); container.html(Handlebars.compile(tpl)(data)); $.fancybox.update(); }, error: function () { container.html(fs.readFileSync(__dirname + '/../../dist/inc/changelog-er.html')); $.fancybox.update(); } }); }); $(window).bind('hashchange', onHashChange); onHashChange(); }
.each(function() { d3.select(this) .call(drawTexts, gd) .call(setupTraceToggle, gd); });
var addDataList = function(dataListSelector) { d3.select(dataListSelector).html(dataListSortedNames); }
function render() { var selection = d3.select(this), p = preset.apply(this, arguments), geom = geometry.apply(this, arguments), picon = p.icon || (geom === 'line' ? 'other-line' : 'marker-stroked'), isMaki = dataFeatureIcons.hasOwnProperty(picon + '-24'); if (picon === 'dentist') { isMaki = true; // workaround for dentist icon missing in `maki-sprite.json` } function tag_classes(p) { var s = ''; for (var i in p.tags) { s += ' tag-' + i; if (p.tags[i] !== '*') { s += ' tag-' + i + '-' + p.tags[i]; } } return s; } var fill = selection.selectAll('.preset-icon-fill') .data([0]); fill = fill.enter() .append('div') .merge(fill); fill .attr('class', function() { return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p); }); var frame = selection.selectAll('.preset-icon-frame') .data([0]); frame = frame.enter() .append('div') .call(svgIcon('#preset-icon-frame')) .merge(frame); frame .attr('class', function() { return 'preset-icon-frame ' + (geom === 'area' ? '' : 'hide'); }); var icon = selection.selectAll('.preset-icon') .data([0]); icon = icon.enter() .append('div') .attr('class', 'preset-icon') .call(svgIcon('')) .merge(icon); icon .attr('class', 'preset-icon preset-icon-' + (isMaki ? '32' : (geom === 'area' ? '44' : '60'))); icon.selectAll('svg') .attr('class', function() { return 'icon ' + picon + tag_classes(p); }); icon.selectAll('use') // workaround: maki parking-24 broken? .attr('href', '#' + picon + (isMaki ? (picon === 'parking' ? '-18' : '-24') : '')); }
/** * Removes all DOM elements from the HTML element provided * * @method removeAll * @param el {HTMLElement} Reference to the HTML Element that * contains the chart * @returns {D3.Selection|D3.Transition.Transition} With the chart * child element removed */ removeAll(el) { return d3.select(el).selectAll('*').remove(); }
CodeHeatmap.prototype.hideTooltip_ = function(element, tooltip) { d3.select(element).attr('class', 'src-line-normal'); tooltip.attr('class', 'tooltip tooltip-invisible'); };
_unhighlight: function(e) { d3.select(e.currentTarget).classed('rowchart__bar--highlight', false); },
it('should put scatterternary trace in \'frontplot\' node', function() { var nodes = d3.select('.frontplot').selectAll('.scatter'); expect(nodes.size()).toEqual(1); });
const mouseout = function () { d3.select(this).style('fill', colorFn); bigText.text(''); resultText.text(''); };
return function () { d3.select(this).classed('dragged', start); };
renderD3(props) { let nodeMap = {}; let svg = d3.select(this.svg); let data = props.data; let max = _.maxBy(data, 'value'); let width = 800, height = 600; // 3200 2400 let config = props.config; let flagOpts = { width: 14, height: 14, transform: [20, 13], left: width - 250, top: 18, } let abbrs = _.groupBy(data, 'abbr'); let areaTotal = _.get(abbrs, 'AREA_TOT.0.value'); if (!areaTotal) { svg.select('g.links').selectAll('.link').data([]).exit().remove(); svg.select('g.nodes').selectAll('.node').data([]).exit().remove(); return; }; let rect = svg.select('g.rects').selectAll('.rect'); rect.select('rect') .attr({ width: height / 4, height: height / 4, rx: height / 40, stroke: "black", fill: "white", }) .style({ "stroke-width": 4, }); rect.select('text').attr({ transform: 'translate(30, ' + (height / 9) + ')', }) let sun = svg.select('g.sun').attr({ transform: 'translate(70, ' + (height * 2 / 3) + ')', }); sun.select('circle').attr({ r: 50, fill: 'yellow', }); sun.select('text') .attr({ transform: 'translate(-20, 10)', }) .text(data[0].year); let placeInfo = svg.select('g.place').attr({ transform: 'translate(20, ' + ((height * 2 / 3) + 70) + ')', }); placeInfo.select('.place-name').text(data[0].place); data = _.filter(data, function(d) { return [ 'SR', 'UPH', 'LP', 'LBP', 'TP', 'BR', 'FW', 'FP', 'LBS', 'LBW', 'FCSI', 'ASI', 'L', 'FCI', 'EI', 'TIC', ].indexOf(d.abbr) !== -1; }); let flag = svg.select('g.flags') .attr({ 'transform': `translate(-${height/16}, -${height/16})`, }) .selectAll('.flag').data(data); let flagEnter = flag.enter().append('g').attr('class', 'flag'); flagEnter.append('text').attr({ 'transform': `translate(${flagOpts.transform[0]}, ${flagOpts.transform[1]})`, }); flag.attr({ transform: function(d, i) { let {left, top} = flagOpts; top = height - top * ((data || []).length - i); return `translate(${left}, ${top})`; }, }); flag.select('text').text(function(d) { return d.abbr + ': ' + d.energy; }); flag.exit().remove(); let nodes = _.map(data, function(n) { if (!config[n.abbr]) { config[n.abbr] = {}; } let c = config[n.abbr]; let node = { ...n, value: (n.value / areaTotal) || 0, x: c.x || width/2, y: c.y || height/2, }; nodeMap[n.abbr] = node; return node; }); if (!config.links) { config.links = [ ['LP', 'TP', []], ['LBP', 'TP', []], ['TP', 'BR', []], ['TP', 'FP', []], ['BR', 'TIC', []], ['FP', 'ASI', []], ['ASI', 'EI', []], ]; } let links = _.map(config.links, function(link) { let l = { source: nodeMap[link[0]], target: nodeMap[link[1]], path: link[2], value: Math.max(nodeMap[link[1]].value, 1), }; if (_.isEmpty(l.source.sourceLinks)) { l.source.sourceLinks = []; } l.source.sourceLinks.push(l); if (_.isEmpty(l.source.targetLinks)) { l.source.targetLinks = []; } l.source.targetLinks.push(l); return l; }); /** play with links to remove BR to TIC link **/ let brticIndex = _.findIndex(links, function(link){ return (link.source.abbr == "BR" && link.target.abbr == "TIC") }); let tpbrIndex = _.findIndex(links, function(link){ return (link.source.abbr == "TP" && link.target.abbr == "BR") }); //console.log(tpbrIndex); /* links[tpbrIndex].path = _.concat(links[tpbrIndex].path, links[brticIndex].path); links[tpbrIndex].target.x = links[brticIndex].target.x; links[tpbrIndex].target.y = links[brticIndex].target.y; links = _.remove(links, function(link){ return !(link.source.abbr == "BR" && link.target.abbr == "TIC") }); */ links[brticIndex].value = links[tpbrIndex].value; /* links[brticIndex].target.abbr = links[tpbrIndex].target.abbr; links[brticIndex].target.value = links[tpbrIndex].target.value; */ //console.log(links); /** end of remove BR to TIC link **/ let path = function(d) { let x0 = d.source.x , y0 = d.source.y , x3 = d.target.x , y3 = d.target.y ; return d3.svg.line().interpolate('cardinal')([ [x0, y0], ...(d.path || []), [x3, y3] ]); }; let link = svg.select('g.links').selectAll('.link').data(links); let linkEnter = link.enter().append('path') .attr({ 'class': 'link', }) .on('contextmenu', function(d) { d3.event.preventDefault(); let { layerX, layerY } = d3.event; let coords = _.sortBy(d.path, function([x, y]) { return (x - layerX) * (x - layerX) + (y - layerY) * (y - layerY); }); let coord = _.first(coords); if (coord) { _.remove(d.path, function(c) { return c[0] === coord[0] && c[1] === coord[1]; }); } d3.select(this).attr('d', path); }) .on('dblclick', function(d) { let { layerX, layerY } = d3.event; if (!d.path) { d.path = []; } d.path.push([layerX, layerY]); }) .call( d3.behavior.drag().origin((d)=>d) .on('drag', function(d) { let { layerX, layerY } = d3.event.sourceEvent; let { dx, dy} = d3.event; let coords = _.sortBy(d.path, function([x, y]) { return (x - layerX) * (x - layerX) + (y - layerY) * (y - layerY); }); let coord = _.first(coords); if (coord) { coord[0] += dx; coord[1] += dy; } d3.select(this).attr('d', path); }) ) ; link .attr({ d: path, }) .style("stroke-width", function(d) { return Math.max(1, d.value); }) .attr("fill", "none") .attr("stroke", "#F28017") ; link.exit().remove(); svg.selectAll('g.node').remove(); let node = svg.select('g.nodes').selectAll(".node").data(nodes); let nodeEnter = node.enter().append('g') .attr({ 'class': 'node', }) .call( d3.behavior.drag().origin((d)=>d) .on('dragstart', function() {this.parentNode.appendChild(this);}) .on('drag', function(d) { let { dx, dy } = d3.event; d.x += dx; d.y += dy; config[d.abbr].x = d.x; config[d.abbr].y = d.y; link.attr('d', path); d3.select(this).attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }); props.onConfigChange(config); }) ) ; nodeEnter.append('text') .text((d)=> { return d.abbr !== "TIC" ? d.abbr + ' ' + Math.round(d.value * 10) / 10 : '' }); node.attr({ 'transform': (d)=>'translate(' + d.x + ',' + d.y + ')', }); node.exit().remove(); node.each(function() { this.parentNode.appendChild(this); }); }
return function (d) { d3.select(this) .classed('selected', over); };
/* Modified from http://bl.ocks.org/ganeshv/6a8e9ada3ab7f2d88022 */ function treemap(slice, payload) { const div = d3.select(slice.selector); const _draw = function (data, eltWidth, eltHeight, formData) { const margin = { top: 0, right: 0, bottom: 0, left: 0 }; const navBarHeight = 36; const navBarTitleSize = navBarHeight / 3; const navBarBuffer = 10; const width = eltWidth - margin.left - margin.right; const height = (eltHeight - navBarHeight - navBarBuffer - margin.top - margin.bottom); const formatNumber = d3.format(formData.number_format); let transitioning; const x = d3.scale.linear() .domain([0, width]) .range([0, width]); const y = d3.scale.linear() .domain([0, height]) .range([0, height]); const treemap = d3.layout.treemap() .children(function (d, depth) { return depth ? null : d._children; }) .sort(function (a, b) { return a.value - b.value; }) .ratio(formData.treemap_ratio) .mode('squarify') .round(false); const svg = div.append('svg') .attr('class', 'treemap') .attr('width', eltWidth) .attr('height', eltHeight); const chartContainer = svg.append('g') .attr('transform', 'translate(' + margin.left + ',' + (margin.top + navBarHeight + navBarBuffer) + ')') .style('shape-rendering', 'crispEdges'); const grandparent = svg.append('g') .attr('class', 'grandparent') .attr('transform', 'translate(0,' + (margin.top + (navBarBuffer / 2)) + ')'); grandparent.append('rect') .attr('width', width) .attr('height', navBarHeight); grandparent.append('text') .attr('x', width / 2) .attr('y', (navBarHeight / 2) + (navBarTitleSize / 2)) .style('font-size', navBarTitleSize + 'px') .style('text-anchor', 'middle'); const initialize = function (root) { root.x = 0; root.y = 0; root.dx = width; root.dy = height; root.depth = 0; }; // Aggregate the values for internal nodes. This is normally done by the // treemap layout, but not here because of our custom implementation. // We also take a snapshot of the original children (_children) to avoid // the children being overwritten when when layout is computed. const accumulate = function (d) { d._children = d.children; if (d._children) { d.value = d.children.reduce(function (p, v) { return p + accumulate(v); }, 0); } return d.value; }; // Compute the treemap layout recursively such that each group of siblings // uses the same size (1x1) rather than the dimensions of the parent cell. // This optimizes the layout for the current zoom state. Note that a wrapper // object is created for the parent node for each group of siblings so that // the parents dimensions are not discarded as we recurse. Since each group // of sibling was laid out in 1x1, we must rescale to fit using absolute // coordinates. This lets us use a viewport to zoom. const layout = function (d) { if (d._children) { treemap.nodes({ _children: d._children }); d._children.forEach(function (c) { c.x = d.x + (c.x * d.dx); c.y = d.y + (c.y * d.dy); c.dx *= d.dx; c.dy *= d.dy; c.parent = d; layout(c); }); } }; const display = function (d) { const transition = function (d) { if (transitioning || !d) { return; } transitioning = true; const g2 = display(d); const t1 = g1.transition().duration(750); const t2 = g2.transition().duration(750); // Update the domain only after entering new elements. x.domain([d.x, d.x + d.dx]); y.domain([d.y, d.y + d.dy]); // Enable anti-aliasing during the transition. chartContainer.style('shape-rendering', null); // Draw child nodes on top of parent nodes. chartContainer.selectAll('.depth').sort(function (a, b) { return a.depth - b.depth; }); // Fade-in entering text. g2.selectAll('text').style('fill-opacity', 0); // Transition to the new view. t1.selectAll('.ptext').call(text).style('fill-opacity', 0); t1.selectAll('.ctext').call(text2).style('fill-opacity', 0); t2.selectAll('.ptext').call(text).style('fill-opacity', 1); t2.selectAll('.ctext').call(text2).style('fill-opacity', 1); t1.selectAll('rect').call(rect); t2.selectAll('rect').call(rect); // Remove the old node when the transition is finished. t1.remove().each('end', function () { chartContainer.style('shape-rendering', 'crispEdges'); transitioning = false; }); }; grandparent .datum(d.parent) .on('click', transition) .select('text') .text(name(d)); const g1 = chartContainer.append('g') .datum(d) .attr('class', 'depth'); const g = g1.selectAll('g') .data(d._children) .enter() .append('g'); g.filter(function (d) { return d._children; }) .classed('children', true) .on('click', transition); const children = g.selectAll('.child') .data(function (d) { return d._children || [d]; }) .enter() .append('g'); children.append('rect') .attr('class', 'child') .call(rect) .append('title') .text(function (d) { return d.name + ' (' + formatNumber(d.value) + ')'; }); children.append('text') .attr('class', 'ctext') .text(function (d) { return d.name; }) .call(text2); g.append('rect') .attr('class', 'parent') .call(rect); const t = g.append('text') .attr('class', 'ptext') .attr('dy', '.75em'); t.append('tspan') .text(function (d) { return d.name; }); t.append('tspan') .attr('dy', '1.0em') .text(function (d) { return formatNumber(d.value); }); t.call(text); g.selectAll('rect') .style('fill', function (d) { return getColorFromScheme(d.name, formData.color_scheme); }); return g; }; const text = function (selection) { selection.selectAll('tspan') .attr('x', function (d) { return x(d.x) + 6; }); selection.attr('x', function (d) { return x(d.x) + 6; }) .attr('y', function (d) { return y(d.y) + 6; }) .style('opacity', function (d) { return this.getComputedTextLength() < x(d.x + d.dx) - x(d.x) ? 1 : 0; }); }; const text2 = function (selection) { selection.attr('x', function (d) { return x(d.x + d.dx) - this.getComputedTextLength() - 6; }) .attr('y', function (d) { return y(d.y + d.dy) - 6; }) .style('opacity', function (d) { return this.getComputedTextLength() < x(d.x + d.dx) - x(d.x) ? 1 : 0; }); }; const rect = function (selection) { selection.attr('x', function (d) { return x(d.x); }) .attr('y', function (d) { return y(d.y); }) .attr('width', function (d) { return x(d.x + d.dx) - x(d.x); }) .attr('height', function (d) { return y(d.y + d.dy) - y(d.y); }); }; const name = function (d) { return d.parent ? name(d.parent) + ' / ' + d.name + ' (' + formatNumber(d.value) + ')' : (slice.datasource.verbose_map[d.name] || d.name) + ' (' + formatNumber(d.value) + ')'; }; initialize(data); accumulate(data); layout(data); display(data); }; div.selectAll('*').remove(); const width = slice.width(); const height = slice.height() / payload.data.length; for (let i = 0, l = payload.data.length; i < l; i += 1) { _draw(payload.data[i], width, height, slice.formData); } }
require("jsdom"); var d3 = require("d3"); var _ = require("underscore"); var fs = require("fs"); var size = 200; var body = d3.select("body").html(""); var svg = body.append("svg") .attr("width",size) .attr("height",size); var data = _.range(20).map(function(t){ var x = Math.cos(2*Math.PI*t/20); var y = Math.sin(2*Math.PI*t/20); return [x,y]; }); var x = d3.scale.linear().domain([-1.2,1.2]).range([0,size]); var y = d3.scale.linear().domain([-1.2,1.2]).range([size,0]); var color = d3.scale.category20(); svg.selectAll("circle").data(data).enter() .append("circle") .attr({ cx: function(d){ return x(d[0]); }, cy:function(d){
elements.map(e => d3.select(e).classed('ds-selected', false));
writingGraph(node, props) { var div = d3.select(node); div.select('svg').remove(); var data = [{ type: 'Analytical' ,value: props.analytical }, { type: 'Confidence', value: props.confident }, { type: 'Tentative', value: props.tentative }]; var colors = ["#969696", "#de9ed6", "#9c9ede"]; var margin = {top: 10, right: 0, bottom: 0, left: 0}, width = 350, height = 173 - margin.top - margin.bottom; var formatPercent = d3.format(".0%"); var x = d3.scale.ordinal() .rangeRoundBands([0, width], .1); var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom"); var tip = d3tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { return "<span style='color:white'>" + Math.round(d.value) + "%</span>"; }); var svg = d3.select(node).append("svg") .attr("viewBox", "0 0 455 225") .append("g") .attr("transform", "translate(52,10)"); svg.call(tip); x.domain(data.map(function(d) { return d.type; })); y.domain([0, d3.max(data, function(d) { return d.value; })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0,175)") .call(xAxis); svg.selectAll(".bar") .data(data) .enter().append("rect") .attr("fill", function(d, i){ return colors[i]; }) .on('mouseover', tip.show) .on('mouseout', tip.hide) .attr("x", function(d) { return x(d.type); }) .attr("width", x.rangeBand()) .attr("y", function(d) { return y(d.value); }) .attr("height", 0) .transition() .duration(900) .attr("height", function(d) { return height - y(d.value); }); svg.selectAll(".bar").on('mouseover', tip.show) .on('mouseout', tip.hide) function type(d) { d.value = +d.value; return d; } }