Exemple #1
0
// Simple chart mapping content as circles along a time axis.
export default function circleChart({svgEl, rootSelection, scale, data = []}) {
    const t = d => Math.floor(scale(new Date(d.date)))

    // For force sim beeswarm example, see
    // http://bl.ocks.org/mbostock/6526445e2b44303eebf21da3b6627320
    const collisionForce = forceCollide().radius(d => d.radius + PADDING)
    const sim = forceSimulation(data)
        .force('x', forceX(d => d.initialX))
        .force('y', forceY(t).strength(1))
        .force('collide', collisionForce)
        .stop()
    for (let i = 0; i < SIM_STEPS; ++i) sim.tick()

    const groups = rootSelection.append('g')
        .selectAll('g.item')
        .data(data.filter(d => t(d) > 0))
        .enter().append('g')
            .attr('class', 'item')

    const links = groups.append('a')
            .attr('xlink:href', d => d.url)
            .attr('transform', d => `translate(${d.x}, ${d.y})`)
            .on('mouseover', _ => svgEl.classList.add('tooltipActive'))
            .on('mouseout', _ => svgEl.classList.remove('tooltipActive'))

    links.append('circle')
        .attr('class', d => d.bubbleClass)
        .attr('r', d => d.radius)

    const TOOLTIP_TEXT_PADDING = 8
    const tooltips = links.append('g').attr('class', 'tooltip')
    tooltips.append('text')
        .text(d => {
            // Manually ellipsis out titles, since we can't really on <text> via css
            const MAX_LENGTH = 60
            return d.title.length > MAX_LENGTH
                ? `${d.title.slice(0, MAX_LENGTH)}…`
                : d.title
        })
        .attr('class', 'tooltipText')
        .attr('text-anchor', 'start')
        .attr('transform', d => `translate(${TOOLTIP_TEXT_PADDING}, -${d.radius + 35})`)

    tooltips.append('text')
        .attr('class', 'date tooltipText')
        .attr('text-anchor', 'start')
        .text(d => (new Date(d.date)).toISOString().split('T')[0])
        .attr('transform', d => `translate(${TOOLTIP_TEXT_PADDING}, -${d.radius + 20})`)

    links.append('line')
        .attr('class', 'tooltipLine')
        .attr('x1', 1)
        .attr('x2', 1)
        .attr('y1', function() {
            const circle = select(this.parentElement.firstChild)
            return -1 * (parseFloat(circle.attr('r')) + 3)
        })
        .attr('y2', function() { return parseFloat(select(this).attr('y1')) - 45 })
}
Exemple #2
0
	drawChart(nodes, parent) {

	    // transition
	    var t = d3.transition().duration(500);
	    let bubbleGWrapper = d3.select('.bubbleGWrapper')

	    // Apply the general update pattern to the nodes.
	    this.bubbleDataJoin = bubbleGWrapper 
	        .selectAll('circle')
	        .data(nodes, d => d.interval)
	        .on('mouseover', d => {
	            console.log('bubbleDataJoin Hover')
	            console.log(d)
	          });
	    let bubbleDataJoinEnter = this.bubbleDataJoin.enter().append('circle');
	    
	    this.bubbleDataJoin
	        .transition(t)
	          .style("fill", d => this.seqClr(d.count))
	          .attr("r", d => d.count);

	    bubbleDataJoinEnter
	        .style("fill", d => this.seqClr(d.count))
	        .merge(this.bubbleDataJoin)
	        .on('mousemove', d => {
				let toolTipObj = {
					val: `${d.index} 1/2 Steps`, 
		  			count: d.count,
		  			pgX: d3.event.pageX,
		  			pgY: d3.event.pageY
				}

				this.props.showTooltip(toolTipObj);
	        })
	        .on('mouseout', this.props.hideTooltip)
	        .transition().duration(1200)
	          .attr("r", d => d.count)

	    this.simulation = d3.forceSimulation(nodes)
	    // .force("charge", d3.forceManyBody().strength(-150))
	    .force("yforce", d3.forceY().strength(.03))
			.force("xforce", d3.forceX().strength(.03))
	    .force("collide", d3.forceCollide().strength(.9).radius(d => d.count + 2))
	    .force("center", d3.forceCenter())
	    .alpha(.9)
	    .velocityDecay(.5)
	    .on("tick", () => {
	      this.bubbleDataJoin
	      .attrs({
	        "cx": d => d.x,
	        "cy": d => d.y
	      });
	      
	      bubbleDataJoinEnter
	      .attrs({
	        "cx": d => d.x,
	        "cy": d => d.y
	      });
	    });

	}
    .call(d3.zoom().on("zoom", redraw));

let vis = svg
    .append('svg:g');

function redraw() {
    vis.attr("transform",
        "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}

let graph = d3.forceSimulation()
    .force("link", d3.forceLink()
        .id(d => d.id)
        .distance(d => d.value / 50))
    .force("centre", d3.forceCenter(w / 2, h / 2))
    .force("size", d3.forceCollide()
        .radius(5)
        .strength(1))
    .alphaDecay(0.001)

d3.json('data/capital_distances.json', (e, data) => {
    if (e) throw e

    //    let link = svg.append("g")
    //        .attr("class", "links")
    //        .selectAll("line")
    //        .data(data.links)
    //        .enter()
    //        .append("line")
    //        .attr("stroke-width", d => 5.0 * d.value / 14000)