chiasm-charts
Advanced tools
Comparing version 0.1.3 to 0.1.4
{ | ||
"name": "chiasm-charts", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "Reusable data visualization components.", | ||
@@ -5,0 +5,0 @@ "repository": "git://github.com/chiasm-project/chiasm-charts.git", |
@@ -8,7 +8,3 @@ var d3 = require("d3"); | ||
var my = ChiasmComponent({ | ||
fill: "black", | ||
stroke: "none", | ||
strokeWidth: "1px" | ||
}); | ||
var my = ChiasmComponent(); | ||
@@ -33,5 +29,3 @@ var svg = d3.select(my.initSVG()); | ||
// The placement of this line ensures that the bars are drawn | ||
// behind the axis. | ||
var barsG = g.append("g"); | ||
var marksG = g.append("g"); | ||
@@ -49,17 +43,29 @@ var xAxisG = mixins.xAxis(my, g); | ||
my.when(["dataset", "xScaled", "yScaled", "height", "xRangeBand", "fill", "stroke", "strokeWidth"], | ||
function (dataset, xScaled, yScaled, height, xRangeBand, fill, stroke, strokeWidth){ | ||
my.when("dataset", function (dataset){ | ||
var marks = marksG.selectAll("rect").data(dataset.data); | ||
marks.enter().append("rect"); | ||
marks.exit().remove(); | ||
my.marks = marks; | ||
}); | ||
var bars = barsG.selectAll("rect").data(dataset.data); | ||
bars.enter().append("rect"); | ||
bars | ||
my.when(["marks", "xScaled", "yScaled", "height", "xRangeBand"], | ||
function (marks, xScaled, yScaled, height, xRangeBand){ | ||
marks | ||
.attr("x", xScaled) | ||
.attr("width", xRangeBand) | ||
.attr("y", yScaled) | ||
.attr("height", function (d){ return height - yScaled(d); }) | ||
.attr("height", function (d){ return height - yScaled(d); }); | ||
}); | ||
// TODO figure out how to deal with color scales, then make this a mixin. | ||
my.addPublicProperties({ | ||
fill: "black", | ||
stroke: "none", | ||
strokeWidth: "1px" | ||
}); | ||
my.when(["marks", "fill", "stroke", "strokeWidth"], function (marks, fill, stroke, strokeWidth){ | ||
marks | ||
.style("stroke", stroke) | ||
.style("stroke-width", strokeWidth) | ||
.style("fill", fill); | ||
bars.exit().remove(); | ||
}); | ||
@@ -66,0 +72,0 @@ |
@@ -28,2 +28,4 @@ var d3 = require("d3"); | ||
var marksG = g.append("g"); | ||
var xAxisG = mixins.xAxis(my, g); | ||
@@ -38,3 +40,3 @@ var yAxisG = mixins.yAxis(my, g); | ||
my.addPublicProperty("colorColumn", Model.None); | ||
my.addPublicProperty("colorRangeMin", "#FFFFFF"); | ||
my.addPublicProperty("colorRangeMin", "#EEEECC"); | ||
my.addPublicProperty("colorRangeMax", "#000000"); | ||
@@ -54,36 +56,33 @@ | ||
my.when(["dataset", "xScaled", "yScaled", "xRangeBand", "yRangeBand", "colorScaled"], | ||
function (dataset, xScaled, yScaled, xRangeBand, yRangeBand, colorScaled) { | ||
my.when("dataset", function (dataset){ | ||
var marks = marksG.selectAll("rect").data(dataset.data); | ||
marks.enter().append("rect"); | ||
marks.exit().remove(); | ||
my.marks = marks; | ||
}); | ||
var bars = g.selectAll("rect").data(dataset.data); | ||
bars.enter().append("rect"); | ||
bars | ||
my.when(["marks", "xScaled", "yScaled", "yScaleType", "xRangeBand", "yRangeBand", "colorScaled"], | ||
function (marks, xScaled, yScaled, yScaleType, xRangeBand, yRangeBand, colorScaled) { | ||
// This line makes it work for both numeric intervals and ordinal scales. | ||
var yOffset = (yScaleType === "linear") ? yRangeBand : 0; | ||
marks | ||
.attr("x", xScaled) | ||
.attr("width", xRangeBand) | ||
.attr("y", function (d){ return yScaled(d) - yRangeBand; }) | ||
.attr("y", function (d){ return yScaled(d) - yOffset; }) | ||
.attr("height", yRangeBand) | ||
.attr("fill", colorScaled); | ||
bars.exit().remove(); | ||
}); | ||
my.when(["marks", "colorScaled"], function (marks, colorScaled){ | ||
marks.style("fill", colorScaled); | ||
}); | ||
//my.when(["data", "yScale", "yColumn", "height"], function (data, yScale, yColumn, height){ | ||
// // TODO move this logic to scale creation | ||
// yScale.rangeBands([height, 0]); | ||
// my.y = function(d) { | ||
// // Using yScale.step here is kind of an ugly hack to get the | ||
// // right behavior for both linear and ordinal id scales on the Y axis. | ||
// return yScale(d[yColumn] + yScale.step); | ||
// }; | ||
//my.when(["fill", "stroke", "strokeWidth"], function (fill, stroke, strokeWidth){ | ||
// marks | ||
// .style("stroke", stroke) | ||
// .style("stroke-width", strokeWidth) | ||
// .style("fill", fill); | ||
//}); | ||
//function updateBarStyles(){ | ||
// my.rects | ||
// .attr("stroke", my.stroke) | ||
// .attr("stroke-width", my.strokeWidth); | ||
//} | ||
//my.when(["rects", "stroke", "strokeWidth"], updateBarStyles) | ||
return my; | ||
@@ -90,0 +89,0 @@ } |
@@ -68,14 +68,29 @@ var d3 = require("d3"); | ||
my.when(["dataset", "xScaled", "yScaled", "circleRadius"], | ||
function (dataset, xScaled, yScaled, circleRadius) { | ||
my.when("dataset", function (dataset) { | ||
var marks = g.selectAll("circle").data(dataset.data); | ||
marks.enter().append("circle"); | ||
marks.exit().remove(); | ||
my.marks = marks; | ||
}); | ||
var circles = g.selectAll("circle").data(dataset.data); | ||
circles.enter().append("circle"); | ||
circles | ||
my.when(["marks", "xScaled", "yScaled", "circleRadius"], | ||
function (marks, xScaled, yScaled, circleRadius) { | ||
marks | ||
.attr("cx", xScaled) | ||
.attr("cy", yScaled) | ||
.attr("r", circleRadius); | ||
circles.exit().remove(); | ||
}); | ||
// TODO figure out how to deal with color scales, then make this a mixin. | ||
my.addPublicProperties({ | ||
fill: "black", | ||
stroke: "none", | ||
strokeWidth: "1px" | ||
}); | ||
my.when(["marks", "fill", "stroke", "strokeWidth"], function (marks, fill, stroke, strokeWidth){ | ||
marks | ||
.style("stroke", stroke) | ||
.style("stroke-width", strokeWidth) | ||
.style("fill", fill); | ||
}); | ||
@@ -82,0 +97,0 @@ return my; |
@@ -20,5 +20,6 @@ var d3 = require("d3"); | ||
var drag = d3.behavior.drag().on("drag", function (d) { | ||
// Mutate the margin object. | ||
my.margin[d] = { | ||
// Update the margin based on the side being dragged. | ||
// "d" is one of "left", "right", "top", "bottom". | ||
my.margin = set(my.margin, d, { | ||
left: d3.event.x, | ||
@@ -28,7 +29,4 @@ right: -d3.event.x, | ||
bottom: -d3.event.y, | ||
}[d]; | ||
}[d]); | ||
// Notify model-js that the margin object has been mutated. | ||
my.margin = my.margin; | ||
// Hide the handles during drag. | ||
@@ -44,3 +42,6 @@ handles.style("fill", "none"); | ||
.on("mouseenter", function (){ | ||
d3.select(this).style("fill", marginEditorFill); | ||
// Do not show the handle if the user is in the middle of dragging something else. | ||
if(!d3.event.buttons){ | ||
d3.select(this).style("fill", marginEditorFill); | ||
} | ||
}) | ||
@@ -117,1 +118,12 @@ .on("mouseout", function (){ | ||
}; | ||
// Creates a new object with the given value changed. | ||
// This is to approximate immutability to avoid issues that | ||
// crop up when multiple components reference the same margin object. | ||
function set(obj, property, value){ | ||
var newObj = {}; | ||
Object.keys(obj).forEach(function (d){ | ||
newObj[d] = (d === property) ? value : obj[d]; | ||
}); | ||
return newObj; | ||
} |
@@ -8,6 +8,33 @@ var d3 = require("d3"); | ||
my.addPublicProperty("xAxisTickDensity", 70); | ||
my.addPublicProperty("xAxisTickAngle", 0); | ||
my.when(["xScale", "xAxisTickDensity", "width"], function (xScale, xAxisTickDensity, width){ | ||
my.when(["xScale", "xAxisTickDensity", "xAxisTickAngle", "width"], function (xScale, xAxisTickDensity, xAxisTickAngle, width){ | ||
axis.scale(xScale).ticks(width / xAxisTickDensity) | ||
axisG.call(axis); | ||
var text = axisG.selectAll("text") | ||
.attr("transform", "rotate(-" + xAxisTickAngle + ")" ); | ||
if(xAxisTickAngle > 45){ | ||
// TODO try to find a way to have this non-hard-coded | ||
text | ||
.attr("dx", "-0.9em") | ||
.attr("dy", "-0.6em") | ||
.style("text-anchor", "end"); | ||
} else { | ||
text | ||
.attr("dx", "0em") | ||
//.attr("dy", "0em") | ||
//.style("text-anchor", "middle"); | ||
} | ||
// Make labels vertical on click. | ||
// TODO add drag interaction here for continuous editing. | ||
text.on("click", function (){ | ||
if(my.xAxisTickAngle === 0){ | ||
my.xAxisTickAngle = 90; | ||
} else { | ||
my.xAxisTickAngle = 0; | ||
} | ||
}); | ||
}); | ||
@@ -14,0 +41,0 @@ |
@@ -49,3 +49,16 @@ var Chiasm = require("chiasm"); | ||
"myHeatmap", | ||
"myLineChart" | ||
{ | ||
"orientation": "vertical", | ||
"children": [ | ||
"myHeatmapOrdinal", | ||
"myHeatmapOrdinalY" | ||
] | ||
}, | ||
{ | ||
"orientation": "vertical", | ||
"children": [ | ||
"myScatterPlotTimeX", | ||
"myLineChart" | ||
] | ||
} | ||
] | ||
@@ -84,4 +97,4 @@ } | ||
"state": { | ||
"xAxisLabelText": "Sepal Length", | ||
"xColumn": "sepal_length", | ||
"xAxisLabelText": "Petal Width", | ||
"xColumn": "petal_width", | ||
"yAxisLabelText": "Petal Length", | ||
@@ -101,2 +114,4 @@ "yColumn": "petal_length", | ||
"yColumn": "petal_length", | ||
"circleRadius": 20, | ||
"fill": "rgba(100, 0, 0, 0.1)", | ||
"xAxisLabelTextOffset": xAxisLabelTextOffset, | ||
@@ -107,2 +122,15 @@ "yAxisLabelTextOffset": yAxisLabelTextOffset, | ||
}, | ||
"myScatterPlotTimeX": { | ||
"plugin": "scatterPlot", | ||
"state": { | ||
"xAxisLabelText": "Time", | ||
"xColumn": "timestamp", | ||
"yAxisLabelText": "Temperature", | ||
"yColumn": "temperature", | ||
"circleRadius": 2, | ||
"xAxisLabelTextOffset": xAxisLabelTextOffset, | ||
"yAxisLabelTextOffset": yAxisLabelTextOffset, | ||
"margin": margin | ||
} | ||
}, | ||
"myBoxPlot": { | ||
@@ -204,2 +232,49 @@ "plugin": "boxPlot", | ||
}, | ||
"heatmapOrdinalData": { | ||
"plugin": "dataReduction", | ||
"state": { | ||
"aggregate": { | ||
"dimensions": [ | ||
{ | ||
"column": "petal_length", | ||
"histogram": true, | ||
"numBins": 15 | ||
}, | ||
{ | ||
"column": "species" | ||
} | ||
], | ||
"measures": [{ | ||
"outColumn": "count", | ||
"operator": "count" | ||
}] | ||
} | ||
} | ||
}, | ||
"myHeatmapOrdinal": { | ||
"plugin": "heatMap", | ||
"state": { | ||
"xAxisLabelText": "Species", | ||
"xColumn": "species", | ||
"yAxisLabelText": "Petal Length", | ||
"yColumn": "petal_length", | ||
"colorColumn": "count", | ||
"xAxisLabelTextOffset": xAxisLabelTextOffset, | ||
"yAxisLabelTextOffset": yAxisLabelTextOffset, | ||
"margin": margin | ||
} | ||
}, | ||
"myHeatmapOrdinalY": { | ||
"plugin": "heatMap", | ||
"state": { | ||
"xAxisLabelText": "Petal Length", | ||
"xColumn": "petal_length", | ||
"yAxisLabelText": "Species", | ||
"yColumn": "species", | ||
"colorColumn": "count", | ||
"xAxisLabelTextOffset": xAxisLabelTextOffset, | ||
"yAxisLabelTextOffset": yAxisLabelTextOffset, | ||
"margin": { top: 10, right: 10, bottom: 40, left: 75 } | ||
} | ||
}, | ||
"myLinks": { | ||
@@ -210,2 +285,3 @@ "plugin": "links", | ||
"lineChartDataLoader.dataset -> myLineChart.dataset", | ||
"lineChartDataLoader.dataset -> myScatterPlotTimeX.dataset", | ||
"scatterPlotDataLoader.dataset -> myScatterPlot.dataset", | ||
@@ -216,5 +292,8 @@ "scatterPlotDataLoader.dataset -> myScatterPlotOrdinalX.dataset", | ||
"scatterPlotDataLoader.dataset -> heatmapData.datasetIn", | ||
"scatterPlotDataLoader.dataset -> heatmapOrdinalData.datasetIn", | ||
"barChartDataLoader.dataset -> myBarChart.dataset", | ||
"histogramData.datasetOut -> myHistogram.dataset", | ||
"heatmapData.datasetOut -> myHeatmap.dataset" | ||
"heatmapData.datasetOut -> myHeatmap.dataset", | ||
"heatmapOrdinalData.datasetOut -> myHeatmapOrdinal.dataset", | ||
"heatmapOrdinalData.datasetOut -> myHeatmapOrdinalY.dataset" | ||
] | ||
@@ -221,0 +300,0 @@ } |
52405
1079